diff --git a/ClassDigitizer2Gen.h b/ClassDigitizer2Gen.h index e690b46..0831989 100644 --- a/ClassDigitizer2Gen.h +++ b/ClassDigitizer2Gen.h @@ -64,10 +64,10 @@ class Digitizer2Gen { Digitizer2Gen(); ~Digitizer2Gen(); - unsigned short GetSerialNumber() {return serialNumber;} + unsigned short GetSerialNumber() const{return serialNumber;} void SetDummy(unsigned short sn); - bool IsDummy() {return isDummy;} + bool IsDummy() const {return isDummy;} int OpenDigitizer(const char * url); bool IsConnected() const {return isConnected;} @@ -100,8 +100,10 @@ class Digitizer2Gen { // 3 = only ch, energy, timestamp, minimum // 15 = raw data int ReadData(); - int ReadStat(); + int ReadStat(); // digitizer update it every 500 msec void PrintStat(); + uint32_t GetTriggerCount(int ch) const {return triggerCount[ch];} + uint64_t GetRealTime(int ch) const {return realTime[ch];} void Reset(); void ProgramPHA(bool testPulse = false); diff --git a/mainwindow.cpp b/mainwindow.cpp index f859f4a..f88d80d 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -43,6 +43,10 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ scalarLayout->setSpacing(0); leTrigger = NULL; + leAccept = NULL; + + scalarThread = new ScalarThread(); + connect(scalarThread, &ScalarThread::updataScalar, this, &MainWindow::UpdateScalar); } QWidget * mainLayoutWidget = new QWidget(this); @@ -203,6 +207,7 @@ MainWindow::~MainWindow(){ printf("- %s\n", __func__); DeleteTriggerLineEdit(); + delete scalarThread; CloseDigitizers(); //---- need manually delete @@ -233,6 +238,9 @@ void MainWindow::StartACQ(){ readDataThread[i]->start(); } + if( !scalar->isVisible() ) scalar->show(); + scalarThread->start(); + bnStartACQ->setEnabled(false); bnStopACQ->setEnabled(true); bnOpenScope->setEnabled(false); @@ -252,6 +260,10 @@ void MainWindow::StopACQ(){ } + scalarThread->Stop(); + scalarThread->quit(); + scalarThread->wait(); + LogMsg("Stop Run"); bnStartACQ->setEnabled(true); bnStopACQ->setEnabled(false); @@ -260,6 +272,9 @@ void MainWindow::StopACQ(){ runID ++; leRunID->setText(QString::number(runID)); + //if( scalarThread->isRunning()) printf("Scalar Thread still running.\n"); + //if( scalarThread->isFinished()) printf("Scalar Thread finsihed.\n"); + } //^###################################################################### open and close digitizer @@ -380,7 +395,7 @@ void MainWindow::OpenScaler(){ void MainWindow::SetUpScalar(){ - scalar->setGeometry(0, 0, 10 + nDigi * 100, 1000); + scalar->setGeometry(0, 0, 10 + nDigi * 200, 1000); int rowID = 0; for( int ch = 0; ch < MaxNumberOfChannel; ch++){ @@ -396,22 +411,30 @@ void MainWindow::SetUpScalar(){ } leTrigger = new QLineEdit**[nDigi]; + leAccept = new QLineEdit**[nDigi]; for( int iDigi = 0; iDigi < nDigi; iDigi++){ rowID = 0; leTrigger[iDigi] = new QLineEdit *[digi[iDigi]->GetNChannels()]; + leAccept[iDigi] = new QLineEdit *[digi[iDigi]->GetNChannels()]; for( int ch = 0; ch < MaxNumberOfChannel; ch++){ if( ch == 0 ){ QLabel * lbDigi = new QLabel("Digi-" + QString::number(digi[iDigi]->GetSerialNumber()), scalar); lbDigi->setAlignment(Qt::AlignCenter); - scalarLayout->addWidget(lbDigi, rowID, iDigi+1); + scalarLayout->addWidget(lbDigi, rowID, 2*iDigi+1, 1, 2); } rowID ++; leTrigger[iDigi][ch] = new QLineEdit(); leTrigger[iDigi][ch]->setReadOnly(true); - scalarLayout->addWidget(leTrigger[iDigi][ch], rowID, iDigi+1); + leTrigger[iDigi][ch]->setAlignment(Qt::AlignRight); + scalarLayout->addWidget(leTrigger[iDigi][ch], rowID, 2*iDigi+1); + + leAccept[iDigi][ch] = new QLineEdit(); + leAccept[iDigi][ch]->setReadOnly(true); + leAccept[iDigi][ch]->setAlignment(Qt::AlignRight); + scalarLayout->addWidget(leAccept[iDigi][ch], rowID, 2*iDigi+2); } } @@ -419,19 +442,55 @@ void MainWindow::SetUpScalar(){ void MainWindow::DeleteTriggerLineEdit(){ - printf("__________ %s \n", __func__); - if( leTrigger == NULL ) return; for( int i = 0; i < nDigi; i++){ for( int ch = 0; ch < digi[i]->GetNChannels(); ch ++){ delete leTrigger[i][ch]; + delete leAccept[i][ch]; } delete [] leTrigger[i]; + delete [] leAccept[i]; } delete [] leTrigger; leTrigger = NULL; - printf("end of ____ %s \n", __func__); + leAccept = NULL; + +} + +void MainWindow::UpdateScalar(){ + if( !digi ) return; + + ///===== Get trigger for all channel + for( int iDigi = 0; iDigi < nDigi; iDigi ++ ){ + if( digi[iDigi]->IsDummy() ) return; + + //=========== use ReadStat to get the trigger rate + //digiMTX.lock(); + //digi[iDigi]->ReadStat(); // digitizer update it every 500 msec; + //digiMTX.unlock(); + //for( int ch = 0; ch < digi[iDigi]->GetNChannels(); ch ++){ + // leTrigger[iDigi][ch]->setText(QString::number(digi[iDigi]->GetTriggerCount(ch)*1e9*1.0/ digi[iDigi]->GetRealTime(ch))); + //} + + //=========== another method, directly readValue + digiMTX.lock(); + for( int ch = 0; ch < digi[iDigi]->GetNChannels(); ch ++){ + std::string time = digi[iDigi]->ReadChValue(std::to_string(ch), DIGIPARA::CH::ChannelRealtime); // for refreashing SelfTrgRate and SavedCount + std::string haha = digi[iDigi]->ReadChValue(std::to_string(ch), DIGIPARA::CH::SelfTrgRate); + leTrigger[iDigi][ch]->setText(QString::fromStdString(haha)); + std::string kaka = digi[iDigi]->ReadChValue(std::to_string(ch), DIGIPARA::CH::ChannelSavedCount); + double acceptRate = atoi(kaka.c_str())*1e9*1.0 / atol(time.c_str()); + //if( kaka != "0" ) { + // printf("%s, %s | %.2f\n", time.c_str(), kaka.c_str(), acceptRate); + //} + leAccept[iDigi][ch]->setText(QString::number(acceptRate,'f', 1)); + + ///TODO============== push the trigger, acceptRate rate database + + } + digiMTX.unlock(); + } } diff --git a/mainwindow.h b/mainwindow.h index a481f6f..a41da53 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -45,6 +45,7 @@ private slots: void OpenScaler(); void SetUpScalar(); void DeleteTriggerLineEdit(); + void UpdateScalar(); void ProgramSettings(); bool OpenProgramSettings(); @@ -59,10 +60,7 @@ private slots: void CreateRawDataFolderAndLink(const QString newExpName); void closeEvent(QCloseEvent * event){ - printf("___ %s \n", __func__); - printf("+++++++++++++++ digiSetting %p\n", digiSetting); if( digiSetting != NULL ) digiSetting->close(); - printf("+++++++++++++++ scope %p\n", scope); if( scope != NULL ) scope->close(); event->accept(); } @@ -90,7 +88,9 @@ private: QMainWindow * scalar; QPushButton * bnOpenScalar; QLineEdit *** leTrigger; // need to delete manually + QLineEdit *** leAccept; // need to delete manually QGridLayout * scalarLayout; + ScalarThread * scalarThread; //@------ ACQ things QPushButton * bnStartACQ; diff --git a/manyThread.h b/manyThread.h index 162398f..31ada72 100644 --- a/manyThread.h +++ b/manyThread.h @@ -31,7 +31,7 @@ public: digi->ErrorMsg("No more data"); break; }else{ - digi->ErrorMsg("ReadDataLoop()"); + //digi->ErrorMsg("ReadDataLoop()"); digi->evt->ClearTrace(); } @@ -83,4 +83,32 @@ private: unsigned int waitTime; //100 of milisec }; +//^#======================================================= Scalar Thread +class ScalarThread : public QThread { + Q_OBJECT +public: + ScalarThread(QObject * parent = 0 ) : QThread(parent){ + waitTime = 20; // 10 x 100 milisec + stop = false; + } + void Stop() { this->stop = true;} + unsigned int GetWaitTimeinSec() const {return waitTime/10;} + void run(){ + unsigned int count = 0; + stop = false; + do{ + usleep(100000); + count ++; + if( count % waitTime == 0){ + emit updataScalar(); + } + }while(!stop); + } +signals: + void updataScalar(); +private: + bool stop; + unsigned int waitTime; +}; + #endif diff --git a/scope.cpp b/scope.cpp index a9f3850..6707708 100644 --- a/scope.cpp +++ b/scope.cpp @@ -334,6 +334,15 @@ Scope::Scope(Digitizer2Gen **digi, unsigned int nDigi, ReadDataThread ** readDat layout->addWidget(bnScopeStop, rowID, 1); connect(bnScopeStop, &QPushButton::clicked, this, &Scope::StopScope); + QLabel * lbTriggerRate = new QLabel("Trigger Rate [Hz] : ", this); + lbTriggerRate->setAlignment(Qt::AlignCenter | Qt::AlignRight); + layout->addWidget(lbTriggerRate, rowID, 2); + + leTriggerRate = new QLineEdit(this); + leTriggerRate->setAlignment(Qt::AlignRight); + leTriggerRate->setReadOnly(true); + layout->addWidget(leTriggerRate, rowID, 3); + QPushButton * bnClose = new QPushButton("Close", this); layout->addWidget(bnClose, rowID, 5); connect(bnClose, &QPushButton::clicked, this, &Scope::close); @@ -458,16 +467,25 @@ void Scope::StopScope(){ void Scope::UpdateScope(){ int iDigi = cbScopeDigi->currentIndex(); + int ch = cbScopeCh->currentIndex(); int sample2ns = DIGIPARA::TraceStep * (1 << cbWaveRes->currentIndex()); if( digi ){ - digiMTX.lock(); - unsigned int traceLength = digi[iDigi]->evt->traceLenght; - unsigned int dataLength = dataTrace[0]->count(); - //---- remove all points + unsigned int dataLength = dataTrace[0]->count(); for( int j = 0; j < 6; j++ ) dataTrace[j]->removePoints(0, dataLength); + digiMTX.lock(); + std::string time = digi[iDigi]->ReadChValue(std::to_string(ch), DIGIPARA::CH::ChannelRealtime); // for refreashing SelfTrgRate and SavedCount + std::string haha = digi[iDigi]->ReadChValue(std::to_string(ch), DIGIPARA::CH::SelfTrgRate); + leTriggerRate->setText(QString::fromStdString(haha)); + if( atoi(haha.c_str()) == 0 ) { + digiMTX.unlock(); + return; + } + + unsigned int traceLength = digi[iDigi]->evt->traceLenght; + for( unsigned int i = 0 ; i < traceLength; i++){ for( int j = 0; j < 2; j++) dataTrace[j]->append(sample2ns * i, digi[iDigi]->evt->analog_probes[j][i]); for( int j = 2; j < 6; j++) dataTrace[j]->append(sample2ns * i, (j-1)*1000 + 4000 * digi[iDigi]->evt->digital_probes[j-2][i]); diff --git a/scope.h b/scope.h index ddca303..009e7d6 100644 --- a/scope.h +++ b/scope.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -164,6 +165,8 @@ private: QComboBox * cbWaveRes; QComboBox * cbTrapPeakAvg; + QLineEdit * leTriggerRate; + QSpinBox * sbBaselineGuard; QSpinBox * sbPileUpGuard; QComboBox * cbBaselineAvg;