diff --git a/ClassData.h b/ClassData.h index 46bdc2a..233c9e4 100644 --- a/ClassData.h +++ b/ClassData.h @@ -29,12 +29,14 @@ class Data{ uint32_t AllocatedSize; double TriggerRate[MaxNChannels]; /// Hz + double NonPileUpRate[MaxNChannels]; /// Hz unsigned long TotNumEvents[MaxNChannels]; - unsigned short NumEventsDecoded[MaxNChannels]; + unsigned short NumEventsDecoded[MaxNChannels]; /// reset at every decode + unsigned short NumNonPileUpDecoded[MaxNChannels]; /// reset at every decode - /// store a single Raw event + /// store data for event building bool IsNotRollOverFakeAgg; - unsigned short NumEvents[MaxNChannels]; + unsigned short NumEvents[MaxNChannels]; /// max 65535, reset only clear Data unsigned long long Timestamp[MaxNChannels][MaxNData]; /// 47 bit unsigned short fineTime[MaxNChannels][MaxNData]; /// 10 bits, in unit of ch2ns / 1000 = ps unsigned short Energy[MaxNChannels][MaxNData]; /// 15 bit @@ -144,7 +146,9 @@ inline void Data::Allocate80MBMemory(){ inline void Data::ClearTriggerRate(){ for( int i = 0 ; i < MaxNChannels; i++) { TriggerRate[i] = 0.0; + NonPileUpRate[i] = 0.0; NumEventsDecoded[i] = 0; + NumNonPileUpDecoded[i] = 0; } } @@ -340,6 +344,7 @@ inline void Data::DecodeBuffer(bool fastDecode, int verbose){ double sec = dTime * ch2ns / 1e9; if( sec != 0 && NumEventsDecoded[ch] > 1 ){ TriggerRate[ch] = NumEventsDecoded[ch]/sec; + NonPileUpRate[ch] = NumNonPileUpDecoded[ch]/sec; } } @@ -532,14 +537,21 @@ inline int Data::DecodePHADualChannelBlock(unsigned int ChannelMask, bool fastDe printf(" trapezoid sat. : %d \n", ((extra >> 10) & 0x1) ); } - if( rollOver == 0 ) { + + if( rollOver == 0 ) { // non-time roll over fake event Energy[channel][NumEvents[channel]] = energy; Timestamp[channel][NumEvents[channel]] = timeStamp; if(extra2Option == 0 || extra2Option == 2 ) fineTime[channel][NumEvents[channel]] = (extra2 & 0x07FF ); NumEvents[channel] ++; NumEventsDecoded[channel] ++; TotNumEvents[channel] ++; + + if( !pileUp ) { + NumNonPileUpDecoded[channel] ++; + } } + + if( NumEvents[channel] >= MaxNData ) ClearData(); if( verbose >= 1 ) printf("%4d | ch : %2d, PileUp : %d , energy : %5d, rollOver: %d, timestamp : %10llu, triggerAt : %d, nSample : %d, %f sec\n", NumEvents[channel], channel, pileUp, energy, rollOver, timeStamp, triggerAtSample, nSample , timeStamp * 4. / 1e9); @@ -710,8 +722,11 @@ inline int Data::DecodePSDDualChannelBlock(unsigned int ChannelMask, bool fastDe NumEvents[channel] ++; NumEventsDecoded[channel] ++; TotNumEvents[channel] ++; + } - + + if( NumEvents[channel] >= MaxNData ) ClearData(); + if( verbose >= 2 ) printf("extra : 0x%08x, Qshort : %d, Qlong : %d \n", extra, Qshort, Qlong); if( verbose >= 1 ) printf("ch : %2d, Qshort : %d, Qlong : %d, timestamp : %llu\n", diff --git a/CustomThreads.h b/CustomThreads.h index d9cc63c..914d950 100644 --- a/CustomThreads.h +++ b/CustomThreads.h @@ -17,8 +17,10 @@ public: this->digi = dig; this->ID = digiID; isSaveData = false; + isScope = false; } - void SetSaveData(bool onOff) {this->isSaveData = onOff;} + void SetSaveData(bool onOff) {this->isSaveData = onOff;} + void SetScopeMode(bool onOff) {this->isScope = onOff;} void run(){ clock_gettime(CLOCK_REALTIME, &ta); while(true){ @@ -28,15 +30,12 @@ public: if( ret == CAEN_DGTZ_Success ){ digiMTX[ID].lock(); - if( isSaveData ) { - digi->GetData()->SaveData(); - }else{ - digi->GetData()->DecodeBuffer(false); - } + digi->GetData()->DecodeBuffer(!isScope); + if( isSaveData ) digi->GetData()->SaveData(); digiMTX[ID].unlock(); }else{ - printf("%s------------ ret : %d \n", __func__, ret); + printf("ReadDataThread::%s------------ ret : %d \n", __func__, ret); if( ret == CAEN_DGTZ_WrongAcqMode) break; } @@ -72,47 +71,19 @@ private: int ID; timespec ta, tb; bool isSaveData; + bool isScope; }; -//^#===================================================== UpdateTrace Thread -class UpdateTraceThread : public QThread { +//^#======================================================= Timing Thread +class TimingThread : public QThread { Q_OBJECT public: - UpdateTraceThread(QObject * parent = 0) : QThread(parent){ - waitTime = 2; - stop = false; - } - unsigned int GetWaitTimeSec() const {return waitTime;} - void SetWaitTimeSec(unsigned sec) {waitTime = sec;} - void Stop() {this->stop = true;} - void run(){ - unsigned int count = 0; - stop = false; - do{ - usleep(100000); - count ++; - if( count % waitTime == 0){ - emit updateTrace(); - } - }while(!stop); - } -signals: - void updateTrace(); - -private: - bool stop; - unsigned int waitTime; //100 of milisec -}; - -//^#======================================================= Scalar Thread -class ScalarThread : public QThread { - Q_OBJECT -public: - ScalarThread(QObject * parent = 0 ) : QThread(parent){ + TimingThread(QObject * parent = 0 ) : QThread(parent){ waitTime = 20; // 10 x 100 milisec stop = false; } void Stop() { this->stop = true;} + void SetWaitTimeinSec(float sec) {waitTime = sec * 10 ;} unsigned int GetWaitTimeinSec() const {return waitTime/10;} void run(){ unsigned int count = 0; diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index cbcf68c..b06fdf2 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -182,8 +182,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ lbLastUpdateTime = nullptr; lbScalarACQStatus = nullptr; - scalarThread = new ScalarThread(); - //connect(scalarThread, &ScalarThread::updataScalar, this, &MainWindow::UpdateScalar); + scalarThread = new TimingThread(); + connect(scalarThread, &TimingThread::updataScalar, this, &MainWindow::UpdateScalar); } @@ -198,6 +198,14 @@ MainWindow::~MainWindow(){ SaveProgramSettings(); if( scope ) delete scope; + + if( scalar ) { + CleanUpScalar(); + scalarThread->Stop(); + scalarThread->quit(); + scalarThread->exit(); + delete scalarThread; + } } @@ -522,7 +530,18 @@ void MainWindow::OpenScalar(){ } void MainWindow::UpdateScalar(){ + if( digi == nullptr ) return; + + lbLastUpdateTime->setText("Last update: " + QDateTime::currentDateTime().toString("MM.dd hh:mm:ss")); + for( unsigned int iDigi = 0; iDigi < nDigi; iDigi++){ + Data * data = digi[iDigi]->GetData(); + + for( int i = 0; i < digi[iDigi]->GetNChannels(); i++){ + leTrigger[iDigi][i]->setText(QString::number(data->TriggerRate[i])); + leAccept[iDigi][i]->setText(QString::number(data->NonPileUpRate[i])); + } + } } @@ -532,34 +551,52 @@ void MainWindow::UpdateScalar(){ void MainWindow::StartACQ(){ if( digi == nullptr ) return; - if( CommentDialog(true) == false) return; + bool commentResult = true; + if( chkSaveData->isChecked() ) commentResult = CommentDialog(true); + if( commentResult == false) return; for( unsigned int i = 0; i < nDigi ; i++){ digi[i]->GetData()->OpenSaveFile((rawDataPath + "/" + prefix).toStdString()); digi[i]->StartACQ(); - readDataThread[i]->SetSaveData(true); + readDataThread[i]->SetSaveData(chkSaveData->isChecked()); readDataThread[i]->start(); } + if( chkSaveData->isChecked() ) SaveLastRunFile(); + scalarThread->start(); - SaveLastRunFile(); + if( !scalar->isVisible() ) { + scalar->show(); + }else{ + scalar->activateWindow(); + } + lbScalarACQStatus->setText("ACQ On"); } void MainWindow::StopACQ(){ if( digi == nullptr ) return; - if( CommentDialog(false) == false) return; + bool commentResult = true; + if( chkSaveData->isChecked() ) commentResult = CommentDialog(true); + if( commentResult == false) return; for( unsigned int i = 0; i < nDigi; i++){ digi[i]->StopACQ(); - digi[i]->GetData()->CloseSaveFile(); + if( chkSaveData->isChecked() ) digi[i]->GetData()->CloseSaveFile(); if( readDataThread[i]->isRunning() ) { readDataThread[i]->quit(); readDataThread[i]->wait(); } } + + if( scalarThread->isRunning()){ + scalarThread->Stop(); + scalarThread->quit(); + scalarThread->wait(); + } + lbScalarACQStatus->setText("ACQ Off"); } void MainWindow::AutoRun(){ diff --git a/FSUDAQ.h b/FSUDAQ.h index d513aa0..d314f68 100644 --- a/FSUDAQ.h +++ b/FSUDAQ.h @@ -92,7 +92,7 @@ private: //@----- Scalar QMainWindow * scalar; QGridLayout * scalarLayout; - ScalarThread * scalarThread; + TimingThread * scalarThread; QLineEdit *** leTrigger; // need to delete manually QLineEdit *** leAccept; // need to delete manually QLabel * lbLastUpdateTime; diff --git a/Scope.cpp b/Scope.cpp index 9a19bf3..b8e4cf2 100644 --- a/Scope.cpp +++ b/Scope.cpp @@ -48,7 +48,9 @@ Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataTh xaxis->setLabelFormat("%.0f"); xaxis->setTitleText("Time [ns]"); - updateTraceThread = new UpdateTraceThread(); + updateTraceThread = new TimingThread(); + updateTraceThread->SetWaitTimeinSec(0.5); + //connect(updateTraceThread, &UpdateTraceThread::updateTrace, this, &Scope::UpdateScope); //*================================== UI @@ -115,7 +117,7 @@ Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataTh QLabel * lbhints = new QLabel("Type 'r' to restore view, '+/-' Zoom in/out, arrow key to pan.", this); layout->addWidget(lbhints, rowID, 0, 1, 4); - QLabel * lbinfo = new QLabel("Trace update every " + QString::number(updateTraceThread->GetWaitTimeSec()) + " sec.", this); + QLabel * lbinfo = new QLabel("Trace update every " + QString::number(updateTraceThread->GetWaitTimeinSec()) + " sec.", this); lbinfo->setAlignment(Qt::AlignRight); layout->addWidget(lbinfo, rowID, 5); diff --git a/Scope.h b/Scope.h index 59f909a..e8d6f83 100644 --- a/Scope.h +++ b/Scope.h @@ -53,7 +53,7 @@ private: int ch2ns; ReadDataThread ** readDataThread; - UpdateTraceThread * updateTraceThread; + TimingThread * updateTraceThread; bool enableSignalSlot;