rename CanvasClass to SingleSPectra, OnlineAnalyzer to Analyser, add historgam settings in SingleSpectra class

This commit is contained in:
splitPoleDAQ 2023-06-02 15:41:26 -04:00
parent d241fec8b5
commit b39a1eff4a
9 changed files with 241 additions and 81 deletions

View File

@ -1,9 +1,9 @@
#include "OnlineAnalyser.h"
#include "Analyser.h"
#include <QRandomGenerator>
#include <random>
OnlineAnalyzer::OnlineAnalyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent ): QMainWindow(parent){
Analyzer::Analyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent ): QMainWindow(parent){
this->digi = digi;
this->nDigi = nDigi;
@ -13,7 +13,7 @@ OnlineAnalyzer::OnlineAnalyzer(Digitizer ** digi, unsigned int nDigi, QMainWindo
buildTimerThread = new TimingThread(this);
buildTimerThread->SetWaitTimeinSec(1.0); //^Set event build interval
connect( buildTimerThread, &TimingThread::timeUp, this, &OnlineAnalyzer::UpdateHistograms);
connect( buildTimerThread, &TimingThread::timeUp, this, &Analyzer::UpdateHistograms);
setWindowTitle("Online Analyzer");
setGeometry(0, 0, 1000, 800);
@ -30,18 +30,18 @@ OnlineAnalyzer::OnlineAnalyzer(Digitizer ** digi, unsigned int nDigi, QMainWindo
}
OnlineAnalyzer::~OnlineAnalyzer(){
Analyzer::~Analyzer(){
for( unsigned int i = 0; i < nDigi; i++ ) delete oeb[i];
delete [] oeb;
}
void OnlineAnalyzer::StartThread(){
void Analyzer::StartThread(){
buildTimerThread->start();
}
void OnlineAnalyzer::StopThread(){
void Analyzer::StopThread(){
buildTimerThread->Stop();
buildTimerThread->quit();
@ -49,7 +49,7 @@ void OnlineAnalyzer::StopThread(){
}
void OnlineAnalyzer::SetUpCanvas(){
void Analyzer::SetUpCanvas(){
h2 = new Histogram2D("testing", "x", "y", 400, 0, 4000, 400, 0, 4000, this);
layout->addWidget(h2);
@ -65,7 +65,7 @@ void OnlineAnalyzer::SetUpCanvas(){
std::mt19937 gen(rd());
std::normal_distribution<double> distribution(2000.0, 1000);
for( int i = 0; i < 1000 ; i++ ){
//h2->Fill(distribution(gen), distribution(gen));
h2->Fill(distribution(gen), distribution(gen));
h1->Fill(distribution(gen));
}
@ -73,7 +73,7 @@ void OnlineAnalyzer::SetUpCanvas(){
}
void OnlineAnalyzer::UpdateHistograms(){
void Analyzer::UpdateHistograms(){
//Set with digitizer to be event build
digiMTX[0].lock();

View File

@ -1,5 +1,5 @@
#ifndef ONLINE_ANALYZER_H
#define ONLINE_ANALYZER_H
#ifndef ANALYZER_H
#define ANALYZER_H
#include <QMainWindow>
#include <QChart>
@ -32,12 +32,12 @@ derivative class should define the SetUpCanvas() and UpdateHistogram();
//^==============================================
//^==============================================
class OnlineAnalyzer : public QMainWindow{
class Analyzer : public QMainWindow{
Q_OBJECT
public:
OnlineAnalyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent = nullptr);
virtual ~OnlineAnalyzer();
Analyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent = nullptr);
virtual ~Analyzer();
virtual void SetUpCanvas();

View File

@ -13,6 +13,10 @@ public:
xAxis->setLabel(xLabel);
legend->setVisible(true);
QPen borderPen = legend->borderPen();
borderPen.setWidth(0);
borderPen.setColor(Qt::transparent);
legend->setBorderPen(borderPen);
legend->setFont(QFont("Helvetica", 9));
addGraph();
@ -31,12 +35,37 @@ public:
graph(0)->setData(xList, yList);
//setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);
setInteractions( QCP::iRangeDrag | QCP::iRangeZoom );
//setInteractions( QCP::iRangeDrag | QCP::iRangeZoom );
//setSelectionRectMode(QCP::SelectionRectMode::srmZoom);
rescaleAxes();
yAxis->setRangeLower(0);
yAxis->setRangeUpper(10);
txtTotEntry = new QCPItemText(this);
txtTotEntry->setPositionAlignment(Qt::AlignLeft);
txtTotEntry->position->setType(QCPItemPosition::ptAxisRectRatio);
txtTotEntry->position->setCoords(0.1, 0.1);;
txtTotEntry->setText("Total Entry : 0");
txtTotEntry->setFont(QFont("Helvetica", 9));
txtUnderFlow = new QCPItemText(this);
txtUnderFlow->setPositionAlignment(Qt::AlignLeft);
txtUnderFlow->position->setType(QCPItemPosition::ptAxisRectRatio);
txtUnderFlow->position->setCoords(0.1, 0.15);;
txtUnderFlow->setText("Under Flow : 0");
txtUnderFlow->setFont(QFont("Helvetica", 9));
txtOverFlow = new QCPItemText(this);
txtOverFlow->setPositionAlignment(Qt::AlignLeft);
txtOverFlow->position->setType(QCPItemPosition::ptAxisRectRatio);
txtOverFlow->position->setCoords(0.1, 0.2);;
txtOverFlow->setText("Over Flow : 0");
txtOverFlow->setFont(QFont("Helvetica", 9));
usingMenu = false;
connect(this, &QCustomPlot::mouseMove, this, [=](QMouseEvent *event){
double x = this->xAxis->pixelToCoord(event->pos().x());
double bin = (x - xMin)/dX;
@ -47,7 +76,12 @@ public:
});
connect(this, &QCustomPlot::mousePress, this, [=](QMouseEvent * event){
if (event->button() == Qt::LeftButton && !usingMenu){
setSelectionRectMode(QCP::SelectionRectMode::srmZoom);
}
if (event->button() == Qt::RightButton) {
usingMenu = true;
setSelectionRectMode(QCP::SelectionRectMode::srmNone);
QMenu *menu = new QMenu(this);
menu->setAttribute(Qt::WA_DeleteOnClose);
@ -61,6 +95,7 @@ public:
yAxis->setRangeLower(0);
yAxis->setRangeUpper(yMax * 1.2 > 10 ? yMax * 1.2 : 10);
replot();
usingMenu = false;
}
}
});
@ -113,8 +148,18 @@ public:
void Fill(double value){
totalEntry ++;
if( value < xMin ) underFlow ++;
if( value > xMax ) overFlow ++;
txtTotEntry->setText("Total Entry : "+ QString::number(totalEntry));
if( value < xMin ) {
underFlow ++;
txtUnderFlow->setText("Under Flow : "+ QString::number(underFlow));
return;
}
if( value > xMax ) {
overFlow ++;
txtOverFlow->setText("Over Flow : "+ QString::number(overFlow));
return;
}
double bin = (value - xMin)/dX;
int index1 = 2*qFloor(bin) + 1;
@ -144,6 +189,12 @@ private:
QVector<double> xList, yList;
QCPItemText * txtTotEntry;
QCPItemText * txtUnderFlow;
QCPItemText * txtOverFlow;
bool usingMenu;
};
//^==============================================
@ -184,6 +235,8 @@ public:
rescaleAxes();
usingMenu = false;
connect(this, &QCustomPlot::mouseMove, this, [=](QMouseEvent *event){
double x = xAxis->pixelToCoord(event->pos().x());
double y = yAxis->pixelToCoord(event->pos().y());
@ -195,9 +248,14 @@ public:
QToolTip::showText(event->globalPosition().toPoint(), coordinates, this);
});
connect(this, &QCustomPlot::mousePress, this, [=](QMouseEvent * event){
if (event->button() == Qt::LeftButton && !usingMenu){
setSelectionRectMode(QCP::SelectionRectMode::srmZoom);
}
if (event->button() == Qt::RightButton) {
usingMenu = true;
setSelectionRectMode(QCP::SelectionRectMode::srmNone);
QMenu *menu = new QMenu(this);
menu->setAttribute(Qt::WA_DeleteOnClose);
@ -211,6 +269,7 @@ public:
yAxis->setRangeLower(yMin);
yAxis->setRangeUpper(yMax);
replot();
usingMenu = false;
}
}
});
@ -218,17 +277,8 @@ public:
}
void UpdatePlot(){
// rescale the data dimension (color) such that all data points lie in the span visualized by the color gradient:
colorMap->rescaleDataRange();
// make sure the axis rect and color scale synchronize their bottom and top margins (so they line up):
// QCPMarginGroup *marginGroup = new QCPMarginGroup(this);
// this->axisRect()->setMarginGroup(QCP::msBottom|QCP::msTop, marginGroup);
// colorScale->setMarginGroup(QCP::msBottom|QCP::msTop, marginGroup);
// rescale the key (x) and value (y) axes so the whole color map is visible:
rescaleAxes();
replot();
}
@ -248,6 +298,8 @@ private:
QCPColorMap * colorMap;
QCPColorScale *colorScale;
bool usingMenu;
};
#endif

View File

@ -520,15 +520,15 @@ void MainWindow::OpenDigitizers(){
}
}else{
LogMsg("Found <b>" + fileName + "</b> for digitizer settings.");
// LogMsg("Found <b>" + fileName + "</b> for digitizer settings.");
if( digi[i]->LoadSettingBinaryToMemory(fileName.toStdString().c_str()) == 0 ){
LogMsg("Loaded settings file <b>" + fileName + "</b> for Digi-" + QString::number(digi[i]->GetSerialNumber()));
digi[i]->ProgramSettingsToBoard();
// if( digi[i]->LoadSettingBinaryToMemory(fileName.toStdString().c_str()) == 0 ){
// LogMsg("Loaded settings file <b>" + fileName + "</b> for Digi-" + QString::number(digi[i]->GetSerialNumber()));
// digi[i]->ProgramSettingsToBoard();
}else{
LogMsg("Fail to Loaded settings file " + fileName + " for Digi-" + QString::number(digi[i]->GetSerialNumber()));
}
// }else{
// LogMsg("Fail to Loaded settings file " + fileName + " for Digi-" + QString::number(digi[i]->GetSerialNumber()));
// }
}
digi[i]->ReadAllSettingsFromBoard(true);
@ -538,12 +538,12 @@ void MainWindow::OpenDigitizers(){
QCoreApplication::processEvents(); //to prevent Qt said application not responding.
}
canvas = new Canvas(digi, nDigi);
canvas = new SingleSpectra(digi, nDigi, rawDataPath);
histThread = new TimingThread(this);
histThread->SetWaitTimeinSec(0.5);
connect(histThread, &TimingThread::timeUp, this, [=](){
if( canvas == nullptr ) return;
canvas->UpdateCanvas();
if( canvas == nullptr && !canvas->IsFillHistograms()) return;
canvas->FillHistograms();
});
LogMsg(QString("Done. Opened %1 digitizer(s).").arg(nDigi));
@ -1060,7 +1060,7 @@ void MainWindow::OpenScope(){
}
if( canvas ){
if( onOff ) {
if( onOff) {
histThread->start();
}else{
if( histThread->isRunning()){
@ -1110,7 +1110,7 @@ void MainWindow::OpenDigiSettings(){
void MainWindow::OpenCanvas(){
if( canvas == nullptr ) {
canvas = new Canvas(digi, nDigi);
canvas = new SingleSpectra(digi, nDigi, rawDataPath);
canvas->show();
}else{
canvas->show();
@ -1123,7 +1123,7 @@ void MainWindow::OpenCanvas(){
void MainWindow::OpenAnalyzer(){
if( onlineAnalyzer == nullptr ) {
onlineAnalyzer = new OnlineAnalyzer(digi, nDigi);
onlineAnalyzer = new Analyzer(digi, nDigi);
onlineAnalyzer->show();
}else{
onlineAnalyzer->show();

View File

@ -16,9 +16,9 @@
#include "CustomWidgets.h"
#include "Scope.h"
#include "DigiSettingsPanel.h"
#include "CanvasClass.h"
#include "SingleSpectra.h"
#include "influxdb.h"
#include "OnlineAnalyser.h"
#include "Analyser.h"
//^#===================================================== MainWindow
class MainWindow : public QMainWindow{
@ -150,12 +150,12 @@ private:
//@----- DigiSettings
DigiSettingsPanel * digiSettings;
//@----- Canvas
Canvas * canvas;
//@----- SingleSpectra
SingleSpectra * canvas;
TimingThread * histThread;
//@----- Analyzer
OnlineAnalyzer * onlineAnalyzer;
Analyzer * onlineAnalyzer;
};

View File

@ -33,9 +33,9 @@ HEADERS += ClassData.h \
RegisterAddress.h \
influxdb.h\
Scope.h \
CanvasClass.h \
SingleSpectra.h \
OnlineEventBuilder.h \
OnlineAnalyser.h \
Analyser.h \
qcustomplot.h
SOURCES += ClassDigitizer.cpp \
DigiSettingsPanel.cpp \
@ -43,7 +43,7 @@ SOURCES += ClassDigitizer.cpp \
main.cpp \
influxdb.cpp\
Scope.cpp \
CanvasClass.cpp \
SingleSpectra.cpp \
OnlineEventBuilder.cpp \
OnlineAnalyser.cpp \
Analyser.cpp \
qcustomplot.cpp

View File

@ -6,6 +6,8 @@ It has scope (updated every half-sec), allow full control of the digitizer (exce
It can be connected to InfluxDB v1.8 and Elog.
Each channel has it own 1D histogram. It will not be filled by default, but can enable it in the "Online 1D histgram" panel.
# Operation
When programSettings.txt is presented in the same folder as the FSUDAQ_Qt, the program will load it can config the following

View File

@ -1,4 +1,4 @@
#include "CanvasClass.h"
#include "SingleSpectra.h"
#include <QValueAxis>
#include <QRandomGenerator>
@ -7,14 +7,15 @@
#include <QLabel>
#include <QRandomGenerator>
Canvas::Canvas(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent) : QMainWindow(parent){
SingleSpectra::SingleSpectra(Digitizer ** digi, unsigned int nDigi, QString rawDataPath, QMainWindow * parent) : QMainWindow(parent){
this->digi = digi;
this->nDigi = nDigi;
this->rawDataPath = rawDataPath;
enableSignalSlot = false;
setWindowTitle("Canvas");
setWindowTitle("1-D Histograms");
setGeometry(0, 0, 1000, 800);
//setWindowFlags( this->windowFlags() & ~Qt::WindowCloseButtonHint );
@ -32,12 +33,12 @@ Canvas::Canvas(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent) : QM
cbDigi = new RComboBox(this);
for( unsigned int i = 0; i < nDigi; i++) cbDigi->addItem("Digi-" + QString::number( digi[i]->GetSerialNumber() ), i);
ctrlLayout->addWidget(cbDigi, 0, 0, 1, 2);
connect( cbDigi, &RComboBox::currentIndexChanged, this, &Canvas::ChangeHistView);
connect( cbDigi, &RComboBox::currentIndexChanged, this, &SingleSpectra::ChangeHistView);
cbCh = new RComboBox(this);
for( int i = 0; i < MaxNChannels; i++) cbCh->addItem("ch-" + QString::number( i ), i);
ctrlLayout->addWidget(cbCh, 0, 2, 1, 2);
connect( cbCh, &RComboBox::currentIndexChanged, this, &Canvas::ChangeHistView);
connect( cbCh, &RComboBox::currentIndexChanged, this, &SingleSpectra::ChangeHistView);
QPushButton * bnClearHist = new QPushButton("Clear Hist.", this);
ctrlLayout->addWidget(bnClearHist, 0, 4, 1, 2);
@ -49,6 +50,12 @@ Canvas::Canvas(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent) : QM
}
});
QCheckBox * chkIsFillHistogram = new QCheckBox("Fill Histograms", this);
ctrlLayout->addWidget(chkIsFillHistogram, 0, 6);
connect(chkIsFillHistogram, &QCheckBox::stateChanged, this, [=](int state){ fillHistograms = state;});
chkIsFillHistogram->setChecked(false);
fillHistograms = false;
QLabel * lbNBin = new QLabel("#Bin:", this);
lbNBin->setAlignment(Qt::AlignRight | Qt::AlignCenter );
ctrlLayout->addWidget(lbNBin, 1, 0);
@ -82,29 +89,20 @@ Canvas::Canvas(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent) : QM
sbXMax->setMinimum(-0x3FFF);
sbXMax->setMaximum(0x3FFF);
ctrlLayout->addWidget(sbXMax, 1, 5);
connect(sbXMin, &RSpinBox::valueChanged, this, [=](){
connect(sbXMax, &RSpinBox::valueChanged, this, [=](){
if( !enableSignalSlot ) return;
sbXMin->setStyleSheet("color : blue;");
sbXMax->setStyleSheet("color : blue;");
bnReBin->setEnabled(true);
});
connect(sbNBin, &RSpinBox::returnPressed, this, &SingleSpectra::RebinHistogram);
connect(sbXMin, &RSpinBox::returnPressed, this, &SingleSpectra::RebinHistogram);
connect(sbXMax, &RSpinBox::returnPressed, this, &SingleSpectra::RebinHistogram);
bnReBin = new QPushButton("Rebin and Clear Histogram", this);
ctrlLayout->addWidget(bnReBin, 1, 6);
bnReBin->setEnabled(false);
connect(bnReBin, &QPushButton::clicked, this, [=](){
if( !enableSignalSlot ) return;
int bd = cbDigi->currentIndex();
int ch = cbCh->currentIndex();
hist[bd][ch]->Rebin( sbNBin->value(), sbXMin->value(), sbXMax->value());
sbNBin->setStyleSheet("");
sbXMin->setStyleSheet("");
sbXMax->setStyleSheet("");
bnReBin->setEnabled(false);
hist[bd][ch]->UpdatePlot();
});
connect(bnReBin, &QPushButton::clicked, this, &SingleSpectra::RebinHistogram);
}
@ -114,9 +112,9 @@ Canvas::Canvas(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent) : QM
histLayout = new QGridLayout(histBox);
histBox->setLayout(histLayout);
double xMax = 4000;
double xMax = 5000;
double xMin = 0;
double nBin = 100;
double nBin = 200;
for( unsigned int i = 0; i < MaxNDigitizer; i++){
if( i >= nDigi ) continue;
@ -129,6 +127,8 @@ Canvas::Canvas(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent) : QM
}
}
LoadSetting();
histLayout->addWidget(hist[0][0], 0, 0);
sbNBin->setValue(nBin);
@ -153,7 +153,10 @@ Canvas::Canvas(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent) : QM
}
Canvas::~Canvas(){
SingleSpectra::~SingleSpectra(){
SaveSetting();
for( unsigned int i = 0; i < nDigi; i++ ){
for( int ch = 0; ch < digi[i]->GetNChannels(); ch++){
delete hist[i][ch];
@ -161,7 +164,7 @@ Canvas::~Canvas(){
}
}
void Canvas::ChangeHistView(){
void SingleSpectra::ChangeHistView(){
if( oldCh >= 0 ) {
histLayout->removeWidget(hist[oldBd][oldCh]);
@ -188,7 +191,8 @@ void Canvas::ChangeHistView(){
oldCh = ch;
}
void Canvas::UpdateCanvas(){
void SingleSpectra::FillHistograms(){
if( !fillHistograms ) return;
for( int i = 0; i < nDigi; i++){
@ -219,3 +223,94 @@ void Canvas::UpdateCanvas(){
}
}
void SingleSpectra::RebinHistogram(){
if( !enableSignalSlot ) return;
int bd = cbDigi->currentIndex();
int ch = cbCh->currentIndex();
hist[bd][ch]->Rebin( sbNBin->value(), sbXMin->value(), sbXMax->value());
sbNBin->setStyleSheet("");
sbXMin->setStyleSheet("");
sbXMax->setStyleSheet("");
bnReBin->setEnabled(false);
hist[bd][ch]->UpdatePlot();
}
void SingleSpectra::SaveSetting(){
QFile file(rawDataPath + "/singleSpectraSetting.txt");
file.open(QIODevice::Text | QIODevice::WriteOnly);
for( unsigned int i = 0; i < nDigi; i++){
file.write(("======= " + QString::number(digi[i]->GetSerialNumber()) + "\n").toStdString().c_str());
for( int ch = 0; ch < digi[i]->GetNChannels() ; ch++){
QString a = QString::number(ch).rightJustified(2, ' ');
QString b = QString::number(hist[i][ch]->GetNBin()).rightJustified(6, ' ');
QString c = QString::number(hist[i][ch]->GetXMin()).rightJustified(6, ' ');
QString d = QString::number(hist[i][ch]->GetXMax()).rightJustified(6, ' ');
file.write( QString("%1 %2 %3 %4\n").arg(a).arg(b).arg(c).arg(d).toStdString().c_str() );
}
}
file.write("//========== End of file\n");
file.close();
}
void SingleSpectra::LoadSetting(){
QFile file(rawDataPath + "/singleSpectraSetting.txt");
if( file.open(QIODevice::Text | QIODevice::ReadOnly) ){
QTextStream in(&file);
QString line = in.readLine();
int digiSN = 0;
int digiID = -1;
while ( !line.isNull() ){
if( line.contains("//========== ") ) break;
if( line.contains("//") ) continue;
if( line.contains("======= ") ){
digiSN = line.mid(7).toInt();
digiID = -1;
for( unsigned int i = 0; i < nDigi; i++){
if( digiSN == digi[i]->GetSerialNumber() ) {
digiID = i;
break;
}
}
line = in.readLine();
continue;
}
if( digiID >= 0 ){
QStringList list = line.split(QRegularExpression("\\s+"));
list.removeAll("");
if( list.count() != 4 ) {
line = in.readLine();
continue;
}
QVector<int> data;
for( int i = 0; i < list.count(); i++){
data.push_back(list[i].toInt());
}
hist[digiID][data[0]]->Rebin(data[1], data[2], data[3]);
}
line = in.readLine();
}
}else{
}
}

View File

@ -1,5 +1,5 @@
#ifndef CANVAS_H
#define CANVAS_H
#ifndef SINGLE_SPECTR_H
#define SINGLE_SPECTR_H
#include <QMainWindow>
#include <QChart>
@ -20,16 +20,23 @@
//^====================================================
//^====================================================
class Canvas : public QMainWindow{
class SingleSpectra : public QMainWindow{
Q_OBJECT
public:
Canvas(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent = nullptr);
~Canvas();
SingleSpectra(Digitizer ** digi, unsigned int nDigi, QString rawDataPath, QMainWindow * parent = nullptr);
~SingleSpectra();
void SetFillHistograms(bool onOff) { fillHistograms = onOff;}
bool IsFillHistograms() const {return fillHistograms;}
void LoadSetting();
void SaveSetting();
public slots:
void UpdateCanvas();
void FillHistograms();
void ChangeHistView();
void RebinHistogram();
private:
@ -57,5 +64,9 @@ private:
int lastFilledIndex[MaxNDigitizer][MaxNChannels];
int loopFilledIndex[MaxNDigitizer][MaxNChannels];
bool fillHistograms;
QString rawDataPath;
};
#endif