added OnlineAnalyser.h/cpp

This commit is contained in:
splitPoleDAQ 2023-05-26 18:06:37 -04:00
parent 322cbca165
commit 5b58083fb3
14 changed files with 273 additions and 69 deletions

View File

@ -151,6 +151,7 @@
"typeinfo": "cpp",
"variant": "cpp",
"qmainwindow": "cpp",
"qchartview": "cpp"
"qchartview": "cpp",
"qthread": "cpp"
}
}

View File

@ -61,7 +61,7 @@ Canvas::Canvas(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent) : QM
for( int j = 0; j < MaxNChannels; j++){
if( i < nDigi ) {
hist[i][j] = new Histogram("Digi-" + QString::number(digi[i]->GetSerialNumber()) +", Ch-" + QString::number(j), xMin, xMax, nBin);
histView[i][j] = new TraceView(hist[i][j]->GetTrace());
histView[i][j] = new RChartView(hist[i][j]->GetChart());
histView[i][j]->SetVRange(0, 10);
}else{
hist[i][j] = nullptr;

View File

@ -4,18 +4,12 @@
#include <QMainWindow>
#include <QChart>
#include <QChartView>
#include <QSpinBox>
#include <QLabel>
#include <QPushButton>
#include <QCheckBox>
#include <QLineEdit>
#include <QComboBox>
#include <QGridLayout>
#include <QGroupBox>
#include <QLineSeries>
#include <QRubberBand>
#include <QMouseEvent>
#include <QGestureEvent>
#include "macro.h"
#include "ClassDigitizer.h"
@ -42,7 +36,7 @@ private:
unsigned short nDigi;
Histogram * hist[MaxNDigitizer][MaxNChannels];
TraceView * histView[MaxNDigitizer][MaxNChannels];
RChartView * histView[MaxNDigitizer][MaxNChannels];
RComboBox * cbDivision;
@ -54,6 +48,4 @@ private:
int oldBd, oldCh;
};
#endif

View File

@ -57,10 +57,6 @@ class Data{
void Allocate80MBMemory();
void AllocateMemory(uint32_t size);
void SetSaveWaveToMemory(bool OnOff) { // store the waveform in memory
this->SaveWaveToMemory = OnOff;
}
void ClearData();
void ClearTriggerRate();
void ClearBuffer();
@ -86,7 +82,7 @@ class Data{
protected:
unsigned int nw;
bool SaveWaveToMemory;
//bool SaveWaveToMemory;
///for temperary
std::vector<short> tempWaveform1;
@ -123,7 +119,6 @@ inline Data::Data(){
for ( int i = 0; i < MaxNChannels; i++) TotNumEvents[i] = 0;
ClearData();
ClearTriggerRate();
SaveWaveToMemory = true;
nw = 0;
outFileIndex = 0;
@ -376,7 +371,6 @@ inline void Data::DecodeBuffer(bool fastDecode, int verbose){
continue;
}
//TODO ====== when NumEventsDecoded is too small, the trigger rate is not reliable?
if( NumEventsDecoded[ch] > 4 ){
int indexStart = DataIndex[ch] - NumEventsDecoded[ch] + 1;
@ -523,9 +517,8 @@ inline int Data::DecodePHADualChannelBlock(unsigned int ChannelMask, bool fastDe
int channel = ChannelMask*2 + channelTag;
if( verbose >= 2 ) printf("ch : %d, timeStamp0 %u \n", channel, timeStamp0);
//TODO Skip
///===== read waveform
if( !fastDecode && SaveWaveToMemory ) {
if( !fastDecode ) {
tempWaveform1.clear();
tempWaveform2.clear();
tempDigiWaveform1.clear();
@ -561,18 +554,16 @@ inline int Data::DecodePHADualChannelBlock(unsigned int ChannelMask, bool fastDe
trace0 = static_cast<short>(wave0);
}
if( SaveWaveToMemory){
if( hasDualTrace ){
tempWaveform1.push_back(trace1);
tempWaveform2.push_back(trace0);
tempDigiWaveform1.push_back(dp1);
tempDigiWaveform2.push_back(dp0);
}else{
tempWaveform1.push_back(trace1);
tempWaveform1.push_back(trace0);
tempDigiWaveform1.push_back(dp1);
tempDigiWaveform1.push_back(dp0);
}
if( hasDualTrace ){
tempWaveform1.push_back(trace1);
tempWaveform2.push_back(trace0);
tempDigiWaveform1.push_back(dp1);
tempDigiWaveform2.push_back(dp0);
}else{
tempWaveform1.push_back(trace1);
tempWaveform1.push_back(trace0);
tempDigiWaveform1.push_back(dp1);
tempDigiWaveform1.push_back(dp0);
}
if( isTrigger0 == 1 ) triggerAtSample = 2*wi ;
@ -641,7 +632,7 @@ inline int Data::DecodePHADualChannelBlock(unsigned int ChannelMask, bool fastDe
NumNonPileUpDecoded[channel] ++;
}
if( SaveWaveToMemory ) {
if( !fastDecode ) {
if( hasDualTrace ){
Waveform1[channel][DataIndex[channel]] = tempWaveform1;
Waveform2[channel][DataIndex[channel]] = tempWaveform2;
@ -759,7 +750,7 @@ inline int Data::DecodePSDDualChannelBlock(unsigned int ChannelMask, bool fastDe
if( verbose >= 2 ) printf("ch : %d, timeStamp %u \n", channel, timeStamp0);
///===== read waveform
if( !fastDecode && SaveWaveToMemory ) {
if( !fastDecode ) {
tempWaveform1.clear();
tempWaveform2.clear();
tempDigiWaveform1.clear();
@ -779,19 +770,17 @@ inline int Data::DecodePSDDualChannelBlock(unsigned int ChannelMask, bool fastDe
bool dp1a = (( word >> 14 ) & 0x1 );
unsigned short wavea = ( word & 0x3FFF);
if( SaveWaveToMemory){
if( hasDualTrace ){
tempWaveform1.push_back(wavea);
tempWaveform2.push_back(waveb);
}else{
tempWaveform1.push_back(wavea);
tempWaveform1.push_back(waveb);
}
tempDigiWaveform1.push_back(dp1a);
tempDigiWaveform1.push_back(dp1b);
tempDigiWaveform2.push_back(dp2a);
tempDigiWaveform2.push_back(dp2b);
if( hasDualTrace ){
tempWaveform1.push_back(wavea);
tempWaveform2.push_back(waveb);
}else{
tempWaveform1.push_back(wavea);
tempWaveform1.push_back(waveb);
}
tempDigiWaveform1.push_back(dp1a);
tempDigiWaveform1.push_back(dp1b);
tempDigiWaveform2.push_back(dp2a);
tempDigiWaveform2.push_back(dp2b);
if( verbose >= 3 ){
printf("%4d| %5d, %d, %d \n", 2*wi, wavea, dp1a, dp2a);
@ -827,7 +816,7 @@ inline int Data::DecodePSDDualChannelBlock(unsigned int ChannelMask, bool fastDe
Energy2[channel][DataIndex[channel]] = Qlong;
Timestamp[channel][DataIndex[channel]] = timeStamp;
if( SaveWaveToMemory ) {
if( !fastDecode ) {
if( hasDualTrace ){
Waveform1[channel][DataIndex[channel]] = tempWaveform1;
Waveform2[channel][DataIndex[channel]] = tempWaveform2;

View File

@ -39,6 +39,7 @@ public:
readCount ++;
if( stop) break;
if( ret == CAEN_DGTZ_Success && !stop){
digiMTX[ID].lock();
digi->GetData()->DecodeBuffer(!isScope, 0);

View File

@ -60,14 +60,14 @@ class RComboBox : public QComboBox{
};
//^====================================================
class Trace : public QChart{
class RChart : public QChart{
public:
explicit Trace(QGraphicsItem *parent = nullptr, Qt::WindowFlags wFlags = {})
explicit RChart(QGraphicsItem *parent = nullptr, Qt::WindowFlags wFlags = {})
: QChart(QChart::ChartTypeCartesian, parent, wFlags){
grabGesture(Qt::PanGesture);
grabGesture(Qt::PinchGesture);
}
~Trace(){}
~RChart(){}
protected:
bool sceneEvent(QEvent *event){
@ -94,9 +94,9 @@ private:
};
//^====================================================
class TraceView : public QChartView{
class RChartView : public QChartView{
public:
TraceView(QChart * chart, QWidget * parent = nullptr): QChartView(chart, parent){
RChartView(QChart * chart, QWidget * parent = nullptr): QChartView(chart, parent){
m_isTouching = false;
this->setRubberBand(QChartView::RectangleRubberBand);
@ -110,6 +110,9 @@ public:
vRangeMin = -(0x1FFF);
vRangeMax = 0x1FFF;
hRangeMin = 0;
hRangeMax = 0;
}
void SetHRange(int min, int max) {
@ -161,7 +164,7 @@ protected:
case Qt::Key_R :
//chart()->axes(Qt::Vertical).first()->setRange(-(0x1FFF), 0x1FFF);
chart()->axes(Qt::Vertical).first()->setRange(vRangeMin, vRangeMax);
//chart()->axes(Qt::Horizontal).first()->setRange(hRangeMin, hRangeMax);
if( hRangeMax != hRangeMin ) chart()->axes(Qt::Horizontal).first()->setRange(hRangeMin, hRangeMax);
break;
default: QGraphicsView::keyPressEvent(event); break;
}
@ -181,7 +184,7 @@ class Histogram {
public:
Histogram(QString title, double xMin, double xMax, int nBin){
plot = new Trace();
plot = new RChart();
dataSeries = new QLineSeries();
Rebin(xMin, xMax, nBin);
@ -216,7 +219,7 @@ public:
delete plot;
}
Trace * GetTrace() { return plot;}
RChart * GetChart() { return plot;}
void Clear(){
for( int i = 0; i <= nBin; i++) {
@ -267,7 +270,7 @@ public:
}
private:
Trace * plot;
RChart * plot;
QLineSeries * dataSeries;
QAreaSeries * areaSeries;

View File

@ -26,6 +26,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
scope = nullptr;
digiSettings = nullptr;
canvas = nullptr;
onlineAnalyzer = nullptr;
QWidget * mainLayoutWidget = new QWidget(this);
setCentralWidget(mainLayoutWidget);
@ -55,8 +56,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
bnAnalyzer = new QPushButton("Online Analyzer", this);
layout->addWidget(bnAnalyzer, 0, 2);
connect(bnAnalyzer, &QPushButton::clicked, this, &MainWindow::OpenScope);
bnAnalyzer->setEnabled(false);
connect(bnAnalyzer, &QPushButton::clicked, this, &MainWindow::OpenAnalyzer);
bnCanvas = new QPushButton("Online 1D Histograms", this);
layout->addWidget(bnCanvas, 1, 2);
@ -287,6 +287,8 @@ MainWindow::~MainWindow(){
if( canvas ) delete canvas;
if( onlineAnalyzer ) delete onlineAnalyzer;
if( scalar ) {
CleanUpScalar();
scalarThread->Stop();
@ -611,6 +613,7 @@ void MainWindow::WaitForDigitizersOpen(bool onOff){
bnStopACQ->setEnabled(!onOff);
chkSaveData->setEnabled(!onOff);
bnCanvas->setEnabled(!onOff);
bnAnalyzer->setEnabled(!onOff);
}
@ -813,7 +816,6 @@ void MainWindow::StartACQ(){
readDataThread[i]->SetSaveData(chkSaveData->isChecked());
LogMsg("Digi-" + QString::number(digi[i]->GetSerialNumber()) + " is starting ACQ." );
digi[i]->WriteRegister(DPP::SoftwareClear_W, 1);
digi[i]->GetData()->SetSaveWaveToMemory(false);
digi[i]->StartACQ();
readDataThread[i]->start();
}
@ -1067,7 +1069,6 @@ void MainWindow::OpenScope(){
bnStartACQ->setEnabled(false);
bnStopACQ->setEnabled(false);
chkSaveData->setChecked(false);
}
@ -1101,6 +1102,19 @@ void MainWindow::OpenCanvas(){
canvas->activateWindow();
}
}
//***************************************************************
//***************************************************************
void MainWindow::OpenAnalyzer(){
if( onlineAnalyzer == nullptr ) {
onlineAnalyzer = new OnlineAnalyzer(digi, nDigi);
onlineAnalyzer->show();
}else{
onlineAnalyzer->show();
onlineAnalyzer->activateWindow();
}
}
//***************************************************************

View File

@ -18,6 +18,7 @@
#include "DigiSettingsPanel.h"
#include "CanvasClass.h"
#include "influxdb.h"
#include "OnlineAnalyser.h"
//^#===================================================== MainWindow
class MainWindow : public QMainWindow{
@ -30,6 +31,7 @@ public:
if( scope ) scope->close();
if( digiSettings ) digiSettings->close();
if( canvas ) canvas->close();
if( onlineAnalyzer ) onlineAnalyzer->close();
event->accept();
}
@ -62,6 +64,8 @@ private slots:
void OpenCanvas();
void OpenAnalyzer();
void UpdateAllPanels(int panelID);
void SetUpInflux();
@ -70,6 +74,7 @@ private slots:
void WriteElog(QString htmlText, QString subject, QString category, int runNumber);
void AppendElog(QString appendHtmlText);
private:
Digitizer ** digi;
@ -149,6 +154,10 @@ private:
Canvas * canvas;
TimingThread * histThread;
//@----- Analyzer
OnlineAnalyzer * onlineAnalyzer;
};

View File

@ -33,7 +33,8 @@ HEADERS += ClassData.h \
influxdb.h\
Scope.h \
CanvasClass.h \
OnlineEventBuilder.h
OnlineEventBuilder.h \
OnlineAnalyser.h
SOURCES += ClassDigitizer.cpp \
DigiSettingsPanel.cpp \
FSUDAQ.cpp \
@ -42,3 +43,4 @@ SOURCES += ClassDigitizer.cpp \
Scope.cpp \
CanvasClass.cpp \
OnlineEventBuilder.cpp \
OnlineAnalyser.cpp

78
OnlineAnalyser.cpp Normal file
View File

@ -0,0 +1,78 @@
#include "OnlineAnalyser.h"
#include <QRandomGenerator>
#include <random>
OnlineAnalyzer::OnlineAnalyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent ): QMainWindow(parent){
this->digi = digi;
this->nDigi = nDigi;
oeb = new OnlineEventBuilder * [nDigi];
for( unsigned int i = 0; i < nDigi; i++ ) oeb[i] = new OnlineEventBuilder(digi[i]);
buildTimerThread = new TimingThread(this);
buildTimerThread->SetWaitTimeinSec(1.0); //^Set event build interval
connect( buildTimerThread, &TimingThread::timeUp, this, &OnlineAnalyzer::UpdateHistograms);
setWindowTitle("Online Analyzer");
setGeometry(0, 0, 1000, 800);
QWidget * layoutWidget = new QWidget(this);
setCentralWidget(layoutWidget);
layout = new QGridLayout(layoutWidget);
layoutWidget->setLayout(layout);
// QPushButton * bnSetting = new QPushButton("Settings", this);
// layout->addWidget(bnSetting);
SetUpCanvas();
}
OnlineAnalyzer::~OnlineAnalyzer(){
for( unsigned int i = 0; i < nDigi; i++ ) delete oeb[i];
delete [] oeb;
}
void OnlineAnalyzer::StartThread(){
}
void OnlineAnalyzer::StopThread(){
}
void OnlineAnalyzer::SetUpCanvas(){
//TODO a simple way to set it at once
Histogram2D * h2 = new Histogram2D("testing", -10, 10, -10, 10);
RChartView * h2View = new RChartView(h2->GetChart());
h2View->SetVRange(-10, 10); // this only set the reset key 'r'
h2View->SetHRange(-10, 10);
layout->addWidget(h2View);
std::random_device rd;
std::mt19937 gen(rd());
std::normal_distribution<double> distribution(0.0, 2.0);
for( int i = 0; i < 1000 ; i++ ){
h2->Fill(distribution(gen), distribution(gen));
}
}
void OnlineAnalyzer::UpdateHistograms(){
//Set with digitizer to be event build
digiMTX[0].lock();
oeb[0]->BuildEvents(100);
digiMTX[0].unlock();
//============ Get events, and do analysis
}

118
OnlineAnalyser.h Normal file
View File

@ -0,0 +1,118 @@
#ifndef ONLINE_ANALYZER_H
#define ONLINE_ANALYZER_H
#include <QMainWindow>
#include <QChart>
#include <QChartView>
#include <QLabel>
#include <QPushButton>
#include <QCheckBox>
#include <QLineEdit>
#include <QGridLayout>
#include <QGroupBox>
#include "macro.h"
#include "ClassDigitizer.h"
#include "CustomThreads.h"
#include "CustomWidgets.h"
#include "OnlineEventBuilder.h"
/**************************************
This class is for, obviously, Online analysis.
It provides essential event building, histograms, and filling.
This is the mother of all other derivative analysis class.
derivative class should define the SetUpCanvas() and UpdateHistogram();
***************************************/
#include <QScatterSeries>
//^==============================================
//^==============================================
class Histogram2D{
public:
Histogram2D(QString title, double xMin, double xMax, double yMin, double yMax){
this->xMin = xMin;
this->xMax = xMax;
this->yMin = yMin;
this->yMax = yMax;
plot = new RChart();
scatterSeries = new QScatterSeries();
scatterSeries->setName(title);
scatterSeries->setMarkerShape(QScatterSeries::MarkerShapeCircle);
scatterSeries->setBorderColor(QColor(0,0,0,0));
scatterSeries->setMarkerSize(5.0);
plot->addSeries(scatterSeries);
plot->createDefaultAxes();
QValueAxis * xaxis = qobject_cast<QValueAxis*> (plot->axes(Qt::Horizontal).first());
xaxis->setRange(xMin, xMax);
QValueAxis * yaxis = qobject_cast<QValueAxis*> (plot->axes(Qt::Vertical).first());
yaxis->setRange(yMin, yMax);
}
~Histogram2D(){
delete scatterSeries;
delete plot;
}
double GetXMin() const {return xMin;}
double GetXMax() const {return xMax;}
double GetyMin() const {return yMin;}
double GetyMax() const {return yMax;}
RChart * GetChart() {return plot;}
void SetMarkerColor(QColor color) { scatterSeries->setColor(color); }
void SetMarkerSize(qreal size) { scatterSeries->setMarkerSize(size);}
void Clear(){ scatterSeries->clear();}
void Fill(double x, double y) { scatterSeries->append(x, y); }
private:
double xMin, xMax, yMin, yMax;
RChart * plot;
QScatterSeries * scatterSeries;
};
//^==============================================
//^==============================================
class OnlineAnalyzer : public QMainWindow{
Q_OBJECT
public:
OnlineAnalyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent = nullptr);
virtual ~OnlineAnalyzer();
virtual void SetUpCanvas();
public slots:
void StartThread();
void StopThread();
private slots:
virtual void UpdateHistograms(); // where event-building, analysis, and ploting
private:
Digitizer ** digi;
unsigned short nDigi;
OnlineEventBuilder ** oeb;
TimingThread * buildTimerThread;
QGridLayout * layout;
};
#endif

View File

@ -27,7 +27,6 @@ OnlineEventBuilder::~OnlineEventBuilder(){
}
void OnlineEventBuilder::FindEarlistTimeAndCh(){
earlistTime = -1;
@ -38,7 +37,7 @@ void OnlineEventBuilder::FindEarlistTimeAndCh(){
chExhaused[i] = false;
}
for(unsigned int ch = 0; ch < nCh; ch ++){
for(unsigned int ch = 0; ch < nCh; ch ++){
if( data->DataIndex[ch] == -1 || nextIndex[ch] > data->DataIndex[ch]) {
nExhaushedCh ++;
chExhaused[ch] = true;

View File

@ -19,7 +19,7 @@ Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataTh
enableSignalSlot = false;
plot = new Trace();
plot = new RChart();
for( int i = 0; i < MaxNumberOfTrace; i++) {
dataTrace[i] = new QLineSeries();
dataTrace[i]->setName("Trace " + QString::number(i));
@ -153,7 +153,7 @@ Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataTh
}
//================ Plot view
rowID ++;
plotView = new TraceView(plot, this);
plotView = new RChartView(plot, this);
layout->addWidget(plotView, rowID, 0, 1, 6);
@ -233,8 +233,6 @@ void Scope::StartScope(){
traceOn[iDigi] = digi[iDigi]->IsRecordTrace(); //remember setting
digi[iDigi]->SetBits(DPP::BoardConfiguration, DPP::Bit_BoardConfig::RecordTrace, 1, -1);
digi[iDigi]->GetData()->SetSaveWaveToMemory(true);
digi[iDigi]->StartACQ();
printf("----- readDataThread running ? %d.\n", readDataThread[iDigi]->isRunning());

View File

@ -79,8 +79,8 @@ private:
bool enableSignalSlot;
Trace * plot;
TraceView * plotView;
RChart * plot;
RChartView * plotView;
QLineSeries * dataTrace[MaxNumberOfTrace]; // 2 analog, 2 digi
RComboBox * cbScopeDigi;