From 6a9f25428917c9e6a188e7be10992dc1e9becdac Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Tue, 20 Aug 2024 14:59:22 -0400 Subject: [PATCH] DigiSetting PSD bug fix, add NeutronGamma analyzer --- ClassDigitizer.cpp | 4 + DigiSettingsPanel.cpp | 16 +- FSUDAQ.cpp | 51 ++++--- FSUDAQ.h | 10 +- FSUDAQ_Qt6.pro | 3 +- analyzers/NeutronGamma.h | 308 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 354 insertions(+), 38 deletions(-) create mode 100644 analyzers/NeutronGamma.h diff --git a/ClassDigitizer.cpp b/ClassDigitizer.cpp index ecf7045..5b3784d 100644 --- a/ClassDigitizer.cpp +++ b/ClassDigitizer.cpp @@ -437,6 +437,10 @@ int Digitizer::ProgramBoard_PSD(){ ret |= CAEN_DGTZ_SetChannelDCOffset(handle, 0xF, 0xAAAA); } + // ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::DPPAlgorithmControl) + 0x7000 , 0x001 ); // baseline 16 sample + + ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::PSD::TriggerThreshold) + 0x7000 , 100 ); + ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::PreTrigger) + 0x7000 , 20 ); ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::RecordLength_G) + 0x7000 , 80 ); diff --git a/DigiSettingsPanel.cpp b/DigiSettingsPanel.cpp index 75fbae3..fd8d46d 100644 --- a/DigiSettingsPanel.cpp +++ b/DigiSettingsPanel.cpp @@ -3847,16 +3847,16 @@ void DigiSettingsPanel::UpdateSettings_PSD(){ chkRejOverRange[ID][ch]->setChecked( Digitizer::ExtractBits(dpp, DPP::Bit_DPPAlgorithmControl_PSD::RejectOverRange)); chkTestPule[ID][ch]->setChecked( Digitizer::ExtractBits(dpp, DPP::Bit_DPPAlgorithmControl_PSD::InternalTestPulse)); + chkDisableOppositePulse[ID][ch]->setChecked( Digitizer::ExtractBits(dpp, DPP::Bit_DPPAlgorithmControl_PSD::DisableOppositePolarityInhibitZeroCrossingOnCFD)); + chkDisableSelfTrigger[ID][ch]->setChecked( Digitizer::ExtractBits(dpp, DPP::Bit_DPPAlgorithmControl_PSD::DisableSelfTrigger)); + chkRejPileUp[ID][ch]->setChecked( Digitizer::ExtractBits(dpp, DPP::Bit_DPPAlgorithmControl_PSD::RejectPileup)); + chkPileUpInGate[ID][ch]->setChecked( Digitizer::ExtractBits(dpp, DPP::Bit_DPPAlgorithmControl_PSD::PileupWithinGate)); + chkDisableTriggerHysteresis[ID][ch]->setChecked( Digitizer::ExtractBits(dpp, DPP::Bit_DPPAlgorithmControl_PSD::DisableTriggerHysteresis)); + uint32_t dpp2 = digi[ID]->GetSettingFromMemory(DPP::PSD::DPPAlgorithmControl2_G, ch); - chkDisableOppositePulse[ID][ch]->setChecked( Digitizer::ExtractBits(dpp2, DPP::Bit_DPPAlgorithmControl_PSD::DisableOppositePolarityInhibitZeroCrossingOnCFD)); - chkDisableSelfTrigger[ID][ch]->setChecked( Digitizer::ExtractBits(dpp2, DPP::Bit_DPPAlgorithmControl_PSD::DisableSelfTrigger)); - chkRejPileUp[ID][ch]->setChecked( Digitizer::ExtractBits(dpp2, DPP::Bit_DPPAlgorithmControl_PSD::RejectPileup)); - chkPileUpInGate[ID][ch]->setChecked( Digitizer::ExtractBits(dpp2, DPP::Bit_DPPAlgorithmControl_PSD::PileupWithinGate)); - chkDisableTriggerHysteresis[ID][ch]->setChecked( Digitizer::ExtractBits(dpp2, DPP::Bit_DPPAlgorithmControl_PSD::DisableTriggerHysteresis)); - chkMarkSaturation[ID][ch]->setChecked( Digitizer::ExtractBits(dpp2, DPP::PSD::Bit_DPPAlgorithmControl2::MarkSaturation)); - chkResetTimestampByTRGIN[ID][ch]->setChecked( Digitizer::ExtractBits(dpp2, DPP::PSD::Bit_DPPAlgorithmControl2::ResetTimestampByTRGIN)); - + chkMarkSaturation[ID][ch]->setChecked( Digitizer::ExtractBits(dpp, DPP::PSD::Bit_DPPAlgorithmControl2::MarkSaturation)); + chkResetTimestampByTRGIN[ID][ch]->setChecked( Digitizer::ExtractBits(dpp, DPP::PSD::Bit_DPPAlgorithmControl2::ResetTimestampByTRGIN)); UpdateComboBoxBit(cbLocalTriggerValid[ID][ch], dpp2, DPP::PSD::Bit_DPPAlgorithmControl2::LocalTrigValidMode); UpdateComboBoxBit(cbAdditionLocalTrigValid[ID][ch], dpp2, DPP::PSD::Bit_DPPAlgorithmControl2::AdditionLocalTrigValid); diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index 478b459..bf3728a 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -20,8 +20,9 @@ #include "analyzers/EncoreAnalyzer.h" #include "analyzers/MUSICAnalyzer.h" #include "analyzers/RAISOR.h" +#include "analyzers/NeutronGamma.h" -std::vector onlineAnalyzerList = {"Coincident","Splie-Pole", "Encore", "RAISOR", "MUSICS"}; +std::vector onlineAnalyzerList = {"Coincident","Splie-Pole", "Encore", "RAISOR", "MUSICS", "Neutron-Gamma"}; FSUDAQ::FSUDAQ(QWidget *parent) : QMainWindow(parent){ DebugPrint("%s", "FSUDAQ"); @@ -34,7 +35,7 @@ FSUDAQ::FSUDAQ(QWidget *parent) : QMainWindow(parent){ scalar = nullptr; scope = nullptr; digiSettings = nullptr; - canvas = nullptr; + singleHistograms = nullptr; histThread = nullptr; onlineAnalyzer = nullptr; runTimer = new QTimer(); @@ -91,7 +92,7 @@ FSUDAQ::FSUDAQ(QWidget *parent) : QMainWindow(parent){ bnCanvas = new QPushButton("Online Histograms", this); layout->addWidget(bnCanvas, 1, 2); - connect(bnCanvas, &QPushButton::clicked, this, &FSUDAQ::OpenCanvas); + connect(bnCanvas, &QPushButton::clicked, this, &FSUDAQ::OpenSingleHistograms); bnSync = new QPushButton("Sync Boards", this); layout->addWidget(bnSync, 2, 1); @@ -333,7 +334,7 @@ FSUDAQ::~FSUDAQ(){ delete histThread; } - if( canvas ) delete canvas; + if( singleHistograms ) delete singleHistograms; if( onlineAnalyzer ) delete onlineAnalyzer; @@ -741,12 +742,12 @@ void FSUDAQ::OpenDigitizers(){ QCoreApplication::processEvents(); //to prevent Qt said application not responding. } - canvas = new SingleSpectra(digi, nDigi, rawDataPath); + singleHistograms = new SingleSpectra(digi, nDigi, rawDataPath); histThread = new TimingThread(this); - histThread->SetWaitTimeinSec(canvas->GetMaxFillTime()/1000.); + histThread->SetWaitTimeinSec(singleHistograms->GetMaxFillTime()/1000.); connect(histThread, &TimingThread::timeUp, this, [=](){ - if( canvas == nullptr && !canvas->IsFillHistograms()) return; - canvas->FillHistograms(); + if( singleHistograms == nullptr && !singleHistograms->IsFillHistograms()) return; + singleHistograms->FillHistograms(); }); LogMsg("====== " + QString("Done. Opened %1 digitizer(s).").arg(nDigi) + " ====="); @@ -799,10 +800,10 @@ void FSUDAQ::CloseDigitizers(){ } - if( canvas ){ - canvas->close(); - delete canvas; - canvas = nullptr; + if( singleHistograms ){ + singleHistograms->close(); + delete singleHistograms; + singleHistograms = nullptr; } if( digiSettings ){ @@ -1180,7 +1181,7 @@ void FSUDAQ::StartACQ(){ } lbScalarACQStatus->setText("ACQ On"); - if( canvas != nullptr ) histThread->start(); + if( singleHistograms != nullptr ) histThread->start(); bnStartACQ->setEnabled(false); bnStartACQ->setStyleSheet(""); @@ -1256,11 +1257,11 @@ void FSUDAQ::StopACQ(){ if( onlineAnalyzer ) onlineAnalyzer->StopThread(); - if( canvas && histThread->isRunning()){ + if( singleHistograms && histThread->isRunning()){ histThread->Stop(); histThread->quit(); histThread->wait(); - canvas->ClearInternalDataCount(); + singleHistograms->ClearInternalDataCount(); } lbScalarACQStatus->setText("ACQ Off"); @@ -1752,7 +1753,7 @@ void FSUDAQ::OpenScope(){ if( digiSettings ) digiSettings->setEnabled(!onOff); - if( canvas ){ + if( singleHistograms ){ if( onOff) { histThread->start(); }else{ @@ -1760,7 +1761,7 @@ void FSUDAQ::OpenScope(){ histThread->Stop(); histThread->quit(); histThread->wait(); - canvas->ClearInternalDataCount(); + singleHistograms->ClearInternalDataCount(); } } } @@ -1802,15 +1803,15 @@ void FSUDAQ::OpenDigiSettings(){ //*************************************************************** //*************************************************************** -void FSUDAQ::OpenCanvas(){ +void FSUDAQ::OpenSingleHistograms(){ DebugPrint("%s", "FSUDAQ"); - if( canvas == nullptr ) { - canvas = new SingleSpectra(digi, nDigi, rawDataPath); - canvas->show(); + if( singleHistograms == nullptr ) { + singleHistograms = new SingleSpectra(digi, nDigi, rawDataPath); + singleHistograms->show(); }else{ - canvas->show(); - canvas->activateWindow(); - canvas->LoadSetting(); + singleHistograms->show(); + singleHistograms->activateWindow(); + singleHistograms->LoadSetting(); } } @@ -1830,6 +1831,7 @@ void FSUDAQ::OpenAnalyzer(){ if( id == 2 ) onlineAnalyzer = new Encore(digi, nDigi); if( id == 3 ) onlineAnalyzer = new RAISOR(digi, nDigi); if( id == 4 ) onlineAnalyzer = new MUSIC(digi, nDigi); + if( id == 5 ) onlineAnalyzer = new NeutronGamma(digi, nDigi, rawDataPath); if( id >= 0 ) onlineAnalyzer->show(); }else{ @@ -1840,6 +1842,7 @@ void FSUDAQ::OpenAnalyzer(){ if( id == 2 ) onlineAnalyzer = new Encore(digi, nDigi); if( id == 3 ) onlineAnalyzer = new RAISOR(digi, nDigi); if( id == 4 ) onlineAnalyzer = new MUSIC(digi, nDigi); + if( id == 4 ) onlineAnalyzer = new NeutronGamma(digi, nDigi, rawDataPath); if( id >= 0 ){ onlineAnalyzer->show(); diff --git a/FSUDAQ.h b/FSUDAQ.h index e77b49c..751dd93 100644 --- a/FSUDAQ.h +++ b/FSUDAQ.h @@ -36,9 +36,9 @@ public: delete digiSettings; digiSettings = nullptr; } - if( canvas ) { - delete canvas; - canvas = nullptr; + if( singleHistograms ) { + delete singleHistograms; + singleHistograms = nullptr; } if( onlineAnalyzer ) { delete onlineAnalyzer; @@ -76,7 +76,7 @@ private slots: void OpenDigiSettings(); - void OpenCanvas(); + void OpenSingleHistograms(); void OpenAnalyzer(); @@ -193,7 +193,7 @@ private: DigiSettingsPanel * digiSettings; //@----- SingleSpectra - SingleSpectra * canvas; + SingleSpectra * singleHistograms; TimingThread * histThread; //@----- Analyzer diff --git a/FSUDAQ_Qt6.pro b/FSUDAQ_Qt6.pro index 11a87db..c0ca0bd 100644 --- a/FSUDAQ_Qt6.pro +++ b/FSUDAQ_Qt6.pro @@ -45,7 +45,8 @@ HEADERS += ClassData.h \ analyzers/SplitPoleAnalyzer.h \ analyzers/EncoreAnalyzer.h \ analyzers/MUSICAnalyzer.h \ - analyzers/RAISOR.h + analyzers/NeutronGamma.h \ + analyzers/RAISOR.h SOURCES += ClassDigitizer.cpp \ DigiSettingsPanel.cpp \ FSUDAQ.cpp \ diff --git a/analyzers/NeutronGamma.h b/analyzers/NeutronGamma.h new file mode 100644 index 0000000..a7494bb --- /dev/null +++ b/analyzers/NeutronGamma.h @@ -0,0 +1,308 @@ +#ifndef NEUTRONGAMMA_H +#define NEUTRONGAMMA_H + + +/***********************************\ + * + * This Analyzer does not use event builder, + * this simply use the energy_short and energy_long for each data. + * + *************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Analyser.h" + +//^==================================================== +//^==================================================== +class NeutronGamma : public Analyzer{ + Q_OBJECT + +public: + NeutronGamma(Digitizer ** digi, unsigned int nDigi, QString rawDataPath, QMainWindow * parent = nullptr): Analyzer(digi, nDigi, parent){ + this->digi = digi; + this->nDigi = nDigi; + this->settingPath = rawDataPath + "/NG_HistogramSettings.txt"; + + SetUpdateTimeInSec(1.0); + + isSignalSlotActive = false; + SetUpCanvas(); + + ClearInternalDataCount(); + }; + + ~NeutronGamma(){ + // for( unsigned int i = 0; i < nDigi; i++ ){ + // for( int ch = 0; ch < digi[i]->GetNumInputCh(); ch++){ + // delete hist2D[i][ch]; + // } + // } + delete hist2D; + } + + void ClearInternalDataCount(); + + // void LoadSetting(); + // void SaveSetting(); + +public slots: + void UpdateHistograms(); + +private: + QVector generateNonRepeatedCombination(int size); + void SetUpCanvas(); + + Digitizer ** digi; + unsigned short nDigi; + + Histogram2D * hist2D; + + RComboBox * cbDigi; + RComboBox * cbCh; + + QGroupBox * histBox; + QGridLayout * histLayout; + + int lastFilledIndex[MaxNDigitizer][MaxNChannels]; + int loopFilledIndex[MaxNDigitizer][MaxNChannels]; + + bool fillHistograms; + + QString settingPath; + + unsigned short maxFillTimeinMilliSec; + unsigned short maxFillTimePerDigi; + + bool isSignalSlotActive; + +}; + +inline void NeutronGamma::SetUpCanvas(){ + + setWindowTitle("Neutron-Gamma Separation"); + + QScreen * screen = QGuiApplication::primaryScreen(); + QRect screenGeo = screen->geometry(); + if( screenGeo.width() < 1000 || screenGeo.height() < 800) { + setGeometry(0, 0, screenGeo.width() - 100, screenGeo.height() - 100); + }else{ + setGeometry(0, 0, 1000, 800); + } + + QWidget * layoutWidget = new QWidget(this); + setCentralWidget(layoutWidget); + QVBoxLayout * layout = new QVBoxLayout(layoutWidget); + layoutWidget->setLayout(layout); + + {//^================================== + QGroupBox * controlBox = new QGroupBox("Control", this); + layout->addWidget(controlBox); + QGridLayout * ctrlLayout = new QGridLayout(controlBox); + controlBox->setLayout(ctrlLayout); + + + 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, [=](int index){ + isSignalSlotActive = false; + cbCh->clear(); + cbCh->addItem("All Ch", digi[index]->GetNumInputCh() ); + for( int i = 0; i < digi[index]->GetNumInputCh(); i++) cbCh->addItem("ch-" + QString::number( i ), i); + + hist2D->Clear(); + isSignalSlotActive = true; + }); + + cbCh = new RComboBox(this); + for( int i = 0; i < digi[0]->GetNumInputCh(); i++) cbCh->addItem("ch-" + QString::number( i ), i); + ctrlLayout->addWidget(cbCh, 0, 2, 1, 2); + // connect( cbCh, &RComboBox::currentIndexChanged, this, &SingleSpectra::ChangeHistView); + connect( cbCh, &RComboBox::currentIndexChanged, this, [=](){ + hist2D->Clear(); + }); + + QCheckBox * chkIsFillHistogram = new QCheckBox("Fill Histograms", this); + ctrlLayout->addWidget(chkIsFillHistogram, 0, 8); + connect(chkIsFillHistogram, &QCheckBox::stateChanged, this, [=](int state){ fillHistograms = state;}); + chkIsFillHistogram->setChecked(false); + fillHistograms = false; + + QLabel * lbSettingPath = new QLabel( settingPath , this); + ctrlLayout->addWidget(lbSettingPath, 1, 0, 1, 8); + + } + + {//^==================================== + + histBox = new QGroupBox("Histgrams", this); + layout->addWidget(histBox, 10); + histLayout = new QGridLayout(histBox); + histBox->setLayout(histLayout); + + double eMax = 50000; + double eMin = 0; + double nBin = 1000; + + // for( unsigned int i = 0; i < MaxNDigitizer; i++){ + // if( i >= nDigi ) continue; + // for( int j = 0; j < digi[i]->GetNumInputCh(); j++){ + // if( i < nDigi ) { + // hist2D[i][j] = new Histogram2D("Digi-" + QString::number(digi[i]->GetSerialNumber()), "Long Energy [ch]", "Short Energy [ch]", nBin, eMin, eMax, nBin, eMin, eMax); + // }else{ + // hist2D[i][j] = nullptr; + // } + // } + // } + // histLayout->addWidget(hist2D[0][0], 0, 0); + + hist2D = new Histogram2D("Neutron-Gamma", "PSD = (l-s)/l", "Short Energy [ch]", nBin, eMin, eMax, nBin, 0, 1); + + histLayout->addWidget(hist2D, 0, 0); + + } + +} + +inline void NeutronGamma::ClearInternalDataCount(){ + for( unsigned int i = 0; i < nDigi; i++){ + for( int ch = 0; ch < MaxRegChannel ; ch++) { + lastFilledIndex[i][ch] = -1; + loopFilledIndex[i][ch] = 0; + } + } +} + +inline void NeutronGamma::UpdateHistograms(){ + if( !fillHistograms ) return; + if( this->isVisible() == false ) return; + + int ID = cbDigi->currentData().toInt(); + int ch = cbCh->currentData().toInt(); + + int lastIndex = digi[ID]->GetData()->GetDataIndex(ch); + if( lastIndex < 0 ) return; + + 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; + + if( temp1 - temp2 > digi[ID]->GetData()->GetDataSize() ) { //DefaultDataSize = 10k + temp2 = temp1 - digi[ID]->GetData()->GetDataSize(); + lastFilledIndex[ID][ch] = lastIndex; + lastFilledIndex[ID][ch] = loopIndex - 1; + } + + 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); + + double psd = (data_long - data_short) *1.0 / data_long; + + 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); + + for (int i = 0; i < size - 1; ++i) { + int j = QRandomGenerator::global()->bounded(i, size); + combination.swapItemsAt(i, j); + } + return combination; +} + +#endif \ No newline at end of file