diff --git a/analyzers/Analyser.cpp b/analyzers/Analyser.cpp index 0039ecc..38330d0 100644 --- a/analyzers/Analyser.cpp +++ b/analyzers/Analyser.cpp @@ -51,7 +51,9 @@ Analyzer::Analyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent ) connect(anaTimer, &QTimer::timeout, anaWorker, [=](){ if( isWorking ) return; + isWorking = true; anaWorker->UpdateHistograms(); + isWorking = false; }); // connect(anaWorker, &AnalyzerWorker::workDone, this, [=](){ diff --git a/analyzers/Analyser.h b/analyzers/Analyser.h index e698a7e..436120f 100644 --- a/analyzers/Analyser.h +++ b/analyzers/Analyser.h @@ -90,7 +90,6 @@ protected: bool isWorking; // a flag to indicate the worker is working -private: Digitizer ** digi; unsigned short nDigi; @@ -109,7 +108,6 @@ private: AnalyzerWorker * anaWorker; QTimer * anaTimer; - }; //^================================================ AnalyzerWorker diff --git a/analyzers/CoincidentAnalyzer.h b/analyzers/CoincidentAnalyzer.h index 682fb29..44556e1 100644 --- a/analyzers/CoincidentAnalyzer.h +++ b/analyzers/CoincidentAnalyzer.h @@ -10,8 +10,6 @@ class CoincidentAnalyzer : public Analyzer{ public: CoincidentAnalyzer(Digitizer ** digi, unsigned int nDigi, QString rawDataPath, QMainWindow * parent = nullptr): Analyzer(digi, nDigi, parent){ - this->digi = digi; - this->nDigi = nDigi; this->rawDataPath = rawDataPath; 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 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(); - evtbder->SetTimeWindow(500); + mb->SetTimeWindow(500); allowSignalSlot = false; SetUpCanvas(); @@ -37,11 +34,6 @@ public slots: private: - Digitizer ** digi; - unsigned int nDigi; - - MultiBuilder *evtbder; - bool allowSignalSlot; QLineEdit * leInfluxIP; @@ -96,6 +88,15 @@ inline void CoincidentAnalyzer::SetUpCanvas(){ chkRunAnalyzer = new QCheckBox("Run Analyzer", this); 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); lbUpdateTime->setAlignment(Qt::AlignRight | Qt::AlignCenter); boxLayout->addWidget(lbUpdateTime, rowID, 1); @@ -127,7 +128,7 @@ inline void CoincidentAnalyzer::SetUpCanvas(){ connect(sbBuildWindow, &RSpinBox::returnPressed, this, [=](){ sbBuildWindow->setStyleSheet(""); - evtbder->SetTimeWindow((int)sbBuildWindow->value()); + mb->SetTimeWindow((int)sbBuildWindow->value()); }); rowID ++; @@ -408,16 +409,13 @@ inline void CoincidentAnalyzer::UpdateHistograms(){ if( this->isVisible() == 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(); BuildEvents(false); // call the event builder to build events // unsigned long long t1 = getTime_ns(); // printf("Event Build time : %llu ns = %.f msec\n", t1 - t0, (t1-t0)/1e6); //============ Get events, and do analysis - long eventBuilt = evtbder->eventBuilt; + long eventBuilt = mb->eventBuilt; if( eventBuilt == 0 ) return; @@ -442,12 +440,12 @@ inline void CoincidentAnalyzer::UpdateHistograms(){ int y_sn = digi[y_bd]->GetSerialNumber(); //============ Processing data and fill histograms - long eventIndex = evtbder->eventIndex; + long eventIndex = mb->eventIndex; long eventStart = eventIndex - eventBuilt + 1; if(eventStart < 0 ) eventStart += MaxNEvent; for( long i = eventStart ; i <= eventIndex; i ++ ){ - std::vector event = evtbder->events[i]; + std::vector event = mb->events[i]; hMulti->Fill((int) event.size()); if( event.size() == 0 ) return; @@ -488,7 +486,6 @@ inline void CoincidentAnalyzer::UpdateHistograms(){ } - // printf("--------------- update histograms\n"); h2D->UpdatePlot(); h1->UpdatePlot(); hMulti->UpdatePlot(); @@ -510,9 +507,6 @@ inline void CoincidentAnalyzer::UpdateHistograms(){ influx->ClearDataPointsBuffer(); } - // printf("<<<<<<<<<<<<< end of UpdateHistorgams\n"); - - isWorking = false; } inline void CoincidentAnalyzer::SaveSettings(){ diff --git a/analyzers/NeutronGamma.h b/analyzers/NeutronGamma.h index a6e6a49..94b10cf 100644 --- a/analyzers/NeutronGamma.h +++ b/analyzers/NeutronGamma.h @@ -221,78 +221,10 @@ inline void NeutronGamma::UpdateHistograms(){ hist2D->Fill(data_long, psd); } - hist2D->UpdatePlot(); } -/* -void NeutronGamma::UpdateHistograms(){ - if( !fillHistograms ) return; - - timespec t0, t1; - - QVector randomDigiList = generateNonRepeatedCombination(nDigi); - - for( int i = 0; i < nDigi; i++){ - int ID = randomDigiList[i]; - - QVector 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 NeutronGamma::generateNonRepeatedCombination(int size) { QVector combination; for (int i = 0; i < size; ++i) combination.append(i); diff --git a/analyzers/RAISOR.h b/analyzers/RAISOR.h index e078ff4..e18c367 100644 --- a/analyzers/RAISOR.h +++ b/analyzers/RAISOR.h @@ -66,7 +66,7 @@ inline void RAISOR::SetUpCanvas(){ inline void RAISOR::UpdateHistograms(){ if( this->isVisible() == false ) return; - + BuildEvents(false); // call the event builder to build events //============ Get events, and do analysis @@ -127,6 +127,7 @@ inline void RAISOR::UpdateHistograms(){ influx->WriteData(dataBaseName.toStdString()); influx->ClearDataPointsBuffer(); } + } diff --git a/analyzers/README.md b/analyzers/README.md new file mode 100644 index 0000000..634104d --- /dev/null +++ b/analyzers/README.md @@ -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 event = mb->events[i]; + + //analysis and fill historgam + } + + //Render histograms + h2D->UpdatePlot(); + h1D->UpdatePlot(); + +} +``` \ No newline at end of file