From 93f89d92646722f398756baf50680249be3eee31 Mon Sep 17 00:00:00 2001 From: "Ryan@WorkStation" Date: Fri, 23 Feb 2024 18:31:39 -0500 Subject: [PATCH] simplify trigger rate calculation --- ClassData.h | 166 ++++++++++++++++++--------------------------- ClassDigitizer.cpp | 11 ++- FSUDAQ.cpp | 13 ++-- README.md | 8 ++- Scope.cpp | 6 +- 5 files changed, 91 insertions(+), 113 deletions(-) diff --git a/ClassData.h b/ClassData.h index 2cf5432..7b4b958 100644 --- a/ClassData.h +++ b/ClassData.h @@ -45,10 +45,6 @@ class Data{ unsigned int aggTime; /// update every decode - /// store data for event building and deduce the trigger rate. - //it is a circular memory - bool IsNotRollOverFakeAgg; - int GetLoopIndex(unsigned short ch) const {return LoopIndex[ch];} int GetDataIndex(unsigned short ch) const {return DataIndex[ch];} @@ -78,6 +74,7 @@ class Data{ void ClearDataPointer(); void ClearData(); void ClearTriggerRate(); + void ClearNumEventsDecoded(); void ClearBuffer(); unsigned short GetNChannel() const {return numInputCh;} @@ -102,6 +99,9 @@ class Data{ uint64_t GetTotalFileSize() const {return FinishedOutFilesSize + outFileSize;} void ZeroTotalFileSize() { FinishedOutFilesSize = 0; } + void CalTriggerRate(); + void ClearReferenceTime(); + protected: const unsigned short numInputCh; @@ -132,7 +132,9 @@ class Data{ std::string outFilePrefix; std::string outFileName; unsigned int outFileSize; // should be max at 2 GB - + + ullong t0[MaxNChannels]; // for trigger rate calculation + short calIndexes[MaxNChannels][2]; /// the index for trigger rate calculation unsigned int ReadBuffer(unsigned int nWord, int verbose = 0); @@ -149,14 +151,17 @@ inline Data::Data(unsigned short numCh, uShort dataSize): numInputCh(numCh){ boardSN = 0; DPPType = DPPType::DPP_PHA_CODE; DPPTypeStr = ""; - IsNotRollOverFakeAgg = false; buffer = NULL; AllocateDataSize(dataSize); - for ( int i = 0; i < MaxNChannels; i++) TotNumNonPileUpEvents[i] = 0; + for ( int i = 0; i < MaxNChannels; i++) { + TotNumNonPileUpEvents[i] = 0; + t0[i] = 0; + } ClearData(); ClearTriggerRate(); + ClearNumEventsDecoded(); nw = 0; outFileIndex = 0; @@ -265,6 +270,11 @@ inline void Data::ClearTriggerRate(){ for( int i = 0 ; i < MaxNChannels; i++) { TriggerRate[i] = 0.0; NonPileUpRate[i] = 0.0; + } +} + +inline void Data::ClearNumEventsDecoded(){ + for( int i = 0 ; i < MaxNChannels; i++) { NumEventsDecoded[i] = 0; NumNonPileUpDecoded[i] = 0; } @@ -273,7 +283,6 @@ inline void Data::ClearTriggerRate(){ inline void Data::ClearData(){ nByte = 0; AllocatedSize = 0; - IsNotRollOverFakeAgg = false; for( int ch = 0 ; ch < MaxNChannels; ch++){ LoopIndex[ch] = 0; DataIndex[ch] = -1; @@ -322,6 +331,50 @@ inline void Data::CopyBuffer(const char * buffer, const unsigned int size){ std::memcpy(this->buffer, buffer, size); } +inline void Data::ClearReferenceTime(){ + for( int ch = 0; ch < numInputCh; ch ++ ) t0[ch] = 0; +} + +inline void Data::CalTriggerRate(){ + + for( int ch = 0; ch < numInputCh; ch ++ ){ + if( t0[ch] == 0 ) { + TriggerRate[ch] = 0; + NonPileUpRate[ch] = 0; + continue; + } + + if( NumEventsDecoded[ch] < dataSize ){ + + unsigned long long dTime = Timestamp[ch][DataIndex[ch]] - t0[ch]; + double sec = dTime / 1e9; + + TriggerRate[ch] = (NumEventsDecoded[ch]-1)/sec; + NonPileUpRate[ch] = (NumNonPileUpDecoded[ch]-1)/sec; + + }else{ + + uShort nEvent = 100; + unsigned long long dTime = Timestamp[ch][DataIndex[ch]] - Timestamp[ch][DataIndex[ch] - 100]; + double sec = dTime / 1e9; + + TriggerRate[ch] = (nEvent-1)/sec; + NonPileUpRate[ch] = (NumNonPileUpDecoded[ch])/sec * (nEvent-1)/(NumEventsDecoded[ch]); + + } + // printf("%2d | %d(%d)| %llu %llu | %d %d | %llu, %.3e | %.2f, %.2f\n", ch, DataIndex[ch], LoopIndex[ch], + // t0[ch], Timestamp[ch][DataIndex[ch]], + // NumEventsDecoded[ch], NumNonPileUpDecoded[ch], + // dTime, sec , + // TriggerRate[ch], NonPileUpRate[ch]); + + t0[ch] = Timestamp[ch][DataIndex[ch]]; + NumEventsDecoded[ch] = 0; + NumNonPileUpDecoded[ch] = 0; + } + +} + //^############################################### //^############################################### Save fsu file inline bool Data::OpenSaveFile(std::string fileNamePrefix){ @@ -400,10 +453,6 @@ inline void Data::CloseSaveFile(){ inline void Data::PrintStat(bool skipEmpty) { printf("============================= Print Stat. Digi-%d\n", boardSN); - if( !IsNotRollOverFakeAgg ) { - printf(" this is roll-over fake event or no events.\n"); - return; - } printf("%2s | %6s | %9s | %9s | %6s | %6s(%4s)\n", "ch", "# Evt.", "Rate [Hz]", "Accept", "Tot. Evt.", "index", "loop"); printf("---+--------+-----------+-----------+----------\n"); for(int ch = 0; ch < numInputCh; ch++){ @@ -414,6 +463,7 @@ inline void Data::PrintStat(bool skipEmpty) { printf("---+--------+-----------+-----------+----------\n"); ClearTriggerRate(); + ClearNumEventsDecoded(); } @@ -566,95 +616,11 @@ inline void Data::DecodeBuffer(bool fastDecode, int verbose){ ///printf("nw : %d ,x 4 = %d, nByte : %d \n", nw, 4*nw, nByte); }while(4*nw < nByte); - // bool debug = false; - // if( DPPType == DPPType::DPP_QDC_CODE ) debug = true; - - ///^===================Calculate trigger rate and first and last Timestamp - for(int ch = 0; ch < MaxNChannels; ch++){ - if( ch > numInputCh ) continue; - if( DataIndex[ch] < 0 ) continue; - - if( NumEventsDecoded[ch] > 0 ) { - // printf("%s | ch %d | %d %d \n", __func__, ch, LoopIndex[ch], DataIndex[ch]); - IsNotRollOverFakeAgg = true; - }else{ - // TriggerRate[ch] = 0; - // NonPileUpRate[ch] = 0; - continue; - } - - // if( debug ) printf("Ch : %2d | Decoded Event : %d \n", ch, NumEventsDecoded[ch]); - - if( NumEventsDecoded[ch] > 4 ){ - - int indexStart = DataIndex[ch] - NumEventsDecoded[ch] + 1; - if( indexStart < 0 ) indexStart += dataSize; - - unsigned long long dTime = Timestamp[ch][DataIndex[ch]] - Timestamp[ch][indexStart]; - double sec = dTime / 1e9; - - TriggerRate[ch] = (NumEventsDecoded[ch]-1)/sec; - NonPileUpRate[ch] = (NumNonPileUpDecoded[ch]-1)/sec; - // if( debug ) printf("%d %d| %d %d | %llu, %.3e | %.2f, %.2f\n", indexStart, DataIndex[ch], NumEventsDecoded[ch], NumNonPileUpDecoded[ch], dTime, sec , TriggerRate[ch], NonPileUpRate[ch]); - - }else{ // look in to the data in the memory, not just this agg. - - const short nEvent = 10; - - if( TotNumNonPileUpEvents[ch] >= nEvent ){ - - calIndexes[ch][1] = DataIndex[ch]; - calIndexes[ch][0] = DataIndex[ch] - nEvent + 1; - if (calIndexes[ch][0] < 0 ) calIndexes[ch][0] += dataSize; - - // std::vector tList ; - // for( int i = 0; i < nEvent ; i ++){ - // int j = (calIndexes[ch][0] + i) % dataSize; - // tList.push_back( Timestamp[ch][j]); - // } - // if( DPPType == DPPType::DPP_QDC_CODE){ - // //std::sort(tList.begin(), tList.end()); - // unsigned long long t0 = tList.front(); // earlier - // unsigned long long t1 = tList.back(); // latest - - // for( int i = 0; i < (int) tList.size(); i++){ - // if( t0 < tList[i]) t0 = tList[i]; - // if( t1 > tList[i]) t1 = tList[i]; - // } - // tList.front() = t0; - // tList.back() = t1; - // } - //double sec = ( tList.back() - tList.front() ) * tick2ns / 1e9; - - - unsigned long long t0 = Timestamp[ch][(calIndexes[ch][0]) % dataSize]; // earlier - unsigned long long t1 = Timestamp[ch][(calIndexes[ch][1]) % dataSize];; // latest - - if( t0 > t1 ) { - printf("digi-%d, ch-%d | data is not in time order\n", boardSN, ch); - unsigned long long tt = t1; - t1 = t0; - t0 = tt; - } - - double sec = ( t1 - t0 ) * tick2ns / 1e9; - - TriggerRate[ch] = nEvent / sec; - - short pileUpCount = 0; - for( int i = 0 ; i < nEvent; i++ ) { - int j = (calIndexes[ch][0] + i) % dataSize; - if( PileUp[ch][j] ) pileUpCount ++; - } - NonPileUpRate[ch] = (nEvent - pileUpCount)/sec; - - // if( debug ) printf("%2d | %10llu %10llu, %d = %f sec, rate = %f, nEvent %d pileUp %d \n", ch, t1, t0, tick2ns, sec, nEvent / sec, nEvent, pileUpCount); - } - - } - + //Set the t0 for when frist hit comes + for( int ch = 0; ch < numInputCh; ch++){ + if( t0[ch] == 0 && DataIndex[ch] > 0 ) t0[ch] = Timestamp[ch][0]; } - + } //*================================================= diff --git a/ClassDigitizer.cpp b/ClassDigitizer.cpp index 30731fc..7328a37 100644 --- a/ClassDigitizer.cpp +++ b/ClassDigitizer.cpp @@ -483,7 +483,7 @@ void Digitizer::StartACQ(){ if( softwareDisable ) return; if ( AcqRun ) return; - ret |= CAEN_DGTZ_SetDPPEventAggregation(handle, 0, 0); // Auto set + // ret |= CAEN_DGTZ_SetDPPEventAggregation(handle, 0, 0); // Auto set unsigned int bufferSize = 0; if( DPPType == V1730_DPP_PHA_CODE ){ @@ -536,6 +536,10 @@ void Digitizer::StartACQ(){ } + AcqRun = true; + data->ClearTriggerRate(); + data->ClearData(); + printf(" ACQ mode : %s (%d), TRG-OUT mode : %s (%d) \n", acqStr.c_str(), acqID, trgOutStr.c_str(), trgOutID); ret = CAEN_DGTZ_SWStartAcquisition(handle); @@ -545,8 +549,7 @@ void Digitizer::StartACQ(){ } printf("\e[1m\e[33m======= Acquisition Started for %d | Board %d, Port %d\e[0m\n", BoardInfo.SerialNumber, boardID, portID); - AcqRun = true; - data->ClearTriggerRate(); + } @@ -559,7 +562,9 @@ void Digitizer::StopACQ(){ AcqRun = false; data->PrintStat(); data->ClearTriggerRate(); + data->ClearNumEventsDecoded(); data->ClearBuffer(); + data->ClearReferenceTime(); data->ZeroTotalFileSize(); } diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index 46dd761..d0438f8 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -340,13 +340,13 @@ void MainWindow::OpenDataPath(){ if( result > 0 ) { leDataPath->setText(fileDialog.selectedFiles().at(0)); rawDataPath = leDataPath->text(); - chkSaveData->setEnabled(true); }else{ leDataPath->clear(); rawDataPath = ""; - chkSaveData->setEnabled(false); } + if( !rawDataPath.isEmpty() ) chkSaveData->setEnabled(true); + SaveProgramSettings(); LoadLastRunFile(); @@ -468,7 +468,7 @@ void MainWindow::LoadProgramSettings(){ if( rawDataDir.mkdir(rawDataPath) ){ LogMsg("Created folder " + rawDataPath + " for storing root files."); }else{ - LogMsg("" + rawDataPath + " cannot be created. Access right problem? " ); + LogMsg("" + rawDataPath + " Raw data folder cannot be created. Access right problem? " ); } }else{ LogMsg("" + rawDataPath + " already exist." ); @@ -830,6 +830,7 @@ void MainWindow::SetupScalar(){ lbScalarACQStatus = nullptr; scalarThread = new TimingThread(scalar); + scalarThread->SetWaitTimeinSec(1.0); connect(scalarThread, &TimingThread::timeUp, this, &MainWindow::UpdateScalar); unsigned short maxNChannel = 0; @@ -987,6 +988,7 @@ void MainWindow::UpdateScalar(){ if(digiSettings && digiSettings->isVisible() && digiSettings->GetTabID() == iDigi) digiSettings->UpdateACQStatus(acqStatus); digiMTX[iDigi].lock(); + digi[iDigi]->GetData()->CalTriggerRate(); // printf("### %d ", iDigi); // digi[iDigi]->GetData()->PrintAllData(true, 10); if( chkSaveData->isChecked() ) totalFileSize += digi[iDigi]->GetData()->GetTotalFileSize(); @@ -995,7 +997,7 @@ void MainWindow::UpdateScalar(){ QString b = ""; if( digi[iDigi]->GetInputChannelOnOff(i) == true ) { - //printf(" %3d %2d | %7.2f %7.2f \n", digi[iDigi]->GetSerialNumber(), i, digi[iDigi]->GetData()->TriggerRate[i], digi[iDigi]->GetData()->NonPileUpRate[i]); + // printf(" %3d %2d | %7.2f %7.2f \n", digi[iDigi]->GetSerialNumber(), i, digi[iDigi]->GetData()->TriggerRate[i], digi[iDigi]->GetData()->NonPileUpRate[i]); QString a = QString::number(digi[iDigi]->GetData()->TriggerRate[i], 'f', 2); QString b = QString::number(digi[iDigi]->GetData()->NonPileUpRate[i], 'f', 2); leTrigger[iDigi][i]->setText(a); @@ -1007,8 +1009,6 @@ void MainWindow::UpdateScalar(){ } } - - digi[iDigi]->GetData()->ClearTriggerRate(); digiMTX[iDigi].unlock(); } @@ -1052,7 +1052,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()->ClearData(); digi[i]->StartACQ(); diff --git a/README.md b/README.md index b8652bd..4740532 100644 --- a/README.md +++ b/README.md @@ -98,8 +98,14 @@ if you want to use GDB debugger, in the *.pro file add There is a folder Aux, this folder contains many auxillary programs, such as EventBuilder. User can `make` under the folder to compile the programs. +# Tested Trigger Rate + +* V1725, 1 MHz to 3 ch (decay = 500 ns), no trace. need to set Agg/Read = 1023 and Evt/Agg = 511. + # Known Issues +* Pile up rate is not accurate for very high input rate ( > 60 kHz ). +* When using the scope, the Agg/Read must be smaller than 512. * Although the Events/Agg used the CAEN API to recalculate before ACQ start, for PHA firmware, when the trigger rate changed, the Events per Agg need to be changed. * The Agg Organization, Event per Agg, Record Length are strongly correlated. Some settings are invalid and will cause the digitizer goes crazy. * load digitizer setting would not load everything, only load the channel settings and some board settings. @@ -109,4 +115,4 @@ There is a folder Aux, this folder contains many auxillary programs, such as Eve # Known Bugs -* There is no known bug. Please report to rtang@fsu.edu if you find one. +* EventBuilder will crash when trigger rate of the data is very high. \ No newline at end of file diff --git a/Scope.cpp b/Scope.cpp index 2d06fbf..31731b2 100644 --- a/Scope.cpp +++ b/Scope.cpp @@ -369,9 +369,11 @@ void Scope::StartScope(){ traceOn[iDigi] = digi[iDigi]->IsRecordTrace(); //remember setting SendLogMsg("Digi-" + QString::number(digi[iDigi]->GetSerialNumber()) + " is starting ACQ." ); digi[iDigi]->WriteRegister(DPP::SoftwareClear_W, 1); - digi[iDigi]->GetData()->ClearData(); digi[iDigi]->SetBits(DPP::BoardConfiguration, DPP::Bit_BoardConfig::RecordTrace, 1, -1); + // SendLogMsg("Set Events/Agg to 1 for scope"); + // digi[iDigi]->WriteRegister(DPP::NumberEventsPerAggregate_G, 1, -1); + readDataThread[iDigi]->SetScopeMode(true); readDataThread[iDigi]->SetSaveData(false); @@ -484,7 +486,7 @@ void Scope::UpdateScope(){ if( traceLength * tick2ns * factor > MaxDisplayTraceTimeLength) traceLength = MaxDisplayTraceTimeLength / tick2ns/ factor; //printf("--- %s| %d, %d, %d | %ld(%d) | %d, %d | %d\n", __func__, ch, data->GetLoopIndex(ch), index, data->Waveform1[ch][index].size(), traceLength, factor, tick2ns, traceLength * tick2ns * factor ); - if( index > 0 && data->TriggerRate[ch] > 0 ){ + if( index > 0 ){ QVector points[5]; if( digi[ID]->GetDPPType() == V1730_DPP_PHA_CODE ) {