修改道址计数问题,新增能谱数据处理
This commit is contained in:
parent
02cb0839b9
commit
9a8a102dcf
|
|
@ -20,7 +20,6 @@
|
|||
#include "DataProcessWorkPool.h"
|
||||
#include "EnergyScaleForm.h"
|
||||
#include "MeasureAnalysisHistoryForm.h"
|
||||
#include "MeasureAnalysisProjectModel.h"
|
||||
#include "NewMeasureAnalysisDlg.h"
|
||||
#include "MeasureAnalysisView.h"
|
||||
#include "MeasureAnalysisTreeView.h"
|
||||
|
|
@ -33,6 +32,8 @@
|
|||
#include <QJsonObject>
|
||||
#include "MeasureClient.h"
|
||||
#include "MeasureAnalysisDataTableView.h"
|
||||
#include "DataCalcProcess/GaussPolyCoe.h"
|
||||
#include "EnergyScaleDataModel.h"
|
||||
#include "csv.h"
|
||||
#include <fstream>
|
||||
|
||||
|
|
@ -388,6 +389,7 @@ void MainWindow::closeProject(const QString& project_name)
|
|||
|
||||
|
||||
|
||||
|
||||
void MainWindow::showEvent(QShowEvent *event)
|
||||
{
|
||||
QMainWindow::showEvent(event);
|
||||
|
|
@ -468,8 +470,8 @@ void MainWindow::on_action_start_measure_triggered()
|
|||
}
|
||||
MeasureAnalysisProjectModel* models = ProjectList::Instance()->GetCurrentProjectModel();
|
||||
QMap<QString, QMap<QString, QStandardItem *> > project_node_items = ProjectList::Instance()->getProjectNodeItems();
|
||||
QMap<QString, QStandardItem *> node = project_node_items[models->GetProjectName()];
|
||||
QStandardItem *nodeItem = node[models->GetProjectName()];
|
||||
nodeMap = project_node_items[models->GetProjectName()];
|
||||
QStandardItem *nodeItem = nodeMap[models->GetProjectName()];
|
||||
ProjectList::Instance()->SetNodeStatus(nodeItem,"测量中",true);
|
||||
|
||||
QString dir = ProjectList::Instance()->GetCurrentProjectModel()->GetProjectDir();
|
||||
|
|
@ -479,7 +481,7 @@ void MainWindow::on_action_start_measure_triggered()
|
|||
QString status = status_ok ? QStringLiteral(u"有效") : QStringLiteral(u"无效");
|
||||
QVariant analys_type = QVariant::fromValue(AnalysisType::ParticleData);
|
||||
QString item_name = QStringLiteral(u"测量粒子数据");
|
||||
QStandardItem * particleData = node[item_name];
|
||||
QStandardItem * particleData = nodeMap[item_name];
|
||||
ProjectList::Instance()->SetNodeStatus(particleData,status,true);
|
||||
//创建通道道址计数文件夹
|
||||
const QString& all_channel_particle_data_filename = models->GetAllChannelParticleDataFilename();
|
||||
|
|
@ -601,7 +603,20 @@ void MainWindow::onRunningInfo(const QString &run_info)
|
|||
void MainWindow::onGvfData(const QByteArray &data)
|
||||
{
|
||||
QList<ParticleData> particles = _gvfToCsv->parseParticleFrames(data);
|
||||
if (particles.isEmpty()) {
|
||||
//处理粒子数据
|
||||
changeParticleData(particles);
|
||||
//处理道址计数
|
||||
changeChannelParticleCount(particles);
|
||||
//处理能谱数据
|
||||
changeParticleEnergyData(particles);
|
||||
//处理能量计数
|
||||
changeEnergyCountData(particles);
|
||||
}
|
||||
|
||||
//处理粒子数据
|
||||
void MainWindow::changeParticleData(QList<ParticleData> &dataList)
|
||||
{
|
||||
if (dataList.isEmpty()) {
|
||||
LOG_INFO(QStringLiteral(u"本次GVF数据未解析到有效粒子,跳过写入CSV"));
|
||||
return;
|
||||
}
|
||||
|
|
@ -625,9 +640,9 @@ void MainWindow::onGvfData(const QByteArray &data)
|
|||
}
|
||||
|
||||
QString csvBuffer;
|
||||
csvBuffer.reserve(particles.size() * 64); // 单条数据约64字节,预分配足够内存
|
||||
csvBuffer.reserve(dataList.size() * 64); // 单条数据约64字节,预分配足够内存
|
||||
|
||||
for (const auto &p : particles) {
|
||||
for (const auto &p : dataList) {
|
||||
csvBuffer += QString("%1,%2,%3,%4\n")
|
||||
.arg(p.boardId)
|
||||
.arg(p.channelId)
|
||||
|
|
@ -638,126 +653,283 @@ void MainWindow::onGvfData(const QByteArray &data)
|
|||
out << csvBuffer;
|
||||
out.flush(); // 确保数据立即写入磁盘,避免程序崩溃丢失数据
|
||||
outFile.close();
|
||||
//处理粒子数据
|
||||
changeUpdata(particles);
|
||||
//处理道址计数
|
||||
changeChannelParticleCount(particles);
|
||||
updataTable();
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::changeUpdata(QList<ParticleData> &data)
|
||||
void MainWindow::updataTable()
|
||||
{
|
||||
QString dir = ProjectList::Instance()->GetCurrentProjectModel()->GetProjectDir();
|
||||
QString csvPath = QStringLiteral(u"%1/%2").arg(dir).arg("粒子数据.csv");
|
||||
auto dockList = _dock_manager->dockWidgetsMap().values();
|
||||
int i = 0;
|
||||
for(auto dock : dockList)
|
||||
{
|
||||
MeasureAnalysisView* view = dynamic_cast<MeasureAnalysisView*>(dock->widget());
|
||||
if(!view) continue;
|
||||
if(view->GetAnalyzeType() == AnalysisType::ParticleData
|
||||
&& view->GetViewType() == MeasureAnalysisView::DataTable)
|
||||
if(view->GetViewType() == MeasureAnalysisView::DataTable)
|
||||
{
|
||||
switch(view->GetAnalyzeType())
|
||||
{
|
||||
case AnalysisType::ParticleData:{
|
||||
MeasureAnalysisDataTableView* table = dynamic_cast<MeasureAnalysisDataTableView*>(view);
|
||||
table->AppendRow();
|
||||
};break;
|
||||
// case AnalysisType::AddressCountData:
|
||||
// {
|
||||
// MeasureAnalysisDataTableView* table = dynamic_cast<MeasureAnalysisDataTableView*>(view);
|
||||
// table->AppendRow();
|
||||
// };break;
|
||||
case AnalysisType::ParticleEnergyData:
|
||||
{
|
||||
MeasureAnalysisDataTableView* table = dynamic_cast<MeasureAnalysisDataTableView*>(view);
|
||||
QString boardId = QString::number(data.at(i).boardId);
|
||||
QString channelId = QString::number(data.at(i).channelId);
|
||||
QString address = QString::number(data.at(i).address);
|
||||
QString timestampCount = QString::number(data.at(i).timestampCount);
|
||||
QStringList dataList;
|
||||
dataList << boardId << channelId << address << timestampCount;
|
||||
|
||||
// dataList << QString("%1,%2,%3,%4").arg(boardId).arg(channelId).arg(address).arg(timestampCount);
|
||||
table->AppendRow(dataList,false);
|
||||
i++;
|
||||
table->AppendRow();
|
||||
};break;
|
||||
case AnalysisType::EnergyCountData:
|
||||
{
|
||||
MeasureAnalysisDataTableView* table = dynamic_cast<MeasureAnalysisDataTableView*>(view);
|
||||
table->AppendRow();
|
||||
};break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::changeChannelParticleCount(QList<ParticleData> &data)
|
||||
{
|
||||
bool ret_ok = true;
|
||||
|
||||
// 通道号 -> 地址 -> 计数
|
||||
for(auto info : data)
|
||||
{
|
||||
// 板卡和通道号计算,通道号 = 板卡号 * 4 + 通道号
|
||||
int channel_num = (info.boardId) * 4 + (info.channelId + 1);
|
||||
// 统计每个通道的粒子计数
|
||||
if (!channel_address_counts.contains(channel_num)) {
|
||||
channel_address_counts[channel_num] = QMap<uint, unsigned long long>();
|
||||
if (data.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
channel_address_counts[channel_num][info.address]++;
|
||||
|
||||
QHash<uint, QHash<uint, unsigned long long>> deltaCounts; // 通道号 -> 道址 -> 增量
|
||||
int totalParticles = 0;
|
||||
|
||||
// 计算本次数据的增量计数
|
||||
for (const auto &info : data) {
|
||||
int channel_num = (info.boardId) * 4 + (info.channelId + 1);
|
||||
deltaCounts[channel_num][info.address]++;
|
||||
totalParticles++;
|
||||
}
|
||||
|
||||
if (deltaCounts.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MeasureAnalysisProjectModel* models = ProjectList::Instance()->GetCurrentProjectModel();
|
||||
if (!models) {
|
||||
LOG_ERROR(QStringLiteral(u"当前没有打开的测量项目,无法写入道址计数数据"));
|
||||
return;
|
||||
}
|
||||
|
||||
const QString& projectName = models->GetProjectName();
|
||||
const QString& every_ch_count_dir = QDir(models->GetProjectDir()).filePath(QStringLiteral(u"通道道址计数"));
|
||||
QDir every_ch_count_output_dir(every_ch_count_dir);
|
||||
|
||||
// 写入每个通道的粒子计数数据(优化:使用一次打开文件,批量写入)
|
||||
QMap<uint, std::shared_ptr<std::ofstream>> channel_file_streams;
|
||||
// 预创建所有通道的文件流
|
||||
for (auto channel_it = channel_address_counts.begin(); channel_it != channel_address_counts.end(); ++channel_it) {
|
||||
uint channel_num = channel_it.key();
|
||||
QString count_data_filename = every_ch_count_output_dir.filePath(QStringLiteral(u"通道%1粒子计数.csv").arg(channel_num));
|
||||
particle_count_filename_list.insert(channel_num, count_data_filename);
|
||||
// 创建文件流
|
||||
std::shared_ptr<std::ofstream> out(new std::ofstream(QStrToSysPath(count_data_filename)));
|
||||
channel_file_streams[channel_num] = out;
|
||||
*out << QString(QStringLiteral(u"道址")).toStdString() << "," << QString(QStringLiteral(u"计数")).toStdString() << std::endl;
|
||||
}
|
||||
// 批量写入数据
|
||||
for (auto channel_it = channel_address_counts.begin(); channel_it != channel_address_counts.end(); ++channel_it) {
|
||||
uint channel_num = channel_it.key();
|
||||
const QMap<uint, unsigned long long>& address_counts = channel_it.value();
|
||||
auto out_stream = channel_file_streams[channel_num];
|
||||
for (auto address_it = address_counts.begin(); address_it != address_counts.end(); ++address_it) {
|
||||
uint address = address_it.key();
|
||||
unsigned long long count = address_it.value();
|
||||
*out_stream << address << "," << count << std::endl;
|
||||
}
|
||||
}
|
||||
channel_file_streams.clear();
|
||||
const QString& project_name = models->GetProjectName();
|
||||
MeasureAnalysisProjectModel* project_model = ProjectList::Instance()->GetProjectModel(project_name);
|
||||
if (project_model == nullptr) {
|
||||
ret_ok = false;
|
||||
} else {
|
||||
// 更新项目模型中的通道粒子计数数据文件名
|
||||
for (auto it = particle_count_filename_list.begin(); it != particle_count_filename_list.end(); ++it) {
|
||||
project_model->SetChannelAddressCountDataFilename(it.key(), it.value());
|
||||
}
|
||||
|
||||
QMap<QString, QMap<QString, QStandardItem *> > project_node_items = ProjectList::Instance()->getProjectNodeItems();
|
||||
QMap<QString, QStandardItem *> node_map = project_node_items[models->GetProjectName()];
|
||||
|
||||
const QString& adrr_count_item_name = QStringLiteral(u"道址计数");
|
||||
const QMap<uint, QString>& filename_list = models->GetChannelAddressCountDataFilenameList();
|
||||
bool status_ok = false;
|
||||
QString status = QStringLiteral(u"无效");
|
||||
if (!filename_list.isEmpty()) {
|
||||
status_ok = true;
|
||||
status = QStringLiteral(u"有效");
|
||||
}
|
||||
|
||||
if (node_map.contains(adrr_count_item_name)) {
|
||||
auto adrr_count_item = node_map[adrr_count_item_name];
|
||||
ProjectList::Instance()->SetNodeStatus(adrr_count_item, status, status_ok);
|
||||
for (auto it = filename_list.begin(); it != filename_list.end(); ++it) {
|
||||
uint ch_num = it.key();
|
||||
QString item_name = QStringLiteral(u"通道%1道址计数").arg(ch_num);
|
||||
if(node_map.contains(item_name))
|
||||
{
|
||||
if (!every_ch_count_output_dir.exists()) {
|
||||
if (!every_ch_count_output_dir.mkpath(every_ch_count_dir)) {
|
||||
LOG_ERROR(QStringLiteral(u"无法创建通道道址计数目录: %1").arg(every_ch_count_dir));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QMutexLocker locker(&m_channelCountMutex);
|
||||
|
||||
bool hasError = false;
|
||||
QHash<uint, QString> newChannelFiles; // 本次新增的通道文件
|
||||
|
||||
// 处理每个通道的计数更新
|
||||
for (auto channelIt = deltaCounts.constBegin(); channelIt != deltaCounts.constEnd(); ++channelIt) {
|
||||
uint channel_num = channelIt.key();
|
||||
const auto& addressDeltas = channelIt.value();
|
||||
|
||||
QString count_data_filename;
|
||||
if (particle_count_filename_list.contains(channel_num)) {
|
||||
count_data_filename = particle_count_filename_list[channel_num];
|
||||
} else {
|
||||
count_data_filename = every_ch_count_output_dir.filePath(QStringLiteral(u"通道%1粒子计数.csv").arg(channel_num));
|
||||
models->SetChannelAddressCountDataFilename(channel_num, count_data_filename);
|
||||
particle_count_filename_list.insert(channel_num, count_data_filename);
|
||||
newChannelFiles.insert(channel_num, count_data_filename);
|
||||
}
|
||||
|
||||
for (auto addressIt = addressDeltas.constBegin(); addressIt != addressDeltas.constEnd(); ++addressIt) {
|
||||
uint address = addressIt.key();
|
||||
unsigned long long delta = addressIt.value();
|
||||
channel_address_counts[channel_num][address] += delta;
|
||||
}
|
||||
|
||||
QFile outFile(count_data_filename);
|
||||
if (!outFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
|
||||
LOG_ERROR(QStringLiteral(u"无法打开通道%1的计数文件: %2,错误: %3")
|
||||
.arg(channel_num)
|
||||
.arg(count_data_filename)
|
||||
.arg(outFile.errorString()));
|
||||
hasError = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
QTextStream out(&outFile);
|
||||
out.setCodec("UTF-8");
|
||||
|
||||
// 写入表头
|
||||
out << QStringLiteral(u"道址,计数\n");
|
||||
|
||||
// 写入所有道址的最新总计数(按道址排序)
|
||||
QString csvBuffer;
|
||||
csvBuffer.reserve(channel_address_counts[channel_num].size() * 32); // 预分配内存
|
||||
|
||||
// 获取排序后的道址列表
|
||||
QList<uint> sortedAddresses = channel_address_counts[channel_num].keys();
|
||||
std::sort(sortedAddresses.begin(), sortedAddresses.end());
|
||||
|
||||
for (uint address : sortedAddresses) {
|
||||
unsigned long long total = channel_address_counts[channel_num][address];
|
||||
csvBuffer += QString("%1,%2\n").arg(address).arg(total);
|
||||
}
|
||||
|
||||
out << csvBuffer;
|
||||
out.flush(); // 确保数据立即写入磁盘
|
||||
outFile.close();
|
||||
}
|
||||
|
||||
// 更新项目树节点状态
|
||||
if (!newChannelFiles.isEmpty() || !hasError) {
|
||||
for (auto it = newChannelFiles.constBegin(); it != newChannelFiles.constEnd(); ++it) {
|
||||
models->SetChannelAddressCountDataFilename(it.key(), it.value());
|
||||
}
|
||||
|
||||
const QString& adrr_count_item_name = QStringLiteral(u"道址计数");
|
||||
if (nodeMap.contains(adrr_count_item_name)) {
|
||||
auto adrr_count_item = nodeMap[adrr_count_item_name];
|
||||
bool status_ok = !particle_count_filename_list.isEmpty();
|
||||
QString status = status_ok ? QStringLiteral(u"有效") : QStringLiteral(u"无效");
|
||||
ProjectList::Instance()->SetNodeStatus(adrr_count_item, status, status_ok);
|
||||
|
||||
for (auto it = newChannelFiles.constBegin(); it != newChannelFiles.constEnd(); ++it) {
|
||||
uint ch_num = it.key();
|
||||
QString item_name = QStringLiteral(u"通道%1道址计数").arg(ch_num);
|
||||
if (nodeMap.contains(item_name)) {
|
||||
continue; // 节点已存在,跳过
|
||||
}
|
||||
models->SaveProjectModel();
|
||||
const QVariant& analys_type = QVariant::fromValue(AnalysisType::AddressCountData);
|
||||
QStandardItem* node_item = ProjectList::Instance()->AddChildNode(adrr_count_item, item_name, status, analys_type, true, status_ok);
|
||||
node_item->setData(project_name, Qt::UserRole + 2);
|
||||
QStandardItem* node_item = ProjectList::Instance()->AddChildNode(
|
||||
adrr_count_item, item_name, status, analys_type, true, status_ok);
|
||||
node_item->setData(projectName, Qt::UserRole + 2);
|
||||
node_item->setData(ch_num, Qt::UserRole + 3);
|
||||
node_map[item_name] = node_item;
|
||||
nodeMap[item_name] = node_item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// updataTable();
|
||||
|
||||
if (hasError) {
|
||||
LOG_WARN(QStringLiteral(u"部分通道的道址计数数据写入失败,请检查磁盘空间和文件权限"));
|
||||
}
|
||||
}
|
||||
|
||||
//处理粒子能量数据
|
||||
void MainWindow::changeParticleEnergyData(QList<ParticleData> &dataList)
|
||||
{
|
||||
if (dataList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MeasureAnalysisProjectModel* project_model = ProjectList::Instance()->GetCurrentProjectModel();
|
||||
if (!project_model) {
|
||||
LOG_ERROR(QStringLiteral(u"当前没有打开的测量项目,无法处理能谱数据"));
|
||||
return;
|
||||
}
|
||||
|
||||
const QString& project_name = project_model->GetProjectName();
|
||||
|
||||
EnergyScaleDataModel energy_scale_data_model(project_model->GetEnergyScaleFilename());
|
||||
if (!energy_scale_data_model.LoadData()) {
|
||||
LOG_WARN(QStringLiteral(u"[%1]加载能量刻度文件失败,跳过本次能谱处理").arg(project_name));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!energy_scale_data_model.IsValid()) {
|
||||
LOG_WARN(QStringLiteral(u"[%1]能量刻度数据无效,请检查刻度配置").arg(project_name));
|
||||
return;
|
||||
}
|
||||
|
||||
QMutexLocker locker(&m_energyDataMutex);
|
||||
|
||||
QString energy_spectrum_filename = QDir(project_model->GetProjectDir()).filePath(QStringLiteral(u"能谱数据.csv"));
|
||||
|
||||
QFile outFile(energy_spectrum_filename);
|
||||
if (!outFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append)) {
|
||||
LOG_ERROR(QStringLiteral(u"[%1]无法打开能谱文件: %2,错误: %3")
|
||||
.arg(project_name)
|
||||
.arg(energy_spectrum_filename)
|
||||
.arg(outFile.errorString()));
|
||||
return;
|
||||
}
|
||||
|
||||
QTextStream out(&outFile);
|
||||
out.setCodec("UTF-8");
|
||||
|
||||
if ( outFile.size() == 0) {
|
||||
out << QStringLiteral(u"板卡号,通道号,道址,能量(KeV),时间计数\n");
|
||||
LOG_DEBUG(QStringLiteral(u"[%1]能谱文件为空,已写入标准表头").arg(project_name));
|
||||
}
|
||||
|
||||
QString csvBuffer;
|
||||
csvBuffer.reserve(dataList.size() * 80); // 单条数据约80字节,预分配足够内存
|
||||
|
||||
int totalProcessed = dataList.size();
|
||||
int successCount = 0;
|
||||
int skipCount = 0;
|
||||
|
||||
for (const auto& particle : dataList) {
|
||||
int channel_num = (particle.boardId) * 4 + (particle.channelId + 1);
|
||||
const QString& channel_name = QStringLiteral(u"通道%1").arg(channel_num);
|
||||
|
||||
std::vector<double> coeffs = energy_scale_data_model.GetEnergyFitResultCoeffs(channel_name);
|
||||
if (coeffs.empty()) {
|
||||
skipCount++;
|
||||
continue; // 该通道未配置能量刻度,跳过
|
||||
}
|
||||
|
||||
double energy = GaussPolyCoe::Predict(coeffs, particle.address);
|
||||
|
||||
csvBuffer += QString("%1,%2,%3,%4,%5\n")
|
||||
.arg(particle.boardId)
|
||||
.arg(particle.channelId)
|
||||
.arg(particle.address)
|
||||
.arg(energy, 0, 'f', 4)
|
||||
.arg(particle.timestampCount);
|
||||
|
||||
successCount++;
|
||||
}
|
||||
|
||||
if (!csvBuffer.isEmpty()) {
|
||||
out << csvBuffer;
|
||||
out.flush(); // 强制写入磁盘,防止程序崩溃丢失数据
|
||||
}
|
||||
|
||||
outFile.close();
|
||||
|
||||
if (successCount > 0) {
|
||||
project_model->SetParticleEnergyDataFilename(energy_spectrum_filename);
|
||||
|
||||
if (!project_model->SaveProjectModel()) {
|
||||
LOG_WARN(QStringLiteral(u"[%1]保存项目模型失败,能谱文件路径未持久化").arg(project_name));
|
||||
}
|
||||
|
||||
const QString& energy_node_name = QStringLiteral(u"粒子能量数据");
|
||||
QMap<QString, QMap<QString, QStandardItem *>> all_nodes = ProjectList::Instance()->getProjectNodeItems();
|
||||
QMap<QString, QStandardItem *> project_nodes = all_nodes[project_name];
|
||||
|
||||
if (project_nodes.contains(energy_node_name)) {
|
||||
QStandardItem* energy_node = project_nodes[energy_node_name];
|
||||
ProjectList::Instance()->SetNodeStatus(energy_node, QStringLiteral(u"有效"), true);
|
||||
}
|
||||
}
|
||||
updataTable();
|
||||
}
|
||||
//处理能量计数
|
||||
void MainWindow::changeEnergyCountData(QList<ParticleData> &dataList)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <QMainWindow>
|
||||
#include <QMutex>
|
||||
#include "GvfToCsv/GvfToCsv.h"
|
||||
#include "MeasureAnalysisProjectModel.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui {
|
||||
|
|
@ -52,10 +53,19 @@ private:
|
|||
void initStatusBar();
|
||||
void applyStyleSheet();
|
||||
void closeProject(const QString &project_name);
|
||||
|
||||
//更新表格
|
||||
void updataTable();
|
||||
|
||||
//处理粒子数据
|
||||
void changeUpdata(QList<ParticleData> &data);
|
||||
void changeParticleData(QList<ParticleData> &dataList);
|
||||
//处理道址计数
|
||||
void changeChannelParticleCount(QList<ParticleData> &data);
|
||||
//处理粒子能量数据
|
||||
void changeParticleEnergyData(QList<ParticleData> &dataList);
|
||||
//处理能量计数
|
||||
void changeEnergyCountData(QList<ParticleData> &dataList);
|
||||
|
||||
signals:
|
||||
void newProject(const QString &project_name);
|
||||
|
||||
|
|
@ -107,8 +117,16 @@ private:
|
|||
|
||||
QMap<uint, QMap<uint, unsigned long long>> channel_address_counts; // 通道号 -> 地址 -> 计数
|
||||
QMap<uint, QString> particle_count_filename_list;
|
||||
//2026-06-11
|
||||
QMap<QString, QStandardItem *> nodeMap;
|
||||
QMutex m_channelCountMutex;//
|
||||
QMutex m_energyDataMutex;//能量谱锁
|
||||
|
||||
|
||||
|
||||
//能量计数
|
||||
QHash<uint, QString> m_channelEnergyCountFiles; // 通道号 -> 能量计数文件路径
|
||||
QHash<uint, QMap<double, unsigned long long>> m_channelEnergyStats; // 通道号 -> 能量bin -> 计数
|
||||
QMap<double, unsigned long long> m_allChannelEnergyStats; // 全通道能量bin -> 计数
|
||||
QMutex m_energyCountMutex; // 保护能量计数数据的互斥锁
|
||||
QHash<QString, std::vector<double>> m_energyScaleCoeffCache;// 能量刻度系数缓存
|
||||
};
|
||||
#endif // MAINWINDOW_H
|
||||
|
|
|
|||
|
|
@ -95,64 +95,21 @@ void MeasureAnalysisDataTableView::RefreshTableData(const QString &csvFilePath)
|
|||
_tableView->setBufferSize(_buffer_size);
|
||||
}
|
||||
|
||||
void MeasureAnalysisDataTableView::AppendRow(const QVariantList &rowData, bool writeToFile)
|
||||
void MeasureAnalysisDataTableView::AppendRow(/*const QVariantList &rowData, bool writeToFile*/)
|
||||
{
|
||||
// 1. 前置校验
|
||||
if (!_tableModel || !_tableModel->dataSource()) {
|
||||
LOG_WARN(QStringLiteral(u"追加行失败:表格模型或数据源未初始化"));
|
||||
return;
|
||||
}
|
||||
|
||||
auto dataSource = std::dynamic_pointer_cast<CsvDataSource>(_tableModel->dataSource());
|
||||
if (!dataSource || !dataSource->isValid()) {
|
||||
LOG_WARN(QStringLiteral(u"追加行失败:CSV数据源无效"));
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 列数匹配
|
||||
const int expectedColumns = _tableModel->columnCount();
|
||||
if (rowData.size() != expectedColumns) {
|
||||
LOG_WARN(QStringLiteral(u"追加行失败:列数不匹配,期望%1列,实际%2列")
|
||||
.arg(expectedColumns).arg(rowData.size()));
|
||||
return;
|
||||
}
|
||||
//需要写入文件的
|
||||
if (writeToFile) {
|
||||
QFile file(dataSource->filePath());
|
||||
QTextStream out(&file);
|
||||
out.setCodec("UTF-8"); // 与读取时的 QString::fromUtf8 保持一致
|
||||
|
||||
QStringList escapedFields;
|
||||
for (const QVariant& field : rowData) {
|
||||
escapedFields.append(escapeCsvField(field.toString()));
|
||||
}
|
||||
|
||||
out << escapedFields.join(',') << "\n";
|
||||
file.close();
|
||||
LOG_DEBUG(QStringLiteral(u"已成功将新行写入CSV文件:%1").arg(dataSource->filePath()));
|
||||
RefreshTableData(dataSource->filePath());
|
||||
return;
|
||||
}
|
||||
|
||||
QFile file(dataSource->filePath());
|
||||
if (!file.open(QIODevice::Append | QIODevice::Text)) {
|
||||
LOG_ERROR(QStringLiteral(u"追加行失败:无法打开文件 %1,错误:%2")
|
||||
.arg(file.fileName()).arg(file.errorString()));
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. 重新加载整个表格,确保模型与文件同步
|
||||
RefreshTableData(dataSource->filePath());
|
||||
|
||||
// 5. 自动滚动到底部
|
||||
_tableView->scrollToBottom();
|
||||
}
|
||||
|
||||
void MeasureAnalysisDataTableView::AppendRow(const QStringList &rowData, bool writeToFile)
|
||||
{
|
||||
QVariantList varList;
|
||||
for (const QString& field : rowData) {
|
||||
varList.append(QVariant(field));
|
||||
}
|
||||
AppendRow(varList, writeToFile);
|
||||
}
|
||||
// void MeasureAnalysisDataTableView::AppendRow(/*const QStringList &rowData, bool writeToFile*/)
|
||||
// {
|
||||
// // QVariantList varList;
|
||||
// // for (const QString& field : rowData) {
|
||||
// // varList.append(QVariant(field));
|
||||
// // }
|
||||
// AppendRow(varList, writeToFile);
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ public:
|
|||
|
||||
|
||||
// 2026-06-10 表尾插入数据函数(支持两种参数类型,默认同时写入CSV文件)
|
||||
void AppendRow(const QVariantList& rowData, bool writeToFile = true);
|
||||
void AppendRow(const QStringList& rowData, bool writeToFile = true);
|
||||
void AppendRow(/*const QVariantList& rowData, bool writeToFile = true*/);
|
||||
// void AppendRow(const QStringList& rowData, bool writeToFile = true);
|
||||
private:
|
||||
// 私有成员变量
|
||||
VirtualTableView *_tableView;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user