added analyzer/README.md, move the isWorking from the custom analyzer to Analyzer, so user don't need to worry
This commit is contained in:
parent
b3ace2cc84
commit
2abdc83549
|
@ -51,7 +51,9 @@ Analyzer::Analyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent )
|
||||||
|
|
||||||
connect(anaTimer, &QTimer::timeout, anaWorker, [=](){
|
connect(anaTimer, &QTimer::timeout, anaWorker, [=](){
|
||||||
if( isWorking ) return;
|
if( isWorking ) return;
|
||||||
|
isWorking = true;
|
||||||
anaWorker->UpdateHistograms();
|
anaWorker->UpdateHistograms();
|
||||||
|
isWorking = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
// connect(anaWorker, &AnalyzerWorker::workDone, this, [=](){
|
// connect(anaWorker, &AnalyzerWorker::workDone, this, [=](){
|
||||||
|
|
|
@ -90,7 +90,6 @@ protected:
|
||||||
|
|
||||||
bool isWorking; // a flag to indicate the worker is working
|
bool isWorking; // a flag to indicate the worker is working
|
||||||
|
|
||||||
private:
|
|
||||||
Digitizer ** digi;
|
Digitizer ** digi;
|
||||||
unsigned short nDigi;
|
unsigned short nDigi;
|
||||||
|
|
||||||
|
@ -109,7 +108,6 @@ private:
|
||||||
AnalyzerWorker * anaWorker;
|
AnalyzerWorker * anaWorker;
|
||||||
QTimer * anaTimer;
|
QTimer * anaTimer;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//^================================================ AnalyzerWorker
|
//^================================================ AnalyzerWorker
|
||||||
|
|
|
@ -10,8 +10,6 @@ class CoincidentAnalyzer : public Analyzer{
|
||||||
public:
|
public:
|
||||||
CoincidentAnalyzer(Digitizer ** digi, unsigned int nDigi, QString rawDataPath, QMainWindow * parent = nullptr): Analyzer(digi, nDigi, parent){
|
CoincidentAnalyzer(Digitizer ** digi, unsigned int nDigi, QString rawDataPath, QMainWindow * parent = nullptr): Analyzer(digi, nDigi, parent){
|
||||||
|
|
||||||
this->digi = digi;
|
|
||||||
this->nDigi = nDigi;
|
|
||||||
this->rawDataPath = rawDataPath;
|
this->rawDataPath = rawDataPath;
|
||||||
|
|
||||||
SetUpdateTimeInSec(1.0);
|
SetUpdateTimeInSec(1.0);
|
||||||
|
@ -19,8 +17,7 @@ public:
|
||||||
//RedefineEventBuilder({0}); // only build for the 0-th digitizer, otherwise, it will build event accross all digitizers
|
//RedefineEventBuilder({0}); // only build for the 0-th digitizer, otherwise, it will build event accross all digitizers
|
||||||
SetBackwardBuild(false, 100); // using normal building (acceding in time) or backward building, int the case of backward building, default events to be build is 100.
|
SetBackwardBuild(false, 100); // using normal building (acceding in time) or backward building, int the case of backward building, default events to be build is 100.
|
||||||
|
|
||||||
evtbder = GetEventBuilder();
|
mb->SetTimeWindow(500);
|
||||||
evtbder->SetTimeWindow(500);
|
|
||||||
|
|
||||||
allowSignalSlot = false;
|
allowSignalSlot = false;
|
||||||
SetUpCanvas();
|
SetUpCanvas();
|
||||||
|
@ -37,11 +34,6 @@ public slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Digitizer ** digi;
|
|
||||||
unsigned int nDigi;
|
|
||||||
|
|
||||||
MultiBuilder *evtbder;
|
|
||||||
|
|
||||||
bool allowSignalSlot;
|
bool allowSignalSlot;
|
||||||
|
|
||||||
QLineEdit * leInfluxIP;
|
QLineEdit * leInfluxIP;
|
||||||
|
@ -96,6 +88,15 @@ inline void CoincidentAnalyzer::SetUpCanvas(){
|
||||||
chkRunAnalyzer = new QCheckBox("Run Analyzer", this);
|
chkRunAnalyzer = new QCheckBox("Run Analyzer", this);
|
||||||
boxLayout->addWidget(chkRunAnalyzer, rowID, 0);
|
boxLayout->addWidget(chkRunAnalyzer, rowID, 0);
|
||||||
|
|
||||||
|
connect(chkRunAnalyzer, &QCheckBox::stateChanged, this, [=](int state){
|
||||||
|
|
||||||
|
sbBuildWindow->setEnabled(state != Qt::Checked);
|
||||||
|
sbUpdateTime->setEnabled(state != Qt::Checked);
|
||||||
|
chkBackWardBuilding->setEnabled(state != Qt::Checked);
|
||||||
|
sbBackwardCount->setEnabled(state != Qt::Checked);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
QLabel * lbUpdateTime = new QLabel("Update Period [s]", this);
|
QLabel * lbUpdateTime = new QLabel("Update Period [s]", this);
|
||||||
lbUpdateTime->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
lbUpdateTime->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
||||||
boxLayout->addWidget(lbUpdateTime, rowID, 1);
|
boxLayout->addWidget(lbUpdateTime, rowID, 1);
|
||||||
|
@ -127,7 +128,7 @@ inline void CoincidentAnalyzer::SetUpCanvas(){
|
||||||
|
|
||||||
connect(sbBuildWindow, &RSpinBox::returnPressed, this, [=](){
|
connect(sbBuildWindow, &RSpinBox::returnPressed, this, [=](){
|
||||||
sbBuildWindow->setStyleSheet("");
|
sbBuildWindow->setStyleSheet("");
|
||||||
evtbder->SetTimeWindow((int)sbBuildWindow->value());
|
mb->SetTimeWindow((int)sbBuildWindow->value());
|
||||||
});
|
});
|
||||||
|
|
||||||
rowID ++;
|
rowID ++;
|
||||||
|
@ -408,16 +409,13 @@ inline void CoincidentAnalyzer::UpdateHistograms(){
|
||||||
if( this->isVisible() == false ) return;
|
if( this->isVisible() == false ) return;
|
||||||
if( chkRunAnalyzer->isChecked() == false ) return;
|
if( chkRunAnalyzer->isChecked() == false ) return;
|
||||||
|
|
||||||
if( isWorking ) return;
|
|
||||||
isWorking = true; // This is important. set the isWorking = true to prevent another call of UpdateHistograms()
|
|
||||||
|
|
||||||
unsigned long long t0 = getTime_ns();
|
unsigned long long t0 = getTime_ns();
|
||||||
BuildEvents(false); // call the event builder to build events
|
BuildEvents(false); // call the event builder to build events
|
||||||
// unsigned long long t1 = getTime_ns();
|
// unsigned long long t1 = getTime_ns();
|
||||||
// printf("Event Build time : %llu ns = %.f msec\n", t1 - t0, (t1-t0)/1e6);
|
// printf("Event Build time : %llu ns = %.f msec\n", t1 - t0, (t1-t0)/1e6);
|
||||||
|
|
||||||
//============ Get events, and do analysis
|
//============ Get events, and do analysis
|
||||||
long eventBuilt = evtbder->eventBuilt;
|
long eventBuilt = mb->eventBuilt;
|
||||||
|
|
||||||
if( eventBuilt == 0 ) return;
|
if( eventBuilt == 0 ) return;
|
||||||
|
|
||||||
|
@ -442,12 +440,12 @@ inline void CoincidentAnalyzer::UpdateHistograms(){
|
||||||
int y_sn = digi[y_bd]->GetSerialNumber();
|
int y_sn = digi[y_bd]->GetSerialNumber();
|
||||||
|
|
||||||
//============ Processing data and fill histograms
|
//============ Processing data and fill histograms
|
||||||
long eventIndex = evtbder->eventIndex;
|
long eventIndex = mb->eventIndex;
|
||||||
long eventStart = eventIndex - eventBuilt + 1;
|
long eventStart = eventIndex - eventBuilt + 1;
|
||||||
if(eventStart < 0 ) eventStart += MaxNEvent;
|
if(eventStart < 0 ) eventStart += MaxNEvent;
|
||||||
|
|
||||||
for( long i = eventStart ; i <= eventIndex; i ++ ){
|
for( long i = eventStart ; i <= eventIndex; i ++ ){
|
||||||
std::vector<Hit> event = evtbder->events[i];
|
std::vector<Hit> event = mb->events[i];
|
||||||
|
|
||||||
hMulti->Fill((int) event.size());
|
hMulti->Fill((int) event.size());
|
||||||
if( event.size() == 0 ) return;
|
if( event.size() == 0 ) return;
|
||||||
|
@ -488,7 +486,6 @@ inline void CoincidentAnalyzer::UpdateHistograms(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// printf("--------------- update histograms\n");
|
|
||||||
h2D->UpdatePlot();
|
h2D->UpdatePlot();
|
||||||
h1->UpdatePlot();
|
h1->UpdatePlot();
|
||||||
hMulti->UpdatePlot();
|
hMulti->UpdatePlot();
|
||||||
|
@ -510,9 +507,6 @@ inline void CoincidentAnalyzer::UpdateHistograms(){
|
||||||
influx->ClearDataPointsBuffer();
|
influx->ClearDataPointsBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
// printf("<<<<<<<<<<<<< end of UpdateHistorgams\n");
|
|
||||||
|
|
||||||
isWorking = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void CoincidentAnalyzer::SaveSettings(){
|
inline void CoincidentAnalyzer::SaveSettings(){
|
||||||
|
|
|
@ -221,78 +221,10 @@ inline void NeutronGamma::UpdateHistograms(){
|
||||||
hist2D->Fill(data_long, psd);
|
hist2D->Fill(data_long, psd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
hist2D->UpdatePlot();
|
hist2D->UpdatePlot();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
void NeutronGamma::UpdateHistograms(){
|
|
||||||
if( !fillHistograms ) return;
|
|
||||||
|
|
||||||
timespec t0, t1;
|
|
||||||
|
|
||||||
QVector<int> randomDigiList = generateNonRepeatedCombination(nDigi);
|
|
||||||
|
|
||||||
for( int i = 0; i < nDigi; i++){
|
|
||||||
int ID = randomDigiList[i];
|
|
||||||
|
|
||||||
QVector<int> randomChList = generateNonRepeatedCombination(digi[ID]->GetNumInputCh());
|
|
||||||
|
|
||||||
digiMTX[ID].lock();
|
|
||||||
|
|
||||||
|
|
||||||
clock_gettime(CLOCK_REALTIME, &t0);
|
|
||||||
for( int k = 0; k < digi[ID]->GetNumInputCh(); k ++ ){
|
|
||||||
int ch = randomChList[k];
|
|
||||||
int lastIndex = digi[ID]->GetData()->GetDataIndex(ch);
|
|
||||||
// printf("--- ch %2d | last index %d \n", ch, lastIndex);
|
|
||||||
if( lastIndex < 0 ) continue;
|
|
||||||
|
|
||||||
int loopIndex = digi[ID]->GetData()->GetLoopIndex(ch);
|
|
||||||
|
|
||||||
int temp1 = lastIndex + loopIndex * digi[ID]->GetData()->GetDataSize();
|
|
||||||
int temp2 = lastFilledIndex[ID][ch] + loopFilledIndex[ID][ch] * digi[ID]->GetData()->GetDataSize() + 1;
|
|
||||||
|
|
||||||
// printf("loopIndx : %d | ID now : %d, ID old : %d \n", loopIndex, temp1, temp2);
|
|
||||||
|
|
||||||
if( temp1 <= temp2 ) continue;
|
|
||||||
|
|
||||||
if( temp1 - temp2 > digi[ID]->GetData()->GetDataSize() ) { //DefaultDataSize = 10k
|
|
||||||
temp2 = temp1 - digi[ID]->GetData()->GetDataSize();
|
|
||||||
lastFilledIndex[ID][ch] = lastIndex;
|
|
||||||
lastFilledIndex[ID][ch] = loopIndex - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// printf("ch %d | regulated ID now %d new %d | last fill idx %d\n", ch, temp2, temp1, lastFilledIndex[ID][ch]);
|
|
||||||
|
|
||||||
for( int j = 0 ; j <= temp1 - temp2; j ++){
|
|
||||||
lastFilledIndex[ID][ch] ++;
|
|
||||||
if( lastFilledIndex[ID][ch] > digi[ID]->GetData()->GetDataSize() ) {
|
|
||||||
lastFilledIndex[ID][ch] = 0;
|
|
||||||
loopFilledIndex[ID][ch] ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
uShort data_long = digi[ID]->GetData()->GetEnergy(ch, lastFilledIndex[ID][ch]);
|
|
||||||
uShort data_short = digi[ID]->GetData()->GetEnergy2(ch, lastFilledIndex[ID][ch]);
|
|
||||||
|
|
||||||
// printf(" ch: %d, last fill idx : %d | %d \n", ch, lastFilledIndex[ID][ch], data);
|
|
||||||
|
|
||||||
hist2D[ID][ch]->Fill(data_long, data_short);
|
|
||||||
}
|
|
||||||
if( histVisibility[ID][ch] ) hist2D[ID][ch]->UpdatePlot();
|
|
||||||
|
|
||||||
clock_gettime(CLOCK_REALTIME, &t1);
|
|
||||||
if( t1.tv_nsec - t0.tv_nsec + (t1.tv_sec - t0.tv_sec)*1e9 > maxFillTimePerDigi * 1e6 ) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
digiMTX[ID].unlock();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
inline QVector<int> NeutronGamma::generateNonRepeatedCombination(int size) {
|
inline QVector<int> NeutronGamma::generateNonRepeatedCombination(int size) {
|
||||||
QVector<int> combination;
|
QVector<int> combination;
|
||||||
for (int i = 0; i < size; ++i) combination.append(i);
|
for (int i = 0; i < size; ++i) combination.append(i);
|
||||||
|
|
|
@ -127,6 +127,7 @@ inline void RAISOR::UpdateHistograms(){
|
||||||
influx->WriteData(dataBaseName.toStdString());
|
influx->WriteData(dataBaseName.toStdString());
|
||||||
influx->ClearDataPointsBuffer();
|
influx->ClearDataPointsBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
93
analyzers/README.md
Normal file
93
analyzers/README.md
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
# Introduction
|
||||||
|
|
||||||
|
This folder stored all online analyzers. The Analyser.cpp/h is the base class for all analyzer.
|
||||||
|
|
||||||
|
The Analyzer.cpp/h has the MultiBuilder (to handle event building) and InfluxDB (to handle pushing data to influxDB database) classes. In Addision, it has a QThread, a AnalyzerWorker, and a QTimer, these three object handle the threading of UpdateHistograms().
|
||||||
|
|
||||||
|
The AnalyzerWorker moves to the QThread. QTimer::timeout will trigger AnalyzerWorker::UpdateHistograms().
|
||||||
|
|
||||||
|
There is an important bool 'isWorking'. This boolean variable is true when AnalyzerWorker::UpdateHistograms() is running, and it is false when finsihed. This prevent UpdateHistograms() runs twice at the same time.
|
||||||
|
|
||||||
|
There are two virual methods
|
||||||
|
- SetupCanvas()
|
||||||
|
- UpdateHistograms()
|
||||||
|
|
||||||
|
Users must implement these two methods in theie custom analyzer.
|
||||||
|
|
||||||
|
|
||||||
|
# Intruction to make new Analyzer
|
||||||
|
|
||||||
|
The CoindientAnalyzer.h is a good example.
|
||||||
|
|
||||||
|
1. inheirate the Analyzer class
|
||||||
|
```cpp
|
||||||
|
class CustomAnalyzer : public Analyzer{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
CustomAnalyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent = nullptr): Analyzer(digi, nDigi, parent){
|
||||||
|
SetUpdateTimeInSec(1.0); // set histogram update period in sec
|
||||||
|
mb->SetTimeWindow(500); // set the event time windows
|
||||||
|
// ... other custom stuffs
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetUpCanvas();
|
||||||
|
public slots:
|
||||||
|
void UpdateHistograms();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Histogram2D * h2D;
|
||||||
|
Histogram1D * h1D;
|
||||||
|
// some priavte variables
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2. implement the SetUpCanvas() method
|
||||||
|
```cpp
|
||||||
|
inline void CustomAnalyzer::SetUpCanvas(){
|
||||||
|
setWindowTitle("Title");
|
||||||
|
setGeometry(0, 0, 1600, 1000);
|
||||||
|
|
||||||
|
h2D = new Histogram2D("Coincident Plot", "XXX", "YYY", 200, 0, 30000, 200, 0, 30000, this, rawDataPath);
|
||||||
|
|
||||||
|
//layout is inheriatge from Analyzer
|
||||||
|
layout->addWidget(h2D, 0, 0); // row-0, col-0
|
||||||
|
|
||||||
|
h1 = new Histogram1D("1D Plot", "XXX", 300, 0, 30000, this);
|
||||||
|
h1->SetColor(Qt::darkGreen);
|
||||||
|
layout->addWidget(h1, 0, 1); // row-0, col-1
|
||||||
|
|
||||||
|
//other GUI elements
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
3. implement the UpdateHistograms() method
|
||||||
|
```cpp
|
||||||
|
inline void CustomAnalyzer::UpdateHistograms(){
|
||||||
|
// don't update histogram when the windows not visible
|
||||||
|
if( this->isVisible() == false ) return;
|
||||||
|
|
||||||
|
BuildEvents(false); // call the event builder to build events, no verbose
|
||||||
|
|
||||||
|
//check number of event built
|
||||||
|
long eventBuilt = mb->eventBuilt;
|
||||||
|
if( eventBuilt == 0 ) return;
|
||||||
|
|
||||||
|
//============ Processing data and fill histograms
|
||||||
|
long eventIndex = mb->eventIndex;
|
||||||
|
long eventStart = eventIndex - eventBuilt + 1;
|
||||||
|
if(eventStart < 0 ) eventStart += MaxNEvent;
|
||||||
|
|
||||||
|
for( long i = eventStart ; i <= eventIndex; i ++ ){
|
||||||
|
std::vector<Hit> event = mb->events[i];
|
||||||
|
|
||||||
|
//analysis and fill historgam
|
||||||
|
}
|
||||||
|
|
||||||
|
//Render histograms
|
||||||
|
h2D->UpdatePlot();
|
||||||
|
h1D->UpdatePlot();
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
Loading…
Reference in New Issue
Block a user