From dcb3d73776a37a55d1319a0c4e7ecae143758fe4 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Mon, 10 Jun 2024 16:22:01 -0400 Subject: [PATCH 01/72] add prefix in RunTimeStamp.dat --- Aux/EventBuilder.cpp | 4 +++- Aux/fsuReader.h | 26 +++++++++++++++----------- FSUDAQ.cpp | 6 +++--- README.md | 1 + 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/Aux/EventBuilder.cpp b/Aux/EventBuilder.cpp index f572582..b3853b6 100644 --- a/Aux/EventBuilder.cpp +++ b/Aux/EventBuilder.cpp @@ -167,7 +167,7 @@ int main(int argc, char **argv) { } reader[i] = new FSUReader(fList, 600, debug); hitList[i] = reader[i]->ReadBatch(batchSize, debug ); - reader[i]->PrintHitListInfo(hitList[i], "hitList-" + std::to_string(reader[i]->GetSN())); + reader[i]->PrintHitListInfo(&hitList[i], "hitList-" + std::to_string(reader[i]->GetSN())); ID[i] = 0; if( debug ) { @@ -216,6 +216,7 @@ int main(int argc, char **argv) { //chekc if reached the end of hitList if( ID[ig] >= hitList[ig].size() ) { hitList[ig] = reader[ig]->ReadBatch(batchSize, debug + 1); + if( debug ) reader[ig]->PrintHitListInfo( &hitList[ig], "hitList-" + std::to_string(ig)); ID[ig] = 0; if( hitList[ig].size() == 0 ) continue; } @@ -234,6 +235,7 @@ int main(int argc, char **argv) { //check if reached the end of hitList if( ID[ig] >= hitList[ig].size() ) { hitList[ig] = reader[ig]->ReadBatch(batchSize, debug); + if( debug ) reader[ig]->PrintHitListInfo( &hitList[ig], "hitList-" + std::to_string(ig)); ID[ig] = 0; if( hitList[ig].size() == 0 ) break; } diff --git a/Aux/fsuReader.h b/Aux/fsuReader.h index a45b545..67c6e8e 100644 --- a/Aux/fsuReader.h +++ b/Aux/fsuReader.h @@ -79,13 +79,14 @@ class FSUReader{ } } - static void PrintHitListInfo(std::vector hitList, std::string name){ - size_t n = hitList.size(); + static void PrintHitListInfo(std::vector * hitList, std::string name){ + size_t n = hitList->size(); size_t s = sizeof(Hit); printf("============== %s, size : %zu | %.2f MByte\n", name.c_str(), n, n*s/1024./1024.); if( n > 0 ){ - printf("t0 : %15llu \n", hitList.at(0).timestamp); - printf("t1 : %15llu \n", hitList.back().timestamp); + printf("t0 : %15llu ns\n", hitList->front().timestamp); + printf("t1 : %15llu ns\n", hitList->back().timestamp); + printf("dt : %15.3f ms\n", (hitList->back().timestamp - hitList->front().timestamp)/1e6); } } @@ -94,8 +95,9 @@ class FSUReader{ size_t s = sizeof(Hit); printf("============== reader.hit, size : %zu | %.2f MByte\n", n, n*s/1024./1024.); if( n > 0 ){ - printf("t0 : %15llu \n", hit.at(0).timestamp); - printf("t1 : %15llu \n", hit.back().timestamp); + printf("t0 : %15llu ns\n", hit.at(0).timestamp); + printf("t1 : %15llu ns\n", hit.back().timestamp); + printf("dt : %15.3f ms\n", (hit.back().timestamp - hit.front().timestamp)/1e6); } } @@ -472,8 +474,9 @@ inline std::vector FSUReader::ReadBatch(unsigned int batchSize, bool verbos uLong t1_B = hit.back().timestamp; if( verbose ) { printf(" hit in memeory : %7zu | %u | %lu \n", hit.size(), filePos, inFileSize); - printf("t0 : %15lu\n", t0_B); - printf("t1 : %15lu\n", t1_B); + printf("t0 : %15lu ns\n", t0_B); + printf("t1 : %15lu ns\n", t1_B); + printf("dt : %15.3f ms\n", (t1_B - t0_B)/1e6); } hitList_A = hit; @@ -500,6 +503,7 @@ inline std::vector FSUReader::ReadBatch(unsigned int batchSize, bool verbos printf(" hit in memeory : %7zu | %u | %lu \n", hit.size(), filePos, inFileSize); printf("t0 : %15lu\n", t0_B); printf("t1 : %15lu\n", t1_B); + printf("dt : %15.3f ms\n", (t1_B - t0_B)/1e6); } uLong t0_A = hitList_A.at(0).timestamp; @@ -552,8 +556,8 @@ inline std::vector FSUReader::ReadBatch(unsigned int batchSize, bool verbos if( verbose ) { printf("----------------- ID_A : %lu, Drop\n", ID_A); printf("----------------- ID_B : %lu, Drop\n", ID_B); - PrintHitListInfo(hitList_A, "hitList_A"); - PrintHitListInfo(hitTemp, "hitTemp"); + PrintHitListInfo(&hitList_A, "hitList_A"); + PrintHitListInfo(&hitTemp, "hitTemp"); PrintHitListInfo(); printf("=========== sume of A + B + Temp : %zu \n", hitList_A.size() + hit.size() + hitTemp.size()); printf("----------------- refill hitList_A \n"); @@ -565,7 +569,7 @@ inline std::vector FSUReader::ReadBatch(unsigned int batchSize, bool verbos hitTemp.clear(); if( verbose ) { - PrintHitListInfo(hitList_A, "hitList_A"); + PrintHitListInfo(&hitList_A, "hitList_A"); PrintHitListInfo(); printf("=========== sume of A + B : %zu \n", hitList_A.size() + hit.size()); } diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index feb768b..5dd9619 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -55,7 +55,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ cbOpenDigitizers = new RComboBox(this); cbOpenDigitizers->addItem("Open Digitizers ... ", 0); - cbOpenDigitizers->addItem("Open Digitizers via Optical", 1); + cbOpenDigitizers->addItem("Open Digitizers via Optical/USB", 1); // cbOpenDigitizers->addItem("Open Digitizers (default program)", 2); // cbOpenDigitizers->addItem("Open Digitizers + load Settings", 3); //cbOpenDigitizers->addItem("Open Digitizers via USB", 3); @@ -1679,9 +1679,9 @@ void MainWindow::WriteRunTimestamp(bool isStartRun){ if( file.open(QIODevice::Text | QIODevice::WriteOnly | QIODevice::Append) ){ if( isStartRun ){ - file.write(("Start Run | " + QString::number(runID) + " | " + dateTime + " | " + startComment + "\n").toStdString().c_str()); + file.write(("Start Run | " + QString::number(runID) + " | " + dateTime + " | " + lePrefix->text() + " | " + startComment + "\n").toStdString().c_str()); }else{ - file.write((" Stop Run | " + QString::number(runID) + " | " + dateTime + " | " + stopComment + "\n").toStdString().c_str()); + file.write((" Stop Run | " + QString::number(runID) + " | " + dateTime + " | " + lePrefix->text() + " | " + stopComment + "\n").toStdString().c_str()); } file.close(); diff --git a/README.md b/README.md index 9dd2f42..8fe1edb 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,7 @@ Ubuntu 22.04 - CAENCOmm v1.5.3 + - CAENDigitizer v2.17.1 + - CAEN A3818 Driver v1.6.8 + +- CAENUSBdrv v1.5.5 + (for V57XX digitizer with USB connection) - qt6-base-dev - libqt6charts6-dec From a9b98c36f3d84b8c27f18c122e615e188b6fd2bb Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Tue, 11 Jun 2024 16:15:50 -0400 Subject: [PATCH 02/72] snapshot --- Aux/test.cpp | 4 +++- FSUDAQ.cpp | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Aux/test.cpp b/Aux/test.cpp index 7282f69..ae5dbae 100644 --- a/Aux/test.cpp +++ b/Aux/test.cpp @@ -324,13 +324,15 @@ int TestDigitizerRaw(){ //^====================================== int main(int argc, char* argv[]){ - TestDigitizerRaw(); + //TestDigitizerRaw(); // CheckBufferSize(5, 4); //GetOneAgg(); + Digitizer * digi = new Digitizer(0, 49093, 0, true); + delete digi; // digi->WriteRegister(DPP::QDC::PreTrigger, 60, -1); diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index 5dd9619..076a902 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -589,6 +589,7 @@ void MainWindow::OpenDigitizers(){ if( !file.open(QIODevice::Text | QIODevice::ReadOnly) ) { LogMsg("" + a4818Path + " not found."); LogMsg("Please create such file and put the a4818 PIDs inseperate lines."); + cbOpenDigitizers->setCurrentIndex(0); return; }else{ QTextStream in(&file); @@ -606,8 +607,8 @@ void MainWindow::OpenDigitizers(){ return; }else{ - if( a4818PIDs.size() > 4){ - LogMsg("There are more than 4 a4818, please edit the MaxNPorts in macro.h and recompile."); + if( a4818PIDs.size() > MaxNPorts){ + LogMsg("There are more than "+ QString::number(MaxNPorts) + " a4818, please edit the MaxNPorts in macro.h and recompile."); } } From e9e5ae3023a84e7667deaa56121a14d026d848fc Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Thu, 13 Jun 2024 14:55:51 -0400 Subject: [PATCH 03/72] ClassData::ClearData reset the outFileIndex = 0 --- Aux/EventBuilder.cpp | 2 +- ClassData.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Aux/EventBuilder.cpp b/Aux/EventBuilder.cpp index b3853b6..f6d5662 100644 --- a/Aux/EventBuilder.cpp +++ b/Aux/EventBuilder.cpp @@ -84,7 +84,7 @@ int main(int argc, char **argv) { totalHitCount += readerA->GetHitCount(); for( int i = 1; i < nFile; i++){ - FSUReader * readerB = new FSUReader(inFileName[i].Data(), 1, 0); + FSUReader * readerB = new FSUReader(inFileName[i].Data(), 1, 1); readerB->ScanNumBlock(0,0); totalHitCount += readerB->GetHitCount(); fileInfo = {inFileName[i].Data(), readerB->GetSN() * 1000 + readerB->GetFileOrder(), readerB->GetHitCount()}; diff --git a/ClassData.h b/ClassData.h index 92cbed4..676cd19 100644 --- a/ClassData.h +++ b/ClassData.h @@ -330,6 +330,8 @@ inline void Data::ClearData(){ tempDigiWaveform3.clear(); tempDigiWaveform4.clear(); + outFileIndex = 0; + ClearNumEventsDecoded(); ClearTriggerRate(); From 106fe3f15533a01eb1427def6e178e0dafa1110c Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Thu, 13 Jun 2024 16:12:29 -0400 Subject: [PATCH 04/72] change some names in MultiBuilder.h, add setting for event time window in SPlitpotle analyszer --- MultiBuilder.h | 6 +++--- analyzers/SplitPoleAnalyzer.h | 20 +++++++++++++++++--- analyzers/SplitPoleHit.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/MultiBuilder.h b/MultiBuilder.h index 9251b94..dd09f58 100644 --- a/MultiBuilder.h +++ b/MultiBuilder.h @@ -14,16 +14,16 @@ public: MultiBuilder(Data * singleData, int type, int sn); ~MultiBuilder(); - void SetTimeWindow(unsigned short ticks) {timeWindow = ticks; leftOverTime = ticks;} + void SetTimeWindow(unsigned short nanosec) {timeWindow = nanosec; leftOverTime = nanosec;} unsigned short GetTimeWindow() const{return timeWindow;} void SetTimeJump(unsigned long long TimeJumpInNanoSec) {timeJump = TimeJumpInNanoSec;} unsigned long long GetTimeJump() const {return timeJump;} - void SetLeftOverTime(unsigned long long ticks) {leftOverTime = ticks;} + void SetLeftOverTime(unsigned long long nanosec) {leftOverTime = nanosec;} unsigned long long GetLeftOverTime() const{return leftOverTime;} - void SetBreakTime(unsigned long long ticks) {breakTime = ticks;} + void SetBreakTime(unsigned long long nanosec) {breakTime = nanosec;} unsigned long long GetBreakTime() const{return breakTime;} unsigned int GetNumOfDigitizer() const {return nData;} diff --git a/analyzers/SplitPoleAnalyzer.h b/analyzers/SplitPoleAnalyzer.h index cee5b81..0bd1748 100644 --- a/analyzers/SplitPoleAnalyzer.h +++ b/analyzers/SplitPoleAnalyzer.h @@ -31,7 +31,7 @@ public: tick2ns = digi[0]->GetTick2ns(); 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); + evtbder->SetTimeWindow(1000); //========== use the influx from the Analyzer influx = new InfluxDB("https://fsunuc.physics.fsu.edu/influx/"); @@ -87,6 +87,7 @@ private: RSpinBox * sbEnergy; RSpinBox * sbAngle; + RSpinBox * sbEventWin; QCheckBox * chkRunAnalyzer; QLineEdit * leMassTablePath; @@ -212,9 +213,22 @@ inline void SplitPole::SetUpCanvas(){ FillConstants(); }); - chkRunAnalyzer = new QCheckBox("Run Analyzer", this); - boxLayout->addWidget(chkRunAnalyzer, 4, 1); + QLabel * lbEventWindow = new QLabel("Event Window [ns] ", box); + lbEventWindow->setAlignment(Qt::AlignRight | Qt::AlignCenter); + boxLayout->addWidget(lbEventWindow, 4, 0); + sbEventWin = new RSpinBox(this); + sbEventWin->setDecimals(0); + sbEventWin->setSingleStep(100); + sbEventWin->setMaximum(1000000); + boxLayout->addWidget(sbEventWin, 4, 1); + sbEventWin->setValue(1000); + connect(sbEventWin, &RSpinBox::returnPressed, this, [=](){ + evtbder->SetTimeWindow(sbEventWin->value()); + }); + + chkRunAnalyzer = new QCheckBox("Run Analyzer", this); + boxLayout->addWidget(chkRunAnalyzer, 4, 3); QFrame *separator = new QFrame(box); separator->setFrameShape(QFrame::HLine); diff --git a/analyzers/SplitPoleHit.h b/analyzers/SplitPoleHit.h index cd2d005..43fbdc0 100644 --- a/analyzers/SplitPoleHit.h +++ b/analyzers/SplitPoleHit.h @@ -42,7 +42,7 @@ namespace SPS{ const short dBR = 10; const short dBL = 11; const short Cathode = 7; - const short AnodeF = 13; + const short AnodeF = 12; const short AnodeB = 15; }; From d0133cc86413b3bbcbd346ef6f5828de4f6632bb Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Mon, 17 Jun 2024 17:44:31 -0400 Subject: [PATCH 05/72] bugs fix on SingleSpectrum 2D historgram not loading saved setting --- Histogram2D.h | 9 ++--- SingleSpectra.cpp | 87 +++++++++++++++++++++++++++++------------------ SingleSpectra.h | 2 +- 3 files changed, 60 insertions(+), 38 deletions(-) diff --git a/Histogram2D.h b/Histogram2D.h index 88f8eed..bafd9f2 100644 --- a/Histogram2D.h +++ b/Histogram2D.h @@ -338,6 +338,9 @@ inline void Histogram2D::Rebin(int xbin, double xmin, double xmax, int ybin, do } } + rescaleAxes(); + UpdatePlot(); + } inline void Histogram2D::RebinY(int ybin, double ymin, double ymax){ @@ -593,7 +596,7 @@ inline void Histogram2D::rightMouseClickRebin(){ lineEditX[i] = new QLineEdit(&dialog); layout.addRow(nameListX[i] + " : ", lineEditX[i]); } - lineEditX[0]->setText(QString::number(xBin)); + lineEditX[0]->setText(QString::number(xBin-2)); lineEditX[1]->setText(QString::number(xMin)); lineEditX[2]->setText(QString::number(xMax)); @@ -603,7 +606,7 @@ inline void Histogram2D::rightMouseClickRebin(){ lineEditY[i] = new QLineEdit(&dialog); layout.addRow(nameListY[i] + " : ", lineEditY[i]); } - lineEditY[0]->setText(QString::number(yBin)); + lineEditY[0]->setText(QString::number(yBin-2)); lineEditY[1]->setText(QString::number(yMin)); lineEditY[2]->setText(QString::number(yMax)); @@ -666,8 +669,6 @@ inline void Histogram2D::rightMouseClickRebin(){ if( dialog.exec() == QDialog::Accepted ){ isBusy = true; Rebin((int)number[0][0], number[1][0], number[2][0], (int)number[0][1], number[1][1], number[2][1]); - rescaleAxes(); - UpdatePlot(); isBusy = false; } diff --git a/SingleSpectra.cpp b/SingleSpectra.cpp index 40e2ad2..85fdad7 100644 --- a/SingleSpectra.cpp +++ b/SingleSpectra.cpp @@ -9,7 +9,7 @@ SingleSpectra::SingleSpectra(Digitizer ** digi, unsigned int nDigi, QString rawD DebugPrint("%s", "SingleSpectra"); this->digi = digi; this->nDigi = nDigi; - this->rawDataPath = rawDataPath; + this->settingPath = rawDataPath + "/HistogramSettings.txt"; maxFillTimeinMilliSec = 1000; maxFillTimePerDigi = maxFillTimeinMilliSec/nDigi; @@ -169,6 +169,9 @@ SingleSpectra::SingleSpectra(Digitizer ** digi, unsigned int nDigi, QString rawD chkIsFillHistogram->setChecked(false); fillHistograms = false; + QLabel * lbSettingPath = new QLabel( settingPath , this); + ctrlLayout->addWidget(lbSettingPath, 1, 0, 1, 8); + } {//^======================== @@ -361,37 +364,53 @@ void SingleSpectra::FillHistograms(){ void SingleSpectra::SaveSetting(){ DebugPrint("%s", "SingleSpectra"); - QFile file(rawDataPath + "/singleSpectraSetting.txt"); - file.open(QIODevice::Text | QIODevice::WriteOnly); + QFile file(settingPath ); - for( unsigned int i = 0; i < nDigi; i++){ - file.write(("======= " + QString::number(digi[i]->GetSerialNumber()) + "\n").toStdString().c_str()); - for( int ch = 0; ch < digi[i]->GetNumInputCh() ; ch++){ - QString a = QString::number(ch).rightJustified(2, ' '); - QString b = QString::number(hist[i][ch]->GetNBin()).rightJustified(6, ' '); - QString c = QString::number(hist[i][ch]->GetXMin()).rightJustified(6, ' '); - QString d = QString::number(hist[i][ch]->GetXMax()).rightJustified(6, ' '); - file.write( QString("%1 %2 %3 %4\n").arg(a).arg(b).arg(c).arg(d).toStdString().c_str() ); + if (!file.exists()) { + // If the file does not exist, create it + if (!file.open(QIODevice::WriteOnly)) { + qWarning() << "Could not create file" << settingPath; + } else { + qDebug() << "File" << settingPath << "created successfully"; + file.close(); } - - QString a = QString::number(digi[i]->GetNumInputCh()).rightJustified(2, ' '); - QString b = QString::number(hist2D[i]->GetXNBin()).rightJustified(6, ' '); - QString c = QString::number(hist2D[i]->GetXMin()).rightJustified(6, ' '); - QString d = QString::number(hist2D[i]->GetXMax()).rightJustified(6, ' '); - QString e = QString::number(hist2D[i]->GetYNBin()).rightJustified(6, ' '); - QString f = QString::number(hist2D[i]->GetYMin()).rightJustified(6, ' '); - QString g = QString::number(hist2D[i]->GetYMax()).rightJustified(6, ' '); - file.write( QString("%1 %2 %3 %4 %5 %6 %7\n").arg(a).arg(b).arg(c).arg(d).arg(e).arg(f).arg(g).toStdString().c_str() ); } - file.write("//========== End of file\n"); - file.close(); + if( file.open(QIODevice::Text | QIODevice::WriteOnly) ){ + + for( unsigned int i = 0; i < nDigi; i++){ + file.write(("======= " + QString::number(digi[i]->GetSerialNumber()) + "\n").toStdString().c_str()); + for( int ch = 0; ch < digi[i]->GetNumInputCh() ; ch++){ + QString a = QString::number(ch).rightJustified(2, ' '); + QString b = QString::number(hist[i][ch]->GetNBin()).rightJustified(6, ' '); + QString c = QString::number(hist[i][ch]->GetXMin()).rightJustified(6, ' '); + QString d = QString::number(hist[i][ch]->GetXMax()).rightJustified(6, ' '); + file.write( QString("%1 %2 %3 %4\n").arg(a).arg(b).arg(c).arg(d).toStdString().c_str() ); + } + + QString a = QString::number(digi[i]->GetNumInputCh()).rightJustified(2, ' '); + QString b = QString::number(hist2D[i]->GetXNBin()-2).rightJustified(6, ' '); + QString c = QString::number(hist2D[i]->GetXMin()).rightJustified(6, ' '); + QString d = QString::number(hist2D[i]->GetXMax()).rightJustified(6, ' '); + QString e = QString::number(hist2D[i]->GetYNBin()-2).rightJustified(6, ' '); + QString f = QString::number(hist2D[i]->GetYMin()).rightJustified(6, ' '); + QString g = QString::number(hist2D[i]->GetYMax()).rightJustified(6, ' '); + file.write( QString("%1 %2 %3 %4 %5 %6 %7\n").arg(a).arg(b).arg(c).arg(d).arg(e).arg(f).arg(g).toStdString().c_str() ); + } + + file.write("##========== End of file\n"); + file.close(); + + }else{ + printf("%s|cannot open HistogramSettings.txt\n", __func__); + } } void SingleSpectra::LoadSetting(){ DebugPrint("%s", "SingleSpectra"); - QFile file(rawDataPath + "/singleSpectraSetting.txt"); + + QFile file(settingPath); if( file.open(QIODevice::Text | QIODevice::ReadOnly) ){ @@ -402,7 +421,7 @@ void SingleSpectra::LoadSetting(){ int digiID = -1; while ( !line.isNull() ){ - if( line.contains("//========== ") ) break; + if( line.contains("##========== ") ) break; if( line.contains("//") ) continue; if( line.contains("======= ") ){ digiSN = line.mid(7).toInt(); @@ -422,21 +441,21 @@ void SingleSpectra::LoadSetting(){ QStringList list = line.split(QRegularExpression("\\s+")); list.removeAll(""); - if( list.count() != 4 ) { - line = in.readLine(); - continue; - } - QVector data; + // if( list.count() != 4 ) { + // line = in.readLine(); + // continue; + // } + QVector data; for( int i = 0; i < list.count(); i++){ - data.push_back(list[i].toInt()); + data.push_back(list[i].toFloat()); } if( 0 <= data[0] && data[0] < digi[digiID]->GetNumInputCh() ){ - hist[digiID][data[0]]->Rebin(data[1], data[2], data[3]); + hist[digiID][int(data[0])]->Rebin(data[1], data[2], data[3]); } - if( data[0] == digi[digiID]->GetNumInputCh() && data.size() == 7 ){ - hist2D[digiID]->Rebin(data[1], data[2], data[3], data[4], data[5], data[6]); + if( int(data[0]) == digi[digiID]->GetNumInputCh() && data.size() == 7 ){ + hist2D[digiID]->Rebin(int(data[1]), data[2], data[3], int(data[4]), data[5], data[6]); } } @@ -446,6 +465,8 @@ void SingleSpectra::LoadSetting(){ }else{ + printf("%s|cannot open HistogramSettings.txt\n", __func__); + } } diff --git a/SingleSpectra.h b/SingleSpectra.h index 4e04a8f..721f05c 100644 --- a/SingleSpectra.h +++ b/SingleSpectra.h @@ -71,7 +71,7 @@ private: bool fillHistograms; - QString rawDataPath; + QString settingPath; unsigned short maxFillTimeinMilliSec; unsigned short maxFillTimePerDigi; From ae6b13313876257fe1e2158b66d7c9ffa526e18c Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Tue, 18 Jun 2024 13:45:08 -0400 Subject: [PATCH 06/72] added FSU2CAEN.cpp, this is a program to timesort the fsu files and output to CoMPASS binary format --- .gitignore | 1 + Aux/FSU2CAEN.cpp | 236 +++++++++++++++++++++++++++++++++++++++++++++++ Aux/Makefile | 12 +-- 3 files changed, 241 insertions(+), 8 deletions(-) create mode 100644 Aux/FSU2CAEN.cpp diff --git a/.gitignore b/.gitignore index 7527a69..bd788c2 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ DAQLock.dat DumpFSU2ROOT SettingsExplorer AggSeparator +FSU2CAEN data diff --git a/Aux/FSU2CAEN.cpp b/Aux/FSU2CAEN.cpp new file mode 100644 index 0000000..a802b20 --- /dev/null +++ b/Aux/FSU2CAEN.cpp @@ -0,0 +1,236 @@ +#include "fsuReader.h" + +struct FileInfo{ + std::string fileName; + int fileevID; + unsigned long hitCount; +}; + +const unsigned short header = 0xCAE1; +const unsigned int flags = 0; + +#define minNARG 4 + +//^############################################################# +//^############################################################# +int main(int argc, char **argv) { + + printf("=========================================\n"); + printf("=== *.fsu to CoMPASS bin ===\n"); + printf("=== no trace, no flags ===\n"); + printf("=========================================\n"); + if (argc < minNARG) { + printf("Incorrect number of arguments:\n"); + printf("%s [tar] [batchSize] [inFile1] [inFile2] .... \n", argv[0]); + printf(" tar : output tar, 0 = no, 1 = yes \n"); + printf(" batchSize : the size of hit in a batch \n"); + printf("\n"); + printf(" Example: %s 100000 '\\ls -1 *001*.fsu'\n", argv[0]); + printf("\n\n"); + + return 1; + } + unsigned int debug = false; + + uInt runStartTime = getTime_us(); + + ///============= read input + // long timeWindow = atoi(argv[1]); + // bool traceOn = atoi(argv[2]); + bool tarFlag = atoi(argv[1]); + unsigned int batchSize = atoi(argv[2]); + int nFile = argc - minNARG + 1; + std::string inFileName[nFile]; + for( int i = 0 ; i < nFile ; i++){ inFileName[i] = argv[i+ minNARG - 1];} + + + std::string temp = inFileName[0]; + size_t pos = temp.find('_'); + pos = temp.find('_', pos + 1); + std::string outFile_prefix = temp.substr(0, pos); + std::string outFileName = outFile_prefix + ".BIN"; + + + printf("========================================= Number of Files : %d \n", nFile); + for( int i = 0; i < nFile; i++) printf("%2d | %s \n", i, inFileName[i].c_str()); + printf("=========================================\n"); + printf(" Include Trace = %s\n", "No"); + printf(" Batch size = %d events/file\n", batchSize); + printf(" Out file name = %s \n", outFileName.c_str()); + printf(" Is tar output = %s \n", tarFlag ? "Yes" : "No"); + printf("========================================= Grouping files\n"); + + std::vector> fileGroupList; // fileName and evID = SN * 1000 + index + std::vector fileList; + + unsigned long long int totalHitCount = 0; + + FSUReader * readerA = new FSUReader(inFileName[0], 1, 1); + readerA->ScanNumBlock(0,0); + FileInfo fileInfo = {inFileName[0], readerA->GetSN() * 1000 + readerA->GetFileOrder(), readerA->GetHitCount()}; + fileList.push_back(fileInfo); + totalHitCount += readerA->GetHitCount(); + + for( int i = 1; i < nFile; i++){ + FSUReader * readerB = new FSUReader(inFileName[i], 1, 1); + readerB->ScanNumBlock(0,0); + totalHitCount += readerB->GetHitCount(); + fileInfo = {inFileName[i], readerB->GetSN() * 1000 + readerB->GetFileOrder(), readerB->GetHitCount()}; + + if( readerA->GetSN() == readerB->GetSN() ){ + fileList.push_back(fileInfo); + }else{ + fileGroupList.push_back(fileList); + fileList.clear(); + fileList.push_back(fileInfo); + } + + delete readerA; + readerA = readerB; + } + fileGroupList.push_back(fileList); + delete readerA; + + printf("======================= total Hit Count : %llu\n", totalHitCount); + + for( size_t i = 0; i < fileGroupList.size(); i++){ + printf("group ----- %ld \n", i); + + //sort by evID + std::sort(fileGroupList[i].begin(), fileGroupList[i].end(), [](const FileInfo & a, const FileInfo & b) { + return a.fileevID < b.fileevID; + }); + + for( size_t j = 0; j < fileGroupList[i].size(); j++){ + printf("%3ld | %8d | %9lu| %s \n", j, fileGroupList[i][j].fileevID, fileGroupList[i][j].hitCount, fileGroupList[i][j].fileName.c_str() ); + } + + } + + //*======================================= Open files + printf("========================================= Open files & Build Events.\n"); + + const short nGroup = fileGroupList.size(); + std::vector hitList[nGroup]; + + FSUReader ** reader = new FSUReader * [nGroup]; + ulong evID[nGroup]; + for( short i = 0; i < nGroup; i++){ + std::vector fList; + for( size_t j = 0; j < fileGroupList[i].size(); j++){ + fList.push_back( fileGroupList[i][j].fileName ); + } + reader[i] = new FSUReader(fList, 600, debug); + hitList[i] = reader[i]->ReadBatch(batchSize, debug ); + reader[i]->PrintHitListInfo(&hitList[i], "hitList-" + std::to_string(reader[i]->GetSN())); + evID[i] = 0; + if( debug ) { + + for( size_t p = 0; p < 10; p ++ ){ + if( hitList[i].size() <= p ) break; + hitList[i][p].Print(); + } + + } + } + + unsigned long long tStart = 0; + unsigned long long tEnd = 0; + + unsigned long long t0 = -1; + short g0 = 0 ; + int nFileFinished = 0; + unsigned long long hitProcessed = 0; + + FILE * outFile = fopen(outFileName.c_str(), "wb"); + + do{ + + // find the earlist time + t0 = -1; + for( short i = 0; i < nGroup; i++){ + + if( hitList[i].size() == 0 ) continue; + + //chekc if reached the end of hitList + if( evID[i] >= hitList[i].size() ) { + hitList[i] = reader[i]->ReadBatch(batchSize, debug + 1); + if( debug ) reader[i]->PrintHitListInfo( &hitList[i], "hitList-" + std::to_string(i)); + evID[i] = 0; + if( hitList[i].size() == 0 ) continue; + } + + if( hitList[i][evID[i]].timestamp < t0 ) { + t0 = hitList[i][evID[i]].timestamp; + g0 = i; + } + + } + + fwrite(&(header), 2, 1, outFile); + fwrite(&(hitList[g0][evID[g0]].sn), 2, 1, outFile); + fwrite(&(hitList[g0][evID[g0]].ch), 2, 1, outFile); + fwrite(&(hitList[g0][evID[g0]].timestamp), 8, 1, outFile); + fwrite(&(hitList[g0][evID[g0]].energy), 2, 1, outFile); + fwrite(&(flags), 4, 1, outFile); + + evID[g0]++; + if( hitProcessed == 0) tStart = hitList[g0][evID[g0]].timestamp; + hitProcessed ++; + if( hitProcessed % 10000 == 0 ) printf("hit Porcessed %llu/%llu hit....%.2f%%\n\033[A\r", hitProcessed, totalHitCount, hitProcessed*100./totalHitCount); + + if( hitProcessed == totalHitCount -1 ) tEnd = hitList[g0][evID[g0]].timestamp; + + //*============= + nFileFinished = 0; + for( int i = 0 ; i < nGroup; i++) { + if( hitList[i].size() == 0 ) { + nFileFinished ++; + continue; + }else{ + if( evID[i] >= hitList[i].size( )) { + hitList[i] = reader[i]->ReadBatch(batchSize, debug); + evID[i] = 0; + if( hitList[i].size() == 0 ) nFileFinished ++; + } + } + } + if( debug > 1 ) printf("========== nFileFinished : %d\n", nFileFinished); + + }while( nFileFinished < nGroup); + + uInt runEndTime = getTime_us(); + double runTime = (runEndTime - runStartTime) * 1e-6; + printf("========================================= finished.\n"); + printf(" event building time = %.2f sec = %.2f min\n", runTime, runTime/60.); + printf(" total hit = %llu \n", hitProcessed); + double tDuration_sec = (tEnd - tStart) * 1e-9; + printf(" first timestamp = %20llu ns\n", tStart); + printf(" last timestamp = %20llu ns\n", tEnd); + printf(" total data duration = %.2f sec = %.2f min\n", tDuration_sec, tDuration_sec/60.); + printf("==============> saved to %s \n", outFileName.c_str()); + + for( int i = 0; i < nGroup; i++) delete reader[i]; + delete [] reader; + + if( tarFlag ){ + std::string tarFileName = outFile_prefix + ".tar"; + + std::string command = "tar -cvf " + tarFileName + " " + outFileName; + int result = std::system(command.c_str()); + + if (result == 0) { + printf("Archive created successfully: %s\n", tarFileName.c_str()); + std::system(("rm -f " + outFileName).c_str()); + printf("Remove %s.\n", outFileName.c_str()); + } else { + printf("Error creating archive\n"); + } + } + + printf("============================================== end of program\n"); + + return 0; + +} + diff --git a/Aux/Makefile b/Aux/Makefile index 27f7e4d..9b731a9 100644 --- a/Aux/Makefile +++ b/Aux/Makefile @@ -14,7 +14,7 @@ ROOTLIBS = `root-config --cflags --glibs` OBJS = ClassDigitizer.o MultiBuilder.o ClassInfluxDB.o -ALL = test EventBuilder DataReader DumpFSU2ROOT SettingsExplorer +ALL = test EventBuilder DataReader DumpFSU2ROOT SettingsExplorer FSU2CAEN ######################################################################### @@ -44,17 +44,13 @@ DataReader : DataReaderScript.cpp ../ClassData.h MultiBuilder.o @echo "--------- making DataReader" $(CC) $(COPTS) -o DataReader DataReaderScript.cpp ../ClassData.h MultiBuilder.o -# EventBuilder_old : EventBuilder_old.cpp ../ClassData.h MultiBuilder.o fsuReader.h -# @echo "--------- making EventBuilder" -# $(CC) $(COPTS) -o EventBuilder_old EventBuilder_old.cpp MultiBuilder.o $(ROOTLIBS) - EventBuilder : EventBuilder.cpp ../ClassData.h fsuReader.h ../Hit.h @echo "--------- making EventBuilder" $(CC) $(COPTS) -o EventBuilder EventBuilder.cpp $(ROOTLIBS) -# EventBuilderNoTrace : EventBuilderNoTrace.cpp ../ClassData.h fsuReader.h ../Hit.h -# @echo "--------- making EventBuilderNoTrace" -# $(CC) $(COPTS) -o EventBuilderNoTrace EventBuilderNoTrace.cpp $(ROOTLIBS) +FSU2CAEN : FSU2CAEN.cpp ../ClassData.h fsuReader.h ../Hit.h + @echo "--------- making FSU2CAEN" + $(CC) $(COPTS) -o FSU2CAEN FSU2CAEN.cpp DumpFSU2ROOT : DumpFSU2ROOT.cpp ../ClassData.h MultiBuilder.o @echo "--------- making DumpFSU2ROOT" From bbe9ef799007334342e64769852e0da59a88b6a4 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Tue, 18 Jun 2024 14:15:46 -0400 Subject: [PATCH 07/72] ClassData, fine timestamp in ps. added flags and trace for FSU2CAEN --- Aux/FSU2CAEN.cpp | 24 +++++++++++++++++++----- ClassData.h | 4 ++-- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/Aux/FSU2CAEN.cpp b/Aux/FSU2CAEN.cpp index a802b20..7d94966 100644 --- a/Aux/FSU2CAEN.cpp +++ b/Aux/FSU2CAEN.cpp @@ -6,8 +6,8 @@ struct FileInfo{ unsigned long hitCount; }; -const unsigned short header = 0xCAE1; -const unsigned int flags = 0; +unsigned short header = 0xCAE1; +unsigned int flags = 0; #define minNARG 4 @@ -54,7 +54,6 @@ int main(int argc, char **argv) { printf("========================================= Number of Files : %d \n", nFile); for( int i = 0; i < nFile; i++) printf("%2d | %s \n", i, inFileName[i].c_str()); printf("=========================================\n"); - printf(" Include Trace = %s\n", "No"); printf(" Batch size = %d events/file\n", batchSize); printf(" Out file name = %s \n", outFileName.c_str()); printf(" Is tar output = %s \n", tarFlag ? "Yes" : "No"); @@ -167,12 +166,27 @@ int main(int argc, char **argv) { } + if( hitList[g0][evID[g0]].energy2 > 0 ) header += 4; + if( hitList[g0][evID[g0]].traceLength > 0 ) header += 8; + if( hitList[g0][evID[g0]].pileUp ) flags += 0x8000; + if( hitList[g0][evID[g0]].fineTime > 0 ) flags += 0x4000; + fwrite(&(header), 2, 1, outFile); fwrite(&(hitList[g0][evID[g0]].sn), 2, 1, outFile); fwrite(&(hitList[g0][evID[g0]].ch), 2, 1, outFile); - fwrite(&(hitList[g0][evID[g0]].timestamp), 8, 1, outFile); + unsigned psTimestamp = hitList[g0][evID[g0]].timestamp * 1000 + hitList[g0][evID[g0]].fineTime; + fwrite(&(psTimestamp), 8, 1, outFile); fwrite(&(hitList[g0][evID[g0]].energy), 2, 1, outFile); fwrite(&(flags), 4, 1, outFile); + if( hitList[g0][evID[g0]].traceLength > 0 ){ + char waveCode = 1; + fwrite(&(waveCode), 1, 1, outFile); + fwrite(&(hitList[g0][evID[g0]].traceLength), 4, 1, outFile); + + for( int i = 0; i < hitList[g0][evID[g0]].traceLength; i++ ){ + fwrite(&(hitList[g0][evID[g0]].trace[i]), 2, 1, outFile); + } + } evID[g0]++; if( hitProcessed == 0) tStart = hitList[g0][evID[g0]].timestamp; @@ -227,7 +241,7 @@ int main(int argc, char **argv) { printf("Error creating archive\n"); } } - + printf("============================================== end of program\n"); return 0; diff --git a/ClassData.h b/ClassData.h index 676cd19..cd07a35 100644 --- a/ClassData.h +++ b/ClassData.h @@ -884,7 +884,7 @@ inline int Data::DecodePHADualChannelBlock(unsigned int ChannelMask, bool fastDe Energy[channel][DataIndex[channel]] = energy; Timestamp[channel][DataIndex[channel]] = timeStamp * tick2ns; - if(extra2Option == 2 ) fineTime[channel][DataIndex[channel]] = (extra2 & 0x03FF ); + if(extra2Option == 2 ) fineTime[channel][DataIndex[channel]] = (extra2 & 0x03FF ) * tick2ns; // in ps, the tick2ns is a conversion factor PileUp[channel][DataIndex[channel]] = pileUp; NumEventsDecoded[channel] ++; @@ -1087,7 +1087,7 @@ inline int Data::DecodePSDDualChannelBlock(unsigned int ChannelMask, bool fastDe Energy2[channel][DataIndex[channel]] = Qshort; Energy[channel][DataIndex[channel]] = Qlong; Timestamp[channel][DataIndex[channel]] = timeStamp * tick2ns; - if( extraOption == 2 ) fineTime[channel][DataIndex[channel]] = extra & 0x3FF; + if( extraOption == 2 ) fineTime[channel][DataIndex[channel]] = (extra & 0x3FF) * tick2ns; //in ps, tick2ns is justa conversion factor NumEventsDecoded[channel] ++; if( !pileup){ From 1b3c1733ce666464b7be79dcb48ba3b9e91c5362 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Tue, 18 Jun 2024 14:37:23 -0400 Subject: [PATCH 08/72] FSU2CAEN add the energy short --- Aux/FSU2CAEN.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Aux/FSU2CAEN.cpp b/Aux/FSU2CAEN.cpp index 7d94966..5addc7d 100644 --- a/Aux/FSU2CAEN.cpp +++ b/Aux/FSU2CAEN.cpp @@ -177,6 +177,7 @@ int main(int argc, char **argv) { unsigned psTimestamp = hitList[g0][evID[g0]].timestamp * 1000 + hitList[g0][evID[g0]].fineTime; fwrite(&(psTimestamp), 8, 1, outFile); fwrite(&(hitList[g0][evID[g0]].energy), 2, 1, outFile); + if( hitList[g0][evID[g0]].energy2 > 0 ) fwrite(&(hitList[g0][evID[g0]].energy2), 2, 1, outFile); fwrite(&(flags), 4, 1, outFile); if( hitList[g0][evID[g0]].traceLength > 0 ){ char waveCode = 1; From 02305314babea1ed0fb96bdf971ee958e0951610 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Tue, 18 Jun 2024 16:33:23 -0400 Subject: [PATCH 09/72] EventBuilder, trace stored as fixed size array of array --- .vscode/settings.json | 3 ++- Aux/EventBuilder.cpp | 45 +++++++++++++++++++++++++++++-------------- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 05f7e93..d0e72c6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -161,6 +161,7 @@ "Analyzer.C": "cpp", "process_Run.C": "cpp", "EncoreAnalyzer.C": "cpp", - "qfiledialog": "cpp" + "qfiledialog": "cpp", + "script.C": "cpp" } } \ No newline at end of file diff --git a/Aux/EventBuilder.cpp b/Aux/EventBuilder.cpp index f6d5662..b91b803 100644 --- a/Aux/EventBuilder.cpp +++ b/Aux/EventBuilder.cpp @@ -7,9 +7,10 @@ #include "TFile.h" #include "TTree.h" #include "TMacro.h" +#include "TMath.h" - -#define MAX_MULTI 2000 +#define MAX_TRACE_LENGTH 2000 +#define MAX_MULTI 100 struct FileInfo{ @@ -143,15 +144,20 @@ int main(int argc, char **argv) { tree->Branch("e_f", e_f, "e_fineTime[multi]/s"); tree->Branch("traceLength", traceLength, "traceLength[multi]/s"); - TClonesArray * arrayTrace = nullptr; - TGraph * trace = nullptr; + // TClonesArray * arrayTrace = nullptr; + // TGraph * trace = nullptr; + short trace[MAX_MULTI][1024]; if( traceOn ) { - arrayTrace = new TClonesArray("TGraph"); - tree->Branch("trace", arrayTrace, 2560000); - arrayTrace->BypassStreamer(); + // arrayTrace = new TClonesArray("TGraph"); + // tree->Branch("trace", arrayTrace, 2560000); + // arrayTrace->BypassStreamer(); + + tree->Branch("trace", trace,"trace[multi][1024]/S"); + tree->GetBranch("trace")->SetCompressionSettings(205); } + //*======================================= Open files printf("========================================= Open files & Build Events.\n"); @@ -260,15 +266,15 @@ int main(int argc, char **argv) { tEnd = events.back().timestamp; hitProcessed += events.size(); - if( hitProcessed % 10000 == 0 ) printf("hit Porcessed %llu/%llu hit....%.2f%%\n\033[A\r", hitProcessed, totalHitCount, hitProcessed*100./totalHitCount); - + if( hitProcessed % (traceOn ? 100 : 10000) == 0 ) printf("hit Porcessed %llu/%llu hit....%.2f%%\n\033[A\r", hitProcessed, totalHitCount, hitProcessed*100./totalHitCount); multi = events.size() ; if( events.size() >= MAX_MULTI ) { - printf("event %lld has size = %d > MAX_MULTI = %d\n", evID, multi, MAX_MULTI); + printf("\033[31m event %lld has size = %d > MAX_MULTI = %d \033[0m\n", evID, multi, MAX_MULTI); multi = MAX_MULTI; } if( debug ) printf("=================================== filling data | %u \n", multi); + for( size_t p = 0; p < multi ; p ++ ) { if( debug ) {printf("%4zu | ", p); events[p].Print();} @@ -281,11 +287,22 @@ int main(int argc, char **argv) { traceLength[p] = events[p].traceLength; if( traceOn ){ - trace = (TGraph *) arrayTrace->ConstructedAt(multi, "C"); - trace->Clear(); - for( int hh = 0; hh < traceLength[multi]; hh++){ - trace->SetPoint(hh, hh, events[p].trace[hh]); + // trace = (TGraph *) arrayTrace->ConstructedAt(p, "C"); + // trace->Clear(); + // for( int hh = 0; hh < traceLength[multi]; hh++){ + // trace->SetPoint(hh, hh, events[p].trace[hh]); + // } + + if( traceLength[p] > MAX_TRACE_LENGTH ) { + printf("\033[31m event %lld has trace length = %d > MAX_TRACE_LENGTH = %d \033[0m\n", evID, traceLength[p], MAX_TRACE_LENGTH); + traceLength[p] = MAX_TRACE_LENGTH; } + + for( int hh = 0; hh < traceLength[p]; hh++){ + trace[p][hh] = events[p].trace[hh]; + } + + } } From 0e8c92a26659d7c748f2d1fccbaa6a5cc957de17 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Tue, 18 Jun 2024 16:47:54 -0400 Subject: [PATCH 10/72] when no event build, the suffix is 'single' instead of '-1' --- Aux/EventBuilder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Aux/EventBuilder.cpp b/Aux/EventBuilder.cpp index b91b803..e813163 100644 --- a/Aux/EventBuilder.cpp +++ b/Aux/EventBuilder.cpp @@ -60,7 +60,7 @@ int main(int argc, char **argv) { pos = outFileName.Index("_", pos+1); // find next "_" if( nFile == 1 ) pos = outFileName.Index("_", pos+1); // find next "_", S/N outFileName.Remove(pos); // remove the rest - outFileName += "_" + std::to_string(timeWindow); + outFileName += "_" + ( timeWindow >= 0 ? std::to_string(timeWindow) : "single"); outFileName += ".root"; printf("-------> Out file name : %s \n", outFileName.Data()); printf("========================================= Number of Files : %d \n", nFile); From b9d1a76b7ebcc7405b8e70448995b159390cd63f Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Wed, 19 Jun 2024 16:55:38 -0400 Subject: [PATCH 11/72] fsuReader, Scanning fsu file will estimate the best batch size --- Aux/EventBuilder.cpp | 34 +-- Aux/FSU2CAEN.cpp | 8 +- Aux/fsuReader.h | 299 ++++++--------------------- Aux/obsolete/EventBuilderNoTrace.cpp | 4 +- Aux/obsolete/EventBuilder_clumsy.cpp | 2 +- 5 files changed, 90 insertions(+), 257 deletions(-) diff --git a/Aux/EventBuilder.cpp b/Aux/EventBuilder.cpp index e813163..6625265 100644 --- a/Aux/EventBuilder.cpp +++ b/Aux/EventBuilder.cpp @@ -20,6 +20,8 @@ struct FileInfo{ }; +#define NMINARG 5 + //^############################################################# //^############################################################# int main(int argc, char **argv) { @@ -27,13 +29,12 @@ int main(int argc, char **argv) { printf("=========================================\n"); printf("=== *.fsu Events Builder ===\n"); printf("=========================================\n"); - if (argc < 6) { + if (argc < NMINARG) { printf("Incorrect number of arguments:\n"); - printf("%s [timeWindow] [withTrace] [verbose] [batchSize] [inFile1] [inFile2] .... \n", argv[0]); + printf("%s [timeWindow] [withTrace] [verbose] [inFile1] [inFile2] .... \n", argv[0]); printf(" timeWindow : in ns, -1 = no event building \n"); printf(" withTrace : 0 for no trace, 1 for trace \n"); printf(" verbose : > 0 for debug \n"); - printf(" batchSize : the size of hit in a batch \n"); printf(" Output file name is contructed from inFile1 \n"); printf("\n"); printf(" Example: %s 0 0 0 10000 '\\ls -1 *001*.fsu'\n", argv[0]); @@ -48,10 +49,10 @@ int main(int argc, char **argv) { long timeWindow = atoi(argv[1]); bool traceOn = atoi(argv[2]); unsigned int debug = atoi(argv[3]); - unsigned int batchSize = atoi(argv[4]); - int nFile = argc - 5; + unsigned int batchSize = 2* DEFAULT_HALFBUFFERSIZE; + int nFile = argc - NMINARG + 1; TString inFileName[nFile]; - for( int i = 0 ; i < nFile ; i++){ inFileName[i] = argv[i+5];} + for( int i = 0 ; i < nFile ; i++){ inFileName[i] = argv[i + NMINARG -1];} /// Form outFileName; TString outFileName = inFileName[0]; @@ -69,7 +70,6 @@ int main(int argc, char **argv) { printf(" Time Window = %ld ns = %.1f us\n", timeWindow, timeWindow/1000.); printf(" Include Trace = %s\n", traceOn ? "Yes" : "No"); printf(" Debug level = %d\n", debug); - printf(" Batch size = %d events/file\n", batchSize); printf(" Max multiplity = %d hits/event (hard coded)\n", MAX_MULTI); printf("========================================= Grouping files\n"); @@ -80,15 +80,18 @@ int main(int argc, char **argv) { FSUReader * readerA = new FSUReader(inFileName[0].Data(), 1, 1); readerA->ScanNumBlock(0,0); - FileInfo fileInfo = {inFileName[0].Data(), readerA->GetSN() * 1000 + readerA->GetFileOrder(), readerA->GetHitCount()}; + if( readerA->GetOptimumBatchSize() > batchSize ) batchSize = readerA->GetOptimumBatchSize(); + FileInfo fileInfo = {inFileName[0].Data(), readerA->GetSN() * 1000 + readerA->GetFileOrder(), readerA->GetTotalHitCount()}; fileList.push_back(fileInfo); - totalHitCount += readerA->GetHitCount(); + totalHitCount += readerA->GetTotalHitCount(); for( int i = 1; i < nFile; i++){ FSUReader * readerB = new FSUReader(inFileName[i].Data(), 1, 1); readerB->ScanNumBlock(0,0); - totalHitCount += readerB->GetHitCount(); - fileInfo = {inFileName[i].Data(), readerB->GetSN() * 1000 + readerB->GetFileOrder(), readerB->GetHitCount()}; + if( readerB->GetOptimumBatchSize() > batchSize ) batchSize = readerB->GetOptimumBatchSize(); + + totalHitCount += readerB->GetTotalHitCount(); + fileInfo = {inFileName[i].Data(), readerB->GetSN() * 1000 + readerB->GetFileOrder(), readerB->GetTotalHitCount()}; if( readerA->GetSN() == readerB->GetSN() ){ fileList.push_back(fileInfo); @@ -105,6 +108,7 @@ int main(int argc, char **argv) { delete readerA; printf("======================= total Hit Count : %llu\n", totalHitCount); + printf(">>>>>>>>>>>>>>>>>>>>>>>>>> Batch size : %d events/file\n", batchSize); for( size_t i = 0; i < fileGroupList.size(); i++){ printf("group ----- %ld \n", i); @@ -171,7 +175,7 @@ int main(int argc, char **argv) { for( size_t j = 0; j < fileGroupList[i].size(); j++){ fList.push_back( fileGroupList[i][j].fileName ); } - reader[i] = new FSUReader(fList, 600, debug); + reader[i] = new FSUReader(fList, 1024, debug); // 1024 is the maximum event / agg. hitList[i] = reader[i]->ReadBatch(batchSize, debug ); reader[i]->PrintHitListInfo(&hitList[i], "hitList-" + std::to_string(reader[i]->GetSN())); ID[i] = 0; @@ -266,7 +270,7 @@ int main(int argc, char **argv) { tEnd = events.back().timestamp; hitProcessed += events.size(); - if( hitProcessed % (traceOn ? 100 : 10000) == 0 ) printf("hit Porcessed %llu/%llu hit....%.2f%%\n\033[A\r", hitProcessed, totalHitCount, hitProcessed*100./totalHitCount); + if( hitProcessed % (traceOn ? 10000 : 10000) == 0 ) printf("hit Porcessed %llu/%llu hit....%.2f%%\n\033[A\r", hitProcessed, totalHitCount, hitProcessed*100./totalHitCount); multi = events.size() ; if( events.size() >= MAX_MULTI ) { @@ -354,7 +358,7 @@ int main(int argc, char **argv) { printf(" first timestamp = %20llu ns\n", tStart); printf(" last timestamp = %20llu ns\n", tEnd); printf(" total data duration = %.2f sec = %.2f min\n", tDuration_sec, tDuration_sec/60.); - printf("==============> saved to %s \n", outFileName.Data()); + printf("========================================> saved to %s \n", outFileName.Data()); TMacro info; info.AddLine(Form("tStart= %20llu ns",tStart)); @@ -366,6 +370,8 @@ int main(int argc, char **argv) { for( int i = 0; i < nGroup; i++) delete reader[i]; delete [] reader; + printf("####################################### end of %s\n", argv[0]); + return 0; } diff --git a/Aux/FSU2CAEN.cpp b/Aux/FSU2CAEN.cpp index 5addc7d..adcae5c 100644 --- a/Aux/FSU2CAEN.cpp +++ b/Aux/FSU2CAEN.cpp @@ -66,15 +66,15 @@ int main(int argc, char **argv) { FSUReader * readerA = new FSUReader(inFileName[0], 1, 1); readerA->ScanNumBlock(0,0); - FileInfo fileInfo = {inFileName[0], readerA->GetSN() * 1000 + readerA->GetFileOrder(), readerA->GetHitCount()}; + FileInfo fileInfo = {inFileName[0], readerA->GetSN() * 1000 + readerA->GetFileOrder(), readerA->GetTotalHitCount()}; fileList.push_back(fileInfo); - totalHitCount += readerA->GetHitCount(); + totalHitCount += readerA->GetTotalHitCount(); for( int i = 1; i < nFile; i++){ FSUReader * readerB = new FSUReader(inFileName[i], 1, 1); readerB->ScanNumBlock(0,0); - totalHitCount += readerB->GetHitCount(); - fileInfo = {inFileName[i], readerB->GetSN() * 1000 + readerB->GetFileOrder(), readerB->GetHitCount()}; + totalHitCount += readerB->GetTotalHitCount(); + fileInfo = {inFileName[i], readerB->GetSN() * 1000 + readerB->GetFileOrder(), readerB->GetTotalHitCount()}; if( readerA->GetSN() == readerB->GetSN() ){ fileList.push_back(fileInfo); diff --git a/Aux/fsuReader.h b/Aux/fsuReader.h index 67c6e8e..fcc8450 100644 --- a/Aux/fsuReader.h +++ b/Aux/fsuReader.h @@ -3,7 +3,7 @@ #include #include -// #include "AggSeparator.h" +#define DEFAULT_HALFBUFFERSIZE 500000 class FSUReader{ @@ -60,21 +60,13 @@ class FSUReader{ return hit[id]; } - void ClearHitCount() {hitCount = 0;} - ulong GetHitCount() const{return hitCount;} + void ClearTotalHitCount() {totalHitCount = 0;} + ulong GetTotalHitCount() const{return totalHitCount;} std::vector ReadBatch(unsigned int batchSize = 1000000, bool verbose = false); // output the sorted Hit - // std::string SaveHit(std::vector hitList, bool isAppend = false); - // std::string SaveHit2NewFile(std::string saveFolder = "./", std::string indexStr = ""); - // void SortAndSaveTS(unsigned int batchSize = 1000000, bool verbose = false); - // off_t GetTSFileSize() const {return tsFileSize;} - - //TODO - //void SplitFile(unsigned long hitSizePreFile); - void PrintHit(ulong numHit = -1, ulong startIndex = 0) { - for( ulong i = startIndex; i < std::min(numHit, hitCount); i++){ + for( ulong i = startIndex; i < std::min(numHit, totalHitCount); i++){ printf("%10zu ", i); hit[i].Print(); } } @@ -101,8 +93,7 @@ class FSUReader{ } } - - //void SaveAsCAENCoMPASSFormat(); + unsigned long GetOptimumBatchSize() const {return optBufferSize;} private: @@ -129,7 +120,7 @@ class FSUReader{ std::vector blockPos; std::vector blockTimeStamp; - unsigned long hitCount; + unsigned long totalHitCount; std::vector hit; @@ -139,8 +130,15 @@ class FSUReader{ off_t tsFileSize; + //checking the t0 and tmin for every 1 million hit + unsigned short nMillion; + std::vector tmin; + + unsigned long optBufferSize; + }; +//^============================================================== inline FSUReader::~FSUReader(){ delete data; @@ -148,6 +146,7 @@ inline FSUReader::~FSUReader(){ } +//^============================================================== inline FSUReader::FSUReader(){ inFile = nullptr; data = nullptr; @@ -161,6 +160,7 @@ inline FSUReader::FSUReader(){ } +//^============================================================== inline FSUReader::FSUReader(std::string fileName, uInt dataSize, int verbose){ inFile = nullptr; data = nullptr; @@ -174,6 +174,7 @@ inline FSUReader::FSUReader(std::string fileName, uInt dataSize, int verbose){ OpenFile(fileName, dataSize, verbose); } +//^============================================================== inline FSUReader::FSUReader(std::vector fileList, uInt dataSize, int verbose){ inFile = nullptr; data = nullptr; @@ -188,6 +189,7 @@ inline FSUReader::FSUReader(std::vector fileList, uInt dataSize, in } +//^============================================================== inline void FSUReader::OpenFile(std::string fileName, uInt dataSize, int verbose){ /// File format must be YYY...Y_runXXX_AAA_BBB_TT_CCC.fsu @@ -223,9 +225,14 @@ inline void FSUReader::OpenFile(std::string fileName, uInt dataSize, int verbose blockPos.clear(); blockTimeStamp.clear(); - hitCount = 0; + totalHitCount = 0; hit.clear(); + nMillion = 0; + tmin.clear(); + tmin.push_back(-1); + optBufferSize = 2*DEFAULT_HALFBUFFERSIZE; + //check is the file is *.fsu or *.fsu.X size_t found = fileName.find_last_of('.'); std::string ext = fileName.substr(found + 1); @@ -279,6 +286,7 @@ inline void FSUReader::OpenFile(std::string fileName, uInt dataSize, int verbose } +//^============================================================== inline int FSUReader::ReadNextBlock(bool traceON, int verbose, uShort saveData){ if( inFile == NULL ) return -1; if( feof(inFile) || filePos >= inFileSize) { @@ -334,13 +342,22 @@ inline int FSUReader::ReadNextBlock(bool traceON, int verbose, uShort saveData){ return -20; } - unsigned int eventCout = 0; - for( int ch = 0; ch < data->GetNChannel(); ch++){ if( data->NumEventsDecoded[ch] == 0 ) continue; - hitCount += data->NumEventsDecoded[ch]; - eventCout += data->NumEventsDecoded[ch]; + totalHitCount += data->NumEventsDecoded[ch]; + + if( totalHitCount / DEFAULT_HALFBUFFERSIZE > nMillion ) { + nMillion ++; + tmin.push_back(-1); + } + + int start = data->GetDataIndex(ch) - data->NumEventsDecoded[ch] + 1; + if( start < 0 ) start = start + data->GetDataSize(); + for( int i = start; i < start + data->NumEventsDecoded[ch]; i++ ){ + int k = i % data->GetDataSize(); + if( data->GetTimestamp(ch, k) < tmin[nMillion] ) tmin[nMillion] = data->GetTimestamp(ch, k); + } if( saveData ){ int start = data->GetDataIndex(ch) - data->NumEventsDecoded[ch] + 1; @@ -375,6 +392,7 @@ inline int FSUReader::ReadNextBlock(bool traceON, int verbose, uShort saveData){ return 0; } +//^============================================================== inline int FSUReader::ReadBlock(unsigned int ID, int verbose){ if( totNumBlock == 0 )return -1; if( ID >= totNumBlock )return -1; @@ -392,6 +410,7 @@ inline int FSUReader::ReadBlock(unsigned int ID, int verbose){ } +//^============================================================== inline void FSUReader::SortHit(int verbose){ if( verbose) printf("\nQuick Sort hit array according to time..."); std::sort(hit.begin(), hit.end(), [](const Hit& a, const Hit& b) { @@ -400,6 +419,7 @@ inline void FSUReader::SortHit(int verbose){ if( verbose) printf(".......done.\n"); } +//^============================================================== inline void FSUReader::ScanNumBlock(int verbose, uShort saveData){ if( inFile == nullptr ) return; if( feof(inFile) ) return; @@ -423,8 +443,8 @@ inline void FSUReader::ScanNumBlock(int verbose, uShort saveData){ totNumBlock = blockID; if(verbose) { printf("\nScan complete: number of data Block : %lu\n", totNumBlock); - printf( " number of hit : %lu", hitCount); - if( hitCount > 1e6 ) printf(" = %.3f million", hitCount/1e6); + printf( " number of hit : %lu", totalHitCount); + if( totalHitCount > 1e6 ) printf(" = %.3f million", totalHitCount/1e6); printf("\n"); if( saveData )printf( " size of the hit array : %lu\n", hit.size()); @@ -445,14 +465,32 @@ inline void FSUReader::ScanNumBlock(int verbose, uShort saveData){ //check is the hitCount == hit.size(); if( saveData ){ - if( hitCount != hit.size()){ + if( totalHitCount != hit.size()){ printf("!!!!!! the Data::dataSize is not big enough. !!!!!!!!!!!!!!!\n"); }else{ SortHit(verbose+1); } } + + //print time structre + if( nMillion > 0 ){ + // printf("------------ time structure\n"); + // printf("%5s | %15s\n", "mil.", "t-min"); + for( int i = 0; i < nMillion; i++){ + // printf("%5d | %15lu", i, tmin[i]); + if( i > 0 && tmin[i] < tmin[i-1] ) { + // printf("<----"); + if( i > 1 && tmin[i] < tmin[i-2]) optBufferSize += 2*DEFAULT_HALFBUFFERSIZE; + } + // printf("\n"); + } + } + + // printf(" recommanded batch size : %lu\n", optBufferSize); + } +//^============================================================== inline std::vector FSUReader::ReadBatch(unsigned int batchSize, bool verbose){ // printf("%s sn:%d. filePos : %lu\n", __func__, sn, ftell(inFile)); @@ -513,6 +551,8 @@ inline std::vector FSUReader::ReadBatch(unsigned int batchSize, bool verbos if( t0_A >= t0_B) { printf("\033[0;31m!!!!!!!!!!!!!!!!! %s | Need to increase the batch size. \033[0m\n", __func__); + printf("t0_A : %15lu\n", t0_A); + printf("t0_B : %15lu\n", t0_B); return std::vector (); } @@ -580,216 +620,3 @@ inline std::vector FSUReader::ReadBatch(unsigned int batchSize, bool verbos } -/* -inline void FSUReader::SortAndSaveTS(unsigned int batchSize, bool verbose){ - - int count = 0; - std::vector hitList_A ; - - do{ - - if( verbose ) printf("***************************************************\n"); - - int res = 0; - do{ - res = ReadNextBlock(true, 0, 3); - }while ( hit.size() < batchSize && res == 0); - - SortHit(); - uLong t0_B = hit.at(0).timestamp; - uLong t1_B = hit.back().timestamp; - - if( verbose ) { - printf(" hit in memeory : %7zu | %u | %lu \n", hit.size(), filePos, inFileSize); - printf("t0 : %15lu\n", t0_B); - printf("t1 : %15lu\n", t1_B); - } - - if( count == 0 ) { - hitList_A = hit; // copy hit - }else{ - - uLong t0_A = hitList_A.at(0).timestamp; - uLong t1_A = hitList_A.back().timestamp; - ulong ID_A = 0; - ulong ID_B = 0; - - if( t0_A > t0_B) { - printf("Need to increase the batch size. \n"); - return; - } - - if( t1_A > t0_B) { // need to sort between two hitList - - if( verbose ) { - printf("############# need to sort \n"); - printf("=========== sume of A + B : %zu \n", hitList_A.size() + hit.size()); - } - - std::vector hitTemp; - - for( size_t j = 0; j < hitList_A.size() ; j++){ - if( hitList_A[j].timestamp < t0_B ) continue; - if( ID_A == 0 ) ID_A = j; - hitTemp.push_back(hitList_A[j]); - } - - hitList_A.erase(hitList_A.begin() + ID_A, hitList_A.end() ); - if( verbose ) { - printf("----------------- ID_A : %lu, Drop\n", ID_A); - PrintHitListInfo(hitList_A, "hitList_A"); - } - - - for( size_t j = 0; j < hit.size(); j++){ - if( hit[j].timestamp > t1_A ) { - ID_B = j; - break; - } - hitTemp.push_back(hit[j]); - } - - std::sort(hitTemp.begin(), hitTemp.end(), [](const Hit& a, const Hit& b) { - return a.timestamp < b.timestamp; - }); - - hit.erase(hit.begin(), hit.begin() + ID_B ); - - if( verbose ) { - PrintHitListInfo(hitTemp, "hitTemp"); - printf("----------------- ID_B : %lu, Drop\n", ID_B); - PrintHitListInfo(hit, "hit"); - printf("=========== sume of A + B + Temp : %zu \n", hitList_A.size() + hit.size() + hitTemp.size()); - printf("----------------- refill hitList_A \n"); - } - ulong ID_Temp = 0; - for( size_t j = 0; j < hitTemp.size(); j++){ - hitList_A.push_back(hitTemp[j]); - if( hitList_A.size() >= batchSize ) { - ID_Temp = j+1; - break; - } - } - - hitTemp.erase(hitTemp.begin(), hitTemp.begin() + ID_Temp ); - for( size_t j = 0 ; j < hit.size(); j ++){ - hitTemp.push_back(hit[j]); - } - SaveHit(hitList_A, count <= 1 ? false : true); - - if( verbose ) { - PrintHitListInfo(hitList_A, "hitList_A"); - PrintHitListInfo(hitTemp, "hitTemp"); - printf("----------------- replace hitList_A by hitTemp \n"); - } - - hitList_A.clear(); - hitList_A = hitTemp; - hit.clear(); - - if( verbose ) { - PrintHitListInfo(hitList_A, "hitList_A"); - printf("===========================================\n"); - } - - }else{ // save hitList_A, replace hitList_A - - SaveHit(hitList_A, count <= 1? false : true); - hitList_A.clear(); - hitList_A = hit; - if( verbose ) PrintHitListInfo(hitList_A, "hitList_A"); - - } - } - - ClearHitList(); - count ++; - }while(filePos < inFileSize); - - SaveHit(hitList_A, count <= 1 ? false : true); - - printf("================= finished.\n"); -} -*/ - -/* -inline std::string FSUReader::SaveHit(std::vector hitList, bool isAppend){ - - std::string outFileName; - if( fileList.empty() ) { - outFileName = fileName + ".ts" ; - }else{ - outFileName = fileList[0] + ".ts" ; - } - uint64_t hitSize = hitList.size(); - - FILE * outFile ; - if( isAppend ) { - outFile = fopen(outFileName.c_str(), "rb+"); //read/write bineary - - rewind(outFile); - fseek( outFile, 4, SEEK_CUR); - uint64_t org_hitSize; - fread(&org_hitSize, 8, 1, outFile); - - rewind(outFile); - fseek( outFile, 4, SEEK_CUR); - - org_hitSize += hitSize; - - fwrite(&org_hitSize, 8, 1, outFile); - fseek(outFile, 0, SEEK_END); - - }else{ - outFile = fopen(outFileName.c_str(), "wb"); //overwrite binary - uint32_t header = 0xAA000000; - header += sn; - fwrite( &header, 4, 1, outFile ); - fwrite( &hitSize, 8, 1, outFile); - } - - - for( ulong i = 0; i < hitSize; i++){ - - if( i% 10000 == 0 ) printf("Saving %lu/%lu Hit (%.2f%%)\n\033[A\r", i, hitSize, i*100./hitSize); - - uint16_t flag = hitList[i].ch + (hitList[i].pileUp << 8) ; - - if( DPPType == DPPTypeCode::DPP_PSD_CODE ) flag += ( 1 << 15); - if( hitList[i].traceLength > 0 ) flag += (1 << 14); - - // fwrite( &(hit[i].ch), 1, 1, outFile); - fwrite( &flag, 2, 1, outFile); - fwrite( &(hitList[i].energy), 2, 1, outFile); - if( DPPType == DPPTypeCode::DPP_PSD_CODE ) fwrite( &(hitList[i].energy2), 2, 1, outFile); - fwrite( &(hitList[i].timestamp), 6, 1, outFile); - fwrite( &(hitList[i].fineTime), 2, 1, outFile); - if( hitList[i].traceLength > 0 ) fwrite( &(hitList[i].traceLength), 2, 1, outFile); - - for( uShort j = 0; j < hitList[i].traceLength; j++){ - fwrite( &(hitList[i].trace[j]), 2, 1, outFile); - } - - } - - off_t tsFileSize = ftello(outFile); // unsigned int = Max ~4GB - fclose(outFile); - - printf("Saved to %s, size: ", outFileName.c_str()); - if( tsFileSize < 1024 ) { - printf(" %ld Byte", tsFileSize); - }else if( tsFileSize < 1024*1024 ) { - printf(" %.2f kB", tsFileSize/1024.); - }else if( tsFileSize < 1024*1024*1024){ - printf(" %.2f MB", tsFileSize/1024./1024.); - }else{ - printf(" %.2f GB", tsFileSize/1024./1024./1024.); - } - printf("\n"); - - return outFileName; - -} -*/ - - diff --git a/Aux/obsolete/EventBuilderNoTrace.cpp b/Aux/obsolete/EventBuilderNoTrace.cpp index acd2427..eb6d870 100644 --- a/Aux/obsolete/EventBuilderNoTrace.cpp +++ b/Aux/obsolete/EventBuilderNoTrace.cpp @@ -81,7 +81,7 @@ int main(int argc, char **argv) { tempInfo.fileName = inFileName[i]; tempInfo.readerID = i; tempInfo.SN = reader[i]->GetSN(); - tempInfo.hitCount = reader[i]->GetHitCount(); + tempInfo.hitCount = reader[i]->GetTotalHitCount(); tempInfo.fileSize = reader[i]->GetFileByteSize(); tempInfo.tick2ns = reader[i]->GetTick2ns(); tempInfo.DPPType = reader[i]->GetDPPType(); @@ -208,7 +208,7 @@ int main(int argc, char **argv) { }else{ group[gpID].hitID = 0; uShort rID = group[gpID].readerIDList[group[gpID].currentID]; - group[gpID].hitCount = reader[rID]->GetHitCount(); + group[gpID].hitCount = reader[rID]->GetTotalHitCount(); printf("-----> go to the next file, %s \n", fileInfo[rID].fileName.c_str() ); } } diff --git a/Aux/obsolete/EventBuilder_clumsy.cpp b/Aux/obsolete/EventBuilder_clumsy.cpp index 371c79e..e97376c 100644 --- a/Aux/obsolete/EventBuilder_clumsy.cpp +++ b/Aux/obsolete/EventBuilder_clumsy.cpp @@ -110,7 +110,7 @@ int main(int argc, char **argv) { tempInfo.fileName = outFileName; tempInfo.readerID = i; tempInfo.SN = reader[i]->GetSN(); - tempInfo.hitCount = reader[i]->GetHitCount(); + tempInfo.hitCount = reader[i]->GetTotalHitCount(); tempInfo.fileSize = reader[i]->GetTSFileSize(); tempInfo.tick2ns = reader[i]->GetTick2ns(); tempInfo.DPPType = reader[i]->GetDPPType(); From 9ea67c4554357e353d64fa3d06b93c09d2c6397d Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Wed, 19 Jun 2024 16:59:16 -0400 Subject: [PATCH 12/72] remove user input for batch size for EventBuilder and FSU2CAEN --- Aux/EventBuilder.cpp | 3 ++- Aux/FSU2CAEN.cpp | 19 ++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Aux/EventBuilder.cpp b/Aux/EventBuilder.cpp index 6625265..7bb2311 100644 --- a/Aux/EventBuilder.cpp +++ b/Aux/EventBuilder.cpp @@ -37,7 +37,8 @@ int main(int argc, char **argv) { printf(" verbose : > 0 for debug \n"); printf(" Output file name is contructed from inFile1 \n"); printf("\n"); - printf(" Example: %s 0 0 0 10000 '\\ls -1 *001*.fsu'\n", argv[0]); + printf(" Example: %s -1 0 0 '\\ls -1 *001*.fsu' (no event build, no trace, no verbose)\n", argv[0]); + printf(" %s 100 0 0 '\\ls -1 *001*.fsu' (event build with 100 ns, no trace, no verbose)\n", argv[0]); printf("\n\n"); return 1; diff --git a/Aux/FSU2CAEN.cpp b/Aux/FSU2CAEN.cpp index adcae5c..f4a9fba 100644 --- a/Aux/FSU2CAEN.cpp +++ b/Aux/FSU2CAEN.cpp @@ -6,10 +6,7 @@ struct FileInfo{ unsigned long hitCount; }; -unsigned short header = 0xCAE1; -unsigned int flags = 0; - -#define minNARG 4 +#define minNARG 3 //^############################################################# //^############################################################# @@ -21,24 +18,25 @@ int main(int argc, char **argv) { printf("=========================================\n"); if (argc < minNARG) { printf("Incorrect number of arguments:\n"); - printf("%s [tar] [batchSize] [inFile1] [inFile2] .... \n", argv[0]); + printf("%s [tar] [inFile1] [inFile2] .... \n", argv[0]); printf(" tar : output tar, 0 = no, 1 = yes \n"); - printf(" batchSize : the size of hit in a batch \n"); printf("\n"); - printf(" Example: %s 100000 '\\ls -1 *001*.fsu'\n", argv[0]); + printf(" Example: %s '\\ls 0 *001*.fsu'\n", argv[0]); printf("\n\n"); return 1; } - unsigned int debug = false; + unsigned int debug = false; uInt runStartTime = getTime_us(); + unsigned short header = 0xCAE1; + unsigned int flags = 0; ///============= read input // long timeWindow = atoi(argv[1]); // bool traceOn = atoi(argv[2]); bool tarFlag = atoi(argv[1]); - unsigned int batchSize = atoi(argv[2]); + unsigned int batchSize = 2* DEFAULT_HALFBUFFERSIZE; int nFile = argc - minNARG + 1; std::string inFileName[nFile]; for( int i = 0 ; i < nFile ; i++){ inFileName[i] = argv[i+ minNARG - 1];} @@ -66,6 +64,7 @@ int main(int argc, char **argv) { FSUReader * readerA = new FSUReader(inFileName[0], 1, 1); readerA->ScanNumBlock(0,0); + if( readerA->GetOptimumBatchSize() > batchSize ) batchSize = readerA->GetOptimumBatchSize(); FileInfo fileInfo = {inFileName[0], readerA->GetSN() * 1000 + readerA->GetFileOrder(), readerA->GetTotalHitCount()}; fileList.push_back(fileInfo); totalHitCount += readerA->GetTotalHitCount(); @@ -73,6 +72,8 @@ int main(int argc, char **argv) { for( int i = 1; i < nFile; i++){ FSUReader * readerB = new FSUReader(inFileName[i], 1, 1); readerB->ScanNumBlock(0,0); + if( readerB->GetOptimumBatchSize() > batchSize ) batchSize = readerB->GetOptimumBatchSize(); + totalHitCount += readerB->GetTotalHitCount(); fileInfo = {inFileName[i], readerB->GetSN() * 1000 + readerB->GetFileOrder(), readerB->GetTotalHitCount()}; From 6fcebf0c06b2cc35013edb0da063f6fa02bc7422 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Thu, 20 Jun 2024 13:50:44 -0400 Subject: [PATCH 13/72] Split-Pole analyzer, disable reaction when run analyzer --- analyzers/SplitPoleAnalyzer.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/analyzers/SplitPoleAnalyzer.h b/analyzers/SplitPoleAnalyzer.h index 0bd1748..d98a3aa 100644 --- a/analyzers/SplitPoleAnalyzer.h +++ b/analyzers/SplitPoleAnalyzer.h @@ -229,6 +229,17 @@ inline void SplitPole::SetUpCanvas(){ chkRunAnalyzer = new QCheckBox("Run Analyzer", this); boxLayout->addWidget(chkRunAnalyzer, 4, 3); + connect(chkRunAnalyzer, &QCheckBox::stateChanged, this, [=](int state){ + + sbBfield->setEnabled(state != Qt::Checked); + leTarget->setEnabled(state != Qt::Checked); + leBeam->setEnabled(state != Qt::Checked); + leRecoil->setEnabled(state != Qt::Checked); + sbEnergy->setEnabled(state != Qt::Checked); + sbAngle->setEnabled(state != Qt::Checked); + sbEventWin->setEnabled(state != Qt::Checked); + + }); QFrame *separator = new QFrame(box); separator->setFrameShape(QFrame::HLine); From 5f2a7f067d45d379e4471097ebdd3ccaffbc39a5 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Wed, 26 Jun 2024 16:40:40 -0400 Subject: [PATCH 14/72] change MainWindow Class to FSUDAQ Class. fix bug on histThread, fix bug on CoincidentAnalyzer.h --- Aux/SettingsExplorer.cpp | 16 +++-- CustomThreads.h | 1 + FSUDAQ.cpp | 118 +++++++++++++++++---------------- FSUDAQ.h | 12 ++-- FSUDAQ_Qt6.pro | 6 +- analyzers/CoincidentAnalyzer.h | 8 ++- main.cpp | 2 +- 7 files changed, 87 insertions(+), 76 deletions(-) diff --git a/Aux/SettingsExplorer.cpp b/Aux/SettingsExplorer.cpp index 1fa495c..bfccf47 100644 --- a/Aux/SettingsExplorer.cpp +++ b/Aux/SettingsExplorer.cpp @@ -64,13 +64,14 @@ void keyPressCommand(){ if( RegList[i].GetRWType() == RW::ReadONLY ) typeStr = "R "; if( RegList[i].GetRWType() == RW::WriteONLY ) typeStr = " W"; + unsigned int value = digi->GetSettingFromMemory(RegList[i], 0); - printf("%2d | 0x%04X %30s %s 0x%08X = %u\n", i, + printf("%2d | 0x%04X %30s %s 0x%08X = %10u\n", i, RegList[i].GetAddress(), RegList[i].GetNameChar(), typeStr.c_str(), - digi->GetSettingFromMemory(RegList[i], 0), - digi->GetSettingFromMemory(RegList[i], 0)); + value, + value); } std::string input = "-1"; @@ -143,12 +144,15 @@ void keyPressCommand(){ RegList[i].ActualAddress(ch); - printf("%2d | 0x%04X %30s %s 0x%08X = %u\n", i, + unsigned int value = digi->GetSettingFromMemory(RegList[i], ch); + + printf("%2d | 0x%04X %30s %s 0x%08X = %10u : %d\n", i, RegList[i].GetAddress(), RegList[i].GetNameChar(), typeStr.c_str(), - digi->GetSettingFromMemory(RegList[i], ch), - digi->GetSettingFromMemory(RegList[i], ch)); + value, + value, + value * abs(RegList[i].GetPartialStep())); } do{ diff --git a/CustomThreads.h b/CustomThreads.h index 6ee9d73..995f7ca 100644 --- a/CustomThreads.h +++ b/CustomThreads.h @@ -119,6 +119,7 @@ public: waitTime = 20; // multiple of 100 mili sec stop = false; } + bool isStopped() const {return stop;} void Stop() { this->stop = true;} void SetWaitTimeinSec(float sec) {waitTime = sec * 10 ;} float GetWaitTimeinSec() const {return waitTime/10.;} diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index 076a902..ff93e4c 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -22,7 +22,7 @@ std::vector onlineAnalyzerList = {"Coincident","Splie-Pole", "Encore", "RAISOR"}; -MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ +FSUDAQ::FSUDAQ(QWidget *parent) : QMainWindow(parent){ DebugPrint("%s", "FSUDAQ"); setWindowTitle("FSU DAQ"); setGeometry(500, 100, 1100, 600); @@ -34,6 +34,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ scope = nullptr; digiSettings = nullptr; canvas = nullptr; + histThread = nullptr; onlineAnalyzer = nullptr; runTimer = new QTimer(); breakAutoRepeat = true; @@ -61,7 +62,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ //cbOpenDigitizers->addItem("Open Digitizers via USB", 3); cbOpenDigitizers->addItem("Open Digitizers via A4818(s)", 4); layout->addWidget(cbOpenDigitizers, 0, 0); - connect(cbOpenDigitizers, &RComboBox::currentIndexChanged, this, &MainWindow::OpenDigitizers); + connect(cbOpenDigitizers, &RComboBox::currentIndexChanged, this, &FSUDAQ::OpenDigitizers); cbOpenMethod = new RComboBox(this); cbOpenMethod->addItem("w/o settings", 0); @@ -71,29 +72,29 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ bnCloseDigitizers = new QPushButton("Close Digitizers", this); layout->addWidget(bnCloseDigitizers, 2, 0); - connect(bnCloseDigitizers, &QPushButton::clicked, this, &MainWindow::CloseDigitizers); + connect(bnCloseDigitizers, &QPushButton::clicked, this, &FSUDAQ::CloseDigitizers); bnDigiSettings = new QPushButton("Digitizers Settings", this); layout->addWidget(bnDigiSettings, 0, 1); - connect(bnDigiSettings, &QPushButton::clicked, this, &MainWindow::OpenDigiSettings); + connect(bnDigiSettings, &QPushButton::clicked, this, &FSUDAQ::OpenDigiSettings); bnOpenScope = new QPushButton("Open Scope", this); layout->addWidget(bnOpenScope, 1, 1); - connect(bnOpenScope, &QPushButton::clicked, this, &MainWindow::OpenScope); + connect(bnOpenScope, &QPushButton::clicked, this, &FSUDAQ::OpenScope); cbAnalyzer = new RComboBox(this); layout->addWidget(cbAnalyzer, 0, 2); cbAnalyzer->addItem("Choose Online Analyzer", -1); for( int i = 0; i < (int) onlineAnalyzerList.size() ; i++) cbAnalyzer->addItem(onlineAnalyzerList[i].c_str(), i); - connect(cbAnalyzer, &RComboBox::currentIndexChanged, this, &MainWindow::OpenAnalyzer); + connect(cbAnalyzer, &RComboBox::currentIndexChanged, this, &FSUDAQ::OpenAnalyzer); bnCanvas = new QPushButton("Online 1D Histograms", this); layout->addWidget(bnCanvas, 1, 2); - connect(bnCanvas, &QPushButton::clicked, this, &MainWindow::OpenCanvas); + connect(bnCanvas, &QPushButton::clicked, this, &FSUDAQ::OpenCanvas); bnSync = new QPushButton("Sync Boards", this); layout->addWidget(bnSync, 2, 1); - connect(bnSync, &QPushButton::clicked, this, &MainWindow::SetSyncMode); + connect(bnSync, &QPushButton::clicked, this, &FSUDAQ::SetSyncMode); } @@ -141,7 +142,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ leElogName->setReadOnly(true); layout->addWidget(leElogName, rowID, 4); - connect(bnLock, &QPushButton::clicked, this, &MainWindow::SetAndLockInfluxElog); + connect(bnLock, &QPushButton::clicked, this, &FSUDAQ::SetAndLockInfluxElog); } @@ -157,10 +158,10 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ leDataPath = new QLineEdit(this); leDataPath->setReadOnly(true); QPushButton * bnSetDataPath = new QPushButton("Set Path", this); - connect(bnSetDataPath, &QPushButton::clicked, this, &MainWindow::OpenDataPath); + connect(bnSetDataPath, &QPushButton::clicked, this, &FSUDAQ::OpenDataPath); QPushButton * bnOpenRecord = new QPushButton("Open Record", this); - connect(bnOpenRecord, &QPushButton::clicked, this, &MainWindow::OpenRecord); + connect(bnOpenRecord, &QPushButton::clicked, this, &FSUDAQ::OpenRecord); layout->addWidget(lbDataPath, rowID, 0); layout->addWidget(leDataPath, rowID, 1, 1, 5); @@ -176,7 +177,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ connect(lePrefix, &QLineEdit::textChanged, this, [=](){ lePrefix->setStyleSheet("color:blue;"); }); - connect(lePrefix, &QLineEdit::returnPressed, this, &MainWindow::SaveLastRunFile); + connect(lePrefix, &QLineEdit::returnPressed, this, &FSUDAQ::SaveLastRunFile); QLabel * lbRunID = new QLabel("Run No. :", this); lbRunID->setAlignment(Qt::AlignRight | Qt::AlignCenter); @@ -202,7 +203,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ cbAutoRun->setEnabled(false); bnStartACQ = new QPushButton("Start ACQ", this); - connect( bnStartACQ, &QPushButton::clicked, this, &MainWindow::AutoRun); + connect( bnStartACQ, &QPushButton::clicked, this, &FSUDAQ::AutoRun); bnStopACQ = new QPushButton("Stop ACQ", this); connect( bnStopACQ, &QPushButton::clicked, this, [=](){ if( runTimer->isActive() ){ @@ -234,7 +235,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ leComment->setReadOnly(true); bnOpenScaler = new QPushButton("Scalar", this); - connect(bnOpenScaler, &QPushButton::clicked, this, &MainWindow::OpenScalar); + connect(bnOpenScaler, &QPushButton::clicked, this, &FSUDAQ::OpenScalar); layout->addWidget(lbComment, rowID, 0); layout->addWidget(leComment, rowID, 1, 1, 6); @@ -297,7 +298,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ } -MainWindow::~MainWindow(){ +FSUDAQ::~FSUDAQ(){ DebugPrint("%s", "FSUDAQ"); if( scalar ) { scalarThread->Stop(); @@ -312,10 +313,13 @@ MainWindow::~MainWindow(){ if( scope ) delete scope; - if( histThread){ - histThread->Stop(); - histThread->quit(); - histThread->wait(); + if( histThread ){ + + if( !histThread->isStopped() ){ + histThread->Stop(); + histThread->quit(); + histThread->wait(); + } delete histThread; } @@ -336,7 +340,7 @@ MainWindow::~MainWindow(){ //*************************************************************** //*************************************************************** -void MainWindow::OpenDataPath(){ +void FSUDAQ::OpenDataPath(){ DebugPrint("%s", "FSUDAQ"); QFileDialog fileDialog(this); fileDialog.setFileMode(QFileDialog::Directory); @@ -359,7 +363,7 @@ void MainWindow::OpenDataPath(){ } -void MainWindow::OpenRecord(){ +void FSUDAQ::OpenRecord(){ DebugPrint("%s", "FSUDAQ"); QString filePath = leDataPath->text() + "/RunTimeStamp.dat"; @@ -391,7 +395,7 @@ void MainWindow::OpenRecord(){ } -void MainWindow::UpdateRecord(){ +void FSUDAQ::UpdateRecord(){ DebugPrint("%s", "FSUDAQ"); if( !runRecord ) return; @@ -422,7 +426,7 @@ void MainWindow::UpdateRecord(){ tableView->scrollToBottom(); } -void MainWindow::LoadProgramSettings(){ +void FSUDAQ::LoadProgramSettings(){ DebugPrint("%s", "FSUDAQ"); LogMsg("Loading " + programSettingsFilePath + " for Program Settings."); QFile file(programSettingsFilePath); @@ -485,7 +489,7 @@ void MainWindow::LoadProgramSettings(){ } -void MainWindow::SaveProgramSettings(){ +void FSUDAQ::SaveProgramSettings(){ DebugPrint("%s", "FSUDAQ"); rawDataPath = leDataPath->text(); @@ -508,7 +512,7 @@ void MainWindow::SaveProgramSettings(){ } -void MainWindow::LoadLastRunFile(){ +void FSUDAQ::LoadLastRunFile(){ DebugPrint("%s", "FSUDAQ"); QFile file(rawDataPath + "/lastRun.sh"); @@ -549,7 +553,7 @@ void MainWindow::LoadLastRunFile(){ } -void MainWindow::SaveLastRunFile(){ +void FSUDAQ::SaveLastRunFile(){ DebugPrint("%s", "FSUDAQ"); QFile file(rawDataPath + "/lastRun.sh"); @@ -569,7 +573,7 @@ void MainWindow::SaveLastRunFile(){ //*************************************************************** //*************************************************************** -void MainWindow::OpenDigitizers(){ +void FSUDAQ::OpenDigitizers(){ DebugPrint("%s", "FSUDAQ"); if( cbOpenDigitizers->currentIndex() == 0 ) return; @@ -723,7 +727,7 @@ void MainWindow::OpenDigitizers(){ digi[i]->ReadAllSettingsFromBoard(true); readDataThread[i] = new ReadDataThread(digi[i], i); - connect(readDataThread[i], &ReadDataThread::sendMsg, this, &MainWindow::LogMsg); + connect(readDataThread[i], &ReadDataThread::sendMsg, this, &FSUDAQ::LogMsg); QCoreApplication::processEvents(); //to prevent Qt said application not responding. } @@ -756,8 +760,8 @@ void MainWindow::OpenDigitizers(){ } -void MainWindow::CloseDigitizers(){ - LogMsg("MainWindow::Closing Digitizer(s)...."); +void FSUDAQ::CloseDigitizers(){ + LogMsg("FSUDAQ::Closing Digitizer(s)...."); if( scope ) { scope->close(); @@ -826,11 +830,11 @@ void MainWindow::CloseDigitizers(){ bnStartACQ->setStyleSheet(""); bnStopACQ->setStyleSheet(""); - printf("End of MainWindow::%s\n", __func__); + printf("End of FSUDAQ::%s\n", __func__); } -void MainWindow::WaitForDigitizersOpen(bool onOff){ +void FSUDAQ::WaitForDigitizersOpen(bool onOff){ DebugPrint("%s", "FSUDAQ"); // bnOpenDigitizers->setEnabled(onOff); @@ -855,7 +859,7 @@ void MainWindow::WaitForDigitizersOpen(bool onOff){ //*************************************************************** //*************************************************************** -void MainWindow::SetupScalar(){ +void FSUDAQ::SetupScalar(){ DebugPrint("%s", "FSUDAQ"); // printf("%s\n", __func__); @@ -883,7 +887,7 @@ void MainWindow::SetupScalar(){ scalarThread = new TimingThread(scalar); scalarThread->SetWaitTimeinSec(1.0); - connect(scalarThread, &TimingThread::timeUp, this, &MainWindow::UpdateScalar); + connect(scalarThread, &TimingThread::timeUp, this, &FSUDAQ::UpdateScalar); unsigned short maxNChannel = 0; for( unsigned int k = 0; k < nDigi; k ++ ){ @@ -1004,7 +1008,7 @@ void MainWindow::SetupScalar(){ } -void MainWindow::CleanUpScalar(){ +void FSUDAQ::CleanUpScalar(){ DebugPrint("%s", "FSUDAQ"); if( scalar == nullptr) return; @@ -1033,12 +1037,12 @@ void MainWindow::CleanUpScalar(){ } -void MainWindow::OpenScalar(){ +void FSUDAQ::OpenScalar(){ DebugPrint("%s", "FSUDAQ"); scalar->show(); } -void MainWindow::UpdateScalar(){ +void FSUDAQ::UpdateScalar(){ DebugPrint("%s", "FSUDAQ"); if( digi == nullptr ) return; if( scalar == nullptr ) return; @@ -1116,7 +1120,7 @@ void MainWindow::UpdateScalar(){ //*************************************************************** //*************************************************************** -void MainWindow::StartACQ(){ +void FSUDAQ::StartACQ(){ DebugPrint("%s", "FSUDAQ"); if( digi == nullptr ) return; @@ -1203,7 +1207,7 @@ void MainWindow::StartACQ(){ } -void MainWindow::StopACQ(){ +void FSUDAQ::StopACQ(){ DebugPrint("%s", "FSUDAQ"); QCoreApplication::processEvents(); @@ -1303,7 +1307,7 @@ void MainWindow::StopACQ(){ } -void MainWindow::AutoRun(){ +void FSUDAQ::AutoRun(){ DebugPrint("%s", "FSUDAQ"); runTimer->disconnect(runTimerConnection); if( chkSaveData->isChecked() == false){ @@ -1375,7 +1379,7 @@ void MainWindow::AutoRun(){ } -void MainWindow::SetSyncMode(){ +void FSUDAQ::SetSyncMode(){ DebugPrint("%s", "FSUDAQ"); QDialog dialog; dialog.setWindowTitle("Board Synchronization"); @@ -1471,7 +1475,7 @@ void MainWindow::SetSyncMode(){ } -void MainWindow::SetAndLockInfluxElog(){ +void FSUDAQ::SetAndLockInfluxElog(){ DebugPrint("%s", "FSUDAQ"); if( leInfluxIP->isReadOnly() ){ bnLock->setText("Lock and Set"); @@ -1591,7 +1595,7 @@ void MainWindow::SetAndLockInfluxElog(){ } } -bool MainWindow::CommentDialog(bool isStartRun){ +bool FSUDAQ::CommentDialog(bool isStartRun){ DebugPrint("%s", "FSUDAQ"); if( isStartRun ) runID ++; QString runIDStr = QString::number(runID).rightJustified(3, '0'); @@ -1672,7 +1676,7 @@ bool MainWindow::CommentDialog(bool isStartRun){ } -void MainWindow::WriteRunTimestamp(bool isStartRun){ +void FSUDAQ::WriteRunTimestamp(bool isStartRun){ DebugPrint("%s", "FSUDAQ"); QFile file(rawDataPath + "/RunTimeStamp.dat"); @@ -1710,12 +1714,12 @@ void MainWindow::WriteRunTimestamp(bool isStartRun){ //*************************************************************** //*************************************************************** -void MainWindow::OpenScope(){ +void FSUDAQ::OpenScope(){ DebugPrint("%s", "FSUDAQ"); QCoreApplication::processEvents(); if( scope == nullptr ) { scope = new Scope(digi, nDigi, readDataThread); - connect(scope, &Scope::SendLogMsg, this, &MainWindow::LogMsg); + connect(scope, &Scope::SendLogMsg, this, &FSUDAQ::LogMsg); connect(scope, &Scope::CloseWindow, this, [=](){ bnStartACQ->setEnabled(true); bnStartACQ->setStyleSheet("background-color: green;"); @@ -1753,7 +1757,7 @@ void MainWindow::OpenScope(){ } }); - connect(scope, &Scope::UpdateScaler, this, &MainWindow::UpdateScalar); + connect(scope, &Scope::UpdateScaler, this, &FSUDAQ::UpdateScalar); connect(scope, &Scope::UpdateOtherPanels, this, [=](){ UpdateAllPanels(1); }); @@ -1773,11 +1777,11 @@ void MainWindow::OpenScope(){ //*************************************************************** //*************************************************************** -void MainWindow::OpenDigiSettings(){ +void FSUDAQ::OpenDigiSettings(){ DebugPrint("%s", "FSUDAQ"); if( digiSettings == nullptr ) { digiSettings = new DigiSettingsPanel(digi, nDigi, rawDataPath); - //connect(scope, &Scope::SendLogMsg, this, &MainWindow::LogMsg); + //connect(scope, &Scope::SendLogMsg, this, &FSUDAQ::LogMsg); connect(digiSettings, &DigiSettingsPanel::UpdateOtherPanels, this, [=](){ UpdateAllPanels(2); }); digiSettings->show(); @@ -1789,7 +1793,7 @@ void MainWindow::OpenDigiSettings(){ //*************************************************************** //*************************************************************** -void MainWindow::OpenCanvas(){ +void FSUDAQ::OpenCanvas(){ DebugPrint("%s", "FSUDAQ"); if( canvas == nullptr ) { canvas = new SingleSpectra(digi, nDigi, rawDataPath); @@ -1802,7 +1806,7 @@ void MainWindow::OpenCanvas(){ } //*************************************************************** //*************************************************************** -void MainWindow::OpenAnalyzer(){ +void FSUDAQ::OpenAnalyzer(){ DebugPrint("%s", "FSUDAQ"); int id = cbAnalyzer->currentData().toInt(); @@ -1837,7 +1841,7 @@ void MainWindow::OpenAnalyzer(){ //*************************************************************** //*************************************************************** -void MainWindow::UpdateAllPanels(int panelID){ +void FSUDAQ::UpdateAllPanels(int panelID){ DebugPrint("%s", "FSUDAQ"); //panelID is the source panel that call // scope = 1; @@ -1898,7 +1902,7 @@ void MainWindow::UpdateAllPanels(int panelID){ //*************************************************************** //*************************************************************** -void MainWindow::SetUpInflux(){ +void FSUDAQ::SetUpInflux(){ DebugPrint("%s", "FSUDAQ"); if( influxIP == "" ) { LogMsg("Influx missing inputs. skip."); @@ -1962,7 +1966,7 @@ void MainWindow::SetUpInflux(){ } -void MainWindow::CheckElog(){ +void FSUDAQ::CheckElog(){ DebugPrint("%s", "FSUDAQ"); LogMsg("---- Checking elog... please wait...."); printf("---- Checking elog... please wait....\n"); @@ -1995,7 +1999,7 @@ void MainWindow::CheckElog(){ } -void MainWindow::WriteElog(QString htmlText, QString subject, QString category, int runNumber){ +void FSUDAQ::WriteElog(QString htmlText, QString subject, QString category, int runNumber){ DebugPrint("%s", "FSUDAQ"); //if( elogID < 0 ) return; if( elogName == "" ) return; @@ -2024,7 +2028,7 @@ void MainWindow::WriteElog(QString htmlText, QString subject, QString category, } -void MainWindow::AppendElog(QString appendHtmlText){ +void FSUDAQ::AppendElog(QString appendHtmlText){ DebugPrint("%s", "FSUDAQ"); if( elogID < 1 ) return; if( elogName == "" ) return; @@ -2061,7 +2065,7 @@ void MainWindow::AppendElog(QString appendHtmlText){ //*************************************************************** //*************************************************************** -void MainWindow::LogMsg(QString msg){ +void FSUDAQ::LogMsg(QString msg){ DebugPrint("%s", "FSUDAQ"); QString outputStr = QStringLiteral("[%1] %2").arg(QDateTime::currentDateTime().toString("MM.dd hh:mm:ss"), msg); if( logMsgHTMLMode ){ diff --git a/FSUDAQ.h b/FSUDAQ.h index 120fd53..8ca1dda 100644 --- a/FSUDAQ.h +++ b/FSUDAQ.h @@ -1,5 +1,5 @@ -#ifndef MAINWINDOW_H -#define MAINWINDOW_H +#ifndef FSUDAQ_H +#define FSUDAQ_H #include #include @@ -20,12 +20,12 @@ #include "ClassInfluxDB.h" #include "analyzers/Analyser.h" -//^#===================================================== MainWindow -class MainWindow : public QMainWindow{ +//^#===================================================== FSUDAQ +class FSUDAQ : public QMainWindow{ Q_OBJECT public: - MainWindow(QWidget *parent = nullptr); - ~MainWindow(); + FSUDAQ(QWidget *parent = nullptr); + ~FSUDAQ(); void closeEvent(QCloseEvent * event){ if( scope ) { diff --git a/FSUDAQ_Qt6.pro b/FSUDAQ_Qt6.pro index 9fc186d..a669aaf 100644 --- a/FSUDAQ_Qt6.pro +++ b/FSUDAQ_Qt6.pro @@ -11,9 +11,9 @@ QT += core widgets charts printsupport LIBS += -lCAENDigitizer -lcurl #==== for enable GDB debug -#QMAKE_CXXFLAGS += -g -#QMAKE_CXXFLAGS_RELEASE = -O0 -#QMAKE_CFLAGS_RELEASE = -O0 +QMAKE_CXXFLAGS += -g +QMAKE_CXXFLAGS_RELEASE = -O0 +QMAKE_CFLAGS_RELEASE = -O0 # You can make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. diff --git a/analyzers/CoincidentAnalyzer.h b/analyzers/CoincidentAnalyzer.h index 9113fe2..50d9075 100644 --- a/analyzers/CoincidentAnalyzer.h +++ b/analyzers/CoincidentAnalyzer.h @@ -25,9 +25,12 @@ public: dataBaseName = "testing"; allowSignalSlot = false; + printf("------------------- dasjkdsaldj\n"); SetUpCanvas(); + printf("------------------- dasjkdsaldj###########\n"); LoadHistRange(); + printf("------------------- dasjkdsaldj##&&&&&&&&&#\n"); } @@ -251,7 +254,7 @@ inline void CoincidentAnalyzer::SetUpCanvas(){ boxLayout->addWidget(lbaDigi, 7, 0); aDigi = new RComboBox(this); for(unsigned int i = 0; i < nDigi; i ++ ){ - aDigi->addItem("Digi-" + QString::number(digi[i]->GetSerialNumber()), digi[i]->GetSerialNumber()); + aDigi->addItem("Digi-" + QString::number(digi[i]->GetSerialNumber()), i); } boxLayout->addWidget(aDigi, 7, 1); @@ -307,7 +310,6 @@ inline void CoincidentAnalyzer::SetUpCanvas(){ } - } //============ histograms @@ -327,12 +329,12 @@ inline void CoincidentAnalyzer::SetUpCanvas(){ h2D->SetYTitle("Digi-" + QString::number(digi[bd]->GetSerialNumber()) + ", Ch-" + QString::number(ch)); h2D->UpdatePlot(); - h1 = new Histogram1D("1D Plot", "XXX", 300, 0, 5000, this); h1->SetColor(Qt::darkGreen); h1->AddDataList("Test", Qt::red); // add another histogram in h1, Max Data List is 10 bd = aDigi->currentData().toInt(); ch = aCh->currentData().toInt(); + printf("%d\n", digi[bd]->GetSerialNumber()); h1->SetXTitle("Digi-" + QString::number(digi[bd]->GetSerialNumber()) + ", Ch-" + QString::number(ch)); h1->UpdatePlot(); layout->addWidget(h1, 1, 1); diff --git a/main.cpp b/main.cpp index 4f2ec66..bdaee58 100644 --- a/main.cpp +++ b/main.cpp @@ -70,7 +70,7 @@ int main(int argc, char *argv[]){ pidFile.write( QString::number(QCoreApplication::applicationPid() ).toStdString().c_str() ); pidFile.close(); - MainWindow w; + FSUDAQ w; w.show(); return a.exec(); } \ No newline at end of file From 0371f0c560ee00e3c0ba42ccf7cf77d8cfcfb7c0 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Wed, 26 Jun 2024 16:42:37 -0400 Subject: [PATCH 15/72] comment out GDB debug in *.pro --- FSUDAQ_Qt6.pro | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/FSUDAQ_Qt6.pro b/FSUDAQ_Qt6.pro index a669aaf..9fc186d 100644 --- a/FSUDAQ_Qt6.pro +++ b/FSUDAQ_Qt6.pro @@ -11,9 +11,9 @@ QT += core widgets charts printsupport LIBS += -lCAENDigitizer -lcurl #==== for enable GDB debug -QMAKE_CXXFLAGS += -g -QMAKE_CXXFLAGS_RELEASE = -O0 -QMAKE_CFLAGS_RELEASE = -O0 +#QMAKE_CXXFLAGS += -g +#QMAKE_CXXFLAGS_RELEASE = -O0 +#QMAKE_CFLAGS_RELEASE = -O0 # You can make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. From 839b3d2a584455e0b00959bbf1e3a0544944ab8d Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Wed, 26 Jun 2024 17:35:09 -0400 Subject: [PATCH 16/72] fix CoincidentAnalyzer.h --- Histogram1D.h | 2 +- Histogram2D.h | 4 ++-- analyzers/CoincidentAnalyzer.h | 30 +++++++++++++++++------------- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/Histogram1D.h b/Histogram1D.h index 9f531a7..1993061 100644 --- a/Histogram1D.h +++ b/Histogram1D.h @@ -234,7 +234,7 @@ public: UpdatePlot(); } - void SetXTitle(QString xTitle) { xAxis->setLabel(xTitle); } + void SetXTitle(QString xTitle) { xAxis->setLabel(xTitle);} void Rebin(int xbin, double xmin, double xmax){ // DebugPrint("%s", "Histogram1D"); diff --git a/Histogram2D.h b/Histogram2D.h index bafd9f2..93f2a46 100644 --- a/Histogram2D.h +++ b/Histogram2D.h @@ -187,8 +187,8 @@ public: //^=================================== - void SetXTitle(QString xTitle) { xAxis->setLabel(xTitle); } - void SetYTitle(QString yTitle) { yAxis->setLabel(yTitle); } + void SetXTitle(QString xTitle) { xAxis->setLabel(xTitle);} + void SetYTitle(QString yTitle) { yAxis->setLabel(yTitle);} void Rebin(int xbin, double xmin, double xmax, int ybin, double ymin, double ymax); void RebinY(int ybin, double ymin, double ymax); diff --git a/analyzers/CoincidentAnalyzer.h b/analyzers/CoincidentAnalyzer.h index 50d9075..f4038c7 100644 --- a/analyzers/CoincidentAnalyzer.h +++ b/analyzers/CoincidentAnalyzer.h @@ -25,12 +25,9 @@ public: dataBaseName = "testing"; allowSignalSlot = false; - printf("------------------- dasjkdsaldj\n"); SetUpCanvas(); - printf("------------------- dasjkdsaldj###########\n"); LoadHistRange(); - printf("------------------- dasjkdsaldj##&&&&&&&&&#\n"); } @@ -84,6 +81,7 @@ private: inline void CoincidentAnalyzer::SetUpCanvas(){ + setWindowTitle("Online Coincident Analyzer"); setGeometry(0, 0, 1600, 1000); {//^====== magnet and reaction setting @@ -143,12 +141,13 @@ inline void CoincidentAnalyzer::SetUpCanvas(){ SetBackwardBuild(true, sbBackwardCount->value()); }); - QLabel * lbBuildWindow = new QLabel("Event Window [tick]", this); + QLabel * lbBuildWindow = new QLabel("Event Window [ns]", this); lbBuildWindow->setAlignment(Qt::AlignRight | Qt::AlignCenter); boxLayout->addWidget(lbBuildWindow, 2, 1); sbBuildWindow = new RSpinBox(this, 0); sbBuildWindow->setMinimum(1); sbBuildWindow->setMaximum(9999999999); + sbBuildWindow->setValue(1000); boxLayout->addWidget(sbBuildWindow, 2, 2); connect(sbBuildWindow, &RSpinBox::valueChanged, this, [=](){ @@ -313,11 +312,11 @@ inline void CoincidentAnalyzer::SetUpCanvas(){ } //============ histograms - hMulti = new Histogram1D("Multiplicity", "", 10, 0, 10, this); + hMulti = new Histogram1D("Multiplicity", "", 16, 0, 16, this); layout->addWidget(hMulti, 0, 1); // the "this" make the histogram a child of the SplitPole class. When SplitPole destory, all childs destory as well. - h2D = new Histogram2D("Coincident Plot", "XXX", "YYY", 100, 0, 5000, 100, 0, 5000, this); + h2D = new Histogram2D("Coincident Plot", "XXX", "YYY", 200, 0, 30000, 200, 0, 30000, this); //layout is inheriatge from Analyzer layout->addWidget(h2D, 1, 0, 2, 1); @@ -329,17 +328,16 @@ inline void CoincidentAnalyzer::SetUpCanvas(){ h2D->SetYTitle("Digi-" + QString::number(digi[bd]->GetSerialNumber()) + ", Ch-" + QString::number(ch)); h2D->UpdatePlot(); - h1 = new Histogram1D("1D Plot", "XXX", 300, 0, 5000, this); + h1 = new Histogram1D("1D Plot", "XXX", 300, 0, 30000, this); h1->SetColor(Qt::darkGreen); - h1->AddDataList("Test", Qt::red); // add another histogram in h1, Max Data List is 10 + // h1->AddDataList("Test", Qt::red); // add another histogram in h1, Max Data List is 10 bd = aDigi->currentData().toInt(); ch = aCh->currentData().toInt(); - printf("%d\n", digi[bd]->GetSerialNumber()); h1->SetXTitle("Digi-" + QString::number(digi[bd]->GetSerialNumber()) + ", Ch-" + QString::number(ch)); h1->UpdatePlot(); layout->addWidget(h1, 1, 1); - h1g = new Histogram1D("1D Plot (PID gated)", "XXX", 300, 0, 5000, this); + h1g = new Histogram1D("1D Plot (PID gated)", "XXX", 300, 0, 30000, this); h1g->SetXTitle("Digi-" + QString::number(digi[bd]->GetSerialNumber()) + ", Ch-" + QString::number(ch)); h1g->UpdatePlot(); layout->addWidget(h1g, 2, 1); @@ -347,6 +345,8 @@ inline void CoincidentAnalyzer::SetUpCanvas(){ layout->setColumnStretch(0, 1); layout->setColumnStretch(1, 1); + allowSignalSlot = true; + } inline void CoincidentAnalyzer::UpdateHistograms(){ @@ -376,6 +376,10 @@ inline void CoincidentAnalyzer::UpdateHistograms(){ int y_bd = yDigi->currentData().toInt(); int y_ch = yCh->currentData().toInt(); + int a_sn = digi[a_bd]->GetSerialNumber(); + int x_sn = digi[x_bd]->GetSerialNumber(); + int y_sn = digi[y_bd]->GetSerialNumber(); + //============ Processing data and fill histograms long eventIndex = evtbder->eventIndex; long eventStart = eventIndex - eventBuilt + 1; @@ -392,16 +396,16 @@ inline void CoincidentAnalyzer::UpdateHistograms(){ unsigned long long xT = 0; for( int k = 0; k < (int) event.size(); k++ ){ //event[k].Print(); - if( event[k].sn == a_bd && event[k].ch == a_ch) { + if( event[k].sn == a_sn && event[k].ch == a_ch) { h1->Fill(event[k].energy); aE = event[k].energy; } - if( event[k].sn == x_bd && event[k].ch == x_ch) { + if( event[k].sn == x_sn && event[k].ch == x_ch) { xE = event[k].energy; xT = event[k].timestamp; } - if( event[k].sn == y_bd && event[k].ch == y_ch) yE = event[k].energy; + if( event[k].sn == y_sn && event[k].ch == y_ch) yE = event[k].energy; } if( xE >= 0 && yE >= 0 ) h2D->Fill(xE, yE); From c8e032390a178ec5e6dcccac5d0c919ff7814927 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Thu, 27 Jun 2024 16:51:31 -0400 Subject: [PATCH 17/72] Histogram2D.h add save/load graphic cuts into/from txt file --- Histogram2D.h | 507 +++++++++++++++++++++++++++++++------------------- 1 file changed, 313 insertions(+), 194 deletions(-) diff --git a/Histogram2D.h b/Histogram2D.h index 93f2a46..3d04030 100644 --- a/Histogram2D.h +++ b/Histogram2D.h @@ -19,173 +19,7 @@ const QList> colorCycle = { {QColor(Qt::red), "Red"}, class Histogram2D : public QCustomPlot{ public: - Histogram2D(QString title, QString xLabel, QString yLabel, int xbin, double xmin, double xmax, int ybin, double ymin, double ymax, QWidget * parent = nullptr) : QCustomPlot(parent){ - // DebugPrint("%s", "Histogram2D"); - for( int i = 0; i < 3; i ++ ){ - for( int j = 0; j < 3; j ++ ){ - box[i][j] = nullptr; - txt[i][j] = nullptr; - } - } - - isChannelMap = false; - tickStep = 1; // only used when isChannelMap = true - isLogZ = false; - - axisRect()->setupFullAxesBox(true); - xAxis->setLabel(xLabel); - yAxis->setLabel(yLabel); - - colorMap = new QCPColorMap(xAxis, yAxis); - Rebin(xbin, xmin, xmax, ybin, ymin, ymax); - colorMap->setInterpolate(false); - - QCPTextElement *titleEle = new QCPTextElement(this, title, QFont("sans", 12)); - plotLayout()->insertRow(0); - plotLayout()->addElement(0, 0, titleEle); - - colorScale = new QCPColorScale(this); - plotLayout()->addElement(1, 1, colorScale); - colorScale->setType(QCPAxis::atRight); - colorMap->setColorScale(colorScale); - - - QCPColorGradient color; - color.setNanHandling(QCPColorGradient::NanHandling::nhNanColor); - color.setNanColor(QColor("white")); - color.clearColorStops(); - // color.setColorStopAt( 0.0, QColor("white" )); - color.setColorStopAt( 0.0, QColor("purple" )); - color.setColorStopAt( 0.2, QColor("blue")); - color.setColorStopAt( 0.4, QColor("cyan")); - color.setColorStopAt( 0.6, QColor("green")); - color.setColorStopAt( 0.8, QColor("yellow")); - color.setColorStopAt( 1.0, QColor("red")); - colorMap->setGradient(color); - - double xPosStart = 0.02; - double xPosStep = 0.07; - double yPosStart = 0.02; - double yPosStep = 0.05; - - for( int i = 0; i < 3; i ++ ){ - for( int j = 0; j < 3; j ++ ){ - box[i][j] = new QCPItemRect(this); - - box[i][j]->topLeft->setType(QCPItemPosition::ptAxisRectRatio); - box[i][j]->topLeft->setCoords(xPosStart + xPosStep*i, yPosStart + yPosStep*j); - box[i][j]->bottomRight->setType(QCPItemPosition::ptAxisRectRatio); - box[i][j]->bottomRight->setCoords(xPosStart + xPosStep*(i+1), yPosStart + yPosStep*(j+1)); - - txt[i][j] = new QCPItemText(this); - txt[i][j]->setPositionAlignment(Qt::AlignLeft); - txt[i][j]->position->setType(QCPItemPosition::ptAxisRectRatio); - txt[i][j]->position->setCoords(xPosStart + xPosStep/2 + xPosStep*i, yPosStart + yPosStep*j);; - txt[i][j]->setText("0"); - txt[i][j]->setFont(QFont("Helvetica", 9)); - - } - } - - cutList.clear(); - cutEntryList.clear(); - - rescaleAxes(); - - usingMenu = false; - isDrawCut = false; - tempCutID = -1; - numCut = 0; - lastPlottableID = -1; - - line = new QCPItemLine(this); - line->setPen(QPen(Qt::gray, 1, Qt::DashLine)); - line->setVisible(false); - - isBusy = false; - - connect(this, &QCustomPlot::mouseMove, this, [=](QMouseEvent *event){ - double x = xAxis->pixelToCoord(event->pos().x()); - double y = yAxis->pixelToCoord(event->pos().y()); - int xI, yI; - colorMap->data()->coordToCell(x, y, &xI, &yI); - double z = colorMap->data()->cell(xI, yI); - - QString coordinates = QString("X: %1, Y: %2, Z: %3").arg(x).arg(y).arg(z); - QToolTip::showText(event->globalPosition().toPoint(), coordinates, this); - - //when drawing cut, show dashhed line - if( isDrawCut && tempCut.size() > 0 ){ - line->end->setCoords(x,y); - line->setVisible(true); - replot(); - } - - }); - - connect(this, &QCustomPlot::mousePress, this, [=](QMouseEvent * event){ - - if (event->button() == Qt::LeftButton && !usingMenu && !isDrawCut){ - setSelectionRectMode(QCP::SelectionRectMode::srmZoom); - } - - if (event->button() == Qt::LeftButton && isDrawCut){ - - oldMouseX = xAxis->pixelToCoord(event->pos().x()); - oldMouseY = yAxis->pixelToCoord(event->pos().y()); - - tempCut.push_back(QPointF(oldMouseX,oldMouseY)); - - line->start->setCoords(oldMouseX, oldMouseY); - line->end->setCoords(oldMouseX, oldMouseY); - line->setVisible(true); - - DrawCut(); - } - - //^================= right click - if (event->button() == Qt::RightButton) rightMouseClickMenu(event); - }); - - //connect( this, &QCustomPlot::mouseDoubleClick, this, [=](QMouseEvent *event){ - connect( this, &QCustomPlot::mouseDoubleClick, this, [=](){ - if( isDrawCut) { - tempCut.push_back(tempCut[0]); - DrawCut(); - isDrawCut = false; - line->setVisible(false); - - plottableIDList.push_back(plottableCount() -1 ); - - cutNameList.push_back("Cut-" + QString::number(cutList.count())); - cutEntryList.push_back(0); - - QCPItemText * text = new QCPItemText(this); - text->setText(cutNameList.last()); - text->position->setCoords(tempCut[0].rx(), tempCut[0].ry()); - int colorID = tempCutID% colorCycle.count(); - text->setColor(colorCycle[colorID].first); - cutTextIDList.push_back(itemCount() - 1); - - replot(); - - cutList.push_back(tempCut); - cutIDList.push_back(tempCutID); - - // qDebug() << "----------- end of create cut"; - // qDebug() << " cutIDList " << cutIDList ; - // qDebug() << "plottableIDList " << plottableIDList << ", " << plottableCount(); - // qDebug() << " cutTextIDList " << cutTextIDList << ", " << itemCount(); - - } - }); - - connect(this, &QCustomPlot::mouseRelease, this, [=](){ - - }); - } - - //^=================================== + Histogram2D(QString title, QString xLabel, QString yLabel, int xbin, double xmin, double xmax, int ybin, double ymin, double ymax, QWidget * parent = nullptr); void SetXTitle(QString xTitle) { xAxis->setLabel(xTitle);} void SetYTitle(QString yTitle) { yAxis->setLabel(yTitle);} @@ -194,25 +28,7 @@ public: void SetChannelMap(bool onOff, int tickStep = 1) { isChannelMap = onOff; this->tickStep = tickStep;} - void UpdatePlot(){ - // QCPColorGradient color; - // color.clearColorStops(); - // color.setNanColor(QColor("white")); - // // color.setColorStopAt( 0.0, QColor("white" )); - // // color.setColorStopAt( 1.0/entry[1][1], QColor("purple" )); - // color.setColorStopAt( 0.0, QColor("purple" )); - // color.setColorStopAt( 0.2, QColor("blue")); - // color.setColorStopAt( 0.4, QColor("cyan")); - // color.setColorStopAt( 0.6, QColor("green")); - // color.setColorStopAt( 0.8, QColor("yellow")); - // color.setColorStopAt( 1.0, QColor("red")); - // colorMap->setGradient(color); - - colorMap->rescaleDataRange(); - - replot(); - } - + void UpdatePlot(){ colorMap->rescaleDataRange(); replot(); } void Clear(); // Clear Data and histrogram void Fill(double x, double y); @@ -232,6 +48,9 @@ public: double GetYMin() const {return yMin;} double GetYMax() const {return yMax;} + void SaveCuts(QString cutFileName); + void LoadCuts(QString cutFileName); + private: double xMin, xMax, yMin, yMax; int xBin, yBin; @@ -252,15 +71,15 @@ private: QPolygonF tempCut; int tempCutID; // only incresing; - QList cutList; - QList cutIDList; int numCut; + QList cutList; + QList cutNameList; // name of the cut + QList cutEntryList; // number of entry inside the cut. + QList cutIDList; // ID of the cut + QList cutTextIDList; // + QList plottableIDList; bool isDrawCut; int lastPlottableID; - QList cutTextIDList; - QList plottableIDList; - QList cutNameList; - QList cutEntryList; QCPItemLine * line; double oldMouseX = 0.0, oldMouseY = 0.0; @@ -275,6 +94,174 @@ private: //^############################################### //^############################################### +inline Histogram2D::Histogram2D(QString title, QString xLabel, QString yLabel, int xbin, double xmin, double xmax, int ybin, double ymin, double ymax, QWidget * parent) : QCustomPlot(parent){ + // DebugPrint("%s", "Histogram2D"); + for( int i = 0; i < 3; i ++ ){ + for( int j = 0; j < 3; j ++ ){ + box[i][j] = nullptr; + txt[i][j] = nullptr; + } + } + + isChannelMap = false; + tickStep = 1; // only used when isChannelMap = true + isLogZ = false; + + axisRect()->setupFullAxesBox(true); + xAxis->setLabel(xLabel); + yAxis->setLabel(yLabel); + + colorMap = new QCPColorMap(xAxis, yAxis); + Rebin(xbin, xmin, xmax, ybin, ymin, ymax); + colorMap->setInterpolate(false); + + QCPTextElement *titleEle = new QCPTextElement(this, title, QFont("sans", 12)); + plotLayout()->insertRow(0); + plotLayout()->addElement(0, 0, titleEle); + + colorScale = new QCPColorScale(this); + plotLayout()->addElement(1, 1, colorScale); + colorScale->setType(QCPAxis::atRight); + colorMap->setColorScale(colorScale); + + + QCPColorGradient color; + color.setNanHandling(QCPColorGradient::NanHandling::nhNanColor); + color.setNanColor(QColor("white")); + color.clearColorStops(); + // color.setColorStopAt( 0.0, QColor("white" )); + color.setColorStopAt( 0.0, QColor("purple" )); + color.setColorStopAt( 0.2, QColor("blue")); + color.setColorStopAt( 0.4, QColor("cyan")); + color.setColorStopAt( 0.6, QColor("green")); + color.setColorStopAt( 0.8, QColor("yellow")); + color.setColorStopAt( 1.0, QColor("red")); + colorMap->setGradient(color); + + double xPosStart = 0.02; + double xPosStep = 0.07; + double yPosStart = 0.02; + double yPosStep = 0.05; + + for( int i = 0; i < 3; i ++ ){ + for( int j = 0; j < 3; j ++ ){ + box[i][j] = new QCPItemRect(this); + + box[i][j]->topLeft->setType(QCPItemPosition::ptAxisRectRatio); + box[i][j]->topLeft->setCoords(xPosStart + xPosStep*i, yPosStart + yPosStep*j); + box[i][j]->bottomRight->setType(QCPItemPosition::ptAxisRectRatio); + box[i][j]->bottomRight->setCoords(xPosStart + xPosStep*(i+1), yPosStart + yPosStep*(j+1)); + + txt[i][j] = new QCPItemText(this); + txt[i][j]->setPositionAlignment(Qt::AlignLeft); + txt[i][j]->position->setType(QCPItemPosition::ptAxisRectRatio); + txt[i][j]->position->setCoords(xPosStart + xPosStep/2 + xPosStep*i, yPosStart + yPosStep*j);; + txt[i][j]->setText("0"); + txt[i][j]->setFont(QFont("Helvetica", 9)); + + } + } + + cutList.clear(); + cutEntryList.clear(); + + rescaleAxes(); + + usingMenu = false; + isDrawCut = false; + tempCutID = -1; + numCut = 0; + lastPlottableID = -1; + + line = new QCPItemLine(this); + line->setPen(QPen(Qt::gray, 1, Qt::DashLine)); + line->setVisible(false); + + isBusy = false; + + connect(this, &QCustomPlot::mouseMove, this, [=](QMouseEvent *event){ + double x = xAxis->pixelToCoord(event->pos().x()); + double y = yAxis->pixelToCoord(event->pos().y()); + int xI, yI; + colorMap->data()->coordToCell(x, y, &xI, &yI); + double z = colorMap->data()->cell(xI, yI); + + QString coordinates = QString("X: %1, Y: %2, Z: %3").arg(x).arg(y).arg(z); + QToolTip::showText(event->globalPosition().toPoint(), coordinates, this); + + //when drawing cut, show dashhed line + if( isDrawCut && tempCut.size() > 0 ){ + line->end->setCoords(x,y); + line->setVisible(true); + replot(); + } + + }); + + connect(this, &QCustomPlot::mousePress, this, [=](QMouseEvent * event){ + + if (event->button() == Qt::LeftButton && !usingMenu && !isDrawCut){ + setSelectionRectMode(QCP::SelectionRectMode::srmZoom); + } + + if (event->button() == Qt::LeftButton && isDrawCut){ + + oldMouseX = xAxis->pixelToCoord(event->pos().x()); + oldMouseY = yAxis->pixelToCoord(event->pos().y()); + + tempCut.push_back(QPointF(oldMouseX,oldMouseY)); + + line->start->setCoords(oldMouseX, oldMouseY); + line->end->setCoords(oldMouseX, oldMouseY); + line->setVisible(true); + + DrawCut(); + } + + //^================= right click + if (event->button() == Qt::RightButton) rightMouseClickMenu(event); + }); + + //connect( this, &QCustomPlot::mouseDoubleClick, this, [=](QMouseEvent *event){ + connect( this, &QCustomPlot::mouseDoubleClick, this, [=](){ + if( isDrawCut) { + tempCut.push_back(tempCut[0]); + DrawCut(); + isDrawCut = false; + line->setVisible(false); + + plottableIDList.push_back(plottableCount() -1 ); + + cutNameList.push_back("Cut-" + QString::number(cutList.count())); + cutEntryList.push_back(0); + + QCPItemText * text = new QCPItemText(this); + text->setText(cutNameList.last()); + text->position->setCoords(tempCut[0].rx(), tempCut[0].ry()); + int colorID = tempCutID% colorCycle.count(); + text->setColor(colorCycle[colorID].first); + cutTextIDList.push_back(itemCount() - 1); + + replot(); + + cutList.push_back(tempCut); + cutIDList.push_back(tempCutID); + + // qDebug() << "----------- end of create cut"; + // qDebug() << " cutIDList " << cutIDList ; + // qDebug() << "plottableIDList " << plottableIDList << ", " << plottableCount(); + // qDebug() << " cutTextIDList " << cutTextIDList << ", " << itemCount(); + + } + }); + + connect(this, &QCustomPlot::mouseRelease, this, [=](){ + + }); +} + + + inline void Histogram2D::Fill(double x, double y){ // DebugPrint("%s", "Histogram2D"); if( isBusy ) return; @@ -391,7 +378,7 @@ inline void Histogram2D::ClearAllCuts(){ inline void Histogram2D::PrintCutEntry() const{ DebugPrint("%s", "Histogram2D"); if( numCut == 0 ) return; - printf("=============== There are %d cuts.\n", numCut); + printf("=============== There are %d cuts. (%lld, %lld)\n", numCut, cutList.count(), cutEntryList.count()); for( int i = 0; i < cutList.count(); i++){ if( cutList[i].isEmpty() ) continue; printf("%10s | %d \n", cutNameList[i].toStdString().c_str(), cutEntryList[i]); @@ -423,7 +410,7 @@ inline void Histogram2D::DrawCut(){ } replot(); - //qDebug() << "Plottable count : " << plottableCount() << ", cutList.count :" << cutList.count() << ", cutID :" << lastPlottableID; + // qDebug() << "Plottable count : " << plottableCount() << ", cutList.count :" << cutList.count() << ", cutID :" << lastPlottableID; } inline void Histogram2D::rightMouseClickMenu(QMouseEvent * event){ @@ -439,8 +426,11 @@ inline void Histogram2D::rightMouseClickMenu(QMouseEvent * event){ QAction * a2 = menu->addAction("Clear hist."); QAction * a3 = menu->addAction("Toggle Stat."); QAction * a4 = menu->addAction("Rebin (clear histogram)"); + QAction * a8 = menu->addAction("Load Cut(s)"); QAction * a5 = menu->addAction("Create a Cut"); + QAction * a7 = nullptr; if( numCut > 0 ) { + a7 = menu->addAction("Save Cut(s)"); menu->addSeparator(); menu->addAction("Add/Edit names to Cuts"); menu->addAction("Clear all Cuts"); @@ -575,6 +565,27 @@ inline void Histogram2D::rightMouseClickMenu(QMouseEvent * event){ return; } + if( selectedAction == a8 ){ // load Cuts + QString filePath = QFileDialog::getOpenFileName(this, + "Load Cuts from File", + QDir::homePath(), + "Text file (*.txt)"); + + if (!filePath.isEmpty()) LoadCuts(filePath); + + } + + if( selectedAction == a7 ){ // Save Cuts + + QString filePath = QFileDialog::getSaveFileName(this, + "Save Cuts to File", + QDir::homePath(), + "Text file (*.txt)"); + + if (!filePath.isEmpty()) SaveCuts(filePath); + + } + } @@ -674,5 +685,113 @@ inline void Histogram2D::rightMouseClickRebin(){ } +inline void Histogram2D::SaveCuts(QString cutFileName){ + + QFile file(cutFileName); + if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { + QTextStream out(&file); + + // Define the text to write + QStringList lines; + + for( int i = 0; i < cutList.size(); i++){ + lines << "====== "+ cutNameList[i]; + for( int pt = 0 ; pt < cutList[i].size(); pt ++){ + lines << QString::number(cutList[i][pt].rx(), 'g', 5) + "," + QString::number(cutList[i][pt].ry(), 'g', 5); + } + } + + lines << "#===== End of File"; + + // Write each line to the file + for (const QString &line : lines) out << line << "\n"; + + // Close the file + file.close(); + qDebug() << "File written successfully to" << cutFileName; + }else{ + qWarning() << "Unable to open file" << cutFileName; + } + +} + +inline void Histogram2D::LoadCuts(QString cutFileName){ + + QFile file(cutFileName); + QString cutNameTemp; + + // Open the file in read mode + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&file); + + ClearAllCuts(); + tempCut.clear(); + + // Read each line and append to the QStringList + + while (!in.atEnd()) { + QString line = in.readLine(); + + if( line.contains("======") ){ + if( !tempCut.isEmpty() ) { + DrawCut(); + plottableIDList.push_back(plottableCount() -1 ); + cutNameList.push_back(cutNameTemp); + cutEntryList.push_back(0); + QCPItemText * text = new QCPItemText(this); + text->setText(cutNameList.last()); + text->position->setCoords(tempCut[0].rx(), tempCut[0].ry()); + int colorID = tempCutID% colorCycle.count(); + text->setColor(colorCycle[colorID].first); + cutTextIDList.push_back(itemCount() - 1); + // cutList.push_back(tempCut); + cutIDList.push_back(tempCutID); + } + tempCut.clear(); + tempCutID ++; + numCut ++; + + int spacePos = line.indexOf(' '); + cutNameTemp = line.mid(spacePos + 1); + continue; + } + + if( line.contains("#==") ) { + DrawCut(); + plottableIDList.push_back(plottableCount() -1 ); + cutNameList.push_back(cutNameTemp); + cutEntryList.push_back(0); + QCPItemText * text = new QCPItemText(this); + text->setText(cutNameList.last()); + text->position->setCoords(tempCut[0].rx(), tempCut[0].ry()); + int colorID = tempCutID% colorCycle.count(); + text->setColor(colorCycle[colorID].first); + cutTextIDList.push_back(itemCount() - 1); + cutList.push_back(tempCut); + cutIDList.push_back(tempCutID); + break; + }else{ + QStringList haha = line.split(","); + // qDebug() << haha; + tempCut.push_back(QPointF(haha[0].toFloat(), haha[1].toFloat())); + DrawCut(); + } + + } + + // Close the file + file.close(); + qDebug() << "File read successfully from" << cutFileName; + + // PrintCutEntry(); + // DrawCut(); + replot(); + + } else { + qWarning() << "Unable to open file" << cutFileName; + } + +} + #endif \ No newline at end of file From dde7e3968599a862a1a3cea410dfafce28a24ab6 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Thu, 27 Jun 2024 17:27:28 -0400 Subject: [PATCH 18/72] added control for using influx and elog --- FSUDAQ.cpp | 42 ++++++++++++++++++++++++++++++------------ FSUDAQ.h | 3 +++ 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index ff93e4c..e34df78 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -124,6 +124,10 @@ FSUDAQ::FSUDAQ(QWidget *parent) : QMainWindow(parent){ leDatabaseName = new QLineEdit(this); leDatabaseName->setReadOnly(true); layout->addWidget(leDatabaseName, rowID, 4); + + chkInflux = new QCheckBox("Enable", this); + chkInflux->setChecked(false); + layout->addWidget(chkInflux, rowID, 5); rowID ++; QLabel * lbElogIP = new QLabel("Elog IP : ", this); @@ -142,6 +146,10 @@ FSUDAQ::FSUDAQ(QWidget *parent) : QMainWindow(parent){ leElogName->setReadOnly(true); layout->addWidget(leElogName, rowID, 4); + chkElog = new QCheckBox("Enable", this); + chkElog->setChecked(false); + layout->addWidget(chkElog, rowID, 5); + connect(bnLock, &QPushButton::clicked, this, &FSUDAQ::SetAndLockInfluxElog); } @@ -1089,7 +1097,7 @@ void FSUDAQ::UpdateScalar(){ leTrigger[iDigi][i]->setText(a); leAccept[iDigi][i]->setText(b); - if( influx && a != "inf" ){ + if( influx && chkInflux->isChecked() && a != "inf" ){ influx->AddDataPoint("TrigRate,Bd="+std::to_string(digi[iDigi]->GetSerialNumber()) + ",Ch=" + QString::number(i).rightJustified(2, '0').toStdString() + " value=" + a.toStdString()); } @@ -1105,7 +1113,7 @@ void FSUDAQ::UpdateScalar(){ repaint(); scalar->repaint(); - if( influx && scalarCount >= 3){ + if( influx && chkInflux->isChecked() && scalarCount >= 3){ if( chkSaveData->isChecked() ) { influx->AddDataPoint("RunID value=" + std::to_string(runID)); influx->AddDataPoint("FileSize value=" + std::to_string(totalFileSize)); @@ -1186,14 +1194,14 @@ void FSUDAQ::StartACQ(){ if( onlineAnalyzer ) onlineAnalyzer->StartThread(); {//^=== elog and database - if( influx ){ + if( influx && chkInflux->isChecked() ){ influx->AddDataPoint("RunID value=" + std::to_string(runID)); if( !elogName.isEmpty() ) influx->AddDataPoint("SavingData,ExpName=" + elogName.toStdString() + " value=1"); influx->WriteData(dataBaseName.toStdString()); influx->ClearDataPointsBuffer(); } - if( elogID > 0 && chkSaveData->isChecked() ){ + if( elogID > 0 && !chkElog->isChecked() && chkSaveData->isChecked() ){ QString msg = "================================= Run-" + QString::number(runID).rightJustified(3, '0') + "

" + QDateTime::currentDateTime().toString("MM.dd hh:mm:ss") + "

" + startComment + "

" @@ -1278,13 +1286,13 @@ void FSUDAQ::StopACQ(){ if( digiSettings ) digiSettings->setEnabled(true); {//^=== elog and database - if( influx && elogName != "" ) { + if( influx && chkInflux->isChecked() && elogName != "" ) { if( !elogName.isEmpty() ) influx->AddDataPoint("SavingData,ExpName=" + elogName.toStdString() + " value=0"); influx->WriteData(dataBaseName.toStdString()); influx->ClearDataPointsBuffer(); } - if( elogID > 0 && chkSaveData->isChecked()){ + if( elogID > 0 && !chkElog->isChecked() && chkSaveData->isChecked()){ QString msg = QDateTime::currentDateTime().toString("MM.dd hh:mm:ss") + "

" + stopComment + "

"; uint64_t totalFileSize = 0; for(unsigned int i = 0 ; i < nDigi; i++){ @@ -1730,12 +1738,12 @@ void FSUDAQ::OpenScope(){ if( scope ) { if( onOff ) { lbScalarACQStatus->setText("ACQ On"); - if( influx && !elogName.isEmpty()) influx->AddDataPoint("SavingData,ExpName=" + elogName.toStdString() + " value=1"); + if( influx && chkInflux->isChecked() && !elogName.isEmpty()) influx->AddDataPoint("SavingData,ExpName=" + elogName.toStdString() + " value=1"); }else{ lbScalarACQStatus->setText("ACQ Off"); - if( influx && !elogName.isEmpty()) influx->AddDataPoint("SavingData,ExpName=" + elogName.toStdString() + " value=0"); + if( influx && chkInflux->isChecked() && !elogName.isEmpty()) influx->AddDataPoint("SavingData,ExpName=" + elogName.toStdString() + " value=0"); } - if( influx ){ + if( influx && chkInflux->isChecked()){ influx->WriteData(dataBaseName.toStdString()); influx->ClearDataPointsBuffer(); } @@ -1967,9 +1975,17 @@ void FSUDAQ::SetUpInflux(){ } void FSUDAQ::CheckElog(){ + elogID = -1; DebugPrint("%s", "FSUDAQ"); + if( !chkElog->isChecked() ) { + LogMsg("Elog is disabled. Please chick the checkbox and lock again to check elog connectivity."); + leElogIP->setEnabled(false); + leElogName->setEnabled(false); + return; + } + LogMsg("---- Checking elog... please wait...."); - printf("---- Checking elog... please wait....\n"); + // printf("---- Checking elog... please wait....\n"); if( elogIP != "" && elogName != "" && elogUser != "" && elogPWD != "" ){ WriteElog("Testing communication.", "Testing communication.", "Other", 0); AppendElog("test append elog."); @@ -1982,13 +1998,13 @@ void FSUDAQ::CheckElog(){ if( elogID >= 0 ) { LogMsg("Elog testing OK."); - printf("Elog testing OK.\n"); + // printf("Elog testing OK.\n"); return; } //QMessageBox::information(nullptr, "Information", "Elog write Fail.\nPlease set the elog User and PWD in the programSettings.txt.\nline 6 = user.\nline 7 = pwd."); LogMsg("Elog testing Fail"); - printf("Elog testing Fail\n"); + // printf("Elog testing Fail\n"); if( elogIP == "" ) LogMsg("no elog IP"); if( elogName == "" ) LogMsg("no elog Name"); if( elogUser == "" ) LogMsg("no elog User name. Please set it in the programSettings.txt, line 6."); @@ -2002,6 +2018,7 @@ void FSUDAQ::CheckElog(){ void FSUDAQ::WriteElog(QString htmlText, QString subject, QString category, int runNumber){ DebugPrint("%s", "FSUDAQ"); //if( elogID < 0 ) return; + if( !chkElog->isChecked() ) return; if( elogName == "" ) return; if( elogUser == "" ) return; if( elogPWD == "" ) return; @@ -2030,6 +2047,7 @@ void FSUDAQ::WriteElog(QString htmlText, QString subject, QString category, int void FSUDAQ::AppendElog(QString appendHtmlText){ DebugPrint("%s", "FSUDAQ"); + if( !chkElog->isChecked() )return; if( elogID < 1 ) return; if( elogName == "" ) return; diff --git a/FSUDAQ.h b/FSUDAQ.h index 8ca1dda..e77b49c 100644 --- a/FSUDAQ.h +++ b/FSUDAQ.h @@ -145,6 +145,9 @@ private: QLineEdit * leElogIP; QLineEdit * leElogName; + QCheckBox * chkInflux; + QCheckBox * chkElog; + //@----- log msg QPlainTextEdit * logInfo; void LogMsg(QString msg); From cc296f6e94e63cf8280bb7d9f0bbd8b29ac0df52 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Fri, 28 Jun 2024 15:08:58 -0400 Subject: [PATCH 19/72] tested Coincident Analyzer for 20 kHz/channel, backward event builder. added save/load settings for that too --- FSUDAQ.cpp | 4 +- Histogram2D.h | 22 +++-- analyzers/CoincidentAnalyzer.h | 169 +++++++++++++++++++++++++++++++-- 3 files changed, 179 insertions(+), 16 deletions(-) diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index e34df78..317c392 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -1823,7 +1823,7 @@ void FSUDAQ::OpenAnalyzer(){ if( onlineAnalyzer == nullptr ) { //onlineAnalyzer = new Analyzer(digi, nDigi); - if( id == 0 ) onlineAnalyzer = new CoincidentAnalyzer(digi, nDigi); + if( id == 0 ) onlineAnalyzer = new CoincidentAnalyzer(digi, nDigi, rawDataPath); if( id == 1 ) onlineAnalyzer = new SplitPole(digi, nDigi); if( id == 2 ) onlineAnalyzer = new Encore(digi, nDigi); if( id == 3 ) onlineAnalyzer = new RAISOR(digi, nDigi); @@ -1832,7 +1832,7 @@ void FSUDAQ::OpenAnalyzer(){ delete onlineAnalyzer; - if( id == 0 ) onlineAnalyzer = new CoincidentAnalyzer(digi, nDigi); + if( id == 0 ) onlineAnalyzer = new CoincidentAnalyzer(digi, nDigi, rawDataPath); if( id == 1 ) onlineAnalyzer = new SplitPole(digi, nDigi); if( id == 2 ) onlineAnalyzer = new Encore(digi, nDigi); if( id == 3 ) onlineAnalyzer = new RAISOR(digi, nDigi); diff --git a/Histogram2D.h b/Histogram2D.h index 3d04030..33492b6 100644 --- a/Histogram2D.h +++ b/Histogram2D.h @@ -19,7 +19,11 @@ const QList> colorCycle = { {QColor(Qt::red), "Red"}, class Histogram2D : public QCustomPlot{ public: - Histogram2D(QString title, QString xLabel, QString yLabel, int xbin, double xmin, double xmax, int ybin, double ymin, double ymax, QWidget * parent = nullptr); + Histogram2D(QString title, QString xLabel, QString yLabel, + int xbin, double xmin, double xmax, + int ybin, double ymin, double ymax, + QWidget * parent = nullptr, + QString defaultPath = QDir::homePath()); void SetXTitle(QString xTitle) { xAxis->setLabel(xTitle);} void SetYTitle(QString yTitle) { yAxis->setLabel(yTitle);} @@ -89,13 +93,17 @@ private: void rightMouseClickMenu(QMouseEvent * event); void rightMouseClickRebin(); + QString settingPath; + }; //^############################################### //^############################################### -inline Histogram2D::Histogram2D(QString title, QString xLabel, QString yLabel, int xbin, double xmin, double xmax, int ybin, double ymin, double ymax, QWidget * parent) : QCustomPlot(parent){ +inline Histogram2D::Histogram2D(QString title, QString xLabel, QString yLabel, int xbin, double xmin, double xmax, int ybin, double ymin, double ymax, QWidget * parent, QString defaultPath) : QCustomPlot(parent){ // DebugPrint("%s", "Histogram2D"); + + settingPath = defaultPath; for( int i = 0; i < 3; i ++ ){ for( int j = 0; j < 3; j ++ ){ box[i][j] = nullptr; @@ -568,7 +576,7 @@ inline void Histogram2D::rightMouseClickMenu(QMouseEvent * event){ if( selectedAction == a8 ){ // load Cuts QString filePath = QFileDialog::getOpenFileName(this, "Load Cuts from File", - QDir::homePath(), + settingPath, "Text file (*.txt)"); if (!filePath.isEmpty()) LoadCuts(filePath); @@ -579,7 +587,7 @@ inline void Histogram2D::rightMouseClickMenu(QMouseEvent * event){ QString filePath = QFileDialog::getSaveFileName(this, "Save Cuts to File", - QDir::homePath(), + settingPath, "Text file (*.txt)"); if (!filePath.isEmpty()) SaveCuts(filePath); @@ -773,8 +781,10 @@ inline void Histogram2D::LoadCuts(QString cutFileName){ }else{ QStringList haha = line.split(","); // qDebug() << haha; - tempCut.push_back(QPointF(haha[0].toFloat(), haha[1].toFloat())); - DrawCut(); + if( haha.size() == 2 ){ + tempCut.push_back(QPointF(haha[0].toFloat(), haha[1].toFloat())); + DrawCut(); + } } } diff --git a/analyzers/CoincidentAnalyzer.h b/analyzers/CoincidentAnalyzer.h index f4038c7..777076b 100644 --- a/analyzers/CoincidentAnalyzer.h +++ b/analyzers/CoincidentAnalyzer.h @@ -2,15 +2,17 @@ #define COINCIDENTANLAYZER_H #include "Analyser.h" +#include "FSUDAQ.h" //^=========================================== class CoincidentAnalyzer : public Analyzer{ Q_OBJECT public: - CoincidentAnalyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent = nullptr): Analyzer(digi, nDigi, parent){ + 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); @@ -21,18 +23,15 @@ public: evtbder->SetTimeWindow(500); //========== use the influx from the Analyzer - influx = new InfluxDB("https://fsunuc.physics.fsu.edu/influx/"); + // influx = new InfluxDB("https://fsunuc.physics.fsu.edu/influx/"); dataBaseName = "testing"; allowSignalSlot = false; SetUpCanvas(); - LoadHistRange(); - } ~CoincidentAnalyzer(){ - SaveHistRange(); } void SetUpCanvas(); @@ -73,6 +72,7 @@ private: RComboBox * aDigi; RComboBox * aCh; + QString rawDataPath; void SaveHistRange(); void LoadHistRange(); @@ -84,7 +84,7 @@ inline void CoincidentAnalyzer::SetUpCanvas(){ setWindowTitle("Online Coincident Analyzer"); setGeometry(0, 0, 1600, 1000); - {//^====== magnet and reaction setting + {//^====== channel settings QGroupBox * box = new QGroupBox("Configuration", this); layout->addWidget(box, 0, 0); QGridLayout * boxLayout = new QGridLayout(box); @@ -297,7 +297,7 @@ inline void CoincidentAnalyzer::SetUpCanvas(){ separator1->setFrameShadow(QFrame::Sunken); boxLayout->addWidget(separator1, 8, 0, 1, 4); - QPushButton * bnClearHist = new QPushButton("Clear All Hist."); + QPushButton * bnClearHist = new QPushButton("Clear All Hist.", this); boxLayout->addWidget(bnClearHist, 9, 1); connect(bnClearHist, &QPushButton::clicked, this, [=](){ @@ -307,6 +307,16 @@ inline void CoincidentAnalyzer::SetUpCanvas(){ hMulti->Clear(); }); + QPushButton * bnSaveSettings = new QPushButton("Save Settings", this); + boxLayout->addWidget(bnSaveSettings, 9, 2); + + connect(bnSaveSettings, &QPushButton::clicked, this, &CoincidentAnalyzer::SaveHistRange); + + QPushButton * bnLoadSettings = new QPushButton("Load Settings", this); + boxLayout->addWidget(bnLoadSettings, 9, 3); + + connect(bnLoadSettings, &QPushButton::clicked, this, &CoincidentAnalyzer::LoadHistRange); + } } @@ -316,7 +326,7 @@ inline void CoincidentAnalyzer::SetUpCanvas(){ layout->addWidget(hMulti, 0, 1); // the "this" make the histogram a child of the SplitPole class. When SplitPole destory, all childs destory as well. - h2D = new Histogram2D("Coincident Plot", "XXX", "YYY", 200, 0, 30000, 200, 0, 30000, this); + h2D = new Histogram2D("Coincident Plot", "XXX", "YYY", 200, 0, 30000, 200, 0, 30000, this, rawDataPath); //layout is inheriatge from Analyzer layout->addWidget(h2D, 1, 0, 2, 1); @@ -354,7 +364,10 @@ inline void CoincidentAnalyzer::UpdateHistograms(){ if( this->isVisible() == false ) return; if( chkRunAnalyzer->isChecked() == false ) return; + unsigned long long t0 = getTime_ns(); BuildEvents(); // 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; @@ -421,6 +434,10 @@ inline void CoincidentAnalyzer::UpdateHistograms(){ if( p == 0 && aE >= 0 ) h1g->Fill(aE); // only for the 1st gate } } + + unsigned long long ta = getTime_ns(); + if( ta - t0 > sbUpdateTime->value() * 0.9 * 1e9 ) break; + } h2D->UpdatePlot(); @@ -444,10 +461,146 @@ inline void CoincidentAnalyzer::UpdateHistograms(){ } inline void CoincidentAnalyzer::SaveHistRange(){ + QString filePath = QFileDialog::getSaveFileName(this, + "Save Settings to File", + QDir::toNativeSeparators(rawDataPath + "/CoinAnaSettings.txt" ), + "Text file (*.txt)"); + if (!filePath.isEmpty()){ + + QFile file(filePath); + if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { + QTextStream out(&file); + + // Define the text to write + QStringList lines; + + lines << QString::number(digi[aDigi->currentData().toInt()]->GetSerialNumber()); + lines << QString::number(aCh->currentData().toInt()); + lines << QString::number(h1->GetNBin()); + lines << QString::number(h1->GetXMin()); + lines << QString::number(h1->GetXMax()); + + lines << QString::number(digi[xDigi->currentData().toInt()]->GetSerialNumber()); + lines << QString::number(xCh->currentData().toInt()); + lines << QString::number(h2D->GetXNBin()); + lines << QString::number(h2D->GetXMin()); + lines << QString::number(h2D->GetXMax()); + + lines << QString::number(digi[yDigi->currentData().toInt()]->GetSerialNumber()); + lines << QString::number(yCh->currentData().toInt()); + lines << QString::number(h2D->GetYNBin()); + lines << QString::number(h2D->GetYMin()); + lines << QString::number(h2D->GetYMax()); + + + lines << QString::number(sbUpdateTime->value()); + lines << QString::number(chkBackWardBuilding->isChecked()); + lines << QString::number(sbBackwardCount->value()); + + lines << "#===== End of File"; + + // Write each line to the file + for (const QString &line : lines) out << line << "\n"; + + // Close the file + file.close(); + qDebug() << "File written successfully to" << filePath; + }else{ + qWarning() << "Unable to open file" << filePath; + } + + } } inline void CoincidentAnalyzer::LoadHistRange(){ + QString filePath = QFileDialog::getOpenFileName(this, + "Load Settings to File", + rawDataPath, + "Text file (*.txt)"); + + int a_sn, a_ch, a_bin; + float a_min, a_max; + int x_sn, x_ch, x_bin; + float x_min, x_max; + int y_sn, y_ch, y_bin; + float y_min, y_max; + + float updateTime; + int bkCount; + bool isBkEvtBuild; + + if (!filePath.isEmpty()) { + + QFile file(filePath); + + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&file); + + short count = 0; + while (!in.atEnd()) { + QString line = in.readLine(); + + if( count == 0 ) a_sn = line.toInt(); + if( count == 1 ) a_ch = line.toInt(); + if( count == 2 ) a_bin = line.toInt(); + if( count == 3 ) a_min = line.toFloat(); + if( count == 4 ) a_max = line.toFloat(); + + if( count == 5 ) x_sn = line.toFloat(); + if( count == 6 ) x_ch = line.toFloat(); + if( count == 7 ) x_bin = line.toFloat(); + if( count == 8 ) x_min = line.toFloat(); + if( count == 9 ) x_max = line.toFloat(); + + if( count == 10 ) y_sn = line.toFloat(); + if( count == 11 ) y_ch = line.toFloat(); + if( count == 12 ) y_bin = line.toFloat(); + if( count == 13 ) y_min = line.toFloat(); + if( count == 14 ) y_max = line.toFloat(); + + if( count == 15 ) updateTime = line.toFloat(); + if( count == 16 ) isBkEvtBuild = line.toInt(); + if( count == 17 ) bkCount = line.toInt(); + + count ++; + } + + file.close(); + qDebug() << "File read successfully from" << filePath; + + if( count >= 18 ){ + + sbUpdateTime->setValue(updateTime); + chkBackWardBuilding->setChecked(isBkEvtBuild); + sbBackwardCount->setValue(bkCount); + + int x_index = xDigi->findText("Digi-" + QString::number(x_sn)); + int y_index = yDigi->findText("Digi-" + QString::number(y_sn)); + int a_index = aDigi->findText("Digi-" + QString::number(a_sn)); + if( x_index == -1 ) qWarning() << " Cannot find digitizer " << x_sn; + if( y_index == -1 ) qWarning() << " Cannot find digitizer " << y_sn; + if( a_index == -1 ) qWarning() << " Cannot find digitizer " << a_sn; + + xDigi->setCurrentIndex(x_index); + yDigi->setCurrentIndex(y_index); + aDigi->setCurrentIndex(a_index); + + xCh->setCurrentIndex(x_ch); + yCh->setCurrentIndex(y_ch); + aCh->setCurrentIndex(a_ch); + + h1->Rebin(a_bin, a_min, a_max); + h1g->Rebin(a_bin, a_min, a_max); + h2D->Rebin(x_bin, x_min, x_max, y_bin, y_min, y_max); + + } + + }else { + qWarning() << "Unable to open file" << filePath; + } + } + } From 84bb439ff38ec8fa24321a8072f7ccd33ea5f556 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Wed, 17 Jul 2024 14:53:49 -0400 Subject: [PATCH 20/72] Event Builder can output CAEN binary --- Aux/EventBuilder.cpp | 119 ++++++++++++++++++++++++------------------- Hit.h | 40 ++++++++++++++- 2 files changed, 107 insertions(+), 52 deletions(-) diff --git a/Aux/EventBuilder.cpp b/Aux/EventBuilder.cpp index 7bb2311..803f92c 100644 --- a/Aux/EventBuilder.cpp +++ b/Aux/EventBuilder.cpp @@ -21,6 +21,7 @@ struct FileInfo{ }; #define NMINARG 5 +#define debug 0 //^############################################################# //^############################################################# @@ -31,10 +32,10 @@ int main(int argc, char **argv) { printf("=========================================\n"); if (argc < NMINARG) { printf("Incorrect number of arguments:\n"); - printf("%s [timeWindow] [withTrace] [verbose] [inFile1] [inFile2] .... \n", argv[0]); + printf("%s [timeWindow] [withTrace] [format] [inFile1] [inFile2] .... \n", argv[0]); printf(" timeWindow : in ns, -1 = no event building \n"); printf(" withTrace : 0 for no trace, 1 for trace \n"); - printf(" verbose : > 0 for debug \n"); + printf(" format : 0 for root, 1 for CoMPASS binary \n"); printf(" Output file name is contructed from inFile1 \n"); printf("\n"); printf(" Example: %s -1 0 0 '\\ls -1 *001*.fsu' (no event build, no trace, no verbose)\n", argv[0]); @@ -49,7 +50,8 @@ int main(int argc, char **argv) { ///============= read input long timeWindow = atoi(argv[1]); bool traceOn = atoi(argv[2]); - unsigned int debug = atoi(argv[3]); + // unsigned int debug = atoi(argv[3]); + unsigned short format = atoi(argv[3]); unsigned int batchSize = 2* DEFAULT_HALFBUFFERSIZE; int nFile = argc - NMINARG + 1; TString inFileName[nFile]; @@ -63,8 +65,15 @@ int main(int argc, char **argv) { if( nFile == 1 ) pos = outFileName.Index("_", pos+1); // find next "_", S/N outFileName.Remove(pos); // remove the rest outFileName += "_" + ( timeWindow >= 0 ? std::to_string(timeWindow) : "single"); - outFileName += ".root"; - printf("-------> Out file name : %s \n", outFileName.Data()); + + TString outFileFullName; + if( format == 0 ){ + outFileFullName = outFileName + ".root"; + }else{ + outFileFullName = outFileName + ".bin"; + } + + printf("-------> Out file name : %s \n", outFileFullName.Data()); printf("========================================= Number of Files : %d \n", nFile); for( int i = 0; i < nFile; i++) printf("%2d | %s \n", i, inFileName[i].Data()); printf("=========================================\n"); @@ -113,22 +122,17 @@ int main(int argc, char **argv) { for( size_t i = 0; i < fileGroupList.size(); i++){ printf("group ----- %ld \n", i); - //sort by ID std::sort(fileGroupList[i].begin(), fileGroupList[i].end(), [](const FileInfo & a, const FileInfo & b) { return a.fileID < b.fileID; }); - for( size_t j = 0; j < fileGroupList[i].size(); j++){ printf("%3ld | %8d | %9lu| %s \n", j, fileGroupList[i][j].fileID, fileGroupList[i][j].hitCount, fileGroupList[i][j].fileName.c_str() ); } - } - // //*====================================== create tree - TFile * outRootFile = new TFile(outFileName, "recreate"); - TTree * tree = new TTree("tree", outFileName); - + TFile * outRootFile = nullptr; + TTree * tree = nullptr; unsigned long long evID = 0; unsigned int multi = 0; unsigned short sn[MAX_MULTI] = {0}; /// board SN @@ -138,31 +142,39 @@ int main(int argc, char **argv) { unsigned long long e_t[MAX_MULTI] = {0}; /// timestamp 47 bit unsigned short e_f[MAX_MULTI] = {0}; /// fine time 10 bit unsigned short traceLength[MAX_MULTI]; + short trace[MAX_MULTI][MAX_TRACE_LENGTH]; - tree->Branch("evID", &evID, "event_ID/l"); - tree->Branch("multi", &multi, "multi/i"); - tree->Branch("sn", sn, "sn[multi]/s"); - tree->Branch("ch", ch, "ch[multi]/s"); - tree->Branch("e", e, "e[multi]/s"); - tree->Branch("e2", e2, "e2[multi]/s"); - tree->Branch("e_t", e_t, "e_timestamp[multi]/l"); - tree->Branch("e_f", e_f, "e_fineTime[multi]/s"); - tree->Branch("traceLength", traceLength, "traceLength[multi]/s"); + FILE * caen = nullptr; + + if( format == 0 ){ + // //*====================================== create tree + outRootFile = new TFile(outFileFullName, "recreate"); + tree = new TTree("tree", outFileFullName); - // TClonesArray * arrayTrace = nullptr; - // TGraph * trace = nullptr; + tree->Branch("evID", &evID, "event_ID/l"); + tree->Branch("multi", &multi, "multi/i"); + tree->Branch("sn", sn, "sn[multi]/s"); + tree->Branch("ch", ch, "ch[multi]/s"); + tree->Branch("e", e, "e[multi]/s"); + tree->Branch("e2", e2, "e2[multi]/s"); + tree->Branch("e_t", e_t, "e_timestamp[multi]/l"); + tree->Branch("e_f", e_f, "e_fineTime[multi]/s"); + tree->Branch("traceLength", traceLength, "traceLength[multi]/s"); + + if( traceOn ) { + tree->Branch("trace", trace,"trace[multi][MAX_TRACE_LENGTH]/S"); + tree->GetBranch("trace")->SetCompressionSettings(205); + } + }else{ - short trace[MAX_MULTI][1024]; - if( traceOn ) { - // arrayTrace = new TClonesArray("TGraph"); - // tree->Branch("trace", arrayTrace, 2560000); - // arrayTrace->BypassStreamer(); + caen = fopen(outFileFullName.Data(), "wb"); + if( caen == nullptr ){ + perror("Failed to open file"); + return -1; + } - tree->Branch("trace", trace,"trace[multi][1024]/S"); - tree->GetBranch("trace")->SetCompressionSettings(205); } - //*======================================= Open files printf("========================================= Open files & Build Events.\n"); @@ -292,12 +304,6 @@ int main(int argc, char **argv) { traceLength[p] = events[p].traceLength; if( traceOn ){ - // trace = (TGraph *) arrayTrace->ConstructedAt(p, "C"); - // trace->Clear(); - // for( int hh = 0; hh < traceLength[multi]; hh++){ - // trace->SetPoint(hh, hh, events[p].trace[hh]); - // } - if( traceLength[p] > MAX_TRACE_LENGTH ) { printf("\033[31m event %lld has trace length = %d > MAX_TRACE_LENGTH = %d \033[0m\n", evID, traceLength[p], MAX_TRACE_LENGTH); traceLength[p] = MAX_TRACE_LENGTH; @@ -306,14 +312,21 @@ int main(int argc, char **argv) { for( int hh = 0; hh < traceLength[p]; hh++){ trace[p][hh] = events[p].trace[hh]; } - - } } - outRootFile->cd(); - tree->Fill(); - // tree->Write(); + if( format == 0 ){ + outRootFile->cd(); + tree->Fill(); + // tree->Write(); + }else{ + if( caen ) { + for( size_t gg = 0; gg < events.size(); gg++ ){ + events[gg].WriteHitsToCAENBinary(caen, traceOn); + } + } + } + multi = 0; evID ++; @@ -348,25 +361,29 @@ int main(int argc, char **argv) { }while( nFileFinished < nGroup); - tree->Write(); + if( format == 0 ) tree->Write(); uInt runEndTime = getTime_us(); double runTime = (runEndTime - runStartTime) * 1e-6; printf("========================================= finished.\n"); printf(" event building time = %.2f sec = %.2f min\n", runTime, runTime/60.); - printf(" total events built = %llu by event builder (%llu in tree)\n", evID, tree->GetEntriesFast()); + // printf(" total events built = %llu by event builder (%llu in tree)\n", evID, tree->GetEntriesFast()); + printf(" total events built = %llu by event builder\n", evID); double tDuration_sec = (tEnd - tStart) * 1e-9; printf(" first timestamp = %20llu ns\n", tStart); printf(" last timestamp = %20llu ns\n", tEnd); printf(" total data duration = %.2f sec = %.2f min\n", tDuration_sec, tDuration_sec/60.); - printf("========================================> saved to %s \n", outFileName.Data()); + printf("========================================> saved to %s \n", outFileFullName.Data()); - TMacro info; - info.AddLine(Form("tStart= %20llu ns",tStart)); - info.AddLine(Form(" tEnd= %20llu ns",tEnd)); - info.Write("info"); - - outRootFile->Close(); + if( format == 0 ){ + TMacro info; + info.AddLine(Form("tStart= %20llu ns",tStart)); + info.AddLine(Form(" tEnd= %20llu ns",tEnd)); + info.Write("info"); + outRootFile->Close(); + }else{ + fclose(caen); + } for( int i = 0; i < nGroup; i++) delete reader[i]; delete [] reader; diff --git a/Hit.h b/Hit.h index 1683ef4..6d8950a 100644 --- a/Hit.h +++ b/Hit.h @@ -6,7 +6,7 @@ class Hit{ public: unsigned short sn; - uint8_t ch; + unsigned short ch; unsigned short energy; unsigned short energy2; unsigned long long timestamp; @@ -45,6 +45,44 @@ public: // Define operator< for sorting bool operator<(const Hit& other) const { return timestamp < other.timestamp; + } + + + void WriteHitsToCAENBinary(FILE * file, bool withTrace){ + if( file == nullptr ) return; + + uint16_t header = 0xCAE1; // default to have the energy only + uint32_t flag = 0; + uint8_t waveFormCode = 1; // input + + size_t dummy; + + if( energy2 > 0 ) header += 0x4; + if( traceLength > 0 && withTrace ) header += 0x8; + + dummy = fwrite(&header, 2, 1, file); + dummy = fwrite(&sn, 2, 1, file); + dummy = fwrite(&ch, 2, 1, file); + + uint64_t timestampPS = timestamp * 1000 + fineTime; + dummy = fwrite(×tampPS, 8, 1, file); + + dummy = fwrite(&energy, 2, 1, file); + + if( energy2 > 0 ) dummy = fwrite(&energy2, 2, 1, file); + + dummy = fwrite(&flag, 4, 1, file); + + if( traceLength > 0 && withTrace ){ + dummy = fwrite(&waveFormCode, 1, 1, file); + dummy = fwrite(&traceLength, 4, 1, file); + for( int j = 0; j < traceLength; j++ ){ + dummy = fwrite(&(trace[j]), 2, 1, file); + } + } + + if( dummy != 1 ) printf("write file error.\n"); + } }; From c4263ab06ce13acb255a435946b75b798570c709 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Wed, 17 Jul 2024 15:30:27 -0400 Subject: [PATCH 21/72] fix CAEN format. the header only at the beginning of the binary file --- Aux/EventBuilder.cpp | 13 ++++++++++++- Aux/Makefile | 4 ++-- Hit.h | 16 +++++++--------- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/Aux/EventBuilder.cpp b/Aux/EventBuilder.cpp index 803f92c..41ff87c 100644 --- a/Aux/EventBuilder.cpp +++ b/Aux/EventBuilder.cpp @@ -73,6 +73,8 @@ int main(int argc, char **argv) { outFileFullName = outFileName + ".bin"; } + uint16_t header = 0; // for caen bin + printf("-------> Out file name : %s \n", outFileFullName.Data()); printf("========================================= Number of Files : %d \n", nFile); for( int i = 0; i < nFile; i++) printf("%2d | %s \n", i, inFileName[i].Data()); @@ -321,8 +323,17 @@ int main(int argc, char **argv) { // tree->Write(); }else{ if( caen ) { + + if( header == 0 ){ + header = 0xCAE1; // default to have the energy only + if( events[0].energy2 > 0 ) header += 0x4; + if( events[0].traceLength > 0 && traceOn ) header += 0x8; + size_t dummy = fwrite(&header, 2, 1, caen); + if( dummy != 1 ) printf("file write error.\n"); + } + for( size_t gg = 0; gg < events.size(); gg++ ){ - events[gg].WriteHitsToCAENBinary(caen, traceOn); + events[gg].WriteHitsToCAENBinary(caen, header); } } } diff --git a/Aux/Makefile b/Aux/Makefile index 9b731a9..8d51ec9 100644 --- a/Aux/Makefile +++ b/Aux/Makefile @@ -5,8 +5,8 @@ CC = g++ -#COPTS = -fPIC -DLINUX -O2 -std=c++17 -lpthread -COPTS = -fPIC -DLINUX -g -O0 -Wall -std=c++17 -lpthread +COPTS = -fPIC -DLINUX -O2 -std=c++17 -lpthread +# COPTS = -fPIC -DLINUX -g -O0 -Wall -std=c++17 -lpthread CAENLIBS = -lCAENDigitizer -lCAENVME diff --git a/Hit.h b/Hit.h index 6d8950a..2154f9e 100644 --- a/Hit.h +++ b/Hit.h @@ -48,19 +48,17 @@ public: } - void WriteHitsToCAENBinary(FILE * file, bool withTrace){ + void WriteHitsToCAENBinary(FILE * file, uint32_t header){ if( file == nullptr ) return; - uint16_t header = 0xCAE1; // default to have the energy only uint32_t flag = 0; uint8_t waveFormCode = 1; // input + // uint16_t header = 0xCAE1; // default to have the energy only + // if( energy2 > 0 ) header += 0x4; + // if( traceLength > 0 && withTrace ) header += 0x8; + size_t dummy; - - if( energy2 > 0 ) header += 0x4; - if( traceLength > 0 && withTrace ) header += 0x8; - - dummy = fwrite(&header, 2, 1, file); dummy = fwrite(&sn, 2, 1, file); dummy = fwrite(&ch, 2, 1, file); @@ -69,11 +67,11 @@ public: dummy = fwrite(&energy, 2, 1, file); - if( energy2 > 0 ) dummy = fwrite(&energy2, 2, 1, file); + if( (header & 0x4) ) dummy = fwrite(&energy2, 2, 1, file); dummy = fwrite(&flag, 4, 1, file); - if( traceLength > 0 && withTrace ){ + if( traceLength > 0 && (header & 0x8) ){ dummy = fwrite(&waveFormCode, 1, 1, file); dummy = fwrite(&traceLength, 4, 1, file); for( int j = 0; j < traceLength; j++ ){ From 064c99256b0103fe579af045e8b14ddc2cfd397f Mon Sep 17 00:00:00 2001 From: splitPoleDAQ Date: Wed, 17 Jul 2024 16:02:36 -0400 Subject: [PATCH 22/72] add spltpole.C/h in Aux --- .gitignore | 3 - Aux/splitpole.C | 185 ++++++++++++++++++++++++++++++++++++++++++++++++ Aux/splitpole.h | 101 ++++++++++++++++++++++++++ 3 files changed, 286 insertions(+), 3 deletions(-) create mode 100644 Aux/splitpole.C create mode 100644 Aux/splitpole.h diff --git a/.gitignore b/.gitignore index bd788c2..9facd53 100644 --- a/.gitignore +++ b/.gitignore @@ -24,9 +24,6 @@ FSU2CAEN data -splitpole.C -splitpole.h - *.d *.pcm diff --git a/Aux/splitpole.C b/Aux/splitpole.C new file mode 100644 index 0000000..87f2c5f --- /dev/null +++ b/Aux/splitpole.C @@ -0,0 +1,185 @@ +#define splitpole_cxx + +#include "splitpole.h" +#include +#include +#include +#include +#include + + +#include "../analyzers/SplitPoleHit.h" + +namespace ChMap{ + + const short ScinR = 0; + const short ScinL = 1; + const short dFR = 8; + const short dFL = 9; + const short dBR = 10; + const short dBL = 11; + const short Cathode = 7; + const short AnodeF = 13; + const short AnodeB = 15; + +}; + +const double c = 299.792458; // mm/ns +const double pi = M_PI; +const double deg2rad = pi/180.; + +SplitPoleHit hit; + +TH2F * PID; +TH2F * coin; + +TH1F * hMulti; + +TH1F * hF; +TH1F * hB; +TH1F * hXavg; + +TH2F * hFocal; + +TH2F * hXavgVQ; + +TH2F * haha; + +TH1F * hEx; + +ULong64_t t1, t2; + +#define XMIN -20 +#define XMAX 100 + +void splitpole::Begin(TTree * /*tree*/){ + + TString option = GetOption(); + + PID = new TH2F("hPID", "PID; Scin_X ; AnodeB", 200, 0, 30000, 100, 0, 70000); + coin = new TH2F("hCoin", "Coincident ", 16, 0, 16, 16, 0, 16); + + hMulti = new TH1F("hMulti", "Multiplicity", 16, 0, 16); + + hF = new TH1F("hF", "Front delay line position", 600, XMIN, XMAX); + hB = new TH1F("hB", "Back delay line position", 600, XMIN, XMAX); + hXavg = new TH1F("hAvg", "Xavg", 600, XMIN, XMAX); + + hFocal = new TH2F("hFocal", "Front vs Back ", 200, XMIN, XMAX, 200, XMIN, XMAX); + hXavgVQ = new TH2F("hXavgVQ", "Xavg vs Q ", 200, XMIN, XMAX, 200, 0, 40000); + + haha = new TH2F("haha", "", 400, XMIN, XMAX, 400, -50, 50); + + hEx = new TH1F("hEx", "Ex; Ex [MeV]; count/100 keV", 250, -5, 20); + + hit.SetMassTablePath("../analyzers/mass20.txt"); + hit.CalConstants("12C", "12C", "4He", 80, 5); // 80MeV, 5 deg + hit.CalZoffset(1.41); // 1.41 T + + t1 = 0; + t2 = 0; + +} + + +Bool_t splitpole::Process(Long64_t entry){ + + b_multi->GetEntry(entry); + b_ch->GetEntry(entry); + b_e->GetEntry(entry); + b_e2->GetEntry(entry); + b_e_t->GetEntry(entry); + b_e_f->GetEntry(entry); + + //if( multi < 9) return kTRUE; + hit.ClearData(); + + hMulti->Fill(multi); + + for( int i = 0; i < multi; i++){ + + t2 = e_t[i]; + + if( t2 < t1 ) printf("entry %lld-%d, timestamp is not in order. %llu, %llu\n", entry, i, t2, t1); + + if( i == 0 ) t1 = e_t[i]; + + if( ch[i] == ChMap::ScinR ) {hit.eSR = e[i]; hit.tSR = e_t[i] + e_f[i]/1000.;} + if( ch[i] == ChMap::ScinL ) {hit.eSL = e[i]; hit.tSL = e_t[i] + e_f[i]/1000.;} + if( ch[i] == ChMap::dFR ) {hit.eFR = e[i]; hit.tFR = e_t[i] + e_f[i]/1000.;} + if( ch[i] == ChMap::dFL ) {hit.eFL = e[i]; hit.tFL = e_t[i] + e_f[i]/1000.;} + if( ch[i] == ChMap::dBR ) {hit.eBR = e[i]; hit.tBR = e_t[i] + e_f[i]/1000.;} + if( ch[i] == ChMap::dBL ) {hit.eBL = e[i]; hit.tBL = e_t[i] + e_f[i]/1000.;} + if( ch[i] == ChMap::Cathode ) {hit.eCath = e[i]; hit.tCath = e_t[i] + e_f[i]/1000.;} + if( ch[i] == ChMap::AnodeF ) {hit.eAF = e[i]; hit.tAF = e_t[i] + e_f[i]/1000.;} + if( ch[i] == ChMap::AnodeB ) {hit.eAB = e[i]; hit.tAB = e_t[i] + e_f[i]/1000.;} + + for( int j = i+1; j < multi; j++){ + coin->Fill(ch[i], ch[j]); + } + } + + unsigned int dQ = hit.eAB; // delta Q + unsigned int Qt = hit.eSR; // total Q + + if( Qt > 0 && dQ > 0 ) { + PID->Fill(Qt, dQ); + } + + // if( hit.eAF < 50000 ) return kTRUE; + // if( hit.eCath == 0 ) return kTRUE; + // if( hit.eCath > 13000 ) return kTRUE; + + hit.CalData(); + + if( !TMath::IsNaN(hit.x1) || !TMath::IsNaN(hit.x2) ) { + hFocal->Fill(hit.x1, hit.x2); + hF->Fill(hit.x1); + hB->Fill(hit.x2); + hXavg->Fill(hit.xAvg); + + hXavgVQ->Fill(hit.xAvg, dQ); + + for( int i = 0; i < 400; i++){ + double y = -50 + 100/400.*i; + + double x = (y/42.8625 + 0.5)* ( hit.x2-hit.x1) + hit.x1; + + haha->Fill(x,y); + } + + double ex = hit.Rho2Ex( (hit.xAvg/100 + 0.363) ); + //if( XMIN < hit.xAvg && hit.xAvg < XMAX) printf("x1 : %6.2f, x2 : %6.2f, xAvg %6.2f cm , ex : %f \n", hit.x1, hit.x2, hit.xAvg, ex); + hEx->Fill(ex); + } + + return kTRUE; +} + + +void splitpole::Terminate(){ + + TCanvas * canvas = new TCanvas("cc", "Split-Pole", 1800, 1200); + + gStyle->SetOptStat("neiou"); + + canvas->Divide(3, 3); + + canvas->cd(1); PID->Draw("colz"); + //canvas->cd(2); coin->Draw("colz"); + canvas->cd(2); haha->Draw("colz"); + + canvas->cd(3); hF->Draw(); + canvas->cd(4); hB->Draw(); + + canvas->cd(5); hXavgVQ->Draw("colz"); + + canvas->cd(6); hXavg->Draw("colz"); + + canvas->cd(7); hEx->Draw(); + + canvas->cd(8); coin->Draw("colz"); + + canvas->cd(9); canvas->cd(9)->SetLogy(); hMulti->Draw(); + +} diff --git a/Aux/splitpole.h b/Aux/splitpole.h new file mode 100644 index 0000000..5928ca3 --- /dev/null +++ b/Aux/splitpole.h @@ -0,0 +1,101 @@ +////////////////////////////////////////////////////////// +// This class has been automatically generated on +// Wed Jun 14 15:51:03 2023 by ROOT version 6.26/04 +// from TTree tree/temp_036.root +// found on file: temp_036.root +////////////////////////////////////////////////////////// + +#ifndef splitpole_h +#define splitpole_h + +#include +#include +#include +#include + +// Header file for the classes stored in the TTree if any. + +#define MaxMulti 100 + +class splitpole : public TSelector { +public : + TTree *fChain; //!pointer to the analyzed TTree or TChain + +// Fixed size dimensions of array or collections stored in the TTree if any. + + // Declaration of leaf types + ULong64_t evID; + UShort_t multi; + UShort_t bd[MaxMulti]; //[multi] + UShort_t ch[MaxMulti]; //[multi] + UShort_t e[MaxMulti]; //[multi] + UShort_t e2[MaxMulti]; //[multi] + ULong64_t e_t[MaxMulti]; //[multi] + UShort_t e_f[MaxMulti]; //[multi] + + // List of branches + TBranch *b_event_ID; //! + TBranch *b_multi; //! + TBranch *b_bd; //! + TBranch *b_ch; //! + TBranch *b_e; //! + TBranch *b_e2; //! + TBranch *b_e_t; //! + TBranch *b_e_f; //! + + splitpole(TTree * /*tree*/ =0) : fChain(0) { } + virtual ~splitpole() { } + virtual Int_t Version() const { return 2; } + virtual void Begin(TTree *tree); + virtual void SlaveBegin(TTree *tree); + virtual void Init(TTree *tree); + virtual Bool_t Notify(); + virtual Bool_t Process(Long64_t entry); + virtual Int_t GetEntry(Long64_t entry, Int_t getall = 0) { return fChain ? fChain->GetTree()->GetEntry(entry, getall) : 0; } + virtual void SetOption(const char *option) { fOption = option; } + virtual void SetObject(TObject *obj) { fObject = obj; } + virtual void SetInputList(TList *input) { fInput = input; } + virtual TList *GetOutputList() const { return fOutput; } + virtual void SlaveTerminate(); + virtual void Terminate(); + + ClassDef(splitpole,0); +}; + +#endif + +#ifdef splitpole_cxx +void splitpole::Init(TTree *tree){ + // Set branch addresses and branch pointers + if (!tree) return; + fChain = tree; + fChain->SetMakeClass(1); + + fChain->SetBranchAddress("evID", &evID, &b_event_ID); + fChain->SetBranchAddress("multi", &multi, &b_multi); + fChain->SetBranchAddress("bd", bd, &b_bd); + fChain->SetBranchAddress("ch", ch, &b_ch); + fChain->SetBranchAddress("e", e, &b_e); + fChain->SetBranchAddress("e2", e2, &b_e2); + fChain->SetBranchAddress("e_t", e_t, &b_e_t); + fChain->SetBranchAddress("e_f", e_f, &b_e_f); +} + +Bool_t splitpole::Notify(){ + + return kTRUE; +} + + +void splitpole::SlaveBegin(TTree * /*tree*/){ + + TString option = GetOption(); + +} + +void splitpole::SlaveTerminate(){ + +} + + +#endif // #ifdef splitpole_cxx From 00ddf3dcf5ce0db5b0d6f97270dc4fdda5b6e9f9 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Wed, 17 Jul 2024 18:41:47 -0400 Subject: [PATCH 23/72] Small change of EventBuilder to support TTreeReader. add SpliitPolePlotter.C --- .vscode/settings.json | 82 +------------- Aux/EventBuilder.cpp | 4 +- Aux/SplitPolePlotter.C | 241 +++++++++++++++++++++++++++++++++++++++++ Aux/script.C | 157 ++++++++++++++------------- Aux/splitpole.C | 1 - 5 files changed, 328 insertions(+), 157 deletions(-) create mode 100644 Aux/SplitPolePlotter.C diff --git a/.vscode/settings.json b/.vscode/settings.json index d0e72c6..02d2d86 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -82,86 +82,6 @@ } ], "files.associations": { - "mainWindow.C": "cpp", - "Scope.C": "cpp", - "new": "cpp", - "allocator": "cpp", - "array": "cpp", - "istream": "cpp", - "ostream": "cpp", - "sstream": "cpp", - "limits": "cpp", - "atomic": "cpp", - "bit": "cpp", - "*.tcc": "cpp", - "bitset": "cpp", - "cctype": "cpp", - "chrono": "cpp", - "clocale": "cpp", - "cmath": "cpp", - "codecvt": "cpp", - "compare": "cpp", - "concepts": "cpp", - "condition_variable": "cpp", - "cstdarg": "cpp", - "cstddef": "cpp", - "cstdint": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "cstring": "cpp", - "ctime": "cpp", - "cwchar": "cpp", - "cwctype": "cpp", - "deque": "cpp", - "list": "cpp", - "map": "cpp", - "string": "cpp", - "unordered_map": "cpp", - "unordered_set": "cpp", - "vector": "cpp", - "exception": "cpp", - "algorithm": "cpp", - "functional": "cpp", - "iterator": "cpp", - "memory": "cpp", - "memory_resource": "cpp", - "numeric": "cpp", - "optional": "cpp", - "random": "cpp", - "ratio": "cpp", - "string_view": "cpp", - "system_error": "cpp", - "tuple": "cpp", - "type_traits": "cpp", - "utility": "cpp", - "future": "cpp", - "initializer_list": "cpp", - "iomanip": "cpp", - "iosfwd": "cpp", - "iostream": "cpp", - "mutex": "cpp", - "numbers": "cpp", - "semaphore": "cpp", - "span": "cpp", - "stdexcept": "cpp", - "stop_token": "cpp", - "streambuf": "cpp", - "thread": "cpp", - "cinttypes": "cpp", - "typeinfo": "cpp", - "variant": "cpp", - "qmainwindow": "cpp", - "qchartview": "cpp", - "qthread": "cpp", - "qrandomgenerator": "cpp", - "source_location": "cpp", - "splitpole.C": "cpp", - "forward_list": "cpp", - "fstream": "cpp", - "Analyzer.C": "cpp", - "process_Run.C": "cpp", - "EncoreAnalyzer.C": "cpp", - "qfiledialog": "cpp", - "script.C": "cpp" + "*.C": "cpp" } } \ No newline at end of file diff --git a/Aux/EventBuilder.cpp b/Aux/EventBuilder.cpp index 41ff87c..223ef6f 100644 --- a/Aux/EventBuilder.cpp +++ b/Aux/EventBuilder.cpp @@ -159,8 +159,8 @@ int main(int argc, char **argv) { tree->Branch("ch", ch, "ch[multi]/s"); tree->Branch("e", e, "e[multi]/s"); tree->Branch("e2", e2, "e2[multi]/s"); - tree->Branch("e_t", e_t, "e_timestamp[multi]/l"); - tree->Branch("e_f", e_f, "e_fineTime[multi]/s"); + tree->Branch("e_t", e_t, "e_t[multi]/l"); + tree->Branch("e_f", e_f, "e_f[multi]/s"); tree->Branch("traceLength", traceLength, "traceLength[multi]/s"); if( traceOn ) { diff --git a/Aux/SplitPolePlotter.C b/Aux/SplitPolePlotter.C new file mode 100644 index 0000000..91613d3 --- /dev/null +++ b/Aux/SplitPolePlotter.C @@ -0,0 +1,241 @@ +#include "TFile.h" +#include "TChain.h" +#include "TH1F.h" +#include "TTreeReader.h" +#include "TTreeReaderValue.h" +#include "TTreeReaderArray.h" +#include "TClonesArray.h" +#include "TGraph.h" +#include "TH2.h" +#include "TCanvas.h" +#include "TStyle.h" +#include "TStopwatch.h" +#include "TMath.h" + +#include "vector" +#include "../analyzers/SplitPoleHit.h" + + +namespace ChMap{ + + const short ScinR = 0; + const short ScinL = 1; + const short dFR = 8; + const short dFL = 9; + const short dBR = 10; + const short dBL = 11; + const short Cathode = 7; + const short AnodeF = 13; + const short AnodeB = 15; + +}; + +const double c = 299.792458; // mm/ns +const double pi = M_PI; +const double deg2rad = pi/180.; + +SplitPoleHit hit; + +TH2F * PID; +TH2F * coin; + +TH1F * hMulti; + +TH1F * hF; +TH1F * hB; +TH1F * hXavg; + +TH2F * hFocal; + +TH2F * hXavgVQ; + +TH2F * haha; + +TH1F * hEx; + +ULong64_t t1, t2; + +#define XMIN -20 +#define XMAX 100 + +//^########################################### + +void SplitPolePlotter(TChain *tree){ + + printf("#####################################################################\n"); + printf("################# SplitPolePlotter.C ####################\n"); + printf("#####################################################################\n"); + + TObjArray * fileList = tree->GetListOfFiles(); + printf("\033[0;31m========================================== Number of Files : %2d\n",fileList->GetEntries()); + fileList->Print(); + printf("========================================== Number of Files : %2d\033[0m\n",fileList->GetEntries()); + + printf("///////////////////////////////////////////////////////////////////\n"); + printf(" Total Number of entries : %llu \n", tree->GetEntries()); + printf("///////////////////////////////////////////////////////////////////\n"); + + if( tree->GetEntries() == 0 ) { + printf("========= no events. Abort.\n"); + return; + } + + //*====================================================== histograms + + PID = new TH2F("hPID", "PID; Scin_X ; AnodeB", 200, 0, 30000, 100, 0, 70000); + coin = new TH2F("hCoin", "Coincident ", 16, 0, 16, 16, 0, 16); + + hMulti = new TH1F("hMulti", "Multiplicity", 16, 0, 16); + + hF = new TH1F("hF", "Front delay line position", 600, XMIN, XMAX); + hB = new TH1F("hB", "Back delay line position", 600, XMIN, XMAX); + hXavg = new TH1F("hAvg", "Xavg", 600, XMIN, XMAX); + + hFocal = new TH2F("hFocal", "Front vs Back ", 200, XMIN, XMAX, 200, XMIN, XMAX); + hXavgVQ = new TH2F("hXavgVQ", "Xavg vs Q ", 200, XMIN, XMAX, 200, 0, 40000); + + haha = new TH2F("haha", "", 400, XMIN, XMAX, 400, -50, 50); + + hEx = new TH1F("hEx", "Ex; Ex [MeV]; count/100 keV", 250, -5, 20); + + hit.SetMassTablePath("../analyzers/mass20.txt"); + hit.CalConstants("12C", "12C", "4He", 80, 5); // 80MeV, 5 deg + hit.CalZoffset(1.41); // 1.41 T + + t1 = 0; + t2 = 0; + + + //*====================================================== Tree Reader + TTreeReader reader(tree); + + TTreeReaderValue evID = {reader, "evID"}; + TTreeReaderValue multi = {reader, "multi"}; + TTreeReaderArray sn = {reader, "sn"}; + TTreeReaderArray ch = {reader, "ch"}; + TTreeReaderArray e = {reader, "e"}; + TTreeReaderArray e2 = {reader, "e2"}; + TTreeReaderArray e_t = {reader, "e_t"}; + TTreeReaderArray e_f = {reader, "e_f"}; + + ULong64_t NumEntries = tree->GetEntries(); + + //^########################################################### + //^ * Process + //^########################################################### + printf("############################################### Processing...\n"); + fflush(stdout); // flush out any printf + + ULong64_t processedEntries = 0; + float Frac = 0.1; + TStopwatch StpWatch; + StpWatch.Start(); + + while (reader.Next()) { + + // if( processedEntries > 10 ) break; + // printf("============== %5llu | multi : %d (%zu) \n", processedEntries, multi.Get()[0], sn.GetSize()); + // for( int i = 0; i < multi.Get()[0]; i++ ){ + // printf(" %d | %5d %2d %7d %10llu\n", i, sn[i], ch[i], e[i], e_t[i]); + // } + + hit.ClearData(); + hMulti->Fill(sn.GetSize()); + + for( int i = 0; i < sn.GetSize(); i++){ + + t2 = e_t[i]; + if( t2 < t1 ) printf("entry %lld-%d, timestamp is not in order. %llu, %llu\n", processedEntries, i, t2, t1); + if( i == 0 ) t1 = e_t[i]; + + if( ch[i] == ChMap::ScinR ) {hit.eSR = e[i]; hit.tSR = e_t[i]/4 + e_f[i]/1000.;} + if( ch[i] == ChMap::ScinL ) {hit.eSL = e[i]; hit.tSL = e_t[i]/4 + e_f[i]/1000.;} + if( ch[i] == ChMap::dFR ) {hit.eFR = e[i]; hit.tFR = e_t[i]/4 + e_f[i]/1000.;} + if( ch[i] == ChMap::dFL ) {hit.eFL = e[i]; hit.tFL = e_t[i]/4 + e_f[i]/1000.;} + if( ch[i] == ChMap::dBR ) {hit.eBR = e[i]; hit.tBR = e_t[i]/4 + e_f[i]/1000.;} + if( ch[i] == ChMap::dBL ) {hit.eBL = e[i]; hit.tBL = e_t[i]/4 + e_f[i]/1000.;} + if( ch[i] == ChMap::Cathode ) {hit.eCath = e[i]; hit.tCath = e_t[i]/4 + e_f[i]/1000.;} + if( ch[i] == ChMap::AnodeF ) {hit.eAF = e[i]; hit.tAF = e_t[i]/4 + e_f[i]/1000.;} + if( ch[i] == ChMap::AnodeB ) {hit.eAB = e[i]; hit.tAB = e_t[i]/4 + e_f[i]/1000.;} + + for( int j = i+1; j < sn.GetSize(); j++){ + coin->Fill(ch[i], ch[j]); + } + } + + unsigned int dQ = hit.eAB; // delta Q + unsigned int Qt = hit.eSR; // total Q + + if( Qt > 0 && dQ > 0 ) { + PID->Fill(Qt, dQ); + } + + // if( hit.eAF < 50000 ) return kTRUE; + // if( hit.eCath == 0 ) return kTRUE; + // if( hit.eCath > 13000 ) return kTRUE; + + hit.CalData(); + + if( !TMath::IsNaN(hit.x1) || !TMath::IsNaN(hit.x2) ) { + hFocal->Fill(hit.x1, hit.x2); + hF->Fill(hit.x1); + hB->Fill(hit.x2); + hXavg->Fill(hit.xAvg); + + hXavgVQ->Fill(hit.xAvg, dQ); + + for( int i = 0; i < 400; i++){ + double y = -50 + 100/400.*i; + + double x = (y/42.8625 + 0.5)* ( hit.x2-hit.x1) + hit.x1; + + haha->Fill(x,y); + } + + double ex = hit.Rho2Ex( (hit.xAvg/100 + 0.363) ); + //if( XMIN < hit.xAvg && hit.xAvg < XMAX) printf("x1 : %6.2f, x2 : %6.2f, xAvg %6.2f cm , ex : %f \n", hit.x1, hit.x2, hit.xAvg, ex); + hEx->Fill(ex); + } + + //*============================================ Progress Bar + processedEntries ++; + if (processedEntries >= NumEntries*Frac - 1 ) { + TString msg; msg.Form("%llu", NumEntries/1000); + int len = msg.Sizeof(); + printf(" %3.0f%% (%*llu/%llu k) processed in %6.1f sec | expect %6.1f sec\n", + Frac*100, len, processedEntries/1000,NumEntries/1000,StpWatch.RealTime(), StpWatch.RealTime()/Frac); + fflush(stdout); + StpWatch.Start(kFALSE); + Frac += 0.1; + } + + + } + + //^########################################################### + //^ * Plot + //^########################################################### + TCanvas * canvas = new TCanvas("cc", "Split-Pole", 1800, 1200); + + gStyle->SetOptStat("neiou"); + + canvas->Divide(3, 3); + + canvas->cd(1); PID->Draw("colz"); + //canvas->cd(2); coin->Draw("colz"); + canvas->cd(2); haha->Draw("colz"); + + canvas->cd(3); hF->Draw(); + canvas->cd(4); hB->Draw(); + + canvas->cd(5); hXavgVQ->Draw("colz"); + + canvas->cd(6); hXavg->Draw("colz"); + + canvas->cd(7); hEx->Draw(); + + canvas->cd(8); coin->Draw("colz"); + + canvas->cd(9); canvas->cd(9)->SetLogy(); hMulti->Draw(); + +} \ No newline at end of file diff --git a/Aux/script.C b/Aux/script.C index 0744458..f6856b4 100644 --- a/Aux/script.C +++ b/Aux/script.C @@ -1,90 +1,101 @@ -#include "fsuReader.h" -#include "../MultiBuilder.cpp" +// #include "fsuReader.h" +// #include "../MultiBuilder.cpp" + +#include "SplitPolePlotter.C" void script(){ - FSUReader * reader = new FSUReader("~/ExpData/testing/.fsu", 16); - Data * data = reader->GetData(); - data->tick2ns = 4; + TChain * chain = new TChain("tree"); - reader->ScanNumBlock(); + chain->Add("data/temp_002_336_1000.root"); - // for( int i = 0; i < 500 ; i++ ) reader->ReadNextBlock(0, 0); - - // int ch = 5; - // std::vector tList; - // int nEvent = 0; - // for( int i = 0; i < data->TotNumNonPileUpEvents[ch]; i++){ - // tList.push_back(data->Timestamp[ch][i]); - // printf("%3d | %d %llu \n", i, data->Energy[ch][i], data->Timestamp[ch][i]); - // nEvent ++; - // } - - // std::sort(tList.begin(), tList.end()); - - // unsigned long long dTime = tList.back() - tList.front(); - // double sec = dTime * data->tick2ns / 1e9; - - // printf("=========== %llu, %llu = %llu | %f sec | %f Hz\n", tList.back(), tList.front(), dTime, sec, nEvent/sec ); - - //data->PrintStat(0); + SplitPolePlotter(chain); - data->ClearData(); - data->ClearTriggerRate(); + //^===================================================== + + // FSUReader * reader = new FSUReader("~/ExpData/testing/.fsu", 16); + // Data * data = reader->GetData(); + // data->tick2ns = 4; + + // reader->ScanNumBlock(); + + // // for( int i = 0; i < 500 ; i++ ) reader->ReadNextBlock(0, 0); + + // // int ch = 5; + // // std::vector tList; + // // int nEvent = 0; + // // for( int i = 0; i < data->TotNumNonPileUpEvents[ch]; i++){ + // // tList.push_back(data->Timestamp[ch][i]); + // // printf("%3d | %d %llu \n", i, data->Energy[ch][i], data->Timestamp[ch][i]); + // // nEvent ++; + // // } + + // // std::sort(tList.begin(), tList.end()); + + // // unsigned long long dTime = tList.back() - tList.front(); + // // double sec = dTime * data->tick2ns / 1e9; + + // // printf("=========== %llu, %llu = %llu | %f sec | %f Hz\n", tList.back(), tList.front(), dTime, sec, nEvent/sec ); + + // //data->PrintStat(0); - MultiBuilder * mb = new MultiBuilder(data, reader->GetDPPType(), 334); - mb->SetTimeWindow(10000); - - unsigned long totNumBlock = reader->GetTotNumBlock(); - - int lastDataIndex = 0; - int lastLoopIndex = 0; - - for( unsigned long i = 0; i < 2; i++){ - - reader->ReadNextBlock(); - - // int maxDataIndex = 0; - // int maxLoopIndex = 0; - - // for( int ch = 0; ch < 16 ; ch++){ - // if( data->DataIndex[ch] > maxDataIndex ) maxDataIndex = data->DataIndex[ch]; - // if( data->LoopIndex[ch] > maxLoopIndex ) maxLoopIndex = data->LoopIndex[ch]; - // } - - // if( (maxLoopIndex * MaxNData + maxDataIndex) - (lastLoopIndex * MaxNData + lastDataIndex) > MaxNData * 0.05){ - - // printf("Agg ID : %lu \n", i ); - - // data->PrintStat(); - // data->PrintAllData(); - - // mb->BuildEvents(); - // mb->PrintAllEvent(); - // mb->PrintStat(); - - // lastDataIndex = maxDataIndex; - // lastLoopIndex = maxLoopIndex; - // } - - } + // data->ClearData(); + // data->ClearTriggerRate(); - data->PrintStat(); - data->PrintAllData(); - - - //mb->BuildEvents(true); + // MultiBuilder * mb = new MultiBuilder(data, reader->GetDPPType(), 334); + // mb->SetTimeWindow(10000); + + // unsigned long totNumBlock = reader->GetTotNumBlock(); + + // int lastDataIndex = 0; + // int lastLoopIndex = 0; - mb->BuildEventsBackWard(300); + // for( unsigned long i = 0; i < 2; i++){ - mb->PrintAllEvent(); - mb->PrintStat(); + // reader->ReadNextBlock(); + + // // int maxDataIndex = 0; + // // int maxLoopIndex = 0; + + // // for( int ch = 0; ch < 16 ; ch++){ + // // if( data->DataIndex[ch] > maxDataIndex ) maxDataIndex = data->DataIndex[ch]; + // // if( data->LoopIndex[ch] > maxLoopIndex ) maxLoopIndex = data->LoopIndex[ch]; + // // } + + // // if( (maxLoopIndex * MaxNData + maxDataIndex) - (lastLoopIndex * MaxNData + lastDataIndex) > MaxNData * 0.05){ + + // // printf("Agg ID : %lu \n", i ); + + // // data->PrintStat(); + // // data->PrintAllData(); + + // // mb->BuildEvents(); + // // mb->PrintAllEvent(); + // // mb->PrintStat(); + + // // lastDataIndex = maxDataIndex; + // // lastLoopIndex = maxLoopIndex; + // // } + + // } - delete mb; - delete reader; + // data->PrintStat(); + // data->PrintAllData(); + + + // //mb->BuildEvents(true); + + // mb->BuildEventsBackWard(300); + + // mb->PrintAllEvent(); + // mb->PrintStat(); + + + // delete mb; + // delete reader; } \ No newline at end of file diff --git a/Aux/splitpole.C b/Aux/splitpole.C index 87f2c5f..ac631eb 100644 --- a/Aux/splitpole.C +++ b/Aux/splitpole.C @@ -7,7 +7,6 @@ #include #include - #include "../analyzers/SplitPoleHit.h" namespace ChMap{ From 3fc682f918525fac53d3bc47cdd484a7ace452a5 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Fri, 19 Jul 2024 15:00:29 -0400 Subject: [PATCH 24/72] replace splitpole.C/h to SplitPolePlotter.C, to TreeReader --- Aux/EventBuilder.cpp | 9 +- Aux/SplitPolePlotter.C | 45 ++++++---- Aux/script.C | 3 +- Aux/splitpole.C | 184 --------------------------------------- Aux/splitpole.h | 101 --------------------- analyzers/SplitPoleHit.h | 6 +- 6 files changed, 36 insertions(+), 312 deletions(-) delete mode 100644 Aux/splitpole.C delete mode 100644 Aux/splitpole.h diff --git a/Aux/EventBuilder.cpp b/Aux/EventBuilder.cpp index 223ef6f..8183b1b 100644 --- a/Aux/EventBuilder.cpp +++ b/Aux/EventBuilder.cpp @@ -79,10 +79,11 @@ int main(int argc, char **argv) { printf("========================================= Number of Files : %d \n", nFile); for( int i = 0; i < nFile; i++) printf("%2d | %s \n", i, inFileName[i].Data()); printf("=========================================\n"); - printf(" Time Window = %ld ns = %.1f us\n", timeWindow, timeWindow/1000.); - printf(" Include Trace = %s\n", traceOn ? "Yes" : "No"); - printf(" Debug level = %d\n", debug); - printf(" Max multiplity = %d hits/event (hard coded)\n", MAX_MULTI); + printf(" Time Window = %ld ns = %.1f us\n", timeWindow, timeWindow/1000.); + printf(" Include Trace = %s\n", traceOn ? "Yes" : "No"); + printf(" Debug level = %d\n", debug); + printf(" Max multiplity = %d hits/event (hard coded)\n", MAX_MULTI); + if( traceOn ) printf(" Max Trace Length = %d (hard coded)\n", MAX_TRACE_LENGTH); printf("========================================= Grouping files\n"); std::vector> fileGroupList; // fileName and ID = SN * 1000 + index diff --git a/Aux/SplitPolePlotter.C b/Aux/SplitPolePlotter.C index 91613d3..c279a13 100644 --- a/Aux/SplitPolePlotter.C +++ b/Aux/SplitPolePlotter.C @@ -47,7 +47,8 @@ TH1F * hXavg; TH2F * hFocal; -TH2F * hXavgVQ; +TH2F * hXavg_Q; +TH2F * hXavg_Theta; TH2F * haha; @@ -56,7 +57,7 @@ TH1F * hEx; ULong64_t t1, t2; #define XMIN -20 -#define XMAX 100 +#define XMAX 150 //^########################################### @@ -82,7 +83,7 @@ void SplitPolePlotter(TChain *tree){ //*====================================================== histograms - PID = new TH2F("hPID", "PID; Scin_X ; AnodeB", 200, 0, 30000, 100, 0, 70000); + PID = new TH2F("hPID", "PID; Scin_X ; AnodeB", 200, 0, 2000, 100, 0, 4000); coin = new TH2F("hCoin", "Coincident ", 16, 0, 16, 16, 0, 16); hMulti = new TH1F("hMulti", "Multiplicity", 16, 0, 16); @@ -92,14 +93,15 @@ void SplitPolePlotter(TChain *tree){ hXavg = new TH1F("hAvg", "Xavg", 600, XMIN, XMAX); hFocal = new TH2F("hFocal", "Front vs Back ", 200, XMIN, XMAX, 200, XMIN, XMAX); - hXavgVQ = new TH2F("hXavgVQ", "Xavg vs Q ", 200, XMIN, XMAX, 200, 0, 40000); + hXavg_Q = new TH2F("hXavg_Q", "Xavg vs Q ", 200, XMIN, XMAX, 200, 0, 5000); + hXavg_Theta = new TH2F("hXavg_Theta", "Xavg vs Theta ", 200, XMIN, XMAX, 200, 2.5, 3); haha = new TH2F("haha", "", 400, XMIN, XMAX, 400, -50, 50); hEx = new TH1F("hEx", "Ex; Ex [MeV]; count/100 keV", 250, -5, 20); hit.SetMassTablePath("../analyzers/mass20.txt"); - hit.CalConstants("12C", "12C", "4He", 80, 5); // 80MeV, 5 deg + hit.CalConstants("36S", "d", "p", 80, 12); // 80MeV, 5 deg hit.CalZoffset(1.41); // 1.41 T t1 = 0; @@ -142,21 +144,23 @@ void SplitPolePlotter(TChain *tree){ hit.ClearData(); hMulti->Fill(sn.GetSize()); + // if( multi.Get()[0] != 9 ) continue; + for( int i = 0; i < sn.GetSize(); i++){ t2 = e_t[i]; if( t2 < t1 ) printf("entry %lld-%d, timestamp is not in order. %llu, %llu\n", processedEntries, i, t2, t1); if( i == 0 ) t1 = e_t[i]; - if( ch[i] == ChMap::ScinR ) {hit.eSR = e[i]; hit.tSR = e_t[i]/4 + e_f[i]/1000.;} - if( ch[i] == ChMap::ScinL ) {hit.eSL = e[i]; hit.tSL = e_t[i]/4 + e_f[i]/1000.;} - if( ch[i] == ChMap::dFR ) {hit.eFR = e[i]; hit.tFR = e_t[i]/4 + e_f[i]/1000.;} - if( ch[i] == ChMap::dFL ) {hit.eFL = e[i]; hit.tFL = e_t[i]/4 + e_f[i]/1000.;} - if( ch[i] == ChMap::dBR ) {hit.eBR = e[i]; hit.tBR = e_t[i]/4 + e_f[i]/1000.;} - if( ch[i] == ChMap::dBL ) {hit.eBL = e[i]; hit.tBL = e_t[i]/4 + e_f[i]/1000.;} - if( ch[i] == ChMap::Cathode ) {hit.eCath = e[i]; hit.tCath = e_t[i]/4 + e_f[i]/1000.;} - if( ch[i] == ChMap::AnodeF ) {hit.eAF = e[i]; hit.tAF = e_t[i]/4 + e_f[i]/1000.;} - if( ch[i] == ChMap::AnodeB ) {hit.eAB = e[i]; hit.tAB = e_t[i]/4 + e_f[i]/1000.;} + if( ch[i] == ChMap::ScinR ) {hit.eSR = e[i]; hit.tSR = e_t[i] + e_f[i]/1000.*4;} + if( ch[i] == ChMap::ScinL ) {hit.eSL = e[i]; hit.tSL = e_t[i] + e_f[i]/1000.*4;} + if( ch[i] == ChMap::dFR ) {hit.eFR = e[i]; hit.tFR = e_t[i] + e_f[i]/1000.*4;} + if( ch[i] == ChMap::dFL ) {hit.eFL = e[i]; hit.tFL = e_t[i] + e_f[i]/1000.*4;} + if( ch[i] == ChMap::dBR ) {hit.eBR = e[i]; hit.tBR = e_t[i] + e_f[i]/1000.*4;} + if( ch[i] == ChMap::dBL ) {hit.eBL = e[i]; hit.tBL = e_t[i] + e_f[i]/1000.*4;} + if( ch[i] == ChMap::Cathode ) {hit.eCath = e[i]; hit.tCath = e_t[i] + e_f[i]/1000.*4;} + if( ch[i] == ChMap::AnodeF ) {hit.eAF = e[i]; hit.tAF = e_t[i] + e_f[i]/1000.*4;} + if( ch[i] == ChMap::AnodeB ) {hit.eAB = e[i]; hit.tAB = e_t[i] + e_f[i]/1000.*4;} for( int j = i+1; j < sn.GetSize(); j++){ coin->Fill(ch[i], ch[j]); @@ -174,7 +178,7 @@ void SplitPolePlotter(TChain *tree){ // if( hit.eCath == 0 ) return kTRUE; // if( hit.eCath > 13000 ) return kTRUE; - hit.CalData(); + hit.CalData(4); if( !TMath::IsNaN(hit.x1) || !TMath::IsNaN(hit.x2) ) { hFocal->Fill(hit.x1, hit.x2); @@ -182,7 +186,8 @@ void SplitPolePlotter(TChain *tree){ hB->Fill(hit.x2); hXavg->Fill(hit.xAvg); - hXavgVQ->Fill(hit.xAvg, dQ); + hXavg_Q->Fill(hit.xAvg, dQ); + hXavg_Theta->Fill( hit.xAvg, hit.theta); for( int i = 0; i < 400; i++){ double y = -50 + 100/400.*i; @@ -215,11 +220,11 @@ void SplitPolePlotter(TChain *tree){ //^########################################################### //^ * Plot //^########################################################### - TCanvas * canvas = new TCanvas("cc", "Split-Pole", 1800, 1200); + TCanvas * canvas = new TCanvas("cc", "Split-Pole", 1600, 1200); gStyle->SetOptStat("neiou"); - canvas->Divide(3, 3); + canvas->Divide(4, 3); canvas->cd(1); PID->Draw("colz"); //canvas->cd(2); coin->Draw("colz"); @@ -228,7 +233,7 @@ void SplitPolePlotter(TChain *tree){ canvas->cd(3); hF->Draw(); canvas->cd(4); hB->Draw(); - canvas->cd(5); hXavgVQ->Draw("colz"); + canvas->cd(5); hXavg_Q->Draw("colz"); canvas->cd(6); hXavg->Draw("colz"); @@ -238,4 +243,6 @@ void SplitPolePlotter(TChain *tree){ canvas->cd(9); canvas->cd(9)->SetLogy(); hMulti->Draw(); + canvas->cd(10); hXavg_Theta->Draw("colz"); + } \ No newline at end of file diff --git a/Aux/script.C b/Aux/script.C index f6856b4..b2572ce 100644 --- a/Aux/script.C +++ b/Aux/script.C @@ -7,7 +7,8 @@ void script(){ TChain * chain = new TChain("tree"); - chain->Add("data/temp_002_336_1000.root"); + // chain->Add("data/temp_002_336_1000.root"); + chain->Add("run123_100000.root"); SplitPolePlotter(chain); diff --git a/Aux/splitpole.C b/Aux/splitpole.C deleted file mode 100644 index ac631eb..0000000 --- a/Aux/splitpole.C +++ /dev/null @@ -1,184 +0,0 @@ -#define splitpole_cxx - -#include "splitpole.h" -#include -#include -#include -#include -#include - -#include "../analyzers/SplitPoleHit.h" - -namespace ChMap{ - - const short ScinR = 0; - const short ScinL = 1; - const short dFR = 8; - const short dFL = 9; - const short dBR = 10; - const short dBL = 11; - const short Cathode = 7; - const short AnodeF = 13; - const short AnodeB = 15; - -}; - -const double c = 299.792458; // mm/ns -const double pi = M_PI; -const double deg2rad = pi/180.; - -SplitPoleHit hit; - -TH2F * PID; -TH2F * coin; - -TH1F * hMulti; - -TH1F * hF; -TH1F * hB; -TH1F * hXavg; - -TH2F * hFocal; - -TH2F * hXavgVQ; - -TH2F * haha; - -TH1F * hEx; - -ULong64_t t1, t2; - -#define XMIN -20 -#define XMAX 100 - -void splitpole::Begin(TTree * /*tree*/){ - - TString option = GetOption(); - - PID = new TH2F("hPID", "PID; Scin_X ; AnodeB", 200, 0, 30000, 100, 0, 70000); - coin = new TH2F("hCoin", "Coincident ", 16, 0, 16, 16, 0, 16); - - hMulti = new TH1F("hMulti", "Multiplicity", 16, 0, 16); - - hF = new TH1F("hF", "Front delay line position", 600, XMIN, XMAX); - hB = new TH1F("hB", "Back delay line position", 600, XMIN, XMAX); - hXavg = new TH1F("hAvg", "Xavg", 600, XMIN, XMAX); - - hFocal = new TH2F("hFocal", "Front vs Back ", 200, XMIN, XMAX, 200, XMIN, XMAX); - hXavgVQ = new TH2F("hXavgVQ", "Xavg vs Q ", 200, XMIN, XMAX, 200, 0, 40000); - - haha = new TH2F("haha", "", 400, XMIN, XMAX, 400, -50, 50); - - hEx = new TH1F("hEx", "Ex; Ex [MeV]; count/100 keV", 250, -5, 20); - - hit.SetMassTablePath("../analyzers/mass20.txt"); - hit.CalConstants("12C", "12C", "4He", 80, 5); // 80MeV, 5 deg - hit.CalZoffset(1.41); // 1.41 T - - t1 = 0; - t2 = 0; - -} - - -Bool_t splitpole::Process(Long64_t entry){ - - b_multi->GetEntry(entry); - b_ch->GetEntry(entry); - b_e->GetEntry(entry); - b_e2->GetEntry(entry); - b_e_t->GetEntry(entry); - b_e_f->GetEntry(entry); - - //if( multi < 9) return kTRUE; - hit.ClearData(); - - hMulti->Fill(multi); - - for( int i = 0; i < multi; i++){ - - t2 = e_t[i]; - - if( t2 < t1 ) printf("entry %lld-%d, timestamp is not in order. %llu, %llu\n", entry, i, t2, t1); - - if( i == 0 ) t1 = e_t[i]; - - if( ch[i] == ChMap::ScinR ) {hit.eSR = e[i]; hit.tSR = e_t[i] + e_f[i]/1000.;} - if( ch[i] == ChMap::ScinL ) {hit.eSL = e[i]; hit.tSL = e_t[i] + e_f[i]/1000.;} - if( ch[i] == ChMap::dFR ) {hit.eFR = e[i]; hit.tFR = e_t[i] + e_f[i]/1000.;} - if( ch[i] == ChMap::dFL ) {hit.eFL = e[i]; hit.tFL = e_t[i] + e_f[i]/1000.;} - if( ch[i] == ChMap::dBR ) {hit.eBR = e[i]; hit.tBR = e_t[i] + e_f[i]/1000.;} - if( ch[i] == ChMap::dBL ) {hit.eBL = e[i]; hit.tBL = e_t[i] + e_f[i]/1000.;} - if( ch[i] == ChMap::Cathode ) {hit.eCath = e[i]; hit.tCath = e_t[i] + e_f[i]/1000.;} - if( ch[i] == ChMap::AnodeF ) {hit.eAF = e[i]; hit.tAF = e_t[i] + e_f[i]/1000.;} - if( ch[i] == ChMap::AnodeB ) {hit.eAB = e[i]; hit.tAB = e_t[i] + e_f[i]/1000.;} - - for( int j = i+1; j < multi; j++){ - coin->Fill(ch[i], ch[j]); - } - } - - unsigned int dQ = hit.eAB; // delta Q - unsigned int Qt = hit.eSR; // total Q - - if( Qt > 0 && dQ > 0 ) { - PID->Fill(Qt, dQ); - } - - // if( hit.eAF < 50000 ) return kTRUE; - // if( hit.eCath == 0 ) return kTRUE; - // if( hit.eCath > 13000 ) return kTRUE; - - hit.CalData(); - - if( !TMath::IsNaN(hit.x1) || !TMath::IsNaN(hit.x2) ) { - hFocal->Fill(hit.x1, hit.x2); - hF->Fill(hit.x1); - hB->Fill(hit.x2); - hXavg->Fill(hit.xAvg); - - hXavgVQ->Fill(hit.xAvg, dQ); - - for( int i = 0; i < 400; i++){ - double y = -50 + 100/400.*i; - - double x = (y/42.8625 + 0.5)* ( hit.x2-hit.x1) + hit.x1; - - haha->Fill(x,y); - } - - double ex = hit.Rho2Ex( (hit.xAvg/100 + 0.363) ); - //if( XMIN < hit.xAvg && hit.xAvg < XMAX) printf("x1 : %6.2f, x2 : %6.2f, xAvg %6.2f cm , ex : %f \n", hit.x1, hit.x2, hit.xAvg, ex); - hEx->Fill(ex); - } - - return kTRUE; -} - - -void splitpole::Terminate(){ - - TCanvas * canvas = new TCanvas("cc", "Split-Pole", 1800, 1200); - - gStyle->SetOptStat("neiou"); - - canvas->Divide(3, 3); - - canvas->cd(1); PID->Draw("colz"); - //canvas->cd(2); coin->Draw("colz"); - canvas->cd(2); haha->Draw("colz"); - - canvas->cd(3); hF->Draw(); - canvas->cd(4); hB->Draw(); - - canvas->cd(5); hXavgVQ->Draw("colz"); - - canvas->cd(6); hXavg->Draw("colz"); - - canvas->cd(7); hEx->Draw(); - - canvas->cd(8); coin->Draw("colz"); - - canvas->cd(9); canvas->cd(9)->SetLogy(); hMulti->Draw(); - -} diff --git a/Aux/splitpole.h b/Aux/splitpole.h deleted file mode 100644 index 5928ca3..0000000 --- a/Aux/splitpole.h +++ /dev/null @@ -1,101 +0,0 @@ -////////////////////////////////////////////////////////// -// This class has been automatically generated on -// Wed Jun 14 15:51:03 2023 by ROOT version 6.26/04 -// from TTree tree/temp_036.root -// found on file: temp_036.root -////////////////////////////////////////////////////////// - -#ifndef splitpole_h -#define splitpole_h - -#include -#include -#include -#include - -// Header file for the classes stored in the TTree if any. - -#define MaxMulti 100 - -class splitpole : public TSelector { -public : - TTree *fChain; //!pointer to the analyzed TTree or TChain - -// Fixed size dimensions of array or collections stored in the TTree if any. - - // Declaration of leaf types - ULong64_t evID; - UShort_t multi; - UShort_t bd[MaxMulti]; //[multi] - UShort_t ch[MaxMulti]; //[multi] - UShort_t e[MaxMulti]; //[multi] - UShort_t e2[MaxMulti]; //[multi] - ULong64_t e_t[MaxMulti]; //[multi] - UShort_t e_f[MaxMulti]; //[multi] - - // List of branches - TBranch *b_event_ID; //! - TBranch *b_multi; //! - TBranch *b_bd; //! - TBranch *b_ch; //! - TBranch *b_e; //! - TBranch *b_e2; //! - TBranch *b_e_t; //! - TBranch *b_e_f; //! - - splitpole(TTree * /*tree*/ =0) : fChain(0) { } - virtual ~splitpole() { } - virtual Int_t Version() const { return 2; } - virtual void Begin(TTree *tree); - virtual void SlaveBegin(TTree *tree); - virtual void Init(TTree *tree); - virtual Bool_t Notify(); - virtual Bool_t Process(Long64_t entry); - virtual Int_t GetEntry(Long64_t entry, Int_t getall = 0) { return fChain ? fChain->GetTree()->GetEntry(entry, getall) : 0; } - virtual void SetOption(const char *option) { fOption = option; } - virtual void SetObject(TObject *obj) { fObject = obj; } - virtual void SetInputList(TList *input) { fInput = input; } - virtual TList *GetOutputList() const { return fOutput; } - virtual void SlaveTerminate(); - virtual void Terminate(); - - ClassDef(splitpole,0); -}; - -#endif - -#ifdef splitpole_cxx -void splitpole::Init(TTree *tree){ - // Set branch addresses and branch pointers - if (!tree) return; - fChain = tree; - fChain->SetMakeClass(1); - - fChain->SetBranchAddress("evID", &evID, &b_event_ID); - fChain->SetBranchAddress("multi", &multi, &b_multi); - fChain->SetBranchAddress("bd", bd, &b_bd); - fChain->SetBranchAddress("ch", ch, &b_ch); - fChain->SetBranchAddress("e", e, &b_e); - fChain->SetBranchAddress("e2", e2, &b_e2); - fChain->SetBranchAddress("e_t", e_t, &b_e_t); - fChain->SetBranchAddress("e_f", e_f, &b_e_f); -} - -Bool_t splitpole::Notify(){ - - return kTRUE; -} - - -void splitpole::SlaveBegin(TTree * /*tree*/){ - - TString option = GetOption(); - -} - -void splitpole::SlaveTerminate(){ - -} - - -#endif // #ifdef splitpole_cxx diff --git a/analyzers/SplitPoleHit.h b/analyzers/SplitPoleHit.h index 43fbdc0..90f6d93 100644 --- a/analyzers/SplitPoleHit.h +++ b/analyzers/SplitPoleHit.h @@ -194,14 +194,14 @@ public: isConstantCal = false; } - void CalData(){ + void CalData(float scale = 2.){ if( eSR > 0 && eSL > 0 ) eSAvg = (eSR + eSL)/2; if( eSR > 0 && eSL == 0 ) eSAvg = eSR; if( eSR == 0 && eSL > 0 ) eSAvg = eSL; - if( tFR > 0 && tFL > 0 ) x1 = (tFL - tFR)/2./2.1; - if( tBR > 0 && tBL > 0 ) x2 = (tBL - tBR)/2./1.98; + if( tFR > 0 && tFL > 0 ) x1 = (tFL - tFR)/scale/2.1; + if( tBR > 0 && tBL > 0 ) x2 = (tBL - tBR)/scale/1.98; if( !std::isnan(x1) && !std::isnan(x2)) { From 779c4a87c9494ea3d6ac5eb70479ab5e54c09117 Mon Sep 17 00:00:00 2001 From: "Calem@RAISOR" Date: Fri, 26 Jul 2024 14:21:16 -0500 Subject: [PATCH 25/72] resize window when screen too small --- .gitignore | 1 + DigiSettingsPanel.cpp | 8 ++++++++ Scope.cpp | 6 ++++++ SingleSpectra.cpp | 6 ++++++ analyzers/CoincidentAnalyzer.h | 6 +++--- analyzers/EncoreAnalyzer.h | 7 +++++++ 6 files changed, 31 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 9facd53..bd65ea5 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ AggSeparator FSU2CAEN data +Data *.d *.pcm diff --git a/DigiSettingsPanel.cpp b/DigiSettingsPanel.cpp index f0f63b0..bd94a7e 100644 --- a/DigiSettingsPanel.cpp +++ b/DigiSettingsPanel.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include #define ComBoxMixed "Mixed" // bit = 0, bit = 1 @@ -40,6 +42,12 @@ DigiSettingsPanel::DigiSettingsPanel(Digitizer ** digi, unsigned int nDigi, QStr setWindowTitle("Digitizer Settings"); setGeometry(0, 0, 1700, 850); + //====== resize window if screen too small + QScreen * screen = QGuiApplication::primaryScreen(); + QRect screenGeo = screen->geometry(); + if( screenGeo.width() < 1700 || screenGeo.height() < 850) this->showMaximized(); + + tabWidget = new QTabWidget(this); setCentralWidget(tabWidget); diff --git a/Scope.cpp b/Scope.cpp index 49e4fe0..0530d43 100644 --- a/Scope.cpp +++ b/Scope.cpp @@ -6,6 +6,7 @@ #include #include #include +#include QVector Scope::TrapezoidFilter(QVector data, int baseLineEndS, int riseTimeS, int flatTopS, float decayTime_ns){ DebugPrint("%s", "Scope"); @@ -56,6 +57,11 @@ Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataTh setGeometry(0, 0, 1000, 800); setWindowFlags( this->windowFlags() & ~Qt::WindowCloseButtonHint ); + //====== resize window if screen too small + QScreen * screen = QGuiApplication::primaryScreen(); + QRect screenGeo = screen->geometry(); + if( screenGeo.width() < 1000 || screenGeo.height() < 800) this->showMaximized(); + enableSignalSlot = false; isACQStarted = false; diff --git a/SingleSpectra.cpp b/SingleSpectra.cpp index 85fdad7..8ae9a92 100644 --- a/SingleSpectra.cpp +++ b/SingleSpectra.cpp @@ -4,6 +4,7 @@ #include #include #include +#include SingleSpectra::SingleSpectra(Digitizer ** digi, unsigned int nDigi, QString rawDataPath, QMainWindow * parent) : QMainWindow(parent){ DebugPrint("%s", "SingleSpectra"); @@ -20,6 +21,11 @@ SingleSpectra::SingleSpectra(Digitizer ** digi, unsigned int nDigi, QString rawD setGeometry(0, 0, 1000, 800); //setWindowFlags( this->windowFlags() & ~Qt::WindowCloseButtonHint ); + //====== resize window if screen too small + QScreen * screen = QGuiApplication::primaryScreen(); + QRect screenGeo = screen->geometry(); + if( screenGeo.width() < 1000 || screenGeo.height() < 800) this->showMaximized(); + QWidget * layoutWidget = new QWidget(this); setCentralWidget(layoutWidget); QVBoxLayout * layout = new QVBoxLayout(layoutWidget); diff --git a/analyzers/CoincidentAnalyzer.h b/analyzers/CoincidentAnalyzer.h index 777076b..b498d90 100644 --- a/analyzers/CoincidentAnalyzer.h +++ b/analyzers/CoincidentAnalyzer.h @@ -526,9 +526,9 @@ inline void CoincidentAnalyzer::LoadHistRange(){ int y_sn, y_ch, y_bin; float y_min, y_max; - float updateTime; - int bkCount; - bool isBkEvtBuild; + float updateTime = 1.0; + int bkCount = 100; + bool isBkEvtBuild = false; if (!filePath.isEmpty()) { diff --git a/analyzers/EncoreAnalyzer.h b/analyzers/EncoreAnalyzer.h index b5a6b64..bdaed55 100644 --- a/analyzers/EncoreAnalyzer.h +++ b/analyzers/EncoreAnalyzer.h @@ -5,6 +5,8 @@ #include "Isotope.h" #include +#include +#include namespace EncoreChMap{ @@ -84,6 +86,11 @@ inline void Encore::SetUpCanvas(){ setGeometry(0, 0, 1600, 1600); + //====== resize window if screen too small + QScreen * screen = QGuiApplication::primaryScreen(); + QRect screenGeo = screen->geometry(); + if( screenGeo.width() < 1600 || screenGeo.height() < 1600) this->showMaximized(); + chkRunAnalyzer = new QCheckBox("Run Analyzer", this); layout->addWidget(chkRunAnalyzer, 0, 0); From f7a7dff2a3bf1cad6e4696ac6edf58e61b0a0eb8 Mon Sep 17 00:00:00 2001 From: MUSIC Date: Fri, 26 Jul 2024 14:48:20 -0500 Subject: [PATCH 26/72] screen too small fix again --- DigiSettingsPanel.cpp | 8 +++++--- Scope.cpp | 7 +++++-- SingleSpectra.cpp | 8 ++++++-- analyzers/EncoreAnalyzer.h | 9 +++++---- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/DigiSettingsPanel.cpp b/DigiSettingsPanel.cpp index bd94a7e..d6f12e9 100644 --- a/DigiSettingsPanel.cpp +++ b/DigiSettingsPanel.cpp @@ -40,13 +40,15 @@ DigiSettingsPanel::DigiSettingsPanel(Digitizer ** digi, unsigned int nDigi, QStr enableSignalSlot = false; setWindowTitle("Digitizer Settings"); - setGeometry(0, 0, 1700, 850); //====== resize window if screen too small QScreen * screen = QGuiApplication::primaryScreen(); QRect screenGeo = screen->geometry(); - if( screenGeo.width() < 1700 || screenGeo.height() < 850) this->showMaximized(); - + if( screenGeo.width() < 1700 || screenGeo.height() < 850) { + setGeometry(0, 0, screenGeo.width() - 100, screenGeo.height() - 100); + }else{ + setGeometry(0, 0, 1700, 850); + } tabWidget = new QTabWidget(this); setCentralWidget(tabWidget); diff --git a/Scope.cpp b/Scope.cpp index 0530d43..1d99c31 100644 --- a/Scope.cpp +++ b/Scope.cpp @@ -54,13 +54,16 @@ Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataTh this->readDataThread = readDataThread; setWindowTitle("Scope"); - setGeometry(0, 0, 1000, 800); setWindowFlags( this->windowFlags() & ~Qt::WindowCloseButtonHint ); //====== resize window if screen too small QScreen * screen = QGuiApplication::primaryScreen(); QRect screenGeo = screen->geometry(); - if( screenGeo.width() < 1000 || screenGeo.height() < 800) this->showMaximized(); + if( screenGeo.width() < 1000 || screenGeo.height() < 800) { + setGeometry(0, 0, screenGeo.width() - 100, screenGeo.height() - 100); + }else{ + setGeometry(0, 0, 1000, 800); + } enableSignalSlot = false; diff --git a/SingleSpectra.cpp b/SingleSpectra.cpp index 8ae9a92..a563e7a 100644 --- a/SingleSpectra.cpp +++ b/SingleSpectra.cpp @@ -18,13 +18,17 @@ SingleSpectra::SingleSpectra(Digitizer ** digi, unsigned int nDigi, QString rawD isSignalSlotActive = true; setWindowTitle("Single Histograms"); - setGeometry(0, 0, 1000, 800); + //setWindowFlags( this->windowFlags() & ~Qt::WindowCloseButtonHint ); //====== resize window if screen too small QScreen * screen = QGuiApplication::primaryScreen(); QRect screenGeo = screen->geometry(); - if( screenGeo.width() < 1000 || screenGeo.height() < 800) this->showMaximized(); + 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); diff --git a/analyzers/EncoreAnalyzer.h b/analyzers/EncoreAnalyzer.h index bdaed55..79a42b3 100644 --- a/analyzers/EncoreAnalyzer.h +++ b/analyzers/EncoreAnalyzer.h @@ -84,13 +84,14 @@ private: inline void Encore::SetUpCanvas(){ - setGeometry(0, 0, 1600, 1600); - //====== resize window if screen too small QScreen * screen = QGuiApplication::primaryScreen(); QRect screenGeo = screen->geometry(); - if( screenGeo.width() < 1600 || screenGeo.height() < 1600) this->showMaximized(); - + if( screenGeo.width() < 1600 || screenGeo.height() < 1600) { + setGeometry(0, 0, screenGeo.width() - 100, screenGeo.height() -100); + }else{ + setGeometry(0, 0, 1600, 1600); + } chkRunAnalyzer = new QCheckBox("Run Analyzer", this); layout->addWidget(chkRunAnalyzer, 0, 0); From 478d1cdf38c4880662b6a921cf5cdd7e9f71c7f6 Mon Sep 17 00:00:00 2001 From: MUSIC Date: Tue, 30 Jul 2024 11:56:10 -0500 Subject: [PATCH 27/72] add MUSIC Analyr. Online evt buidr fail... --- DigiSettingsPanel.cpp | 1 + FSUDAQ.cpp | 5 +- Scope.cpp | 1 + SingleSpectra.cpp | 1 + analyzers/MUSICAnalyzer.h | 182 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 analyzers/MUSICAnalyzer.h diff --git a/DigiSettingsPanel.cpp b/DigiSettingsPanel.cpp index d6f12e9..ae95f35 100644 --- a/DigiSettingsPanel.cpp +++ b/DigiSettingsPanel.cpp @@ -49,6 +49,7 @@ DigiSettingsPanel::DigiSettingsPanel(Digitizer ** digi, unsigned int nDigi, QStr }else{ setGeometry(0, 0, 1700, 850); } + // setGeometry(0, 0, 1700, 850); tabWidget = new QTabWidget(this); setCentralWidget(tabWidget); diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index 317c392..b118ba7 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -18,9 +18,10 @@ #include "analyzers/CoincidentAnalyzer.h" #include "analyzers/SplitPoleAnalyzer.h" #include "analyzers/EncoreAnalyzer.h" +#include "analyzers/MUSICAnalyzer.h" #include "analyzers/RAISOR.h" -std::vector onlineAnalyzerList = {"Coincident","Splie-Pole", "Encore", "RAISOR"}; +std::vector onlineAnalyzerList = {"Coincident","Splie-Pole", "Encore", "RAISOR", "MUSICS"}; FSUDAQ::FSUDAQ(QWidget *parent) : QMainWindow(parent){ DebugPrint("%s", "FSUDAQ"); @@ -1827,6 +1828,7 @@ void FSUDAQ::OpenAnalyzer(){ if( id == 1 ) onlineAnalyzer = new SplitPole(digi, nDigi); 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 >= 0 ) onlineAnalyzer->show(); }else{ @@ -1836,6 +1838,7 @@ void FSUDAQ::OpenAnalyzer(){ if( id == 1 ) onlineAnalyzer = new SplitPole(digi, nDigi); 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 >= 0 ){ onlineAnalyzer->show(); diff --git a/Scope.cpp b/Scope.cpp index 1d99c31..18d17f8 100644 --- a/Scope.cpp +++ b/Scope.cpp @@ -64,6 +64,7 @@ Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataTh }else{ setGeometry(0, 0, 1000, 800); } + // setGeometry(0, 0, 1000, 800); enableSignalSlot = false; diff --git a/SingleSpectra.cpp b/SingleSpectra.cpp index a563e7a..605b5bd 100644 --- a/SingleSpectra.cpp +++ b/SingleSpectra.cpp @@ -29,6 +29,7 @@ SingleSpectra::SingleSpectra(Digitizer ** digi, unsigned int nDigi, QString rawD }else{ setGeometry(0, 0, 1000, 800); } + // setGeometry(0, 0, 1000, 800); QWidget * layoutWidget = new QWidget(this); setCentralWidget(layoutWidget); diff --git a/analyzers/MUSICAnalyzer.h b/analyzers/MUSICAnalyzer.h new file mode 100644 index 0000000..b86626a --- /dev/null +++ b/analyzers/MUSICAnalyzer.h @@ -0,0 +1,182 @@ +#ifndef MUSICANLAYZER_H +#define MUSICANLAYZER_H + +#include "Analyser.h" +#include "Isotope.h" + +#include +#include +#include + +namespace MUSICChMap{ + + const std::map SN2Bd = { + {16828, 0}, + {16829, 1}, + {16827, 2}, + {23986, 3} + }; + + //Left 0->15 + //Right 16->31 + //Individual{32=Grid, 33=S0, 34=cathode, 35=S17, 36=Si_dE, 100>pulser}, + //-1=empty + const int mapping[4][16] = { + // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 + {34, -1, 1, -1, 33, 101, 5, -1, 0, -1, 9, -1, 17, 13, -1, 32}, + { 2, -1, 16, -1, 21, 102, 20, -1, 8, -1, 24, -1, 27, 28, -1, 14}, + {19, -1, 3, -1, 6, 103, 7, -1, 25, -1, 11, -1, 12, 15, -1, 10}, + { 4, -1, 18, 36, 23, 104, 22, -1, 29, -1, 26, -1, 31, 30, -1, 35} + }; + + // Gain matching [ch][bd] + const double corr[16][4] = { + { 1.00000, 1.00000, 1.00000, 1.0000}, + { 1.00000, 1.00000, 1.03158, 1.0000}, + { 1.00000, 1.00000, 0.99240, 1.0000}, + { 1.00000, 1.03704, 0.94004, 1.0000}, + { 1.01031, 1.02084, 1.10114, 1.0000}, + { 1.00000, 0.94685, 1.00513, 1.0000}, + { 1.00000, 1.03431, 1.00513, 1.0000}, + { 1.00000, 0.92670, 0.96078, 1.0000}, + { 1.03431, 0.94685, 0.96314, 1.0000}, + { 1.00000, 1.03158, 0.95145, 1.0000}, + { 0.95145, 1.00256, 0.97270, 1.0000}, + { 1.00000, 1.00256, 0.90950, 1.0000}, + { 1.03704, 0.99492, 0.98740, 1.0000}, + { 1.00000, 1.00000, 0.99746, 1.0000}, + { 0.96078, 1.03980, 1.00513, 1.0000}, + { 1.00000, 1.05095, 1.00000, 1.0000}, + }; + + +}; + +class MUSIC : public Analyzer{ + Q_OBJECT +public: + + MUSIC(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent = nullptr): Analyzer(digi, nDigi, parent){ + + SetUpdateTimeInSec(1.0); + + 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(10000); + + SetUpCanvas(); + } + + // MUSIC(){}; + + void SetUpCanvas(); + +public slots: + void UpdateHistograms(); + +private: + + MultiBuilder *evtbder; + + Histogram2D * hLeft; + Histogram2D * hRight; + Histogram2D * hLR; + + Histogram1D * hMulti; + + QCheckBox * chkRunAnalyzer; + +}; + + +inline void MUSIC::SetUpCanvas(){ + + //====== resize window if screen too small + QScreen * screen = QGuiApplication::primaryScreen(); + QRect screenGeo = screen->geometry(); + if( screenGeo.width() < 1600 || screenGeo.height() < 1600) { + setGeometry(0, 0, screenGeo.width() - 100, screenGeo.height() -100); + }else{ + setGeometry(0, 0, 1600, 1600); + } + chkRunAnalyzer = new QCheckBox("Run Analyzer", this); + layout->addWidget(chkRunAnalyzer, 0, 0); + + hLeft = new Histogram2D("Left", "Ch", "Energy", 17, 0, 16, 200, 0, 20000, this); + layout->addWidget(hLeft, 1, 0); + hRight = new Histogram2D("Right", "Ch", "Energy", 17, 0, 16, 200, 0, 20000, this); + layout->addWidget(hRight, 1, 1); + hLR = new Histogram2D("Left + Right", "Ch", "Energy", 17, 0, 16, 200, 0, 20000, this); + layout->addWidget(hLR, 2, 0); + hMulti = new Histogram1D("Multi", "multiplicity", 40, 0, 40); + layout->addWidget(hMulti, 2, 1); + +} + +inline void MUSIC::UpdateHistograms(){ + + if( this->isVisible() == false ) return; + if( chkRunAnalyzer->isChecked() == false ) return; + + BuildEvents(); // call the event builder to build events + + printf("MUSIC::%s----------- 1\n", __func__); + + //============ Get events, and do analysis + long eventBuilt = evtbder->eventBuilt; + if( eventBuilt == 0 ) return; + + //============ Processing data and fill histograms + long eventIndex = evtbder->eventIndex; + long eventStart = eventIndex - eventBuilt + 1; + if(eventStart < 0 ) eventStart += MaxNEvent; + + printf("MUSIC::%s----------- 2\n", __func__); + for( long i = eventStart ; i <= eventIndex; i ++ ){ + std::vector event = evtbder->events[i]; + //printf("-------------- %ld\n", i); + + hMulti->Fill((int) event.size()); + //if( event.size() < 9 ) return; + if( event.size() == 0 ) return; + + double sum[17] = {0}; + for( int k = 0; k < (int) event.size(); k++ ){ + + printf("MUSIC::%s----------- i, k %d, %d\n", __func__, i, k); + int bd = MUSICChMap::SN2Bd.at(event[k].sn); + + int ch = event[k].ch; + + int ID = MUSICChMap::mapping[bd][ch]; + + if( ID < 0 ) continue; + + double eC = event[k].energy; + if( 0 <= ID && ID < 100 ) { + eC *= MUSICChMap::corr[ch][bd]; + hLeft->Fill(ID, eC); + sum[ID] += eC; + } + if( 100 <= ID && ID < 200 ) { + eC *= MUSICChMap::corr[ch][bd]; + hRight->Fill(ID-100, eC ); + sum[ID-100] += eC ; + } + } + + for( int ch = 0; ch < 17; ch++){ + if( sum[ch] > 0 ) hLR->Fill(ch, sum[ch]); + //printf("%d | sum %d\n", ch, sum[ch]); + } + + } + + hLeft->UpdatePlot(); + hRight->UpdatePlot(); + hMulti->UpdatePlot(); + hLR->UpdatePlot(); + +} + +#endif \ No newline at end of file From 002a10b4e0883328fb102d380ae347314ef35566 Mon Sep 17 00:00:00 2001 From: MUSIC Date: Thu, 1 Aug 2024 16:03:50 -0500 Subject: [PATCH 28/72] bug fix on MUSICAnalyzer.h --- ClassDigitizer.cpp | 2 +- DigiSettingsPanel.cpp | 2 +- MultiBuilder.cpp | 2 ++ Scope.cpp | 2 +- SingleSpectra.cpp | 2 +- analyzers/Analyser.cpp | 2 +- analyzers/EncoreAnalyzer.h | 7 +++--- analyzers/MUSICAnalyzer.h | 44 +++++++++++++++++--------------------- 8 files changed, 31 insertions(+), 32 deletions(-) diff --git a/ClassDigitizer.cpp b/ClassDigitizer.cpp index 8d10f82..ecf7045 100644 --- a/ClassDigitizer.cpp +++ b/ClassDigitizer.cpp @@ -667,7 +667,7 @@ unsigned int Digitizer::CalByteForBufferCAEN(){ uint32_t AllocatedSize; ret = CAEN_DGTZ_MallocReadoutBuffer(handle, &BufferCAEN, &AllocatedSize); - delete BufferCAEN; + if( BufferCAEN) delete BufferCAEN; return AllocatedSize; } diff --git a/DigiSettingsPanel.cpp b/DigiSettingsPanel.cpp index ae95f35..75fbae3 100644 --- a/DigiSettingsPanel.cpp +++ b/DigiSettingsPanel.cpp @@ -269,7 +269,7 @@ DigiSettingsPanel::DigiSettingsPanel(Digitizer ** digi, unsigned int nDigi, QStr // connect(bnSaveSettingsToText, &QPushButton::clicked, this, [=](){ SaveSetting(1);}); //checkBox, to coupled or decouple the setting file. - chkCoupledSettingFile = new QCheckBox("Update Setting", this); + chkCoupledSettingFile = new QCheckBox("Live Setting Update", this); buttonLayout->addWidget(chkCoupledSettingFile, rowID, 2); chkCoupledSettingFile->setCheckState(Qt::CheckState::Unchecked); connect(chkCoupledSettingFile, &QCheckBox::stateChanged, this, [=](int state){ diff --git a/MultiBuilder.cpp b/MultiBuilder.cpp index c7c8228..1b76acc 100644 --- a/MultiBuilder.cpp +++ b/MultiBuilder.cpp @@ -279,6 +279,8 @@ void MultiBuilder::BuildEvents(bool isFinal, bool skipTrace, bool verbose){ if( timeWindow <= 0 ) break; } + if( events[eventIndex].size() == 0 ) continue; + if( events[eventIndex].size() > 1) { std::sort(events[eventIndex].begin(), events[eventIndex].end(), [](const Hit& a, const Hit& b) { return a.timestamp < b.timestamp; diff --git a/Scope.cpp b/Scope.cpp index 18d17f8..c25f1a9 100644 --- a/Scope.cpp +++ b/Scope.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +// #include QVector Scope::TrapezoidFilter(QVector data, int baseLineEndS, int riseTimeS, int flatTopS, float decayTime_ns){ DebugPrint("%s", "Scope"); diff --git a/SingleSpectra.cpp b/SingleSpectra.cpp index 605b5bd..cc2b849 100644 --- a/SingleSpectra.cpp +++ b/SingleSpectra.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +// #include SingleSpectra::SingleSpectra(Digitizer ** digi, unsigned int nDigi, QString rawDataPath, QMainWindow * parent) : QMainWindow(parent){ DebugPrint("%s", "SingleSpectra"); diff --git a/analyzers/Analyser.cpp b/analyzers/Analyser.cpp index 5156c66..9c8d666 100644 --- a/analyzers/Analyser.cpp +++ b/analyzers/Analyser.cpp @@ -98,7 +98,7 @@ void Analyzer::BuildEvents(bool verbose){ if( isBuildBackward ){ mb->BuildEventsBackWard(maxNumEventBuilt, verbose); }else{ - mb->BuildEvents(0, 0, verbose); + mb->BuildEvents(0, true, verbose); } for( unsigned int i = 0; i < nData; i++ ) digiMTX[idList[i]].unlock(); diff --git a/analyzers/EncoreAnalyzer.h b/analyzers/EncoreAnalyzer.h index 79a42b3..ad77632 100644 --- a/analyzers/EncoreAnalyzer.h +++ b/analyzers/EncoreAnalyzer.h @@ -6,7 +6,7 @@ #include #include -#include +// #include namespace EncoreChMap{ @@ -87,11 +87,12 @@ inline void Encore::SetUpCanvas(){ //====== resize window if screen too small QScreen * screen = QGuiApplication::primaryScreen(); QRect screenGeo = screen->geometry(); - if( screenGeo.width() < 1600 || screenGeo.height() < 1600) { + if( screenGeo.width() < 1000 || screenGeo.height() < 1000) { setGeometry(0, 0, screenGeo.width() - 100, screenGeo.height() -100); }else{ - setGeometry(0, 0, 1600, 1600); + setGeometry(0, 0, 1000, 1000); } + // setGeometry(0, 0, 1600, 1600); chkRunAnalyzer = new QCheckBox("Run Analyzer", this); layout->addWidget(chkRunAnalyzer, 0, 0); diff --git a/analyzers/MUSICAnalyzer.h b/analyzers/MUSICAnalyzer.h index b86626a..c1d0913 100644 --- a/analyzers/MUSICAnalyzer.h +++ b/analyzers/MUSICAnalyzer.h @@ -6,7 +6,7 @@ #include #include -#include +// #include namespace MUSICChMap{ @@ -60,7 +60,7 @@ public: SetUpdateTimeInSec(1.0); - 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. + SetBackwardBuild(true, 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(10000); @@ -94,19 +94,20 @@ inline void MUSIC::SetUpCanvas(){ //====== resize window if screen too small QScreen * screen = QGuiApplication::primaryScreen(); QRect screenGeo = screen->geometry(); - if( screenGeo.width() < 1600 || screenGeo.height() < 1600) { + if( screenGeo.width() < 1000 || screenGeo.height() < 1000) { setGeometry(0, 0, screenGeo.width() - 100, screenGeo.height() -100); }else{ - setGeometry(0, 0, 1600, 1600); + setGeometry(0, 0, 1000, 1000); } + // setGeometry(0, 0, 1600, 1600); chkRunAnalyzer = new QCheckBox("Run Analyzer", this); layout->addWidget(chkRunAnalyzer, 0, 0); - hLeft = new Histogram2D("Left", "Ch", "Energy", 17, 0, 16, 200, 0, 20000, this); + hLeft = new Histogram2D("Left", "Ch", "Energy", 16, 0, 16, 200, 0, 200, this); layout->addWidget(hLeft, 1, 0); - hRight = new Histogram2D("Right", "Ch", "Energy", 17, 0, 16, 200, 0, 20000, this); + hRight = new Histogram2D("Right", "Ch", "Energy", 16, 0, 16, 200, 0, 200, this); layout->addWidget(hRight, 1, 1); - hLR = new Histogram2D("Left + Right", "Ch", "Energy", 17, 0, 16, 200, 0, 20000, this); + hLR = new Histogram2D("Left + Right", "Ch", "Energy", 17, 0, 16, 200, 0, 200, this); layout->addWidget(hLR, 2, 0); hMulti = new Histogram1D("Multi", "multiplicity", 40, 0, 40); layout->addWidget(hMulti, 2, 1); @@ -118,9 +119,7 @@ inline void MUSIC::UpdateHistograms(){ if( this->isVisible() == false ) return; if( chkRunAnalyzer->isChecked() == false ) return; - BuildEvents(); // call the event builder to build events - - printf("MUSIC::%s----------- 1\n", __func__); + BuildEvents(false); // call the event builder to build events //============ Get events, and do analysis long eventBuilt = evtbder->eventBuilt; @@ -131,21 +130,19 @@ inline void MUSIC::UpdateHistograms(){ long eventStart = eventIndex - eventBuilt + 1; if(eventStart < 0 ) eventStart += MaxNEvent; - printf("MUSIC::%s----------- 2\n", __func__); + // printf("MUSIC::%s----------- 2 : %ld %ld \n", __func__, eventStart, eventIndex); for( long i = eventStart ; i <= eventIndex; i ++ ){ std::vector event = evtbder->events[i]; - //printf("-------------- %ld\n", i); + // printf("MUSIC::%s----------- %ld, %zu\n", __func__, i, event.size()); hMulti->Fill((int) event.size()); - //if( event.size() < 9 ) return; if( event.size() == 0 ) return; double sum[17] = {0}; for( int k = 0; k < (int) event.size(); k++ ){ - - printf("MUSIC::%s----------- i, k %d, %d\n", __func__, i, k); + + // printf("--- %d\n", k); int bd = MUSICChMap::SN2Bd.at(event[k].sn); - int ch = event[k].ch; int ID = MUSICChMap::mapping[bd][ch]; @@ -153,23 +150,22 @@ inline void MUSIC::UpdateHistograms(){ if( ID < 0 ) continue; double eC = event[k].energy; - if( 0 <= ID && ID < 100 ) { + if( 0 <= ID && ID < 16 ) { eC *= MUSICChMap::corr[ch][bd]; hLeft->Fill(ID, eC); sum[ID] += eC; } - if( 100 <= ID && ID < 200 ) { + if( 16 <= ID && ID < 32 ) { eC *= MUSICChMap::corr[ch][bd]; - hRight->Fill(ID-100, eC ); - sum[ID-100] += eC ; + hRight->Fill(ID-16, eC ); + sum[ID-16] += eC ; } } for( int ch = 0; ch < 17; ch++){ - if( sum[ch] > 0 ) hLR->Fill(ch, sum[ch]); - //printf("%d | sum %d\n", ch, sum[ch]); - } - + if( sum[ch] > 0 ) hLR->Fill(ch, sum[ch]); + //printf("%d | sum %d\n", ch, sum[ch]); + } } hLeft->UpdatePlot(); From 8c9f8df08e992711567b105e2de97f5dd8365221 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Tue, 6 Aug 2024 16:00:33 -0400 Subject: [PATCH 29/72] edited Aux/SplitPolePlotter.C --- Aux/SplitPolePlotter.C | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Aux/SplitPolePlotter.C b/Aux/SplitPolePlotter.C index c279a13..8a20e7d 100644 --- a/Aux/SplitPolePlotter.C +++ b/Aux/SplitPolePlotter.C @@ -152,15 +152,15 @@ void SplitPolePlotter(TChain *tree){ if( t2 < t1 ) printf("entry %lld-%d, timestamp is not in order. %llu, %llu\n", processedEntries, i, t2, t1); if( i == 0 ) t1 = e_t[i]; - if( ch[i] == ChMap::ScinR ) {hit.eSR = e[i]; hit.tSR = e_t[i] + e_f[i]/1000.*4;} - if( ch[i] == ChMap::ScinL ) {hit.eSL = e[i]; hit.tSL = e_t[i] + e_f[i]/1000.*4;} - if( ch[i] == ChMap::dFR ) {hit.eFR = e[i]; hit.tFR = e_t[i] + e_f[i]/1000.*4;} - if( ch[i] == ChMap::dFL ) {hit.eFL = e[i]; hit.tFL = e_t[i] + e_f[i]/1000.*4;} - if( ch[i] == ChMap::dBR ) {hit.eBR = e[i]; hit.tBR = e_t[i] + e_f[i]/1000.*4;} - if( ch[i] == ChMap::dBL ) {hit.eBL = e[i]; hit.tBL = e_t[i] + e_f[i]/1000.*4;} - if( ch[i] == ChMap::Cathode ) {hit.eCath = e[i]; hit.tCath = e_t[i] + e_f[i]/1000.*4;} - if( ch[i] == ChMap::AnodeF ) {hit.eAF = e[i]; hit.tAF = e_t[i] + e_f[i]/1000.*4;} - if( ch[i] == ChMap::AnodeB ) {hit.eAB = e[i]; hit.tAB = e_t[i] + e_f[i]/1000.*4;} + if( ch[i] == ChMap::ScinR ) {hit.eSR = e[i]; hit.tSR = e_t[i] + e_f[i]/1000;} + if( ch[i] == ChMap::ScinL ) {hit.eSL = e[i]; hit.tSL = e_t[i] + e_f[i]/1000;} + if( ch[i] == ChMap::dFR ) {hit.eFR = e[i]; hit.tFR = e_t[i] + e_f[i]/1000;} + if( ch[i] == ChMap::dFL ) {hit.eFL = e[i]; hit.tFL = e_t[i] + e_f[i]/1000;} + if( ch[i] == ChMap::dBR ) {hit.eBR = e[i]; hit.tBR = e_t[i] + e_f[i]/1000;} + if( ch[i] == ChMap::dBL ) {hit.eBL = e[i]; hit.tBL = e_t[i] + e_f[i]/1000;} + if( ch[i] == ChMap::Cathode ) {hit.eCath = e[i]; hit.tCath = e_t[i] + e_f[i]/1000;} + if( ch[i] == ChMap::AnodeF ) {hit.eAF = e[i]; hit.tAF = e_t[i] + e_f[i]/1000;} + if( ch[i] == ChMap::AnodeB ) {hit.eAB = e[i]; hit.tAB = e_t[i] + e_f[i]/1000;} for( int j = i+1; j < sn.GetSize(); j++){ coin->Fill(ch[i], ch[j]); From 6f0cdb22b68971cb26d8654988356f916380512e Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Tue, 6 Aug 2024 16:05:21 -0400 Subject: [PATCH 30/72] update FSUDAQ_Qt6.pro for the MUSICAnalyzer --- .vscode/settings.json | 3 ++- FSUDAQ_Qt6.pro | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 02d2d86..2e0fb90 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -82,6 +82,7 @@ } ], "files.associations": { - "*.C": "cpp" + "*.C": "cpp", + "*.pro": "makefile" } } \ No newline at end of file diff --git a/FSUDAQ_Qt6.pro b/FSUDAQ_Qt6.pro index 9fc186d..11a87db 100644 --- a/FSUDAQ_Qt6.pro +++ b/FSUDAQ_Qt6.pro @@ -11,9 +11,9 @@ QT += core widgets charts printsupport LIBS += -lCAENDigitizer -lcurl #==== for enable GDB debug -#QMAKE_CXXFLAGS += -g -#QMAKE_CXXFLAGS_RELEASE = -O0 -#QMAKE_CFLAGS_RELEASE = -O0 +QMAKE_CXXFLAGS += -g +QMAKE_CXXFLAGS_RELEASE = -O0 +QMAKE_CFLAGS_RELEASE = -O0 # You can make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. @@ -44,6 +44,7 @@ HEADERS += ClassData.h \ analyzers/CoincidentAnalyzer.h \ analyzers/SplitPoleAnalyzer.h \ analyzers/EncoreAnalyzer.h \ + analyzers/MUSICAnalyzer.h \ analyzers/RAISOR.h SOURCES += ClassDigitizer.cpp \ DigiSettingsPanel.cpp \ From 3f24baa0aa0bddc9f458601634eaf01ffe7b52d4 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Tue, 6 Aug 2024 17:28:25 -0400 Subject: [PATCH 31/72] small tune for MultiBuilder.cpp --- Aux/SplitPolePlotter.C | 6 +++--- MultiBuilder.cpp | 22 +++++++++++----------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Aux/SplitPolePlotter.C b/Aux/SplitPolePlotter.C index 8a20e7d..dfa7bab 100644 --- a/Aux/SplitPolePlotter.C +++ b/Aux/SplitPolePlotter.C @@ -190,11 +190,11 @@ void SplitPolePlotter(TChain *tree){ hXavg_Theta->Fill( hit.xAvg, hit.theta); for( int i = 0; i < 400; i++){ - double y = -50 + 100/400.*i; + double z = -50 + 100/400.*i; - double x = (y/42.8625 + 0.5)* ( hit.x2-hit.x1) + hit.x1; + double x = (z/42.8625 + 0.5)* ( hit.x2-hit.x1) + hit.x1; - haha->Fill(x,y); + haha->Fill(x,z); } double ex = hit.Rho2Ex( (hit.xAvg/100 + 0.363) ); diff --git a/MultiBuilder.cpp b/MultiBuilder.cpp index 1b76acc..9907a53 100644 --- a/MultiBuilder.cpp +++ b/MultiBuilder.cpp @@ -105,7 +105,7 @@ void MultiBuilder::FindEarlistTimeAndCh(bool verbose){ for(unsigned int ch = 0; ch < data[i]->GetNChannel(); ch ++){ int index = data[i]->GetDataIndex(ch); - if( ch >= data[i]->GetNChannel() || index < 0 ) { + if( index < 0 ) { nExhaushedCh ++; chExhaused[i][ch] = true; continue; @@ -145,9 +145,9 @@ void MultiBuilder::FindLatestTimeAndCh(bool verbose){ for( int j = 0; j < data[i]->GetNChannel(); j++ ) chExhaused[i][j] = false; - for(unsigned int ch = 0; ch < MaxNChannels; ch ++){ + for(unsigned int ch = 0; ch < data[i]->GetNChannel(); ch ++){ - if( nextIndex[i][ch] < 0 || ch >= data[i]->GetNChannel() || data[i]->GetDataIndex(ch) < 0 ) { + if( nextIndex[i][ch] < 0 || data[i]->GetDataIndex(ch) < 0 ) { nExhaushedCh ++; chExhaused[i][ch] = true; // printf(", exhanshed. %d \n", nExhaushedCh); @@ -211,7 +211,7 @@ void MultiBuilder::FindLatestTimeOfData(bool verbose){ void MultiBuilder::BuildEvents(bool isFinal, bool skipTrace, bool verbose){ DebugPrint("%s", "MultiBuilder"); - FindEarlistTimeAmongLastData(verbose); // give lastest Time, Ch, and Digi + FindEarlistTimeAmongLastData(verbose); // give lastest Time, Ch, and Digi for event building FindEarlistTimeAndCh(verbose); //Give the earliest time, ch, digi if( earlistCh == -1 || nExhaushedCh == nData * MaxNChannels) return; /// no data @@ -225,9 +225,6 @@ void MultiBuilder::BuildEvents(bool isFinal, bool skipTrace, bool verbose){ if( eventIndex >= MaxNEvent ) eventIndex = 0; events[eventIndex].clear(); - eventBuilt ++; - totalEventBuilt ++; - em.Clear(); for( int k = 0; k < nData; k++){ @@ -295,14 +292,17 @@ void MultiBuilder::BuildEvents(bool isFinal, bool skipTrace, bool verbose){ // //if there is a time jump, say, bigger than TimeJump. break if( earlistTime - lastEventTime > timeJump ) { if( verbose ){ - printf("%6lu, %16llu\n", eventIndex, earlistTime); - printf("%5s - %16llu \n", "", lastEventTime); - printf("%5s > %16llu \n", "", timeJump); - printf("!!!!!!!! Time Jump detected stop event building. stop event buinding and get more data.\n"); + printf("!!!!!!!! Time Jump detected stop event building and get more data.\n"); + printf("event index : %6lu, earlist time : %16llu\n", eventIndex, earlistTime); + printf(" %6s last event time : %16llu \n", "", lastEventTime); + printf(" %6s time jump > %16llu \n", "", timeJump); } return; } + eventBuilt ++; + totalEventBuilt ++; + if( verbose ){ printf(">>>>>>>>>>>>>>>>> Event ID : %ld, total built: %ld, multiplicity : %ld\n", eventIndex, totalEventBuilt, events[eventIndex].size()); for( int i = 0; i <(int) events[eventIndex].size(); i++){ From 9af7ff721cb17a7a9374238cdc5ed12709821657 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Tue, 13 Aug 2024 12:45:24 -0400 Subject: [PATCH 32/72] after SPS test --- Aux/EventBuilder.cpp | 10 +++++-- Aux/SplitPolePlotter.C | 32 ++++++++++---------- Aux/fsuReader.h | 20 ++++++++----- Aux/script.C | 26 ++++++++++------- FSUDAQ.cpp | 4 +-- Scope.cpp | 5 ++-- analyzers/SplitPoleAnalyzer.h | 55 ++++++++++++++++++++--------------- analyzers/SplitPoleHit.h | 36 ++++++++++++++--------- 8 files changed, 109 insertions(+), 79 deletions(-) diff --git a/Aux/EventBuilder.cpp b/Aux/EventBuilder.cpp index 8183b1b..012e6ed 100644 --- a/Aux/EventBuilder.cpp +++ b/Aux/EventBuilder.cpp @@ -101,7 +101,8 @@ int main(int argc, char **argv) { for( int i = 1; i < nFile; i++){ FSUReader * readerB = new FSUReader(inFileName[i].Data(), 1, 1); readerB->ScanNumBlock(0,0); - if( readerB->GetOptimumBatchSize() > batchSize ) batchSize = readerB->GetOptimumBatchSize(); + // if( readerB->GetOptimumBatchSize() > batchSize ) batchSize = readerB->GetOptimumBatchSize(); + batchSize = readerB->GetOptimumBatchSize(); totalHitCount += readerB->GetTotalHitCount(); fileInfo = {inFileName[i].Data(), readerB->GetSN() * 1000 + readerB->GetFileOrder(), readerB->GetTotalHitCount()}; @@ -251,8 +252,8 @@ int main(int argc, char **argv) { do{ - if( (long int)(hitList[ig].at(ID[ig]).timestamp - t0) <= timeWindow ){ - events.push_back(hitList[ig].at(ID[ig])); + if( (long int)(hitList[ig][ID[ig]].timestamp - t0) <= timeWindow ){ + events.push_back(hitList[ig][ID[ig]]); ID[ig] ++; }else{ break; @@ -291,6 +292,9 @@ int main(int argc, char **argv) { multi = events.size() ; if( events.size() >= MAX_MULTI ) { printf("\033[31m event %lld has size = %d > MAX_MULTI = %d \033[0m\n", evID, multi, MAX_MULTI); + for( int po = 0 ; po < 10 ; po ++){ + events[po].Print(); + } multi = MAX_MULTI; } if( debug ) printf("=================================== filling data | %u \n", multi); diff --git a/Aux/SplitPolePlotter.C b/Aux/SplitPolePlotter.C index dfa7bab..92f0aed 100644 --- a/Aux/SplitPolePlotter.C +++ b/Aux/SplitPolePlotter.C @@ -20,10 +20,10 @@ namespace ChMap{ const short ScinR = 0; const short ScinL = 1; - const short dFR = 8; - const short dFL = 9; - const short dBR = 10; - const short dBL = 11; + const short dFR = 9; + const short dFL = 8; + const short dBR = 11; + const short dBL = 10; const short Cathode = 7; const short AnodeF = 13; const short AnodeB = 15; @@ -56,8 +56,8 @@ TH1F * hEx; ULong64_t t1, t2; -#define XMIN -20 -#define XMAX 150 +#define XMIN -200 +#define XMAX 200 //^########################################### @@ -83,7 +83,7 @@ void SplitPolePlotter(TChain *tree){ //*====================================================== histograms - PID = new TH2F("hPID", "PID; Scin_X ; AnodeB", 200, 0, 2000, 100, 0, 4000); + PID = new TH2F("hPID", "PID; Scin_X ; AnodeB", 200, 0, 20000, 100, 0, 40000); coin = new TH2F("hCoin", "Coincident ", 16, 0, 16, 16, 0, 16); hMulti = new TH1F("hMulti", "Multiplicity", 16, 0, 16); @@ -93,16 +93,16 @@ void SplitPolePlotter(TChain *tree){ hXavg = new TH1F("hAvg", "Xavg", 600, XMIN, XMAX); hFocal = new TH2F("hFocal", "Front vs Back ", 200, XMIN, XMAX, 200, XMIN, XMAX); - hXavg_Q = new TH2F("hXavg_Q", "Xavg vs Q ", 200, XMIN, XMAX, 200, 0, 5000); - hXavg_Theta = new TH2F("hXavg_Theta", "Xavg vs Theta ", 200, XMIN, XMAX, 200, 2.5, 3); + hXavg_Q = new TH2F("hXavg_Q", "Xavg vs Q ", 200, XMIN, XMAX, 200, 0, 40000); + hXavg_Theta = new TH2F("hXavg_Theta", "Xavg vs Theta ", 200, XMIN, XMAX, 200, 0.5, 2); haha = new TH2F("haha", "", 400, XMIN, XMAX, 400, -50, 50); - hEx = new TH1F("hEx", "Ex; Ex [MeV]; count/100 keV", 250, -5, 20); + hEx = new TH1F("hEx", "Ex; Ex [MeV]; count/100 keV", 250, -5, 5); hit.SetMassTablePath("../analyzers/mass20.txt"); - hit.CalConstants("36S", "d", "p", 80, 12); // 80MeV, 5 deg - hit.CalZoffset(1.41); // 1.41 T + hit.CalConstants("12C", "d", "p", 16, 20); // 80MeV, 5 deg + hit.CalZoffset(0.751); // 1.41 T t1 = 0; t2 = 0; @@ -152,6 +152,8 @@ void SplitPolePlotter(TChain *tree){ if( t2 < t1 ) printf("entry %lld-%d, timestamp is not in order. %llu, %llu\n", processedEntries, i, t2, t1); if( i == 0 ) t1 = e_t[i]; + // if( e[i] == 65535 ) continue; + if( ch[i] == ChMap::ScinR ) {hit.eSR = e[i]; hit.tSR = e_t[i] + e_f[i]/1000;} if( ch[i] == ChMap::ScinL ) {hit.eSL = e[i]; hit.tSL = e_t[i] + e_f[i]/1000;} if( ch[i] == ChMap::dFR ) {hit.eFR = e[i]; hit.tFR = e_t[i] + e_f[i]/1000;} @@ -168,7 +170,7 @@ void SplitPolePlotter(TChain *tree){ } unsigned int dQ = hit.eAB; // delta Q - unsigned int Qt = hit.eSR; // total Q + unsigned int Qt = hit.eSL; // total Q if( Qt > 0 && dQ > 0 ) { PID->Fill(Qt, dQ); @@ -178,9 +180,9 @@ void SplitPolePlotter(TChain *tree){ // if( hit.eCath == 0 ) return kTRUE; // if( hit.eCath > 13000 ) return kTRUE; - hit.CalData(4); + hit.CalData(2); - if( !TMath::IsNaN(hit.x1) || !TMath::IsNaN(hit.x2) ) { + if( (!TMath::IsNaN(hit.x1) || !TMath::IsNaN(hit.x2)) && 1000 < dQ && dQ < 9000) { hFocal->Fill(hit.x1, hit.x2); hF->Fill(hit.x1); hB->Fill(hit.x2); diff --git a/Aux/fsuReader.h b/Aux/fsuReader.h index fcc8450..a264290 100644 --- a/Aux/fsuReader.h +++ b/Aux/fsuReader.h @@ -3,7 +3,7 @@ #include #include -#define DEFAULT_HALFBUFFERSIZE 500000 +#define DEFAULT_HALFBUFFERSIZE 5000000 class FSUReader{ @@ -262,14 +262,16 @@ inline void FSUReader::OpenFile(std::string fileName, uInt dataSize, int verbose std::string token; while (std::getline(iss, token, '_')) { tokens.push_back(token); } - sn = atoi(tokens[2].c_str()); - tick2ns = atoi(tokens[4].c_str()); - order = atoi(tokens[5].c_str()); + short token_size = tokens.size(); + // for( short i = 0; i < token_size; i ++ ) printf("%d | %s\n", i, tokens[i].c_str()); + sn = atoi(tokens[token_size-4].c_str()); + tick2ns = atoi(tokens[token_size-2].c_str()); + order = atoi(tokens[token_size-1].c_str()); DPPType = 0; - if( fileName.find("PHA") != std::string::npos ) DPPType = DPPTypeCode::DPP_PHA_CODE; - if( fileName.find("PSD") != std::string::npos ) DPPType = DPPTypeCode::DPP_PSD_CODE; - if( fileName.find("QDC") != std::string::npos ) DPPType = DPPTypeCode::DPP_QDC_CODE; + if( fileName.find("PHA") != std::string::npos ) { printf("Using PHA decode.\n"); DPPType = DPPTypeCode::DPP_PHA_CODE;} + if( fileName.find("PSD") != std::string::npos ) { printf("Using PSD decode.\n"); DPPType = DPPTypeCode::DPP_PSD_CODE;} + if( fileName.find("QDC") != std::string::npos ) { printf("Using QDC decode.\n"); DPPType = DPPTypeCode::DPP_QDC_CODE;} if( DPPType == 0 ){ fclose(inFile); inFile = nullptr; @@ -365,7 +367,7 @@ inline int FSUReader::ReadNextBlock(bool traceON, int verbose, uShort saveData){ for( int i = start; i < start + data->NumEventsDecoded[ch]; i++ ){ int k = i % data->GetDataSize(); - + temp.sn = sn; temp.ch = ch; temp.energy = data->GetEnergy(ch, k); @@ -381,6 +383,8 @@ inline int FSUReader::ReadNextBlock(bool traceON, int verbose, uShort saveData){ if( temp.trace.size() > 0 ) temp.trace.clear(); } + // temp.Print(); + hit.push_back(temp); } } diff --git a/Aux/script.C b/Aux/script.C index b2572ce..6a0c556 100644 --- a/Aux/script.C +++ b/Aux/script.C @@ -1,27 +1,31 @@ -// #include "fsuReader.h" +#include "fsuReader.h" // #include "../MultiBuilder.cpp" #include "SplitPolePlotter.C" void script(){ - TChain * chain = new TChain("tree"); + TChain * chain = new TChain("tree"); - // chain->Add("data/temp_002_336_1000.root"); - chain->Add("run123_100000.root"); + chain->Add("data/12C_dp_009_3000.root"); +// chain->Add("run13._3000.root"); - SplitPolePlotter(chain); + SplitPolePlotter(chain); //^===================================================== - // FSUReader * reader = new FSUReader("~/ExpData/testing/.fsu", 16); - // Data * data = reader->GetData(); - // data->tick2ns = 4; + // FSUReader * reader = new FSUReader("data/12C_dp_002_19555_PSD_4_000.fsu", 10000, 2); - // reader->ScanNumBlock(); + // reader->ScanNumBlock(1, 0); - // // for( int i = 0; i < 500 ; i++ ) reader->ReadNextBlock(0, 0); + // reader->ReadNextBlock(0, 9); + + // for( int i = 0; i < 10 ; i++ ) reader->ReadNextBlock(0, 9); + + // std::vector hitList = reader->ReadBatch(10, true); + + // for ( int i = 0; i < 10 ; i ++) hitList[i].Print(); // // int ch = 5; // // std::vector tList; @@ -99,4 +103,4 @@ void script(){ // delete mb; // delete reader; -} \ No newline at end of file +} diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index b118ba7..0f34b1b 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -127,7 +127,7 @@ FSUDAQ::FSUDAQ(QWidget *parent) : QMainWindow(parent){ layout->addWidget(leDatabaseName, rowID, 4); chkInflux = new QCheckBox("Enable", this); - chkInflux->setChecked(false); + chkInflux->setChecked(true); layout->addWidget(chkInflux, rowID, 5); rowID ++; @@ -148,7 +148,7 @@ FSUDAQ::FSUDAQ(QWidget *parent) : QMainWindow(parent){ layout->addWidget(leElogName, rowID, 4); chkElog = new QCheckBox("Enable", this); - chkElog->setChecked(false); + chkElog->setChecked(true); layout->addWidget(chkElog, rowID, 5); connect(bnLock, &QPushButton::clicked, this, &FSUDAQ::SetAndLockInfluxElog); diff --git a/Scope.cpp b/Scope.cpp index c25f1a9..d151237 100644 --- a/Scope.cpp +++ b/Scope.cpp @@ -746,7 +746,7 @@ void Scope::SetUpSpinBox(RSpinBox * &sb, QString str, int row, int col, const Re value = uint16_t((1.0 - sb->value()/100.) * 0xFFFF); } - if( para == DPP::PHA::TriggerThreshold ){ + if( para == DPP::PHA::TriggerThreshold || para == DPP::PSD::TriggerThreshold){ value = sb->value(); } @@ -755,7 +755,7 @@ void Scope::SetUpSpinBox(RSpinBox * &sb, QString str, int row, int col, const Re if( digi[ID]->GetDPPType() == DPPTypeCode::DPP_QDC_CODE ){ int grp = ch/8; // convert ch to grp digiMTX[ID].lock(); - digi[ID]->WriteRegister(para, value, grp); + digi[ID]->WriteRegister(para, value, grp); digiMTX[ID].unlock(); }else{ digiMTX[ID].lock(); @@ -1264,6 +1264,7 @@ void Scope::UpdatePanel_PSD(){ UpdateSpinBox(sbShortGate, DPP::PSD::ShortGateWidth); UpdateSpinBox(sbLongGate, DPP::PSD::LongGateWidth); UpdateSpinBox(sbGateOffset, DPP::PSD::GateOffset); + UpdateSpinBox(sbThreshold, DPP::PSD::TriggerThreshold); uint32_t BdCfg = digi[ID]->GetSettingFromMemory(DPP::BoardConfiguration, ch); diff --git a/analyzers/SplitPoleAnalyzer.h b/analyzers/SplitPoleAnalyzer.h index d98a3aa..f1725c5 100644 --- a/analyzers/SplitPoleAnalyzer.h +++ b/analyzers/SplitPoleAnalyzer.h @@ -31,7 +31,7 @@ public: tick2ns = digi[0]->GetTick2ns(); 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(1000); + evtbder->SetTimeWindow(3000); //========== use the influx from the Analyzer influx = new InfluxDB("https://fsunuc.physics.fsu.edu/influx/"); @@ -41,7 +41,7 @@ public: leTarget->setText("12C"); leBeam->setText("d"); leRecoil->setText("p"); - sbBfield->setValue(0.76); + sbBfield->setValue(0.75); sbAngle->setValue(20); sbEnergy->setValue(16); @@ -222,7 +222,7 @@ inline void SplitPole::SetUpCanvas(){ sbEventWin->setSingleStep(100); sbEventWin->setMaximum(1000000); boxLayout->addWidget(sbEventWin, 4, 1); - sbEventWin->setValue(1000); + sbEventWin->setValue(3000); connect(sbEventWin, &RSpinBox::returnPressed, this, [=](){ evtbder->SetTimeWindow(sbEventWin->value()); }); @@ -323,20 +323,20 @@ inline void SplitPole::SetUpCanvas(){ } //============ histograms - hMulti = new Histogram1D("Multiplicity", "", 10, 0, 10, this); + hMulti = new Histogram1D("Multiplicity", "", 16, 0, 16, this); layout->addWidget(hMulti, 0, 1); // the "this" make the histogram a child of the SplitPole class. When SplitPole destory, all childs destory as well. - hPID = new Histogram2D("Split Pole PID", "Scin-L", "Anode-Font", 100, 0, 5000, 100, 0, 5000, this); + hPID = new Histogram2D("Split Pole PID", "Scin-L", "Anode-Back", 100, 0, 20000, 100, 0, 40000, this); //layout is inheriatge from Analyzer layout->addWidget(hPID, 1, 0, 2, 1); - h1 = new Histogram1D("Spectrum", "x", 300, 30, 70, this); + h1 = new Histogram1D("Spectrum", "x1", 300, -200, 200, this); h1->SetColor(Qt::darkGreen); //h1->AddDataList("Test", Qt::red); // add another histogram in h1, Max Data List is 10 layout->addWidget(h1, 1, 1); - h1g = new Histogram1D("Spectrum (PID gated)", "Ex", 300, -2, 10, this); + h1g = new Histogram1D("Spectrum (PID gated)", "x1", 300, -200, 200, this); layout->addWidget(h1g, 2, 1); layout->setColumnStretch(0, 1); @@ -378,28 +378,32 @@ inline void SplitPole::UpdateHistograms(){ for( int k = 0; k < (int) event.size(); k++ ){ //event[k].Print(); - if( event[k].ch == SPS::ChMap::ScinR ) {hit.eSR = event[k].energy; hit.tSR = event[k].timestamp;} - if( event[k].ch == SPS::ChMap::ScinL ) {hit.eSL = event[k].energy; hit.tSL = event[k].timestamp;} - if( event[k].ch == SPS::ChMap::dFR ) {hit.eFR = event[k].energy; hit.tFR = event[k].timestamp;} - if( event[k].ch == SPS::ChMap::dFL ) {hit.eFL = event[k].energy; hit.tFL = event[k].timestamp;} - if( event[k].ch == SPS::ChMap::dBR ) {hit.eBL = event[k].energy; hit.tBL = event[k].timestamp;} - if( event[k].ch == SPS::ChMap::dBL ) {hit.eBL = event[k].energy; hit.tBL = event[k].timestamp;} - if( event[k].ch == SPS::ChMap::Cathode ) {hit.eCath = event[k].energy; hit.tCath = event[k].timestamp;} - if( event[k].ch == SPS::ChMap::AnodeF ) {hit.eAF = event[k].energy; hit.tAF = event[k].timestamp;} - if( event[k].ch == SPS::ChMap::AnodeB ) {hit.eAB = event[k].energy; hit.tAB = event[k].timestamp;} + if( event[k].ch == SPS::ChMap::ScinR ) {hit.eSR = event[k].energy; hit.tSR = event[k].timestamp + event[k].fineTime/1000.;} + if( event[k].ch == SPS::ChMap::ScinL ) {hit.eSL = event[k].energy; hit.tSL = event[k].timestamp + event[k].fineTime/1000.;} + if( event[k].ch == SPS::ChMap::dFR ) {hit.eFR = event[k].energy; hit.tFR = event[k].timestamp + event[k].fineTime/1000.;} + if( event[k].ch == SPS::ChMap::dFL ) {hit.eFL = event[k].energy; hit.tFL = event[k].timestamp + event[k].fineTime/1000.;} + if( event[k].ch == SPS::ChMap::dBR ) {hit.eBL = event[k].energy; hit.tBL = event[k].timestamp + event[k].fineTime/1000.;} + if( event[k].ch == SPS::ChMap::dBL ) {hit.eBL = event[k].energy; hit.tBL = event[k].timestamp + event[k].fineTime/1000.;} + if( event[k].ch == SPS::ChMap::Cathode ) {hit.eCath = event[k].energy; hit.tCath = event[k].timestamp + event[k].fineTime/1000.;} + if( event[k].ch == SPS::ChMap::AnodeF ) {hit.eAF = event[k].energy; hit.tAF = event[k].timestamp + event[k].fineTime/1000.;} + if( event[k].ch == SPS::ChMap::AnodeB ) {hit.eAB = event[k].energy; hit.tAB = event[k].timestamp + event[k].fineTime/1000.;} } hit.CalData(); double pidX = hit.eSL; unsigned long long tPidX = hit.tSL; - double pidY = hit.eAF; + double pidY = hit.eAB; - hPID->Fill(pidX, pidY); // x, y - - h1->Fill(hit.xAvg); + if( pidX > 0 && pidY > 0 ){ + hPID->Fill(pidX, pidY); // x, y + } + if( !std::isnan(hit.x1) ) { + h1->Fill(hit.x1); + } //h1->Fill(hit.eSR, 1); + //check events inside any Graphical cut and extract the rate, using tSR only for(int p = 0; p < cutList.count(); p++ ){ if( cutList[p].isEmpty() ) continue; @@ -408,10 +412,13 @@ inline void SplitPole::UpdateHistograms(){ if( tPidX > tMax[p] ) tMax[p] = tPidX; count[p] ++; //printf(".... %d \n", count[p]); - if( p == 0 ) { - double xAvg = hit.xAvg * 10; - double xAvgC = xAvg * sbRhoScale->value() + sbRhoOffset->value(); - h1g->Fill(hit.Rho2Ex(xAvgC/1000.)); + // if( p == 0 ) { + // double xAvg = hit.xAvg * 10; + // double xAvgC = xAvg * sbRhoScale->value() + sbRhoOffset->value(); + // h1g->Fill(hit.Rho2Ex(xAvgC/1000.)); + // } + if( p == 0 ){ + h1g->Fill(hit.x1); } } } diff --git a/analyzers/SplitPoleHit.h b/analyzers/SplitPoleHit.h index 90f6d93..23f048a 100644 --- a/analyzers/SplitPoleHit.h +++ b/analyzers/SplitPoleHit.h @@ -39,10 +39,10 @@ namespace SPS{ const short ScinL = 1; const short dFR = 9; const short dFL = 8; - const short dBR = 10; - const short dBL = 11; + const short dBR = 11; + const short dBL = 10; const short Cathode = 7; - const short AnodeF = 12; + const short AnodeF = 13; const short AnodeB = 15; }; @@ -64,19 +64,19 @@ public: ClearData(); } - unsigned int eSR; unsigned long long tSR; - unsigned int eSL; unsigned long long tSL; - unsigned int eFR; unsigned long long tFR; - unsigned int eFL; unsigned long long tFL; - unsigned int eBR; unsigned long long tBR; - unsigned int eBL; unsigned long long tBL; + unsigned int eSR; unsigned long long tSR; + unsigned int eSL; unsigned long long tSL; + unsigned int eFR; unsigned long long tFR; + unsigned int eFL; unsigned long long tFL; + unsigned int eBR; unsigned long long tBR; + unsigned int eBL; unsigned long long tBL; unsigned int eCath; unsigned long long tCath; - unsigned int eAF; unsigned long long tAF; - unsigned int eAB; unsigned long long tAB; + unsigned int eAF; unsigned long long tAF; + unsigned int eAB; unsigned long long tAB; float eSAvg; float x1, x2, theta; - float xAvg; + double xAvg; double GetQ0() const {return Q0;} double GetRho0() const {return rho0;} @@ -200,8 +200,16 @@ public: if( eSR > 0 && eSL == 0 ) eSAvg = eSR; if( eSR == 0 && eSL > 0 ) eSAvg = eSL; - if( tFR > 0 && tFL > 0 ) x1 = (tFL - tFR)/scale/2.1; - if( tBR > 0 && tBL > 0 ) x2 = (tBL - tBR)/scale/1.98; + if( tFR > 0 && tFL > 0 ) { + if( tFL > tFR) x1 = (tFL - tFR)/scale/2.1; + if( tFL < tFR) x1 = (tFR - tFL)/scale/-2.1; + } + if( tBR > 0 && tBL > 0 ) { + if( tBL > tBR) x2 = (tBL - tBR)/scale/1.98; + if( tBR > tBL) x2 = (tBR - tBL)/scale/-1.98; + } + + // printf("x1: %f, x2 : %f \n", x1, x2); if( !std::isnan(x1) && !std::isnan(x2)) { From f65a6f9ef5a0043939b3a991bddf7510db04818d Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Wed, 14 Aug 2024 13:46:52 -0400 Subject: [PATCH 33/72] EventBuilder only output root file, and FSU2CAEN output CoMPASS BIN. the CoMPASS BIN can be converted to root using other repository --- .gitignore | 5 ++ .vscode/settings.json | 3 +- Aux/EventBuilder.cpp | 104 ++++++++++--------------------- Aux/FSU2CAEN.cpp | 137 ++++++++++++++++++++++++++++------------- Aux/SplitPolePlotter.C | 71 +++++++++++++-------- Aux/fsuReader.h | 3 + Aux/script.C | 12 +++- 7 files changed, 193 insertions(+), 142 deletions(-) diff --git a/.gitignore b/.gitignore index bd65ea5..91497de 100644 --- a/.gitignore +++ b/.gitignore @@ -21,14 +21,19 @@ DumpFSU2ROOT SettingsExplorer AggSeparator FSU2CAEN +Bin2Root data Data +raw_binary *.d *.pcm *.txt +*.tar +*.tar.gz +*.BIN *~ *.autosave diff --git a/.vscode/settings.json b/.vscode/settings.json index 2e0fb90..1f9a97d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -83,6 +83,7 @@ ], "files.associations": { "*.C": "cpp", - "*.pro": "makefile" + "*.pro": "makefile", + "regex": "cpp" } } \ No newline at end of file diff --git a/Aux/EventBuilder.cpp b/Aux/EventBuilder.cpp index 012e6ed..8265098 100644 --- a/Aux/EventBuilder.cpp +++ b/Aux/EventBuilder.cpp @@ -20,7 +20,7 @@ struct FileInfo{ }; -#define NMINARG 5 +#define NMINARG 4 #define debug 0 //^############################################################# @@ -32,14 +32,13 @@ int main(int argc, char **argv) { printf("=========================================\n"); if (argc < NMINARG) { printf("Incorrect number of arguments:\n"); - printf("%s [timeWindow] [withTrace] [format] [inFile1] [inFile2] .... \n", argv[0]); + printf("%s [timeWindow] [withTrace] [inFile1] [inFile2] .... \n", argv[0]); printf(" timeWindow : in ns, -1 = no event building \n"); printf(" withTrace : 0 for no trace, 1 for trace \n"); - printf(" format : 0 for root, 1 for CoMPASS binary \n"); printf(" Output file name is contructed from inFile1 \n"); printf("\n"); - printf(" Example: %s -1 0 0 '\\ls -1 *001*.fsu' (no event build, no trace, no verbose)\n", argv[0]); - printf(" %s 100 0 0 '\\ls -1 *001*.fsu' (event build with 100 ns, no trace, no verbose)\n", argv[0]); + printf(" Example: %s -1 0 '\\ls -1 *001*.fsu' (no event build, no trace, no verbose)\n", argv[0]); + printf(" %s 100 0 '\\ls -1 *001*.fsu' (event build with 100 ns, no trace, no verbose)\n", argv[0]); printf("\n\n"); return 1; @@ -51,7 +50,7 @@ int main(int argc, char **argv) { long timeWindow = atoi(argv[1]); bool traceOn = atoi(argv[2]); // unsigned int debug = atoi(argv[3]); - unsigned short format = atoi(argv[3]); + // unsigned short format = atoi(argv[3]); unsigned int batchSize = 2* DEFAULT_HALFBUFFERSIZE; int nFile = argc - NMINARG + 1; TString inFileName[nFile]; @@ -67,13 +66,9 @@ int main(int argc, char **argv) { outFileName += "_" + ( timeWindow >= 0 ? std::to_string(timeWindow) : "single"); TString outFileFullName; - if( format == 0 ){ - outFileFullName = outFileName + ".root"; - }else{ - outFileFullName = outFileName + ".bin"; - } + outFileFullName = outFileName + ".root"; - uint16_t header = 0; // for caen bin + // uint16_t header = 0; // for caen bin printf("-------> Out file name : %s \n", outFileFullName.Data()); printf("========================================= Number of Files : %d \n", nFile); @@ -148,37 +143,26 @@ int main(int argc, char **argv) { unsigned short traceLength[MAX_MULTI]; short trace[MAX_MULTI][MAX_TRACE_LENGTH]; - FILE * caen = nullptr; + // //*====================================== create tree + outRootFile = new TFile(outFileFullName, "recreate"); + tree = new TTree("tree", outFileFullName); - if( format == 0 ){ - // //*====================================== create tree - outRootFile = new TFile(outFileFullName, "recreate"); - tree = new TTree("tree", outFileFullName); - - tree->Branch("evID", &evID, "event_ID/l"); - tree->Branch("multi", &multi, "multi/i"); - tree->Branch("sn", sn, "sn[multi]/s"); - tree->Branch("ch", ch, "ch[multi]/s"); - tree->Branch("e", e, "e[multi]/s"); - tree->Branch("e2", e2, "e2[multi]/s"); - tree->Branch("e_t", e_t, "e_t[multi]/l"); - tree->Branch("e_f", e_f, "e_f[multi]/s"); - tree->Branch("traceLength", traceLength, "traceLength[multi]/s"); - - if( traceOn ) { - tree->Branch("trace", trace,"trace[multi][MAX_TRACE_LENGTH]/S"); - tree->GetBranch("trace")->SetCompressionSettings(205); - } - }else{ - - caen = fopen(outFileFullName.Data(), "wb"); - if( caen == nullptr ){ - perror("Failed to open file"); - return -1; - } + tree->Branch("evID", &evID, "event_ID/l"); + tree->Branch("multi", &multi, "multi/i"); + tree->Branch("sn", sn, "sn[multi]/s"); + tree->Branch("ch", ch, "ch[multi]/s"); + tree->Branch("e", e, "e[multi]/s"); + tree->Branch("e2", e2, "e2[multi]/s"); + tree->Branch("e_t", e_t, "e_t[multi]/l"); + tree->Branch("e_f", e_f, "e_f[multi]/s"); + tree->Branch("traceLength", traceLength, "traceLength[multi]/s"); + if( traceOn ) { + tree->Branch("trace", trace,"trace[multi][MAX_TRACE_LENGTH]/S"); + tree->GetBranch("trace")->SetCompressionSettings(205); } + //*======================================= Open files printf("========================================= Open files & Build Events.\n"); @@ -322,27 +306,10 @@ int main(int argc, char **argv) { } } - if( format == 0 ){ - outRootFile->cd(); - tree->Fill(); - // tree->Write(); - }else{ - if( caen ) { - - if( header == 0 ){ - header = 0xCAE1; // default to have the energy only - if( events[0].energy2 > 0 ) header += 0x4; - if( events[0].traceLength > 0 && traceOn ) header += 0x8; - size_t dummy = fwrite(&header, 2, 1, caen); - if( dummy != 1 ) printf("file write error.\n"); - } - - for( size_t gg = 0; gg < events.size(); gg++ ){ - events[gg].WriteHitsToCAENBinary(caen, header); - } - } - } - + outRootFile->cd(); + tree->Fill(); + // tree->Write(); + multi = 0; evID ++; @@ -377,7 +344,7 @@ int main(int argc, char **argv) { }while( nFileFinished < nGroup); - if( format == 0 ) tree->Write(); + tree->Write(); uInt runEndTime = getTime_us(); double runTime = (runEndTime - runStartTime) * 1e-6; @@ -391,15 +358,12 @@ int main(int argc, char **argv) { printf(" total data duration = %.2f sec = %.2f min\n", tDuration_sec, tDuration_sec/60.); printf("========================================> saved to %s \n", outFileFullName.Data()); - if( format == 0 ){ - TMacro info; - info.AddLine(Form("tStart= %20llu ns",tStart)); - info.AddLine(Form(" tEnd= %20llu ns",tEnd)); - info.Write("info"); - outRootFile->Close(); - }else{ - fclose(caen); - } + TMacro info; + info.AddLine(Form("tStart= %20llu ns",tStart)); + info.AddLine(Form(" tEnd= %20llu ns",tEnd)); + info.Write("info"); + outRootFile->Close(); + for( int i = 0; i < nGroup; i++) delete reader[i]; delete [] reader; diff --git a/Aux/FSU2CAEN.cpp b/Aux/FSU2CAEN.cpp index f4a9fba..672e1a1 100644 --- a/Aux/FSU2CAEN.cpp +++ b/Aux/FSU2CAEN.cpp @@ -4,6 +4,9 @@ struct FileInfo{ std::string fileName; int fileevID; unsigned long hitCount; + int sn; + int numCh; + int runNum; }; #define minNARG 3 @@ -14,14 +17,13 @@ int main(int argc, char **argv) { printf("=========================================\n"); printf("=== *.fsu to CoMPASS bin ===\n"); - printf("=== no trace, no flags ===\n"); printf("=========================================\n"); if (argc < minNARG) { printf("Incorrect number of arguments:\n"); printf("%s [tar] [inFile1] [inFile2] .... \n", argv[0]); printf(" tar : output tar, 0 = no, 1 = yes \n"); printf("\n"); - printf(" Example: %s '\\ls 0 *001*.fsu'\n", argv[0]); + printf(" Example: %s 0 '\\ls -1 *001*.fsu'\n", argv[0]); printf("\n\n"); return 1; @@ -29,8 +31,6 @@ int main(int argc, char **argv) { unsigned int debug = false; uInt runStartTime = getTime_us(); - unsigned short header = 0xCAE1; - unsigned int flags = 0; ///============= read input // long timeWindow = atoi(argv[1]); @@ -41,19 +41,11 @@ int main(int argc, char **argv) { std::string inFileName[nFile]; for( int i = 0 ; i < nFile ; i++){ inFileName[i] = argv[i+ minNARG - 1];} - - std::string temp = inFileName[0]; - size_t pos = temp.find('_'); - pos = temp.find('_', pos + 1); - std::string outFile_prefix = temp.substr(0, pos); - std::string outFileName = outFile_prefix + ".BIN"; - - printf("========================================= Number of Files : %d \n", nFile); for( int i = 0; i < nFile; i++) printf("%2d | %s \n", i, inFileName[i].c_str()); printf("=========================================\n"); printf(" Batch size = %d events/file\n", batchSize); - printf(" Out file name = %s \n", outFileName.c_str()); + // printf(" Out file name = %s \n", outFileName.c_str()); printf(" Is tar output = %s \n", tarFlag ? "Yes" : "No"); printf("========================================= Grouping files\n"); @@ -65,7 +57,7 @@ int main(int argc, char **argv) { FSUReader * readerA = new FSUReader(inFileName[0], 1, 1); readerA->ScanNumBlock(0,0); if( readerA->GetOptimumBatchSize() > batchSize ) batchSize = readerA->GetOptimumBatchSize(); - FileInfo fileInfo = {inFileName[0], readerA->GetSN() * 1000 + readerA->GetFileOrder(), readerA->GetTotalHitCount()}; + FileInfo fileInfo = {inFileName[0], readerA->GetSN() * 1000 + readerA->GetFileOrder(), readerA->GetTotalHitCount(), readerA->GetSN(), readerA->GetNumCh(), readerA->GetRunNum()}; fileList.push_back(fileInfo); totalHitCount += readerA->GetTotalHitCount(); @@ -75,7 +67,7 @@ int main(int argc, char **argv) { if( readerB->GetOptimumBatchSize() > batchSize ) batchSize = readerB->GetOptimumBatchSize(); totalHitCount += readerB->GetTotalHitCount(); - fileInfo = {inFileName[i], readerB->GetSN() * 1000 + readerB->GetFileOrder(), readerB->GetTotalHitCount()}; + fileInfo = {inFileName[i], readerB->GetSN() * 1000 + readerB->GetFileOrder(), readerB->GetTotalHitCount(), readerB->GetSN(), readerB->GetNumCh(), readerB->GetRunNum()}; if( readerA->GetSN() == readerB->GetSN() ){ fileList.push_back(fileInfo); @@ -107,6 +99,34 @@ int main(int argc, char **argv) { } + //*====================================== format output files + + const short numFileGroup = fileGroupList.size(); + + FILE ** outFile[numFileGroup]; + + std::vector outFileName[numFileGroup]; + std::vector header[numFileGroup]; + std::vector flags[numFileGroup]; + + for( int i = 0; i < numFileGroup; i++ ){ + outFile[i] = new FILE * [fileGroupList[i][0].numCh]; + for( int ch = 0; ch < fileGroupList[i][0].numCh; ch++ ){ + std::string dudu = "Data_CH" + std::to_string(ch) + "@DIGI_" + std::to_string(fileGroupList[i][0].sn) + "_run_" + std::to_string(fileGroupList[i][0].runNum) + ".BIN"; + // printf("|%s| \n", dudu.c_str()); + outFile[i][ch] = fopen(dudu.c_str(), "wb"); + outFileName[i].push_back(dudu); + header[i].push_back(0); + flags[i].push_back(0); + } + } + + // std::string temp = inFileName[0]; + // size_t pos = temp.find('_'); + // pos = temp.find('_', pos + 1); + // std::string outFile_prefix = temp.substr(0, pos); + // std::string outFileName = outFile_prefix + ".BIN"; + //*======================================= Open files printf("========================================= Open files & Build Events.\n"); @@ -142,8 +162,6 @@ int main(int argc, char **argv) { int nFileFinished = 0; unsigned long long hitProcessed = 0; - FILE * outFile = fopen(outFileName.c_str(), "wb"); - do{ // find the earlist time @@ -167,29 +185,38 @@ int main(int argc, char **argv) { } - if( hitList[g0][evID[g0]].energy2 > 0 ) header += 4; - if( hitList[g0][evID[g0]].traceLength > 0 ) header += 8; - if( hitList[g0][evID[g0]].pileUp ) flags += 0x8000; - if( hitList[g0][evID[g0]].fineTime > 0 ) flags += 0x4000; + // Set file header + int p_ch = hitList[g0][evID[g0]].ch; // present ch - fwrite(&(header), 2, 1, outFile); - fwrite(&(hitList[g0][evID[g0]].sn), 2, 1, outFile); - fwrite(&(hitList[g0][evID[g0]].ch), 2, 1, outFile); - unsigned psTimestamp = hitList[g0][evID[g0]].timestamp * 1000 + hitList[g0][evID[g0]].fineTime; - fwrite(&(psTimestamp), 8, 1, outFile); - fwrite(&(hitList[g0][evID[g0]].energy), 2, 1, outFile); - if( hitList[g0][evID[g0]].energy2 > 0 ) fwrite(&(hitList[g0][evID[g0]].energy2), 2, 1, outFile); - fwrite(&(flags), 4, 1, outFile); - if( hitList[g0][evID[g0]].traceLength > 0 ){ - char waveCode = 1; - fwrite(&(waveCode), 1, 1, outFile); - fwrite(&(hitList[g0][evID[g0]].traceLength), 4, 1, outFile); + if( header[g0][p_ch] == 0 ) { + header[g0][p_ch] = 0xCAE1; + if( hitList[g0][evID[g0]].energy2 > 0 ) header[g0][p_ch] += 4; + if( hitList[g0][evID[g0]].traceLength > 0 ) header[g0][p_ch] += 8; + if( hitList[g0][evID[g0]].pileUp ) flags[g0][p_ch] += 0x8000; + if( hitList[g0][evID[g0]].fineTime > 0 ) flags[g0][p_ch] += 0x4000; - for( int i = 0; i < hitList[g0][evID[g0]].traceLength; i++ ){ - fwrite(&(hitList[g0][evID[g0]].trace[i]), 2, 1, outFile); - } + fwrite(&(header[g0][p_ch]), 2, 1, outFile[g0][p_ch]); } + hitList[g0][evID[g0]].WriteHitsToCAENBinary(outFile[g0][p_ch], header[g0][p_ch]); + + // fwrite(&(hitList[g0][evID[g0]].sn), 2, 1, outFile); + // fwrite(&(hitList[g0][evID[g0]].ch), 2, 1, outFile); + // unsigned psTimestamp = hitList[g0][evID[g0]].timestamp * 1000 + hitList[g0][evID[g0]].fineTime; + // fwrite(&(psTimestamp), 8, 1, outFile); + // fwrite(&(hitList[g0][evID[g0]].energy), 2, 1, outFile); + // if( hitList[g0][evID[g0]].energy2 > 0 ) fwrite(&(hitList[g0][evID[g0]].energy2), 2, 1, outFile); + // fwrite(&(flags), 4, 1, outFile); + // if( hitList[g0][evID[g0]].traceLength > 0 ){ + // char waveCode = 1; + // fwrite(&(waveCode), 1, 1, outFile); + // fwrite(&(hitList[g0][evID[g0]].traceLength), 4, 1, outFile); + + // for( int i = 0; i < hitList[g0][evID[g0]].traceLength; i++ ){ + // fwrite(&(hitList[g0][evID[g0]].trace[i]), 2, 1, outFile); + // } + // } + evID[g0]++; if( hitProcessed == 0) tStart = hitList[g0][evID[g0]].timestamp; hitProcessed ++; @@ -224,21 +251,47 @@ int main(int argc, char **argv) { printf(" first timestamp = %20llu ns\n", tStart); printf(" last timestamp = %20llu ns\n", tEnd); printf(" total data duration = %.2f sec = %.2f min\n", tDuration_sec, tDuration_sec/60.); - printf("==============> saved to %s \n", outFileName.c_str()); for( int i = 0; i < nGroup; i++) delete reader[i]; delete [] reader; - if( tarFlag ){ - std::string tarFileName = outFile_prefix + ".tar"; + //============================== delete empty files and close FILE + std::vector nonEmptyFileList; - std::string command = "tar -cvf " + tarFileName + " " + outFileName; + printf("================= Removing Empty Files ....\n"); + printf("============================> saved to ...."); + + if( tarFlag == false ) printf("\n"); + + for( int i = 0; i < numFileGroup; i++ ){ + for( int ch = 0; ch < fileGroupList[i][0].numCh; ch++){ + if( ftell(outFile[i][ch]) == 0 ){ + int dummy = std::system(("rm -f " + outFileName[i][ch]).c_str()); + // printf("Remove %s.\n", outFileName[i][ch].c_str()); + }else{ + nonEmptyFileList.push_back(outFileName[i][ch]); + if( tarFlag == false ) printf("%s\n", outFileName[i][ch].c_str()); + } + } + } + + if( tarFlag ){ + std::string tarFileName = "run_" + std::to_string(fileGroupList[0][0].runNum) + ".tar.gz"; + + printf("%s\n", tarFileName.c_str()); + printf("============================> tar.gz the BIN\n"); + std::string command = "tar -czf " + tarFileName + " "; + for( size_t i = 0; i < nonEmptyFileList.size(); i++ ){ + command += nonEmptyFileList[i] + " "; + } int result = std::system(command.c_str()); if (result == 0) { printf("Archive created successfully: %s\n", tarFileName.c_str()); - std::system(("rm -f " + outFileName).c_str()); - printf("Remove %s.\n", outFileName.c_str()); + for( size_t i = 0; i < nonEmptyFileList.size(); i++ ){ + int dummy = std::system(("rm -f " + nonEmptyFileList[i]).c_str()); + // printf("Remove %s.\n", nonEmptyFileList[i].c_str()); + } } else { printf("Error creating archive\n"); } diff --git a/Aux/SplitPolePlotter.C b/Aux/SplitPolePlotter.C index 92f0aed..f538d1d 100644 --- a/Aux/SplitPolePlotter.C +++ b/Aux/SplitPolePlotter.C @@ -6,6 +6,7 @@ #include "TTreeReaderArray.h" #include "TClonesArray.h" #include "TGraph.h" +#include "TCutG.h" #include "TH2.h" #include "TCanvas.h" #include "TStyle.h" @@ -50,10 +51,11 @@ TH2F * hFocal; TH2F * hXavg_Q; TH2F * hXavg_Theta; -TH2F * haha; - +TH2F * hRay; TH1F * hEx; +TH2F * hEx_Multi; + ULong64_t t1, t2; #define XMIN -200 @@ -61,7 +63,7 @@ ULong64_t t1, t2; //^########################################### -void SplitPolePlotter(TChain *tree){ +void SplitPolePlotter(TChain *tree, TCutG * pidCut = nullptr, double rhoOffset = 0, double rhoScaling = 1, bool isFSUDAQ = true){ printf("#####################################################################\n"); printf("################# SplitPolePlotter.C ####################\n"); @@ -83,26 +85,34 @@ void SplitPolePlotter(TChain *tree){ //*====================================================== histograms - PID = new TH2F("hPID", "PID; Scin_X ; AnodeB", 200, 0, 20000, 100, 0, 40000); coin = new TH2F("hCoin", "Coincident ", 16, 0, 16, 16, 0, 16); - hMulti = new TH1F("hMulti", "Multiplicity", 16, 0, 16); + if( isFSUDAQ ){ + PID = new TH2F("hPID", "PID; Scin_X ; AnodeB", 200, 0, 20000, 100, 0, 40000); + hXavg_Q = new TH2F("hXavg_Q", "Xavg vs Q ", 200, XMIN, XMAX, 200, 0, 40000); + }else{ + PID = new TH2F("hPID", "PID; Scin_X ; AnodeB", 200, 0, 4000, 100, 0, 5000); + hXavg_Q = new TH2F("hXavg_Q", "Xavg vs Q ", 200, XMIN, XMAX, 200, 0, 5000); + } + + hF = new TH1F("hF", "Front delay line position", 600, XMIN, XMAX); hB = new TH1F("hB", "Back delay line position", 600, XMIN, XMAX); hXavg = new TH1F("hAvg", "Xavg", 600, XMIN, XMAX); hFocal = new TH2F("hFocal", "Front vs Back ", 200, XMIN, XMAX, 200, XMIN, XMAX); - hXavg_Q = new TH2F("hXavg_Q", "Xavg vs Q ", 200, XMIN, XMAX, 200, 0, 40000); - hXavg_Theta = new TH2F("hXavg_Theta", "Xavg vs Theta ", 200, XMIN, XMAX, 200, 0.5, 2); + hXavg_Theta = new TH2F("hXavg_Theta", "Xavg vs Theta ", 200, XMIN, XMAX, 200, 0.5, 1.4); - haha = new TH2F("haha", "", 400, XMIN, XMAX, 400, -50, 50); + hRay = new TH2F("hRay", "Ray plot", 400, XMIN, XMAX, 400, -50, 50); - hEx = new TH1F("hEx", "Ex; Ex [MeV]; count/100 keV", 250, -5, 5); + hEx = new TH1F("hEx", "Ex; Ex [MeV]; count/10 keV", 600, -1, 5); + + hEx_Multi = new TH2F("hEx_Multi", "Ex vs Multi; Ex; Multi", 600, -1, 5, 16, 0, 16); hit.SetMassTablePath("../analyzers/mass20.txt"); - hit.CalConstants("12C", "d", "p", 16, 20); // 80MeV, 5 deg - hit.CalZoffset(0.751); // 1.41 T + hit.CalConstants("12C", "d", "p", 16, 18); // 80MeV, 5 deg + hit.CalZoffset(0.750); // 1.41 T t1 = 0; t2 = 0; @@ -142,11 +152,11 @@ void SplitPolePlotter(TChain *tree){ // } hit.ClearData(); - hMulti->Fill(sn.GetSize()); + hMulti->Fill(*multi); - // if( multi.Get()[0] != 9 ) continue; + // if( *multi != 9 ) continue; - for( int i = 0; i < sn.GetSize(); i++){ + for( int i = 0; i < *multi; i++){ t2 = e_t[i]; if( t2 < t1 ) printf("entry %lld-%d, timestamp is not in order. %llu, %llu\n", processedEntries, i, t2, t1); @@ -176,13 +186,16 @@ void SplitPolePlotter(TChain *tree){ PID->Fill(Qt, dQ); } - // if( hit.eAF < 50000 ) return kTRUE; - // if( hit.eCath == 0 ) return kTRUE; - // if( hit.eCath > 13000 ) return kTRUE; + //=============== PID gate cut + if( pidCut ){ + if( !pidCut->IsInside(Qt, dQ) ) continue; + } hit.CalData(2); - if( (!TMath::IsNaN(hit.x1) || !TMath::IsNaN(hit.x2)) && 1000 < dQ && dQ < 9000) { + if( hit.theta > 1.2 || 0.5 > hit.theta ) continue; + + if( (!TMath::IsNaN(hit.x1) || !TMath::IsNaN(hit.x2)) ) { hFocal->Fill(hit.x1, hit.x2); hF->Fill(hit.x1); hB->Fill(hit.x2); @@ -196,12 +209,14 @@ void SplitPolePlotter(TChain *tree){ double x = (z/42.8625 + 0.5)* ( hit.x2-hit.x1) + hit.x1; - haha->Fill(x,z); + hRay->Fill(x,z); } - double ex = hit.Rho2Ex( (hit.xAvg/100 + 0.363) ); + double ex = hit.Rho2Ex( ((hit.xAvg - rhoOffset)/1000/rhoScaling + hit.GetRho0() ) ); //if( XMIN < hit.xAvg && hit.xAvg < XMAX) printf("x1 : %6.2f, x2 : %6.2f, xAvg %6.2f cm , ex : %f \n", hit.x1, hit.x2, hit.xAvg, ex); hEx->Fill(ex); + + hEx_Multi->Fill(ex, *multi); } //*============================================ Progress Bar @@ -222,15 +237,18 @@ void SplitPolePlotter(TChain *tree){ //^########################################################### //^ * Plot //^########################################################### - TCanvas * canvas = new TCanvas("cc", "Split-Pole", 1600, 1200); + TCanvas * canvas = new TCanvas("cc", "Split-Pole", 2500, 1000); gStyle->SetOptStat("neiou"); - canvas->Divide(4, 3); + canvas->Divide(5, 2); - canvas->cd(1); PID->Draw("colz"); - //canvas->cd(2); coin->Draw("colz"); - canvas->cd(2); haha->Draw("colz"); + canvas->cd(1); { + PID->Draw("colz"); + if( pidCut ) pidCut->Draw("same"); + } + + canvas->cd(2); hRay->Draw("colz"); canvas->cd(3); hF->Draw(); canvas->cd(4); hB->Draw(); @@ -241,7 +259,8 @@ void SplitPolePlotter(TChain *tree){ canvas->cd(7); hEx->Draw(); - canvas->cd(8); coin->Draw("colz"); + //canvas->cd(8); coin->Draw("colz"); + canvas->cd(8); hEx_Multi->Draw("colz"); canvas->cd(9); canvas->cd(9)->SetLogy(); hMulti->Draw(); diff --git a/Aux/fsuReader.h b/Aux/fsuReader.h index a264290..e3b802b 100644 --- a/Aux/fsuReader.h +++ b/Aux/fsuReader.h @@ -49,6 +49,7 @@ class FSUReader{ int GetNumCh() const{return numCh;} int GetFileOrder() const{return order;} int GetChMask() const{return chMask;} + int GetRunNum() const{return runNum;} unsigned long GetFileByteSize() const {return inFileSize;} void ClearHitList() { hit.clear();} @@ -116,6 +117,7 @@ class FSUReader{ uShort order; uShort chMask; uShort numCh; + uShort runNum; std::vector blockPos; std::vector blockTimeStamp; @@ -264,6 +266,7 @@ inline void FSUReader::OpenFile(std::string fileName, uInt dataSize, int verbose while (std::getline(iss, token, '_')) { tokens.push_back(token); } short token_size = tokens.size(); // for( short i = 0; i < token_size; i ++ ) printf("%d | %s\n", i, tokens[i].c_str()); + runNum = atoi(tokens[token_size-5].c_str()); sn = atoi(tokens[token_size-4].c_str()); tick2ns = atoi(tokens[token_size-2].c_str()); order = atoi(tokens[token_size-1].c_str()); diff --git a/Aux/script.C b/Aux/script.C index 6a0c556..af1259d 100644 --- a/Aux/script.C +++ b/Aux/script.C @@ -7,12 +7,18 @@ void script(){ TChain * chain = new TChain("tree"); - chain->Add("data/12C_dp_009_3000.root"); -// chain->Add("run13._3000.root"); + chain->Add("raw_binary/run_13/run013_3000.root"); +// chain->Add("data/12C_dp_009_3000.root"); - SplitPolePlotter(chain); + TFile * pidCutFile = new TFile("cut_proton.root"); +// TFile * pidCutFile = new TFile("cut_proton_FSU.root"); + TCutG * pidCut = (TCutG *) pidCutFile->Get("protons"); + + SplitPolePlotter(chain, pidCut, 123.307, 2.75, false); +// SplitPolePlotter(chain, pidCut, 123.307, 2.75, true); + //^===================================================== // FSUReader * reader = new FSUReader("data/12C_dp_002_19555_PSD_4_000.fsu", 10000, 2); From 36621dcf31cf198fb3dff3ef56154741f5ba2fcc Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Wed, 14 Aug 2024 13:52:36 -0400 Subject: [PATCH 34/72] update Aux/README.md --- Aux/README.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Aux/README.md b/Aux/README.md index 2e080c4..de72023 100644 --- a/Aux/README.md +++ b/Aux/README.md @@ -37,18 +37,16 @@ With this approach, it is guaranteed that the output hitList_A is always time-so This defines the EventBuilder. The arguments are ```sh -./EventBuilder [timeWindow] [withTrace] [verbose] [batchSize] [inFile1] [inFile2] .... +./EventBuilder [timeWindow] [withTrace] [inFile1] [inFile2] .... timeWindow : in ns, -1 = no event building withTrace : 0 for no trace, 1 for trace - verbose : > 0 for debug - batchSize : the size of hit in a batch Output file name is contructed from inFile1 ``` as an example, ```sh -/EventBuilder 0 0 0 1000000 '\ls -1 test_001*.fsu' +/EventBuilder 0 0'\ls -1 test_001*.fsu' ``` setting the timeWindow to be -1, will split out a timesorted Hit. @@ -115,6 +113,16 @@ Evenbuilder output is standard information, an example structure is *............................................................................* ``` +# FSU2CAEN.cpp + +This convert the *.fsu to Data_CHXX@DIGI_YYYYY_run_ZZ.BIN. the BIN is CoMPASS format and could be useful for couple with existing analysis routine. + + +```sh +./FSU2CAEN [tarFlag] [inFile1] [inFile2] .... + targFlag : if 1, tar ball all output files. +``` + # SettingsExplorer.cpp From e13db06ed37267c40cafc9305e5fcd097b399f23 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Mon, 19 Aug 2024 12:27:51 -0400 Subject: [PATCH 35/72] remove unneccesary mutex lock aand unlock for read only operations --- SingleSpectra.cpp | 4 ++-- analyzers/Analyser.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/SingleSpectra.cpp b/SingleSpectra.cpp index cc2b849..110bae2 100644 --- a/SingleSpectra.cpp +++ b/SingleSpectra.cpp @@ -319,7 +319,7 @@ void SingleSpectra::FillHistograms(){ // qDebug() << randomChList; - digiMTX[ID].lock(); + // digiMTX[ID].lock(); // digi[ID]->GetData()->PrintAllData(); @@ -368,7 +368,7 @@ void SingleSpectra::FillHistograms(){ } if( hist2DVisibility[ID] ) hist2D[ID]->UpdatePlot(); - digiMTX[ID].unlock(); + // digiMTX[ID].unlock(); } } diff --git a/analyzers/Analyser.cpp b/analyzers/Analyser.cpp index 9c8d666..7e3cf6c 100644 --- a/analyzers/Analyser.cpp +++ b/analyzers/Analyser.cpp @@ -94,13 +94,13 @@ void Analyzer::BuildEvents(bool verbose){ unsigned int nData = mb->GetNumOfDigitizer(); std::vector idList = mb->GetDigiIDList(); - for( unsigned int i = 0; i < nData; i++ ) digiMTX[idList[i]].lock(); + // for( unsigned int i = 0; i < nData; i++ ) digiMTX[idList[i]].lock(); if( isBuildBackward ){ mb->BuildEventsBackWard(maxNumEventBuilt, verbose); }else{ mb->BuildEvents(0, true, verbose); } - for( unsigned int i = 0; i < nData; i++ ) digiMTX[idList[i]].unlock(); + // for( unsigned int i = 0; i < nData; i++ ) digiMTX[idList[i]].unlock(); } From 0895ad57edf55ea6a3e1bd10ab98c7782f320e25 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Mon, 19 Aug 2024 18:53:59 -0400 Subject: [PATCH 36/72] SingleHistogram add energy Long for PSD, add SplotPolePlotter_MT.C --- Aux/SplitPolePlotter.C | 7 +- Aux/SplitPolePlotter_MT.C | 194 ++++++++++++++++++++++++++++++++++++++ Aux/script.C | 20 ++-- FSUDAQ.cpp | 5 +- SingleSpectra.cpp | 12 ++- 5 files changed, 225 insertions(+), 13 deletions(-) create mode 100644 Aux/SplitPolePlotter_MT.C diff --git a/Aux/SplitPolePlotter.C b/Aux/SplitPolePlotter.C index f538d1d..387f88a 100644 --- a/Aux/SplitPolePlotter.C +++ b/Aux/SplitPolePlotter.C @@ -1,3 +1,6 @@ +#ifndef SPLITPOLEPLOTTER +#define SPLITPOLEPLOTTER + #include "TFile.h" #include "TChain.h" #include "TH1F.h" @@ -266,4 +269,6 @@ void SplitPolePlotter(TChain *tree, TCutG * pidCut = nullptr, double rhoOffset = canvas->cd(10); hXavg_Theta->Draw("colz"); -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/Aux/SplitPolePlotter_MT.C b/Aux/SplitPolePlotter_MT.C new file mode 100644 index 0000000..5f5dc9f --- /dev/null +++ b/Aux/SplitPolePlotter_MT.C @@ -0,0 +1,194 @@ +#include +#include "TTreeReader.h" +#include "TTreeReaderValue.h" +#include "TTreeReaderArray.h" +#include +#include +#include "ROOT/TProcessExecutor.hxx" +#include "ROOT/TThreadedObject.hxx" + +#include "TH2F.h" +#include "TH1F.h" +#include "TCutG.h" +#include "TCanvas.h" + +#include "SplitPolePlotter.C" +#include "../analyzers/SplitPoleHit.h" + + +void SplotPolePlotter_MT(TChain * chain, const int nThread, TCutG * pidCut = nullptr, double rhoOffset = 0, double rhoScaling = 1, bool isFSUDAQ = true){ + + //^====================== Thread Object, destoryed when merge + ROOT::TThreadedObject pCoin("hCoin", "Coincident ", 16, 0, 16, 16, 0, 16); + ROOT::TThreadedObject phMulti("hMulti", "Multiplicity", 16, 0, 16); + ROOT::TThreadedObject pPID("hPID", "PID; Scin_X ; AnodeB", 200, 0, 20000, 100, 0, isFSUDAQ ? 40000 : 5000); + ROOT::TThreadedObject phXavg_Q("hXavg_Q", "Xavg vs Q ", 200, XMIN, XMAX, 200, 0, isFSUDAQ ? 40000 : 5000); + ROOT::TThreadedObject phF("hF", "Front delay line position", 600, XMIN, XMAX); + ROOT::TThreadedObject phB("hB", "Back delay line position", 600, XMIN, XMAX); + ROOT::TThreadedObject phXavg("hAvg", "Xavg", 600, XMIN, XMAX); + ROOT::TThreadedObject phFocal("hFocal", "Front vs Back ", 200, XMIN, XMAX, 200, XMIN, XMAX); + ROOT::TThreadedObject phXavg_Theta("hXavg_Theta", "Xavg vs Theta ", 200, XMIN, XMAX, 200, 0.5, 1.4); + ROOT::TThreadedObject phRay("hRay", "Ray plot", 400, XMIN, XMAX, 400, -50, 50); + ROOT::TThreadedObject phEx("hEx", "Ex; Ex [MeV]; count/10 keV", 600, -1, 5); + ROOT::TThreadedObject phEx_Multi("hEx_Multi", "Ex vs Multi; Ex; Multi", 600, -1, 5, 16, 0, 16); + + + //^==================== TTreeProcessorMT + ROOT::EnableImplicitMT(nThread); + + std::vector fileList_view; + std::vector fileList; + for( int k = 0; k < chain->GetNtrees(); k++){ + fileList_view.push_back(chain->GetListOfFiles()->At(k)->GetTitle()); + fileList.push_back(chain->GetListOfFiles()->At(k)->GetTitle()); + } + ROOT::TTreeProcessorMT tp(fileList_view, "tree"); + // tp.SetTasksPerWorkerHint(1); + + std::mutex mutex; + + int count = 0; + + //^======================= Define process + auto ProcessTask = [&](TTreeReader &reader){ + + TTreeReaderValue evID = {reader, "evID"}; + TTreeReaderValue multi = {reader, "multi"}; + TTreeReaderArray sn = {reader, "sn"}; + TTreeReaderArray ch = {reader, "ch"}; + TTreeReaderArray e = {reader, "e"}; + TTreeReaderArray e2 = {reader, "e2"}; + TTreeReaderArray e_t = {reader, "e_t"}; + TTreeReaderArray e_f = {reader, "e_f"}; + + mutex.lock(); + count++; + printf("-------------- Thread_ID: %d \n", count); + mutex.unlock(); + + SplitPoleHit hit; + hit.SetMassTablePath("../analyzers/mass20.txt"); + hit.CalConstants("12C", "d", "p", 16, 18); // 80MeV, 5 deg + hit.CalZoffset(0.750); // 1.41 T + + + while (reader.Next()) { + + hit.ClearData(); + + phMulti->Fill(*multi); + + // if( *multi != 9 ) continue; + + for( int i = 0; i < *multi; i++){ + + // t2 = e_t[i]; + // if( t2 < t1 ) printf("entry %lld-%d, timestamp is not in order. %llu, %llu\n", processedEntries, i, t2, t1); + if( i == 0 ) t1 = e_t[i]; + // if( e[i] == 65535 ) continue; + + if( ch[i] == ChMap::ScinR ) {hit.eSR = e[i]; hit.tSR = e_t[i] + e_f[i]/1000;} + if( ch[i] == ChMap::ScinL ) {hit.eSL = e[i]; hit.tSL = e_t[i] + e_f[i]/1000;} + if( ch[i] == ChMap::dFR ) {hit.eFR = e[i]; hit.tFR = e_t[i] + e_f[i]/1000;} + if( ch[i] == ChMap::dFL ) {hit.eFL = e[i]; hit.tFL = e_t[i] + e_f[i]/1000;} + if( ch[i] == ChMap::dBR ) {hit.eBR = e[i]; hit.tBR = e_t[i] + e_f[i]/1000;} + if( ch[i] == ChMap::dBL ) {hit.eBL = e[i]; hit.tBL = e_t[i] + e_f[i]/1000;} + if( ch[i] == ChMap::Cathode ) {hit.eCath = e[i]; hit.tCath = e_t[i] + e_f[i]/1000;} + if( ch[i] == ChMap::AnodeF ) {hit.eAF = e[i]; hit.tAF = e_t[i] + e_f[i]/1000;} + if( ch[i] == ChMap::AnodeB ) {hit.eAB = e[i]; hit.tAB = e_t[i] + e_f[i]/1000;} + + for( int j = i+1; j < sn.GetSize(); j++){ + pCoin->Fill(ch[i], ch[j]); + } + } + + unsigned int dQ = hit.eAB; // delta Q + unsigned int Qt = hit.eSL; // total Q + + if( Qt > 0 && dQ > 0 ) { + pPID->Fill(Qt, dQ); + } + + //=============== PID gate cut + if( pidCut ){ + if( !pidCut->IsInside(Qt, dQ) ) continue; + } + + hit.CalData(2); + + if( hit.theta > 1.2 || 0.5 > hit.theta ) continue; + + if( (!TMath::IsNaN(hit.x1) || !TMath::IsNaN(hit.x2)) ) { + phFocal->Fill(hit.x1, hit.x2); + phF->Fill(hit.x1); + phB->Fill(hit.x2); + phXavg->Fill(hit.xAvg); + phXavg_Q->Fill(hit.xAvg, dQ); + phXavg_Theta->Fill( hit.xAvg, hit.theta); + + for( int i = 0; i < 400; i++){ + double z = -50 + 100/400.*i; + + double x = (z/42.8625 + 0.5)* ( hit.x2-hit.x1) + hit.x1; + + phRay->Fill(x,z); + } + + double ex = hit.Rho2Ex( ((hit.xAvg - rhoOffset)/1000/rhoScaling + hit.GetRho0() ) ); + //if( XMIN < hit.xAvg && hit.xAvg < XMAX) printf("x1 : %6.2f, x2 : %6.2f, xAvg %6.2f cm , ex : %f \n", hit.x1, hit.x2, hit.xAvg, ex); + + phEx->Fill(ex); + phEx_Multi->Fill(ex, *multi); + } + } + + return 0; + }; + + //^============================ Run TP + tp.Process(ProcessTask); + + //^============================ Merge all ThreadedObject + auto coin = pCoin.Merge(); + auto hMulti= phMulti.Merge(); + auto hEx = phEx.Merge(); + auto hEx_Multi = phEx_Multi.Merge(); + auto PID = pPID.Merge(); + auto hFocal = phFocal.Merge(); + auto hF = phF.Merge(); + auto hB = phB.Merge(); + auto hXavg = phXavg.Merge(); + auto hXavg_Q = phXavg_Q.Merge(); + auto hXavg_Theta = phXavg_Theta.Merge(); + auto hRay = phRay.Merge(); + + //^============================== Plot + gStyle->SetOptStat("neiou"); + + TCanvas * canvas = new TCanvas("cc", "Split-Pole", 2500, 1000); + canvas->Divide(5, 2); + + canvas->cd(1); { + PID->DrawCopy("colz"); + if( pidCut ) pidCut->Draw("same"); + } + + canvas->cd(2); hRay->DrawCopy("colz"); + + canvas->cd(3); hF->DrawCopy(); + canvas->cd(4); hB->DrawCopy(); + + canvas->cd(5); hXavg_Q->DrawCopy("colz"); + + canvas->cd(6); hXavg->DrawCopy("colz"); + + canvas->cd(7); hEx->DrawCopy(); + + //canvas->cd(8); coin->DrawCopy("colz"); + canvas->cd(8); hEx_Multi->DrawCopy("colz"); + + canvas->cd(9); canvas->cd(9)->SetLogy(); hMulti->DrawCopy(); + + canvas->cd(10); hXavg_Theta->DrawCopy("colz"); + +} \ No newline at end of file diff --git a/Aux/script.C b/Aux/script.C index af1259d..2cebb08 100644 --- a/Aux/script.C +++ b/Aux/script.C @@ -2,22 +2,24 @@ // #include "../MultiBuilder.cpp" #include "SplitPolePlotter.C" +#include "SplitPolePlotter_MT.C" void script(){ - TChain * chain = new TChain("tree"); + TChain * chain = new TChain("tree"); + // chain->Add("raw_binary/run_13/run013_3000.root"); + // chain->Add("data/run*_3000.root"); + chain->Add("data/12C_dp_*_3000.root"); - chain->Add("raw_binary/run_13/run013_3000.root"); -// chain->Add("data/12C_dp_009_3000.root"); - - TFile * pidCutFile = new TFile("cut_proton.root"); -// TFile * pidCutFile = new TFile("cut_proton_FSU.root"); - TCutG * pidCut = (TCutG *) pidCutFile->Get("protons"); + // TFile * pidCutFile = new TFile("cut_proton.root"); + TFile * pidCutFile = new TFile("cut_proton_FSU.root"); + TCutG * pidCut = (TCutG *) pidCutFile->Get("protons"); - SplitPolePlotter(chain, pidCut, 123.307, 2.75, false); + // SplitPolePlotter(chain, pidCut, 123.307, 2.75, false); // for CoMPASS data + // SplitPolePlotter(chain, pidCut, 123.307, 2.75, true); // faster then MT? + SplotPolePlotter_MT(chain, 5, pidCut, 123.307, 2.75, true); -// SplitPolePlotter(chain, pidCut, 123.307, 2.75, true); //^===================================================== diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index 0f34b1b..366a697 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -1077,7 +1077,7 @@ void FSUDAQ::UpdateScalar(){ if(digiSettings && digiSettings->isVisible() && digiSettings->GetTabID() == iDigi) digiSettings->UpdateACQStatus(acqStatus); - digiMTX[iDigi].lock(); + // digiMTX[iDigi].lock(); QString blockCountStr = QString::number(digi[iDigi]->GetData()->AggCount); blockCountStr += "/" + QString::number(readDataThread[iDigi]->GetReadCount()); @@ -1105,7 +1105,7 @@ void FSUDAQ::UpdateScalar(){ } } - digiMTX[iDigi].unlock(); + // digiMTX[iDigi].unlock(); } @@ -1810,6 +1810,7 @@ void FSUDAQ::OpenCanvas(){ }else{ canvas->show(); canvas->activateWindow(); + canvas->LoadSetting(); } } diff --git a/SingleSpectra.cpp b/SingleSpectra.cpp index 110bae2..3a4aa8c 100644 --- a/SingleSpectra.cpp +++ b/SingleSpectra.cpp @@ -181,7 +181,11 @@ SingleSpectra::SingleSpectra(Digitizer ** digi, unsigned int nDigi, QString rawD fillHistograms = false; QLabel * lbSettingPath = new QLabel( settingPath , this); - ctrlLayout->addWidget(lbSettingPath, 1, 0, 1, 8); + ctrlLayout->addWidget(lbSettingPath, 1, 0, 1, 6); + + QPushButton * bnSaveButton = new QPushButton("Save Hist. Settings", this); + ctrlLayout->addWidget(bnSaveButton, 1, 6, 1, 2); + connect(bnSaveButton, &QPushButton::click, this, &SingleSpectra::SaveSetting); } @@ -207,6 +211,9 @@ SingleSpectra::SingleSpectra(Digitizer ** digi, unsigned int nDigi, QString rawD for( int j = 0; j < digi[i]->GetNumInputCh(); j++){ if( i < nDigi ) { hist[i][j] = new Histogram1D("Digi-" + QString::number(digi[i]->GetSerialNumber()) +", Ch-" + QString::number(j), "Raw Energy [ch]", nBin, eMin, eMax); + if( digi[i]->GetDPPType() == DPPTypeCode::DPP_PSD_CODE ){ + hist[i][j]->AddDataList("Long Energy", Qt::green); + } }else{ hist[i][j] = nullptr; } @@ -359,6 +366,9 @@ void SingleSpectra::FillHistograms(){ // printf(" ch: %d, last fill idx : %d | %d \n", ch, lastFilledIndex[ID][ch], data); hist[ID][ch]->Fill( data ); + if( digi[i]->GetDPPType() == DPPTypeCode::DPP_PSD_CODE ){ + hist[ID][ch]->Fill( digi[ID]->GetData()->GetEnergy2(ch, lastFilledIndex[ID][ch])); + } hist2D[ID]->Fill(ch, data); } if( histVisibility[ID][ch] ) hist[ID][ch]->UpdatePlot(); From a58ddbc6d4970b80907bc4492416dcb28e515aef Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Tue, 20 Aug 2024 11:20:12 -0400 Subject: [PATCH 37/72] bugs fix for online histograms --- FSUDAQ.cpp | 2 +- SingleSpectra.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index 366a697..478b459 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -89,7 +89,7 @@ FSUDAQ::FSUDAQ(QWidget *parent) : QMainWindow(parent){ for( int i = 0; i < (int) onlineAnalyzerList.size() ; i++) cbAnalyzer->addItem(onlineAnalyzerList[i].c_str(), i); connect(cbAnalyzer, &RComboBox::currentIndexChanged, this, &FSUDAQ::OpenAnalyzer); - bnCanvas = new QPushButton("Online 1D Histograms", this); + bnCanvas = new QPushButton("Online Histograms", this); layout->addWidget(bnCanvas, 1, 2); connect(bnCanvas, &QPushButton::clicked, this, &FSUDAQ::OpenCanvas); diff --git a/SingleSpectra.cpp b/SingleSpectra.cpp index 3a4aa8c..c1b91de 100644 --- a/SingleSpectra.cpp +++ b/SingleSpectra.cpp @@ -185,7 +185,7 @@ SingleSpectra::SingleSpectra(Digitizer ** digi, unsigned int nDigi, QString rawD QPushButton * bnSaveButton = new QPushButton("Save Hist. Settings", this); ctrlLayout->addWidget(bnSaveButton, 1, 6, 1, 2); - connect(bnSaveButton, &QPushButton::click, this, &SingleSpectra::SaveSetting); + connect(bnSaveButton, &QPushButton::clicked, this, &SingleSpectra::SaveSetting); } @@ -367,7 +367,7 @@ void SingleSpectra::FillHistograms(){ hist[ID][ch]->Fill( data ); if( digi[i]->GetDPPType() == DPPTypeCode::DPP_PSD_CODE ){ - hist[ID][ch]->Fill( digi[ID]->GetData()->GetEnergy2(ch, lastFilledIndex[ID][ch])); + hist[ID][ch]->Fill( digi[ID]->GetData()->GetEnergy2(ch, lastFilledIndex[ID][ch]), 1); } hist2D[ID]->Fill(ch, data); } @@ -423,9 +423,11 @@ void SingleSpectra::SaveSetting(){ file.write("##========== End of file\n"); file.close(); + printf("Saved Histogram Settings to %s\n", settingPath.toStdString().c_str()); }else{ printf("%s|cannot open HistogramSettings.txt\n", __func__); } + } void SingleSpectra::LoadSetting(){ From 6faeaf7c9bb91403bcfd0f71786a3156c1717e7b Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Tue, 20 Aug 2024 12:22:26 -0400 Subject: [PATCH 38/72] add Toggle line display on histogram 1D --- Histogram1D.h | 79 ++++++++++++++++++++++++++++++++++++----------- SingleSpectra.cpp | 6 ++-- 2 files changed, 65 insertions(+), 20 deletions(-) diff --git a/Histogram1D.h b/Histogram1D.h index 1993061..323a9dd 100644 --- a/Histogram1D.h +++ b/Histogram1D.h @@ -15,6 +15,8 @@ public: // DebugPrint("%s", "Histogram1D"); isLogY = false; + for( int i = 0; i < MaxNHist; i++ ) showHist[i] = true; + for( int i = 0; i < 3; i ++) txt[i] = nullptr; nData = 1; Rebin(xbin, xmin, xmax); @@ -86,12 +88,15 @@ public: QAction * a1 = menu.addAction("UnZoom"); QAction * a5 = menu.addAction("Set/UnSet Log-y"); + QAction * a6 = nullptr; + if( nData > 1 ) a6 = menu.addAction("Toggle lines display"); QAction * a2 = menu.addAction("Clear hist."); QAction * a3 = menu.addAction("Toggle Stat."); QAction * a4 = menu.addAction("Rebin (clear histogram)"); //TODO fitGuass QAction *selectedAction = menu.exec(event->globalPosition().toPoint()); + //*========================================== UnZoom if( selectedAction == a1 ){ xAxis->setRangeLower(xMin); xAxis->setRangeUpper(xMax); @@ -101,11 +106,13 @@ public: usingMenu = false; } + //*========================================== Clear Hist if( selectedAction == a2 ){ Clear(); usingMenu = false; } + //*========================================== Toggle Stat. if( selectedAction == a3 ){ for( int i = 0; i < 3; i++){ txt[i]->setVisible( !txt[i]->visible()); @@ -113,6 +120,7 @@ public: replot(); usingMenu = false; } + //*========================================== Rebin if( selectedAction == a4 ){ QDialog dialog(this); dialog.setWindowTitle("Rebin histogram"); @@ -145,25 +153,25 @@ public: double number[3]; QObject::connect(&buttonBox, &QDialogButtonBox::accepted, [&]() { - int OKcount = 0; - bool conversionOk = true; - for( int i = 0; i < 3; i++ ){ - number[i] = lineEdit[i]->text().toDouble(&conversionOk); - if( conversionOk ){ - OKcount++; - }else{ - msg->setText(nameList[i] + " is invalid."); - return; - } + int OKcount = 0; + bool conversionOk = true; + for( int i = 0; i < 3; i++ ){ + number[i] = lineEdit[i]->text().toDouble(&conversionOk); + if( conversionOk ){ + OKcount++; + }else{ + msg->setText(nameList[i] + " is invalid."); + return; } + } - if( OKcount == 3 ) { - if( number[2] > number[1] ) { - dialog.accept(); - }else{ - msg->setText(nameList[2] + " is smaller than " + nameList[1]); - } + if( OKcount == 3 ) { + if( number[2] > number[1] ) { + dialog.accept(); + }else{ + msg->setText(nameList[2] + " is smaller than " + nameList[1]); } + } }); QObject::connect(&buttonBox, &QDialogButtonBox::rejected, [&]() { dialog.reject();}); @@ -174,8 +182,38 @@ public: } } - if( selectedAction == a5 ){ + //*========================================== Toggle line Display + if( selectedAction == a6 ){ + QDialog dialog(this); + dialog.setWindowTitle("Toggle lines Display"); + + QFormLayout layout(&dialog); + + QCheckBox ** cbline = new QCheckBox *[nData]; + for( int i = 0; i < nData; i++ ){ + cbline[i] = new QCheckBox(graph(i)->name(), &dialog); + layout.addRow(cbline[i]); + if( showHist[i] ) cbline[i]->setChecked(true); + } + + QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &dialog); + layout.addRow(&buttonBox); + + QObject::connect(&buttonBox, &QDialogButtonBox::accepted, [&]() { + for( int i = 0; i < nData; i++ ){ + showHist[i] = cbline[i]->isChecked(); + } + dialog.accept(); + }); + QObject::connect(&buttonBox, &QDialogButtonBox::rejected, [&]() { dialog.reject();}); + + if( dialog.exec() == QDialog::Accepted ){ + UpdatePlot(); + } + } + //*========================================== Set Log y + if( selectedAction == a5 ){ if( !isLogY ){ this->yAxis->setScaleType(QCPAxis::stLogarithmic); isLogY = true; @@ -211,7 +249,10 @@ public: void UpdatePlot(){ DebugPrint("%s", "Histogram1D"); - for( int ID = 0 ; ID < nData; ID ++) graph(ID)->setData(xList, yList[ID]); + for( int ID = 0 ; ID < nData; ID ++) { + graph(ID)->setVisible(showHist[ID]); + graph(ID)->setData(xList, yList[ID]); + } xAxis->setRangeLower(xMin); xAxis->setRangeUpper(xMax); yAxis->setRangeLower(0); @@ -324,6 +365,8 @@ private: bool usingMenu; + bool showHist[MaxNHist]; + }; diff --git a/SingleSpectra.cpp b/SingleSpectra.cpp index c1b91de..346af9f 100644 --- a/SingleSpectra.cpp +++ b/SingleSpectra.cpp @@ -212,7 +212,7 @@ SingleSpectra::SingleSpectra(Digitizer ** digi, unsigned int nDigi, QString rawD if( i < nDigi ) { hist[i][j] = new Histogram1D("Digi-" + QString::number(digi[i]->GetSerialNumber()) +", Ch-" + QString::number(j), "Raw Energy [ch]", nBin, eMin, eMax); if( digi[i]->GetDPPType() == DPPTypeCode::DPP_PSD_CODE ){ - hist[i][j]->AddDataList("Long Energy", Qt::green); + hist[i][j]->AddDataList("Short Energy", Qt::green); } }else{ hist[i][j] = nullptr; @@ -367,7 +367,9 @@ void SingleSpectra::FillHistograms(){ hist[ID][ch]->Fill( data ); if( digi[i]->GetDPPType() == DPPTypeCode::DPP_PSD_CODE ){ - hist[ID][ch]->Fill( digi[ID]->GetData()->GetEnergy2(ch, lastFilledIndex[ID][ch]), 1); + uShort e2 = digi[ID]->GetData()->GetEnergy2(ch, lastFilledIndex[ID][ch]); + // printf("%u \n", e2); + hist[ID][ch]->Fill( e2, 1); } hist2D[ID]->Fill(ch, data); } From 5ebff17f89bb527a20e8efbb3111d3419bfd488f Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Tue, 20 Aug 2024 12:31:36 -0400 Subject: [PATCH 39/72] Histogram1D: ymax only update when line is visible --- Histogram1D.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Histogram1D.h b/Histogram1D.h index 323a9dd..0117a04 100644 --- a/Histogram1D.h +++ b/Histogram1D.h @@ -333,7 +333,7 @@ public: if( 0 <= index1 && index1 <= 2*xBin) yList[ID][index1] += 1; if( 0 <= index1 && index2 <= 2*xBin) yList[ID][index2] += 1; - if( yList[ID][index1] > yMax ) yMax = yList[ID][index1]; + if( showHist[ID] && yList[ID][index1] > yMax ) yMax = yList[ID][index1]; } void Print(unsigned int ID = 0){ From 6a9f25428917c9e6a188e7be10992dc1e9becdac Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Tue, 20 Aug 2024 14:59:22 -0400 Subject: [PATCH 40/72] 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 From e780345557cb429c6f2fe5e6ed4eb72a695fea15 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Wed, 21 Aug 2024 13:40:11 -0400 Subject: [PATCH 41/72] edit README.md --- README.md | 38 +++++++++++++++++++++++++++----------- analyzers/Analyser.h | 6 ++++++ 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 8fe1edb..3bb01f4 100644 --- a/README.md +++ b/README.md @@ -6,19 +6,19 @@ https://discord.gg/xVsRhNZF8G This is a DAQ for 1st gen CAEN digitizer for -- V1725, V17255S, V1230 with PHA and PSD firmware. +- x725, x725S, x730 with PHA and PSD firmware. - V1740 with QDC firmware It has scope (updated every half-sec), allow full control of the digitizer (except LVDS), and allow saving waveform. It can be connected to InfluxDB v1.8+ and Elog. -Each channel has it own 1D histogram. It will not be filled by default, but can enable it in the "Online 1D histgram" panel. The binning of each histogram will be saved under the raw data path as singleSpectaSetting.txt +Each channel has it own 1D histogram. It will not be filled by default, but can enable it in the "Online Histgrams" panel. The binning of each histogram will be saved under the raw data path as singleSpectaSetting.txt ## Wiki https://fsunuc.physics.fsu.edu/wiki/index.php/CAEN_digitizer -## Online analyzer +# Online analyzer A Multi-builder (event builder that can build event across multiple digitizer) is made. It has normal event building code and also a backward event building code that build events from the latest data up to certain amont of event. A 1-D and 2-D histogram is avalible. In the 2-D histogram, graphical cuts can be created and rename. @@ -27,6 +27,25 @@ An online analyzer class is created as a template for online analysis. An exampl Notice that, when the FSUDAQ is started, the online analyzer is not created, no event will be built. Once the online anlyzer is created and opened, event will be built, even the window is closed. +## Create a custom online analyzer + +Under the analyzer folder, there are few examples can be followed. Teh idea is create a derivative class based on the Analyzer.h. To implement the new online analyzer, user need to modify a few things: +- add the code file into FSUDAQ_At.pro +- add the header to the top of FSUDAQ.cpp +- edit the vector onlienAnalyzerList at th etop of FSUDAQ.cpp +- edit the FSUDAQ::OpenAnalyzer() + +after that, we need to update the makefile by + +```sh +>qmake6 FSUDAQ_Qt6.pro +``` + +and then recompile by +```sh +>make +``` + # Operation When programSettings.txt is presented in the same folder as the FSUDAQ_Qt, the program will load it can config the following @@ -65,8 +84,7 @@ User must setup the data path for data take. Without the data path, user still c # ToDo -- Gaussians fitting for 1D Histogram -- Improve the color scheme for 2D histogram +- Gaussians fitting for 1D Histogra - Save Histogram? # Required / Development enviroment @@ -136,13 +154,11 @@ if you want to use GDB debugger, in the *.pro file add ` QMAKE_CXXFLAGS += -g` + # Auxillary programs (e.g. Event Builder) 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 = 100 and Evt/Agg = 511. # Known Issues @@ -151,10 +167,10 @@ There is a folder Aux, this folder contains many auxillary programs, such as Eve * 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. +* Load digitizer setting would not load everything, only load the channel settings and some board settings. * Sometimes, the buffer is not in time order, and make the trigger/Accept rate to be nagative. This is nothing to do with the program but the digitizer settings. Recommand reporgram the digitizer. -* for 1740 QDC, RecordLenght is board setting, but readout is indivuial group. -* FOr PHA, the trapezoid scaling and fine-gain register are calculated before ACQ start. +* For 1740 QDC, RecordLenght is board setting, but readout is indivuial group. +* For PHA, the trapezoid scaling and fine-gain register are calculated before ACQ start. # Known Bugs diff --git a/analyzers/Analyser.h b/analyzers/Analyser.h index e0605d6..86ac723 100644 --- a/analyzers/Analyser.h +++ b/analyzers/Analyser.h @@ -28,6 +28,12 @@ This is the mother of all other derivative analysis class. derivative class should define the SetUpCanvas() and UpdateHistogram(); +After creating a new class based on the Analyzer class, +users need to add the class files to the FSUDAQ_Qt6.pro project file, +include the header file in FSUDAQ.cpp, +modify the MainWindow::OpenAnalyzer() method, +and recompile FSUDAQ to incorporate the changes and activate the custom analyzer. + ***************************************/ #include "Histogram1D.h" #include "Histogram2D.h" From 82de3763a9c4db9cadf573f5c0470ef39b247552 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Wed, 21 Aug 2024 14:50:55 -0400 Subject: [PATCH 42/72] delete the timing thread in Analyzer --- analyzers/Analyser.cpp | 10 ++++++++++ analyzers/NeutronGamma.h | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/analyzers/Analyser.cpp b/analyzers/Analyser.cpp index 7e3cf6c..417c16f 100644 --- a/analyzers/Analyser.cpp +++ b/analyzers/Analyser.cpp @@ -43,6 +43,16 @@ Analyzer::Analyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent ) } Analyzer::~Analyzer(){ + + if( buildTimerThread ){ + if( !buildTimerThread->isStopped() ){ + buildTimerThread->Stop(); + buildTimerThread->quit(); + buildTimerThread->wait(); + } + delete buildTimerThread; + } + delete influx; delete mb; delete [] dataList; diff --git a/analyzers/NeutronGamma.h b/analyzers/NeutronGamma.h index a7494bb..6b505ed 100644 --- a/analyzers/NeutronGamma.h +++ b/analyzers/NeutronGamma.h @@ -167,7 +167,7 @@ inline void NeutronGamma::SetUpCanvas(){ // } // 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); + hist2D = new Histogram2D("Neutron-Gamma", "Long Energy [ch]", "PSD = (l-s)/l", nBin, eMin, eMax, nBin, 0, 1); histLayout->addWidget(hist2D, 0, 0); From 1cb60d1aa4b11a30699afaa50608fd0ae062826b Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Thu, 22 Aug 2024 12:42:08 -0400 Subject: [PATCH 43/72] bugfix NeutronGamma; if scalarThred running + Analyzer created -> start updateHistograms thread --- FSUDAQ.cpp | 6 +++++- analyzers/NeutronGamma.h | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index bf3728a..b543c17 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -1833,6 +1833,9 @@ void FSUDAQ::OpenAnalyzer(){ if( id == 4 ) onlineAnalyzer = new MUSIC(digi, nDigi); if( id == 5 ) onlineAnalyzer = new NeutronGamma(digi, nDigi, rawDataPath); if( id >= 0 ) onlineAnalyzer->show(); + + if( scalarThread->isRunning() ) onlineAnalyzer->StartThread(); + }else{ delete onlineAnalyzer; @@ -1842,11 +1845,12 @@ 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 == 5 ) onlineAnalyzer = new NeutronGamma(digi, nDigi, rawDataPath); if( id >= 0 ){ onlineAnalyzer->show(); onlineAnalyzer->activateWindow(); + if( scalarThread->isRunning() ) onlineAnalyzer->StartThread(); } } diff --git a/analyzers/NeutronGamma.h b/analyzers/NeutronGamma.h index 6b505ed..cdc1c18 100644 --- a/analyzers/NeutronGamma.h +++ b/analyzers/NeutronGamma.h @@ -118,7 +118,6 @@ inline void NeutronGamma::SetUpCanvas(){ 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(); @@ -185,6 +184,7 @@ inline void NeutronGamma::ClearInternalDataCount(){ } inline void NeutronGamma::UpdateHistograms(){ + printf("%s | %d \n", __func__, fillHistograms); if( !fillHistograms ) return; if( this->isVisible() == false ) return; From fa2b1012dd793e618ef07919a2cbef915142734f Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Thu, 22 Aug 2024 13:03:43 -0400 Subject: [PATCH 44/72] Digiti Panel is not disable when ACQ started, but the value does not change --- ClassDigitizer.cpp | 19 +++++++++++++------ DigiSettingsPanel.cpp | 1 + FSUDAQ.cpp | 4 ++-- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/ClassDigitizer.cpp b/ClassDigitizer.cpp index 5b3784d..fc1051b 100644 --- a/ClassDigitizer.cpp +++ b/ClassDigitizer.cpp @@ -258,6 +258,7 @@ int Digitizer::OpenDigitizer(int boardID, int portID, bool program, bool verbose ErrorMsg("end of OpenDigitizer"); softwareDisable = false; + AcqRun = false; if( isConnected ) isDummy = false; @@ -288,6 +289,7 @@ int Digitizer::CloseDigitizer(){ void Digitizer::SetRegChannelMask(uint32_t mask){ DebugPrint("%s", "Digitizer"); if( softwareDisable ) return; + if( AcqRun ) return; if( !isConnected ) return; regChannelMask = mask; ret |= CAEN_DGTZ_SetChannelEnableMask(handle, regChannelMask); @@ -309,6 +311,7 @@ bool Digitizer::GetInputChannelOnOff(unsigned ch) { void Digitizer::SetRegChannelOnOff(unsigned short ch, bool onOff){ DebugPrint("%s", "Digitizer"); if( softwareDisable ) return; + if( AcqRun ) return; if( !isConnected ) return; regChannelMask = ((regChannelMask & ~( 1 << ch) ) | ( onOff << ch)) ; SetRegChannelMask(regChannelMask); @@ -316,6 +319,8 @@ void Digitizer::SetRegChannelOnOff(unsigned short ch, bool onOff){ void Digitizer::ProgramBoard(){ DebugPrint("%s", "Digitizer"); + if( softwareDisable ) return; + if( AcqRun ) return; if( DPPType == DPPTypeCode::DPP_PHA_CODE ) ProgramBoard_PHA(); if( DPPType == DPPTypeCode::DPP_PSD_CODE ) ProgramBoard_PSD(); if( DPPType == DPPTypeCode::DPP_QDC_CODE ) ProgramBoard_QDC(); @@ -323,7 +328,6 @@ void Digitizer::ProgramBoard(){ int Digitizer::ProgramBoard_PHA(){ DebugPrint("%s", "Digitizer"); - if( softwareDisable ) return 0; printf("===== Digitizer::%s\n", __func__); @@ -402,8 +406,6 @@ int Digitizer::ProgramBoard_PHA(){ } int Digitizer::ProgramBoard_PSD(){ - if( softwareDisable ) return 0; - printf("===== Digitizer::%s\n", __func__); //ret = CAEN_DGTZ_Reset(handle); @@ -465,8 +467,6 @@ int Digitizer::ProgramBoard_PSD(){ } int Digitizer::ProgramBoard_QDC(){ - if( softwareDisable ) return 0; - printf("===== Digitizer::%s\n", __func__); Reset(); @@ -727,6 +727,7 @@ void Digitizer::ReadAndPrintACQStatue(){ //=========================================================== void Digitizer::WriteRegister (Reg registerAddress, uint32_t value, int ch, bool isSave2MemAndFile){ if( softwareDisable ) return; + if( AcqRun ) return; printf("WRITE|%30s[0x%04X](digi-%d,ch-%02d) [0x%04X]: 0x%08X \n", registerAddress.GetNameChar(), registerAddress.GetAddress(),GetSerialNumber(), ch, registerAddress.ActualAddress(ch), value); if( !isConnected ) { @@ -773,6 +774,7 @@ void Digitizer::WriteRegister (Reg registerAddress, uint32_t value, int ch, bool uint32_t Digitizer::ReadRegister(Reg registerAddress, unsigned short ch, bool isSave2MemAndFile, std::string str ){ DebugPrint("%s", "Digitizer"); if( softwareDisable ) return 0; + if( AcqRun ) return 0; if( !isConnected ) return 0; if( registerAddress.GetRWType() == RW::WriteONLY ) return 0; // if( registerAddress == DPP::QDC::RecordLength_W ) return 0; @@ -861,8 +863,8 @@ Reg Digitizer::FindRegister(uint32_t address){ void Digitizer::ReadAllSettingsFromBoard(bool force){ if( softwareDisable ) return; - if( !isConnected ) return; if( AcqRun ) return; + if( !isConnected ) return; if( isSettingFilledinMemeory && !force) return; printf("===== Digitizer(%d)::%s \n", GetSerialNumber(), __func__); @@ -921,6 +923,7 @@ void Digitizer::ReadAllSettingsFromBoard(bool force){ void Digitizer::ProgramSettingsToBoard(){ DebugPrint("%s", "Digitizer"); if( softwareDisable ) return; + if( AcqRun ) return; if( !isConnected || isDummy ) return; printf("========== %s \n", __func__); @@ -1009,6 +1012,7 @@ void Digitizer::ProgramSettingsToBoard(){ } void Digitizer::SetSettingToMemory(Reg registerAddress, unsigned int value, unsigned short ch ){ + if( AcqRun ) return; DebugPrint("%s", "Digitizer"); unsigned short index = registerAddress.Index(ch); if( index > SETTINGSIZE ) return; @@ -1304,6 +1308,7 @@ void Digitizer::ErrorMsg(std::string header){ void Digitizer::SetDPPAlgorithmControl(uint32_t bit, int ch){ DebugPrint("%s", "Digitizer"); if( softwareDisable ) return; + if( AcqRun ) return; WriteRegister( DPP::DPPAlgorithmControl, bit, ch); if( ret != 0 ) ErrorMsg(__func__); } @@ -1311,6 +1316,7 @@ void Digitizer::SetDPPAlgorithmControl(uint32_t bit, int ch){ unsigned int Digitizer::ReadBits(Reg address, unsigned int bitLength, unsigned int bitSmallestPos, int ch ){ DebugPrint("%s", "Digitizer"); if( softwareDisable ) return 0; + if( AcqRun ) return 0; int tempCh = ch; if (ch < 0 && address < 0x8000 ) tempCh = 0; /// take ch-0 uint32_t bit = ReadRegister(address, tempCh); @@ -1321,6 +1327,7 @@ unsigned int Digitizer::ReadBits(Reg address, unsigned int bitLength, unsigned i void Digitizer::SetBits(Reg address, unsigned int bitValue, unsigned int bitLength, unsigned int bitSmallestPos, int ch){ DebugPrint("%s", "Digitizer"); if( softwareDisable ) return; + if( AcqRun ) return; ///printf("address : 0x%X, value : 0x%X, len : %d, pos : %d, ch : %d \n", address, bitValue, bitLength, bitSmallestPos, ch); uint32_t bit ; uint32_t bitmask = (uint(pow(2, bitLength)-1) << bitSmallestPos); diff --git a/DigiSettingsPanel.cpp b/DigiSettingsPanel.cpp index fd8d46d..b51a18b 100644 --- a/DigiSettingsPanel.cpp +++ b/DigiSettingsPanel.cpp @@ -1377,6 +1377,7 @@ void DigiSettingsPanel::SetUpChannelMask(unsigned int digiID){ connect(bnChEnableMask[digiID][i], &QPushButton::clicked, this, [=](){ if( !enableSignalSlot) return; + if( digi[digiID]->IsRunning() ) return; if( bnChEnableMask[digiID][i]->styleSheet() == "" ){ bnChEnableMask[digiID][i]->setStyleSheet("background-color : green;"); diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index b543c17..bb30194 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -1191,7 +1191,7 @@ void FSUDAQ::StartACQ(){ cbAutoRun->setEnabled(false); bnSync->setEnabled(false); - if( digiSettings ) digiSettings->setEnabled(false); + // if( digiSettings ) digiSettings->setEnabled(false); if( onlineAnalyzer ) onlineAnalyzer->StartThread(); @@ -1285,7 +1285,7 @@ void FSUDAQ::StopACQ(){ } } - if( digiSettings ) digiSettings->setEnabled(true); + if( digiSettings ) digiSettings->ReadSettingsFromBoard(); {//^=== elog and database if( influx && chkInflux->isChecked() && elogName != "" ) { From bf989d2c72b531515c0f02c14d9a16941c696304 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Thu, 22 Aug 2024 15:56:19 -0400 Subject: [PATCH 45/72] allow open digitizer panel when ACQ started --- DigiSettingsPanel.cpp | 12 ++++++------ FSUDAQ.cpp | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/DigiSettingsPanel.cpp b/DigiSettingsPanel.cpp index b51a18b..63edc01 100644 --- a/DigiSettingsPanel.cpp +++ b/DigiSettingsPanel.cpp @@ -367,12 +367,12 @@ DigiSettingsPanel::DigiSettingsPanel(Digitizer ** digi, unsigned int nDigi, QStr enableSignalSlot = true; //If any digitizer is running ACQ, disable the panel. - for( unsigned int iDigi = 0; iDigi < nDigi; iDigi ++){ - if( digi[iDigi]->IsRunning() ) { - this->setEnabled(false); - break; - } - } + // for( unsigned int iDigi = 0; iDigi < nDigi; iDigi ++){ + // if( digi[iDigi]->IsRunning() ) { + // this->setEnabled(false); + // break; + // } + // } } diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index bb30194..6d1acd0 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -1213,7 +1213,7 @@ void FSUDAQ::StartACQ(){ } chkSaveData->setEnabled(false); - bnDigiSettings->setEnabled(false); + // bnDigiSettings->setEnabled(false); } @@ -1310,7 +1310,7 @@ void FSUDAQ::StopACQ(){ } chkSaveData->setEnabled(true); - bnDigiSettings->setEnabled(true); + // bnDigiSettings->setEnabled(true); repaint(); printf("================ end of %s \n", __func__); From 823adf67eb1e3758b96951d7c1cee1ef276ab77f Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Fri, 23 Aug 2024 16:24:17 -0400 Subject: [PATCH 46/72] disable digitizer panel button when ACQ started --- ClassDigitizer.cpp | 4 +--- DigiSettingsPanel.cpp | 33 ++++++++++++++++++++++++--------- DigiSettingsPanel.h | 5 ++++- FSUDAQ.cpp | 7 +++++-- 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/ClassDigitizer.cpp b/ClassDigitizer.cpp index fc1051b..e7dede4 100644 --- a/ClassDigitizer.cpp +++ b/ClassDigitizer.cpp @@ -572,14 +572,13 @@ void Digitizer::StartACQ(){ } - AcqRun = true; data->ClearTriggerRate(); data->ClearData(); - if( DPPType == DPPTypeCode::DPP_QDC_CODE ) SetOptimialAggOrg(); printf(" ACQ mode : %s (%d), TRG-OUT mode : %s (%d) \n", acqStr.c_str(), acqID, trgOutStr.c_str(), trgOutID); + AcqRun = true; usleep(1000); // wait for 1 msec to start/Arm ACQ; ret = CAEN_DGTZ_SWStartAcquisition(handle); @@ -1372,7 +1371,6 @@ void Digitizer::SetOptimialAggOrg(){ printf(" Record Length (bit) : %u = %u sample = %u ns\n", RecordLen, RecordLen*8, RecordLen*8*16); printf("==============================================================\n"); - int eventSize = 6 + 2 * Ex + traceOn * RecordLen * 8; // sample printf(" estimated event size : %d sample \n", eventSize); double maxAggOrg = log2( MemorySizekSample * 1024 / eventSize / EventAgg ); diff --git a/DigiSettingsPanel.cpp b/DigiSettingsPanel.cpp index 63edc01..8a3f009 100644 --- a/DigiSettingsPanel.cpp +++ b/DigiSettingsPanel.cpp @@ -196,9 +196,9 @@ DigiSettingsPanel::DigiSettingsPanel(Digitizer ** digi, unsigned int nDigi, QStr {//^======================= Buttons - QWidget * buttonsWidget = new QWidget(tab); - tabLayout_V1->addWidget(buttonsWidget); - QGridLayout * buttonLayout = new QGridLayout(buttonsWidget); + buttonsWidget[iDigi] = new QWidget(tab); + tabLayout_V1->addWidget(buttonsWidget[iDigi]); + QGridLayout * buttonLayout = new QGridLayout(buttonsWidget[iDigi]); buttonLayout->setSpacing(2); int rowID = 0 ; @@ -367,12 +367,13 @@ DigiSettingsPanel::DigiSettingsPanel(Digitizer ** digi, unsigned int nDigi, QStr enableSignalSlot = true; //If any digitizer is running ACQ, disable the panel. - // for( unsigned int iDigi = 0; iDigi < nDigi; iDigi ++){ - // if( digi[iDigi]->IsRunning() ) { - // this->setEnabled(false); - // break; - // } - // } + for( unsigned int iDigi = 0; iDigi < nDigi; iDigi ++){ + if( digi[iDigi]->IsRunning() ) { + // this->setEnabled(false); + EnableButtons(false); + break; + } + } } @@ -3632,6 +3633,20 @@ void DigiSettingsPanel::SyncCheckBox(QCheckBox *(&chk)[][MaxRegChannel+1]){ } } +void DigiSettingsPanel::EnableButtons(bool enable){ + for( int i = 0; i < nDigi; i++ ){ + if( !enable ) { + leSaveFilePath[i]->setText("changing setting is disabled due to ACQ is running."); + leSaveFilePath[i]->setStyleSheet("color:red;"); + }else{ + leSaveFilePath[i]->setText((QString::fromStdString(digi[i]->GetSettingFileName()))); + leSaveFilePath[i]->setStyleSheet(""); + + } + buttonsWidget[i]->setEnabled(enable); + } +} + void DigiSettingsPanel::SyncAllChannelsTab_PHA(){ DebugPrint("%s", "DigiSettingsPanel"); SyncSpinBox(sbRecordLength); diff --git a/DigiSettingsPanel.h b/DigiSettingsPanel.h index ea82950..495d972 100644 --- a/DigiSettingsPanel.h +++ b/DigiSettingsPanel.h @@ -33,6 +33,8 @@ public slots: void SaveSetting(int opt); void LoadSetting(); + void EnableButtons(bool enable); + signals: void SendLogMsg(const QString &msg); void UpdateOtherPanels(); @@ -69,7 +71,6 @@ private: void SyncComboBox(RComboBox *(&cb)[][MaxRegChannel+1]); void SyncCheckBox(QCheckBox *(&chk)[][MaxRegChannel+1]); - void SyncAllChannelsTab_PHA(); void UpdateSettings_PHA(); void SyncAllChannelsTab_PSD(); @@ -102,6 +103,8 @@ private: QLineEdit * leSaveFilePath[MaxNDigitizer]; + QWidget * buttonsWidget[MaxNDigitizer]; + QPushButton * bnRefreshSetting; // read setting from board QPushButton * bnProgramPreDefined; QPushButton * bnClearBuffer; diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index 6d1acd0..4c34c8f 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -1191,7 +1191,7 @@ void FSUDAQ::StartACQ(){ cbAutoRun->setEnabled(false); bnSync->setEnabled(false); - // if( digiSettings ) digiSettings->setEnabled(false); + if( digiSettings ) digiSettings->EnableButtons(false); if( onlineAnalyzer ) onlineAnalyzer->StartThread(); @@ -1285,7 +1285,10 @@ void FSUDAQ::StopACQ(){ } } - if( digiSettings ) digiSettings->ReadSettingsFromBoard(); + if( digiSettings ) { + digiSettings->EnableButtons(true); + digiSettings->ReadSettingsFromBoard(); + } {//^=== elog and database if( influx && chkInflux->isChecked() && elogName != "" ) { From f3fea48bf692f5620b42fee06f009d2748416fdd Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Fri, 23 Aug 2024 18:26:56 -0400 Subject: [PATCH 47/72] bug fix on filling Historgram 1D --- Histogram1D.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Histogram1D.h b/Histogram1D.h index 0117a04..a0f5704 100644 --- a/Histogram1D.h +++ b/Histogram1D.h @@ -244,7 +244,8 @@ public: addGraph(); graph(nData - 1)->setName(title); SetColor(color, nData-1); - yList[nData-1] = yList[0]; + yList[nData-1].clear(); + for( int i = 0; i < xList.count(); i++) yList[nData-1].append(0); } void UpdatePlot(){ @@ -263,7 +264,7 @@ public: void Clear(){ DebugPrint("%s", "Histogram1D"); for( int ID = 0 ; ID < nData; ID ++) { - for( int i = 0; i <= yList[ID].count(); i++) yList[ID][i] = 0; + for( int i = 0; i < xList.count(); i++) yList[ID][i] = 0; } yMax = 0; txt[0]->setText("Under Flow : 0"); @@ -324,10 +325,12 @@ public: txt[2]->setText("Over Flow : "+ QString::number(overFlow)); return; } + }else{ + if( value < xMin || value > xMax ) return; } - double bin = (value - xMin)/dX; - int index1 = 2*qFloor(bin) + 1; + int bin = qFloor((value - xMin)/dX); + int index1 = 2*bin + 1; int index2 = index1 + 1; if( 0 <= index1 && index1 <= 2*xBin) yList[ID][index1] += 1; From ef8dca54303c6e43ff509cdcac5570755123d248 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Fri, 23 Aug 2024 18:39:21 -0400 Subject: [PATCH 48/72] remove printf in NeutronGamma::UpdateHistograms --- analyzers/NeutronGamma.h | 1 - 1 file changed, 1 deletion(-) diff --git a/analyzers/NeutronGamma.h b/analyzers/NeutronGamma.h index cdc1c18..a6e6a49 100644 --- a/analyzers/NeutronGamma.h +++ b/analyzers/NeutronGamma.h @@ -184,7 +184,6 @@ inline void NeutronGamma::ClearInternalDataCount(){ } inline void NeutronGamma::UpdateHistograms(){ - printf("%s | %d \n", __func__, fillHistograms); if( !fillHistograms ) return; if( this->isVisible() == false ) return; From dbfb9f96bfbfdd5a6988104dba273c9ea13295f6 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Mon, 26 Aug 2024 13:59:04 -0400 Subject: [PATCH 49/72] add SetDataBase in Analysis, so all analyzsis class can use --- .vscode/settings.json | 73 ++++++++++++- analyzers/Analyser.cpp | 111 +++++++++++++++++++- analyzers/Analyser.h | 11 +- analyzers/CoincidentAnalyzer.h | 185 ++++++++++++++++++++------------- analyzers/RAISOR.h | 2 +- analyzers/SplitPoleAnalyzer.h | 2 +- 6 files changed, 305 insertions(+), 79 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 1f9a97d..7c56aa7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -84,6 +84,77 @@ "files.associations": { "*.C": "cpp", "*.pro": "makefile", - "regex": "cpp" + "regex": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "bitset": "cpp", + "charconv": "cpp", + "chrono": "cpp", + "codecvt": "cpp", + "compare": "cpp", + "concepts": "cpp", + "condition_variable": "cpp", + "cstdint": "cpp", + "deque": "cpp", + "list": "cpp", + "map": "cpp", + "set": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "source_location": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "format": "cpp", + "fstream": "cpp", + "future": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "numbers": "cpp", + "ostream": "cpp", + "semaphore": "cpp", + "shared_mutex": "cpp", + "span": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "cinttypes": "cpp", + "typeinfo": "cpp", + "variant": "cpp" } } \ No newline at end of file diff --git a/analyzers/Analyser.cpp b/analyzers/Analyser.cpp index 417c16f..6e3c781 100644 --- a/analyzers/Analyser.cpp +++ b/analyzers/Analyser.cpp @@ -13,7 +13,9 @@ Analyzer::Analyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent ) setGeometry(0, 0, 1000, 800); influx = nullptr; + dataBaseIP = ""; dataBaseName = ""; + dataBaseToken = ""; dataList = new Data*[nDigi]; typeList.clear(); @@ -70,6 +72,61 @@ double Analyzer::RandomGauss(double mean, double sigma){ } +void Analyzer::SetDatabase(QString IP, QString Name, QString Token){ + dataBaseIP = IP; + dataBaseName = Name; + dataBaseToken = Token; + + if( influx ) { + delete influx; + influx = nullptr; + } + + influx = new InfluxDB(dataBaseIP.toStdString()); + + if( influx->TestingConnection() ){ + printf("InfluxDB URL (%s) is Valid. Version : %s\n", dataBaseIP.toStdString().c_str(), influx->GetVersionString().c_str()); + + if( influx->GetVersionNo() > 1 && dataBaseToken.isEmpty() ) { + printf("A Token is required for accessing the database.\n"); + delete influx; + influx = nullptr; + return; + } + + influx->SetToken(dataBaseToken.toStdString()); + + //==== chck database exist + influx->CheckDatabases(); + std::vector databaseList = influx->GetDatabaseList(); + bool foundDatabase = false; + for( int i = 0; i < (int) databaseList.size(); i++){ + if( databaseList[i] == dataBaseName.toStdString() ) foundDatabase = true; + } + if( foundDatabase ){ + influx->AddDataPoint("test value=1"); + influx->WriteData(dataBaseName.toStdString()); + influx->ClearDataPointsBuffer(); + if( influx->IsWriteOK() ){ + printf("test write database OK.\n"); + }else{ + printf("################# test write database FAIL.\n"); + delete influx; + influx = nullptr; + } + }else{ + printf("Database name : %s NOT found.\n", dataBaseName.toStdString().c_str()); + delete influx; + influx = nullptr; + } + }else{ + printf("InfluxDB URL (%s) is NOT Valid. \n", dataBaseIP.toStdString().c_str()); + delete influx; + influx = nullptr; + } + +} + void Analyzer::RedefineEventBuilder(std::vector idList){ delete mb; delete [] dataList; @@ -98,8 +155,6 @@ void Analyzer::StopThread(){ buildTimerThread->wait(); } - - void Analyzer::BuildEvents(bool verbose){ unsigned int nData = mb->GetNumOfDigitizer(); @@ -114,6 +169,58 @@ void Analyzer::BuildEvents(bool verbose){ } +void Analyzer::SetDatabaseButton(){ + + QDialog dialog; + dialog.setWindowTitle("Influx Database"); + + QGridLayout layout(&dialog); + + //------------------------------ + QLabel ipLabel("Database IP : "); + layout.addWidget(&ipLabel, 0, 0); + + QLineEdit ipLineEdit; + ipLineEdit.setFixedSize(1000, 20); + ipLineEdit.setText(dataBaseIP); + layout.addWidget(&ipLineEdit, 0, 1); + + //------------------------------ + QLabel nameLabel("Database Name : "); + layout.addWidget(&nameLabel, 1, 0); + + QLineEdit nameLineEdit; + nameLineEdit.setFixedSize(1000, 20); + nameLineEdit.setText(dataBaseName); + layout.addWidget(&nameLineEdit, 1, 1); + + //------------------------------ + QLabel tokenLabel("Database Token : "); + layout.addWidget(&tokenLabel, 2, 0); + + QLineEdit tokenLineEdit; + tokenLineEdit.setFixedSize(1000, 20); + tokenLineEdit.setText(dataBaseToken); + layout.addWidget(&tokenLineEdit, 2, 1); + + layout.addWidget(new QLabel("Only for version 2+, version 1+ can be skipped."), 3, 0, 1, 2); + + // Buttons for OK and Cancel + QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + layout.addWidget(&buttonBox); + + QObject::connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); + QObject::connect(&buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); + + dialog.resize(400, dialog.sizeHint().height()); // Set the width to 400 pixels + + // Show the dialog and get the result + if (dialog.exec() == QDialog::Accepted) { + SetDatabase(ipLineEdit.text(), nameLineEdit.text(),tokenLineEdit.text()); + } + +} + //^####################################### below are open to customization void Analyzer::SetUpCanvas(){ diff --git a/analyzers/Analyser.h b/analyzers/Analyser.h index 86ac723..d8a57e9 100644 --- a/analyzers/Analyser.h +++ b/analyzers/Analyser.h @@ -47,30 +47,33 @@ public: Analyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent = nullptr); virtual ~Analyzer(); - virtual void SetUpCanvas(); - MultiBuilder * GetEventBuilder() { return mb;} void RedefineEventBuilder(std::vector idList); void SetBackwardBuild(bool TF, int maxNumEvent = 100) { isBuildBackward = TF; maxNumEventBuilt = maxNumEvent;} + void SetDatabase(QString IP, QString Name, QString Token); double RandomGauss(double mean, double sigma); public slots: void StartThread(); void StopThread(); + void SetDatabaseButton(); + + virtual void SetUpCanvas(); virtual void UpdateHistograms(); // where event-building, analysis, and ploting private slots: - protected: QGridLayout * layout; void BuildEvents(bool verbose = false); void SetUpdateTimeInSec(double sec = 1.0) {waitTimeinSec = sec; buildTimerThread->SetWaitTimeinSec(waitTimeinSec);} InfluxDB * influx; - std::string dataBaseName; + QString dataBaseIP; + QString dataBaseName; + QString dataBaseToken; private: Digitizer ** digi; diff --git a/analyzers/CoincidentAnalyzer.h b/analyzers/CoincidentAnalyzer.h index b498d90..a60ae52 100644 --- a/analyzers/CoincidentAnalyzer.h +++ b/analyzers/CoincidentAnalyzer.h @@ -21,10 +21,6 @@ public: evtbder = GetEventBuilder(); evtbder->SetTimeWindow(500); - - //========== use the influx from the Analyzer - // influx = new InfluxDB("https://fsunuc.physics.fsu.edu/influx/"); - dataBaseName = "testing"; allowSignalSlot = false; SetUpCanvas(); @@ -73,8 +69,8 @@ private: RComboBox * aCh; QString rawDataPath; - void SaveHistRange(); - void LoadHistRange(); + void SaveSettings(); + void LoadSettings(); }; @@ -91,18 +87,20 @@ inline void CoincidentAnalyzer::SetUpCanvas(){ boxLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft); box->setLayout(boxLayout); + int rowID = 0; + { chkRunAnalyzer = new QCheckBox("Run Analyzer", this); - boxLayout->addWidget(chkRunAnalyzer, 0, 0); + boxLayout->addWidget(chkRunAnalyzer, rowID, 0); QLabel * lbUpdateTime = new QLabel("Update Period [s]", this); lbUpdateTime->setAlignment(Qt::AlignRight | Qt::AlignCenter); - boxLayout->addWidget(lbUpdateTime, 0, 1); + boxLayout->addWidget(lbUpdateTime, rowID, 1); sbUpdateTime = new RSpinBox(this, 1); sbUpdateTime->setMinimum(0.1); sbUpdateTime->setMaximum(5); sbUpdateTime->setValue(1); - boxLayout->addWidget(sbUpdateTime, 0, 2); + boxLayout->addWidget(sbUpdateTime, rowID, 2); connect(sbUpdateTime, &RSpinBox::valueChanged, this, [=](){ sbUpdateTime->setStyleSheet("color : blue"); }); @@ -111,17 +109,36 @@ inline void CoincidentAnalyzer::SetUpCanvas(){ SetUpdateTimeInSec(sbUpdateTime->value()); }); + QLabel * lbBuildWindow = new QLabel("Event Window [ns]", this); + lbBuildWindow->setAlignment(Qt::AlignRight | Qt::AlignCenter); + boxLayout->addWidget(lbBuildWindow, rowID, 3); + sbBuildWindow = new RSpinBox(this, 0); + sbBuildWindow->setMinimum(1); + sbBuildWindow->setMaximum(9999999999); + sbBuildWindow->setValue(1000); + boxLayout->addWidget(sbBuildWindow, rowID, 4); + + connect(sbBuildWindow, &RSpinBox::valueChanged, this, [=](){ + sbBuildWindow->setStyleSheet("color : blue;"); + }); + + connect(sbBuildWindow, &RSpinBox::returnPressed, this, [=](){ + sbBuildWindow->setStyleSheet(""); + evtbder->SetTimeWindow((int)sbBuildWindow->value()); + }); + + rowID ++; chkBackWardBuilding = new QCheckBox("Use Backward builder", this); - boxLayout->addWidget(chkBackWardBuilding, 1, 0); + boxLayout->addWidget(chkBackWardBuilding, rowID, 0); QLabel * lbBKWindow = new QLabel("Max No. Backward Event", this); lbBKWindow->setAlignment(Qt::AlignRight | Qt::AlignCenter); - boxLayout->addWidget(lbBKWindow, 1, 1); + boxLayout->addWidget(lbBKWindow, rowID, 1); sbBackwardCount = new RSpinBox(this, 0); sbBackwardCount->setMinimum(1); sbBackwardCount->setMaximum(9999); sbBackwardCount->setValue(100); - boxLayout->addWidget(sbBackwardCount, 1, 2); + boxLayout->addWidget(sbBackwardCount, rowID, 2); chkBackWardBuilding->setChecked(false); sbBackwardCount->setEnabled(false); @@ -141,62 +158,48 @@ inline void CoincidentAnalyzer::SetUpCanvas(){ SetBackwardBuild(true, sbBackwardCount->value()); }); - QLabel * lbBuildWindow = new QLabel("Event Window [ns]", this); - lbBuildWindow->setAlignment(Qt::AlignRight | Qt::AlignCenter); - boxLayout->addWidget(lbBuildWindow, 2, 1); - sbBuildWindow = new RSpinBox(this, 0); - sbBuildWindow->setMinimum(1); - sbBuildWindow->setMaximum(9999999999); - sbBuildWindow->setValue(1000); - boxLayout->addWidget(sbBuildWindow, 2, 2); - - connect(sbBuildWindow, &RSpinBox::valueChanged, this, [=](){ - sbBuildWindow->setStyleSheet("color : blue;"); - }); - - connect(sbBuildWindow, &RSpinBox::returnPressed, this, [=](){ - sbBuildWindow->setStyleSheet(""); - evtbder->SetTimeWindow((int)sbBuildWindow->value()); - }); } { - QFrame *separator = new QFrame(box); - separator->setFrameShape(QFrame::HLine); - separator->setFrameShadow(QFrame::Sunken); - boxLayout->addWidget(separator, 3, 0, 1, 4); + rowID ++; + QFrame *separator0 = new QFrame(box); + separator0->setFrameShape(QFrame::HLine); + separator0->setFrameShadow(QFrame::Sunken); + boxLayout->addWidget(separator0, rowID, 0, 1, 4); + rowID ++; QLabel * lbXDigi = new QLabel("X-Digi", this); lbXDigi->setAlignment(Qt::AlignRight | Qt::AlignCenter); - boxLayout->addWidget(lbXDigi, 4, 0); + boxLayout->addWidget(lbXDigi, rowID, 0); xDigi = new RComboBox(this); for(unsigned int i = 0; i < nDigi; i ++ ){ xDigi->addItem("Digi-" + QString::number(digi[i]->GetSerialNumber()), i); } - boxLayout->addWidget(xDigi, 4, 1); + boxLayout->addWidget(xDigi, rowID, 1); QLabel * lbXCh = new QLabel("X-Ch", this); lbXCh->setAlignment(Qt::AlignRight | Qt::AlignCenter); - boxLayout->addWidget(lbXCh, 4, 2); + boxLayout->addWidget(lbXCh, rowID, 2); xCh = new RComboBox(this); for( int i = 0; i < digi[0]->GetNumInputCh(); i++) xCh->addItem("Ch-" + QString::number(i), i); - boxLayout->addWidget(xCh, 4, 3); + boxLayout->addWidget(xCh, rowID, 3); + rowID ++; QLabel * lbYDigi = new QLabel("Y-Digi", this); lbYDigi->setAlignment(Qt::AlignRight | Qt::AlignCenter); - boxLayout->addWidget(lbYDigi, 5, 0); + boxLayout->addWidget(lbYDigi, rowID, 0); yDigi = new RComboBox(this); for(unsigned int i = 0; i < nDigi; i ++ ){ yDigi->addItem("Digi-" + QString::number(digi[i]->GetSerialNumber()), i); } - boxLayout->addWidget(yDigi, 5, 1); + boxLayout->addWidget(yDigi, rowID, 1); QLabel * lbYCh = new QLabel("Y-Ch", this); lbYCh->setAlignment(Qt::AlignRight | Qt::AlignCenter); - boxLayout->addWidget(lbYCh, 5, 2); + boxLayout->addWidget(lbYCh, rowID, 2); yCh = new RComboBox(this); for( int i = 0; i < digi[0]->GetNumInputCh(); i++) yCh->addItem("Ch-" + QString::number(i), i); - boxLayout->addWidget(yCh, 5, 3); + boxLayout->addWidget(yCh, rowID, 3); connect(xDigi, &RComboBox::currentIndexChanged, this, [=](){ allowSignalSlot = false; @@ -243,26 +246,28 @@ inline void CoincidentAnalyzer::SetUpCanvas(){ } { + rowID ++; QFrame *separator1 = new QFrame(box); separator1->setFrameShape(QFrame::HLine); separator1->setFrameShadow(QFrame::Sunken); - boxLayout->addWidget(separator1, 6, 0, 1, 4); + boxLayout->addWidget(separator1, rowID, 0, 1, 4); + rowID ++; QLabel * lbaDigi = new QLabel("ID-Digi", this); lbaDigi->setAlignment(Qt::AlignRight | Qt::AlignCenter); - boxLayout->addWidget(lbaDigi, 7, 0); + boxLayout->addWidget(lbaDigi, rowID, 0); aDigi = new RComboBox(this); for(unsigned int i = 0; i < nDigi; i ++ ){ aDigi->addItem("Digi-" + QString::number(digi[i]->GetSerialNumber()), i); } - boxLayout->addWidget(aDigi, 7, 1); + boxLayout->addWidget(aDigi, rowID, 1); QLabel * lbaCh = new QLabel("1D-Ch", this); lbaCh->setAlignment(Qt::AlignRight | Qt::AlignCenter); - boxLayout->addWidget(lbaCh, 7, 2); + boxLayout->addWidget(lbaCh, rowID, 2); aCh = new RComboBox(this); for( int i = 0; i < digi[0]->GetNumInputCh(); i++) aCh->addItem("Ch-" + QString::number(i), i); - boxLayout->addWidget(aCh, 7, 3); + boxLayout->addWidget(aCh, rowID, 3); connect(aDigi, &RComboBox::currentIndexChanged, this, [=](){ allowSignalSlot = false; @@ -292,13 +297,41 @@ inline void CoincidentAnalyzer::SetUpCanvas(){ } { - QFrame *separator1 = new QFrame(box); - separator1->setFrameShape(QFrame::HLine); - separator1->setFrameShadow(QFrame::Sunken); - boxLayout->addWidget(separator1, 8, 0, 1, 4); + rowID ++; + QFrame *separator2 = new QFrame(box); + separator2->setFrameShape(QFrame::HLine); + separator2->setFrameShadow(QFrame::Sunken); + boxLayout->addWidget(separator2, rowID, 0, 1, 4); + + rowID ++; + QLabel * lbIP = new QLabel("Database IP :", box); + lbIP->setAlignment(Qt::AlignRight | Qt::AlignCenter); + boxLayout->addWidget(lbIP, rowID, 0); + QLineEdit * leInfluxIP = new QLineEdit(box); + leInfluxIP->setReadOnly(true); + boxLayout->addWidget(leInfluxIP, rowID, 1, 1, 3); + + QPushButton * bnInflux = new QPushButton("Set Influx", box); + boxLayout->addWidget(bnInflux, rowID, 1, 1, 3); + + rowID ++; + QLabel * lbDBName = new QLabel("Database name :", box); + lbDBName->setAlignment(Qt::AlignRight | Qt::AlignCenter); + boxLayout->addWidget(lbDBName, rowID, 0); + QLineEdit * leDBName= new QLineEdit(box); + leDBName->setReadOnly(true); + boxLayout->addWidget(leDBName, rowID, 1); + + connect(bnInflux, &QPushButton::clicked, this, &Analyzer::SetDatabaseButton); + + // rowID ++; + // QFrame *separator3 = new QFrame(box); + // separator3->setFrameShape(QFrame::HLine); + // separator3->setFrameShadow(QFrame::Sunken); + // boxLayout->addWidget(separator3, rowID, 0, 1, 4); QPushButton * bnClearHist = new QPushButton("Clear All Hist.", this); - boxLayout->addWidget(bnClearHist, 9, 1); + boxLayout->addWidget(bnClearHist, rowID, 2); connect(bnClearHist, &QPushButton::clicked, this, [=](){ h2D->Clear(); @@ -308,14 +341,14 @@ inline void CoincidentAnalyzer::SetUpCanvas(){ }); QPushButton * bnSaveSettings = new QPushButton("Save Settings", this); - boxLayout->addWidget(bnSaveSettings, 9, 2); + boxLayout->addWidget(bnSaveSettings, rowID, 3); - connect(bnSaveSettings, &QPushButton::clicked, this, &CoincidentAnalyzer::SaveHistRange); + connect(bnSaveSettings, &QPushButton::clicked, this, &CoincidentAnalyzer::SaveSettings); QPushButton * bnLoadSettings = new QPushButton("Load Settings", this); - boxLayout->addWidget(bnLoadSettings, 9, 3); + boxLayout->addWidget(bnLoadSettings, rowID, 4); - connect(bnLoadSettings, &QPushButton::clicked, this, &CoincidentAnalyzer::LoadHistRange); + connect(bnLoadSettings, &QPushButton::clicked, this, &CoincidentAnalyzer::LoadSettings); } @@ -445,22 +478,24 @@ inline void CoincidentAnalyzer::UpdateHistograms(){ hMulti->UpdatePlot(); h1g->UpdatePlot(); - // QList cutNameList = h2D->GetCutNameList(); - // for( int p = 0; p < cutList.count(); p ++){ - // if( cutList[p].isEmpty() ) continue; - // double dT = (tMax[p]-tMin[p]) * tick2ns / 1e9; // tick to sec - // double rate = count[p]*1.0/(dT); - //printf("%llu %llu, %f %d\n", tMin[p], tMax[p], dT, count[p]); - //printf("%10s | %d | %f Hz \n", cutNameList[p].toStdString().c_str(), count[p], rate); - - // influx->AddDataPoint("Cut,name=" + cutNameList[p].toStdString()+ " value=" + std::to_string(rate)); - // influx->WriteData(dataBaseName); - // influx->ClearDataPointsBuffer(); - // } + if( influx ){ + QList cutNameList = h2D->GetCutNameList(); + for( int p = 0; p < cutList.count(); p ++){ + if( cutList[p].isEmpty() ) continue; + double dT = (tMax[p]-tMin[p]) / 1e9; + double rate = count[p]*1.0/(dT); + printf("%llu %llu, %f %d\n", tMin[p], tMax[p], dT, count[p]); + printf("%10s | %d | %f Hz \n", cutNameList[p].toStdString().c_str(), count[p], rate); + + influx->AddDataPoint("Cut,name=" + cutNameList[p].toStdString()+ " value=" + std::to_string(rate)); + } + influx->WriteData(dataBaseName.toStdString()); + influx->ClearDataPointsBuffer(); + } } -inline void CoincidentAnalyzer::SaveHistRange(){ +inline void CoincidentAnalyzer::SaveSettings(){ QString filePath = QFileDialog::getSaveFileName(this, "Save Settings to File", QDir::toNativeSeparators(rawDataPath + "/CoinAnaSettings.txt" ), @@ -498,6 +533,10 @@ inline void CoincidentAnalyzer::SaveHistRange(){ lines << QString::number(chkBackWardBuilding->isChecked()); lines << QString::number(sbBackwardCount->value()); + lines<< dataBaseIP; + lines<< dataBaseName; + lines<< dataBaseToken; + lines << "#===== End of File"; // Write each line to the file @@ -512,7 +551,7 @@ inline void CoincidentAnalyzer::SaveHistRange(){ } } -inline void CoincidentAnalyzer::LoadHistRange(){ +inline void CoincidentAnalyzer::LoadSettings(){ QString filePath = QFileDialog::getOpenFileName(this, "Load Settings to File", @@ -563,13 +602,17 @@ inline void CoincidentAnalyzer::LoadHistRange(){ if( count == 16 ) isBkEvtBuild = line.toInt(); if( count == 17 ) bkCount = line.toInt(); + if( count == 18 ) dataBaseIP = line; + if( count == 19 ) dataBaseName = line; + if( count == 20 ) dataBaseToken = line; + count ++; } file.close(); qDebug() << "File read successfully from" << filePath; - if( count >= 18 ){ + if( count >= 21 ){ sbUpdateTime->setValue(updateTime); chkBackWardBuilding->setChecked(isBkEvtBuild); @@ -594,6 +637,8 @@ inline void CoincidentAnalyzer::LoadHistRange(){ h1g->Rebin(a_bin, a_min, a_max); h2D->Rebin(x_bin, x_min, x_max, y_bin, y_min, y_max); + SetDatabase(dataBaseIP, dataBaseName, dataBaseToken); + } }else { diff --git a/analyzers/RAISOR.h b/analyzers/RAISOR.h index a10b7db..e078ff4 100644 --- a/analyzers/RAISOR.h +++ b/analyzers/RAISOR.h @@ -124,7 +124,7 @@ inline void RAISOR::UpdateHistograms(){ //printf("%10s | %d | %f Hz \n", cutNameList[p].toStdString().c_str(), count[p], rate); influx->AddDataPoint("Cut,name=" + cutNameList[p].toStdString()+ " value=" + std::to_string(rate)); - influx->WriteData(dataBaseName); + influx->WriteData(dataBaseName.toStdString()); influx->ClearDataPointsBuffer(); } } diff --git a/analyzers/SplitPoleAnalyzer.h b/analyzers/SplitPoleAnalyzer.h index f1725c5..5137997 100644 --- a/analyzers/SplitPoleAnalyzer.h +++ b/analyzers/SplitPoleAnalyzer.h @@ -438,7 +438,7 @@ inline void SplitPole::UpdateHistograms(){ //printf("%10s | %d | %f Hz \n", cutNameList[p].toStdString().c_str(), count[p], rate); influx->AddDataPoint("Cut,name=" + cutNameList[p].toStdString()+ " value=" + std::to_string(rate)); - influx->WriteData(dataBaseName); + influx->WriteData(dataBaseName.toStdString()); influx->ClearDataPointsBuffer(); } From a32a1e0e7134b448e55bcfa46671dbbf4703527d Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Mon, 26 Aug 2024 15:25:19 -0400 Subject: [PATCH 50/72] bug fix, remove trailling space for influx inputs --- analyzers/Analyser.cpp | 3 ++- analyzers/CoincidentAnalyzer.h | 21 +++++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/analyzers/Analyser.cpp b/analyzers/Analyser.cpp index 6e3c781..2fcc2ae 100644 --- a/analyzers/Analyser.cpp +++ b/analyzers/Analyser.cpp @@ -102,6 +102,7 @@ void Analyzer::SetDatabase(QString IP, QString Name, QString Token){ bool foundDatabase = false; for( int i = 0; i < (int) databaseList.size(); i++){ if( databaseList[i] == dataBaseName.toStdString() ) foundDatabase = true; + // printf("%d | %s\n", i, databaseList[i].c_str()); } if( foundDatabase ){ influx->AddDataPoint("test value=1"); @@ -216,7 +217,7 @@ void Analyzer::SetDatabaseButton(){ // Show the dialog and get the result if (dialog.exec() == QDialog::Accepted) { - SetDatabase(ipLineEdit.text(), nameLineEdit.text(),tokenLineEdit.text()); + SetDatabase(ipLineEdit.text().trimmed(), nameLineEdit.text().trimmed(),tokenLineEdit.text().trimmed()); } } diff --git a/analyzers/CoincidentAnalyzer.h b/analyzers/CoincidentAnalyzer.h index a60ae52..b34db4c 100644 --- a/analyzers/CoincidentAnalyzer.h +++ b/analyzers/CoincidentAnalyzer.h @@ -44,6 +44,9 @@ private: bool allowSignalSlot; + QLineEdit * leInfluxIP; + QLineEdit * leDBName; + // declaie histograms Histogram2D * h2D; Histogram1D * h1; @@ -307,22 +310,28 @@ inline void CoincidentAnalyzer::SetUpCanvas(){ QLabel * lbIP = new QLabel("Database IP :", box); lbIP->setAlignment(Qt::AlignRight | Qt::AlignCenter); boxLayout->addWidget(lbIP, rowID, 0); - QLineEdit * leInfluxIP = new QLineEdit(box); + leInfluxIP = new QLineEdit(box); leInfluxIP->setReadOnly(true); boxLayout->addWidget(leInfluxIP, rowID, 1, 1, 3); QPushButton * bnInflux = new QPushButton("Set Influx", box); - boxLayout->addWidget(bnInflux, rowID, 1, 1, 3); + boxLayout->addWidget(bnInflux, rowID, 4); rowID ++; QLabel * lbDBName = new QLabel("Database name :", box); lbDBName->setAlignment(Qt::AlignRight | Qt::AlignCenter); boxLayout->addWidget(lbDBName, rowID, 0); - QLineEdit * leDBName= new QLineEdit(box); + leDBName = new QLineEdit(box); leDBName->setReadOnly(true); boxLayout->addWidget(leDBName, rowID, 1); - connect(bnInflux, &QPushButton::clicked, this, &Analyzer::SetDatabaseButton); + connect(bnInflux, &QPushButton::clicked, this, [=](){ + SetDatabaseButton(); + if( influx ) { + leDBName->setText(dataBaseName); + leInfluxIP->setText(dataBaseIP); + } + }); // rowID ++; // QFrame *separator3 = new QFrame(box); @@ -638,6 +647,10 @@ inline void CoincidentAnalyzer::LoadSettings(){ h2D->Rebin(x_bin, x_min, x_max, y_bin, y_min, y_max); SetDatabase(dataBaseIP, dataBaseName, dataBaseToken); + if( influx ){ + leDBName->setText(dataBaseName); + leInfluxIP->setText(dataBaseIP); + } } From ffb009e6da6943d13ca2f0d8a9902be6da898126 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Tue, 27 Aug 2024 12:48:00 -0400 Subject: [PATCH 51/72] bug fix on Data::CopyBuffer() --- ClassData.h | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/ClassData.h b/ClassData.h index cd07a35..2002cf1 100644 --- a/ClassData.h +++ b/ClassData.h @@ -90,6 +90,7 @@ class Data{ unsigned short GetNChannel() const {return numInputCh;} + void PrintBuffer(); void CopyBuffer( const char * buffer, const unsigned int size); void DecodeBuffer(bool fastDecode, int verbose = 0); /// fastDecode will not save waveform @@ -346,7 +347,10 @@ inline void Data::ClearBuffer(){ } inline void Data::CopyBuffer(const char * buffer, const unsigned int size){ + if( this->buffer ) delete this->buffer; + this->buffer = (char*) malloc(size); std::memcpy(this->buffer, buffer, size); + this->nByte = size; } inline void Data::ClearReferenceTime(){ @@ -559,12 +563,21 @@ inline void Data::PrintChData(unsigned short ch, unsigned int maxRowDisplay) con //^####################################################### //^####################################################### Decode +inline void Data::PrintBuffer(){ + if( buffer == NULL || nByte == 0 ) return; + printf("============== Received nByte : %u\n", nByte); + for( int i = 0; i < nByte/4; i++ ) { + ReadBuffer(i, 2); + printf("\n"); + } +} + inline unsigned int Data::ReadBuffer(unsigned int nWord, int verbose){ if( buffer == NULL ) return 0; unsigned int word = 0; for( int i = 0 ; i < 4 ; i++) word += ((buffer[i + 4 * nWord] & 0xFF) << 8*i); - if( verbose >= 2) printf("%6d | 0x%08X | ", nWord, word); + if( verbose >= 2) printf("%6d | 0x%08X |", nWord, word); return word; } @@ -1112,10 +1125,10 @@ inline int Data::DecodePSDDualChannelBlock(unsigned int ChannelMask, bool fastDe //if( DataIndex[channel] >= dataSize ) ClearData(); //if( verbose >= 2 ) printf("extra : 0x%08x, Qshort : %d, Qlong : %d \n", extra, Qshort, Qlong); - if( verbose == 1 ) printf("ch : %2d, Qshort : %6d, Qlong : %6d, timestamp : %llu\n", - channel, Qshort, Qlong, timeStamp * tick2ns); - if( verbose >= 2 ) printf("Qshort : %6d, Qlong : %6d, timestamp : %llu\n", - Qshort, Qlong, timeStamp * tick2ns); + if( verbose == 1 ) printf("ch : %2d, Qshort : %6d, Qlong : %6d, timestamp : %llu, fineTime : %u\n", + channel, Qshort, Qlong, timeStamp * tick2ns, (extra & 0x3FF) * tick2ns); + if( verbose >= 2 ) printf("Qshort : %6d, Qlong : %6d, timestamp : %llu, fineTime : %u\n", + Qshort, Qlong, timeStamp * tick2ns, (extra & 0x3FF) * tick2ns); From 76f8f22204635d107be7039842f302ebb483bc4a Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Tue, 27 Aug 2024 18:13:01 -0400 Subject: [PATCH 52/72] default PSD program set baseline to be 16 samples --- ClassData.h | 2 +- ClassDigitizer.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ClassData.h b/ClassData.h index 2002cf1..0fdbe66 100644 --- a/ClassData.h +++ b/ClassData.h @@ -566,7 +566,7 @@ inline void Data::PrintChData(unsigned short ch, unsigned int maxRowDisplay) con inline void Data::PrintBuffer(){ if( buffer == NULL || nByte == 0 ) return; printf("============== Received nByte : %u\n", nByte); - for( int i = 0; i < nByte/4; i++ ) { + for( unsigned int i = 0; i < nByte/4; i++ ) { ReadBuffer(i, 2); printf("\n"); } diff --git a/ClassDigitizer.cpp b/ClassDigitizer.cpp index e7dede4..bae427c 100644 --- a/ClassDigitizer.cpp +++ b/ClassDigitizer.cpp @@ -439,7 +439,7 @@ 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::DPPAlgorithmControl) + 0x7000 , 0x00100000 ); // baseline 16 sample ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::PSD::TriggerThreshold) + 0x7000 , 100 ); From 55210083fcd518d33bcc29c19ae28dfbd35bda2a Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Wed, 28 Aug 2024 14:17:39 -0400 Subject: [PATCH 53/72] in Aux/test.cpp, compare CAEN_DGTZ_GetDPPEvents for decode data --- Aux/Makefile | 2 +- Aux/test.cpp | 132 +++++++++++++++++++++++++-------------------------- 2 files changed, 66 insertions(+), 68 deletions(-) diff --git a/Aux/Makefile b/Aux/Makefile index 8d51ec9..1433ca5 100644 --- a/Aux/Makefile +++ b/Aux/Makefile @@ -34,7 +34,7 @@ ClassInfluxDB.o : ../ClassInfluxDB.cpp ../ClassInfluxDB.h test : test.cpp ../ClassDigitizer.o ../MultiBuilder.o ../ClassInfluxDB.o @echo "--------- making test" - $(CC) $(COPTS) -o test test.cpp ../ClassDigitizer.o ../MultiBuilder.o ../ClassInfluxDB.o $(CAENLIBS) $(ROOTLIBS) -lcurl + $(CC) -fPIC -DLINUX -O0 -std=c++17 -lpthread -g -o test test.cpp ../ClassDigitizer.o ../MultiBuilder.o ../ClassInfluxDB.o $(CAENLIBS) $(ROOTLIBS) -lcurl # test_indep : test_indep.cpp ../RegisterAddress.h ../macro.h # @echo "--------- making test_indep" diff --git a/Aux/test.cpp b/Aux/test.cpp index ae5dbae..63966c2 100644 --- a/Aux/test.cpp +++ b/Aux/test.cpp @@ -321,84 +321,82 @@ int TestDigitizerRaw(){ } + +void Compare_CAEN_Decoder(){ + + std::unique_ptr digi = std::make_unique(0, 49093, false, true); + Data * data = digi->GetData(); + + int ret; + int handle = digi->GetHandle(); + CAEN_DGTZ_DPP_PSD_Event_t *Events[16]; /// events buffer + uint32_t NumEvents[16]; + + uint32_t AllocatedSize = 0; + + ret |= CAEN_DGTZ_MallocDPPEvents(handle, reinterpret_cast(&Events), &AllocatedSize) ; + printf("allowcated %d byte for Events\n", AllocatedSize); + + + printf("======================== start ACQ \n"); + digi->StartACQ(); + + int ch = 0; + for( int i = 0; i < 5; i ++ ){ + usleep(1000*1000); // every 1 second + + digi->ReadData(); + // data->CopyBuffer(cpBuffer, bufferSize); + data->DecodeBuffer(false, 4); + + if( data->nByte > 0 ){ + ret = (CAEN_DGTZ_ErrorCode) CAEN_DGTZ_GetDPPEvents(handle, data->buffer, data->nByte, reinterpret_cast(&Events), NumEvents); + if (ret) { + printf("Error when getting events from data %d\n", ret); + continue; + } + + printf("============ %u\n", NumEvents[0]); + + for( int ev = 0; ev < NumEvents[0]; ev++ ){ + + printf("-------- ev %d\n", ev); + printf( " Format : 0x%04x\n", Events[ch][ev].Format); + printf( "TimeTag : 0x%08x\n", Events[ch][ev].TimeTag); + printf(" E_short : 0x%04x\n", Events[ch][ev].ChargeShort); + printf(" E_long : 0x%04x\n", (Events[ch][ev].ChargeLong & 0xffff)); + printf("Baseline : 0x%04x\n", (Events[ch][ev].Baseline & 0xffff)); + printf(" Pur : 0x%04x\n", Events[ch][ev].Pur); + printf(" Extra : 0x%08x\n", Events[ch][ev].Extras); + + + } + } + + } + + digi->StopACQ(); + + printf("======================== ACQ Stopped.\n"); + +} + //^====================================== int main(int argc, char* argv[]){ - //TestDigitizerRaw(); - - // CheckBufferSize(5, 4); + Compare_CAEN_Decoder(); - //GetOneAgg(); + // Data * data = digi->GetData(); - Digitizer * digi = new Digitizer(0, 49093, 0, true); + // MultiBuilder * builder = new MultiBuilder(data, DPPType::DPP_PHA_CODE, digi->GetSerialNumber()); + // builder->SetTimeWindow(100); - delete digi; - // digi->WriteRegister(DPP::QDC::PreTrigger, 60, -1); - // digi->WriteRegister(DPP::QDC::TriggerThreshold_sub2, 17, -1); - // digi->SetBits(DPP::QDC::DPPAlgorithmControl, DPP::QDC::Bit_DPPAlgorithmControl::ChargeSensitivity, 0, -1); - // digi->SetBits(DPP::QDC::DPPAlgorithmControl, DPP::QDC::Bit_DPPAlgorithmControl::InputSmoothingFactor, 4, -1); - // digi->SetBits(DPP::QDC::DPPAlgorithmControl, DPP::QDC::Bit_DPPAlgorithmControl::BaselineAvg, 2, -1); - - // digi->WriteRegister(DPP::QDC::GateWidth, 608/16, -1); - - // digi->WriteRegister(DPP::QDC::GroupEnableMask, 0x01); - - // digi->WriteRegister(DPP::QDC::NumberEventsPerAggregate, 10, -1); - // digi->WriteRegister(DPP::AggregateOrganization, 0, -1); - // digi->WriteRegister(DPP::MaxAggregatePerBlockTransfer, 100, -1); - - // digi->SetBits(DPP::QDC::DPPAlgorithmControl, DPP::QDC::Bit_DPPAlgorithmControl::Polarity, 0, -1); - - /* - digi->SetBits(DPP::BoardConfiguration, DPP::Bit_BoardConfig::EnableExtra2, 1, -1); - digi->SetBits(DPP::BoardConfiguration, DPP::Bit_BoardConfig::RecordTrace, 0, -1); - - Data * data = digi->GetData(); - - MultiBuilder * builder = new MultiBuilder(data, DPPType::DPP_PHA_CODE, digi->GetSerialNumber()); - builder->SetTimeWindow(100); - - //remove("haha_*.fsu"); - //data->OpenSaveFile("haha"); - - digi->StartACQ(); - - for( int i = 0; i < 5; i ++ ){ - usleep(1000*1000); - digi->ReadData(); - data->DecodeBuffer(true, 0); - //data->DecodeBuffer(false, 2); - //data->SaveData(); - //data->PrintStat(); - - data->PrintAllData(true); - - //builder->BuildEvents(false, true, true); - builder->BuildEventsBackWard(20, true); - - builder->PrintStat(); - // int index = data->NumEventsDecoded[0]; - // printf("-------------- %ld \n", data->Waveform1[0][index].size()); - - } - digi->StopACQ(); - - //data->CloseSaveFile(); - builder->BuildEvents(true, true, true); - - data->PrintAllData(); - - builder->PrintAllEvent(); // TODO - */ - - // digi->CloseDigitizer(); - // delete digi; - return 0; } + //********************************* //********************************* From 0a751eaab1dc06788f041a9c6690dc1df65721eb Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Wed, 28 Aug 2024 16:45:23 -0400 Subject: [PATCH 54/72] [Major] remove histogram timing thread, make a new worker, move to a thread to fill histograms --- FSUDAQ.cpp | 58 +++++-------------- FSUDAQ.h | 2 +- SingleSpectra.cpp | 102 +++++++------------------------- SingleSpectra.h | 145 +++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 163 insertions(+), 144 deletions(-) diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index 4c34c8f..bcdd1b6 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -36,7 +36,6 @@ FSUDAQ::FSUDAQ(QWidget *parent) : QMainWindow(parent){ scope = nullptr; digiSettings = nullptr; singleHistograms = nullptr; - histThread = nullptr; onlineAnalyzer = nullptr; runTimer = new QTimer(); breakAutoRepeat = true; @@ -323,17 +322,6 @@ FSUDAQ::~FSUDAQ(){ if( scope ) delete scope; - if( histThread ){ - - if( !histThread->isStopped() ){ - histThread->Stop(); - histThread->quit(); - histThread->wait(); - } - - delete histThread; - } - if( singleHistograms ) delete singleHistograms; if( onlineAnalyzer ) delete onlineAnalyzer; @@ -743,12 +731,6 @@ void FSUDAQ::OpenDigitizers(){ } singleHistograms = new SingleSpectra(digi, nDigi, rawDataPath); - histThread = new TimingThread(this); - histThread->SetWaitTimeinSec(singleHistograms->GetMaxFillTime()/1000.); - connect(histThread, &TimingThread::timeUp, this, [=](){ - if( singleHistograms == nullptr && !singleHistograms->IsFillHistograms()) return; - singleHistograms->FillHistograms(); - }); LogMsg("====== " + QString("Done. Opened %1 digitizer(s).").arg(nDigi) + " ====="); @@ -784,22 +766,12 @@ void FSUDAQ::CloseDigitizers(){ scalarThread->exit(); CleanUpScalar(); - if( histThread){ - histThread->Stop(); - histThread->quit(); - histThread->wait(); - - delete histThread; - histThread = nullptr; - } - if( onlineAnalyzer ){ onlineAnalyzer->close(); delete onlineAnalyzer; onlineAnalyzer = nullptr; } - if( singleHistograms ){ singleHistograms->close(); delete singleHistograms; @@ -1054,6 +1026,9 @@ void FSUDAQ::OpenScalar(){ void FSUDAQ::UpdateScalar(){ DebugPrint("%s", "FSUDAQ"); + + // printf("================== FSUDAQ::%s\n", __func__); + if( digi == nullptr ) return; if( scalar == nullptr ) return; //if( !scalar->isVisible() ) return; @@ -1066,6 +1041,7 @@ void FSUDAQ::UpdateScalar(){ uint64_t totalFileSize = 0; for( unsigned int iDigi = 0; iDigi < nDigi; iDigi++){ + // printf("======== digi-%d\n", iDigi); if( digi[iDigi]->IsBoardDisabled() ) continue; uint32_t acqStatus = digi[iDigi]->GetACQStatusFromMemory(); @@ -1107,6 +1083,7 @@ void FSUDAQ::UpdateScalar(){ } // digiMTX[iDigi].unlock(); + // printf("============= end of FSUDAQ::%s\n", __func__); } @@ -1181,7 +1158,7 @@ void FSUDAQ::StartACQ(){ } lbScalarACQStatus->setText("ACQ On"); - if( singleHistograms != nullptr ) histThread->start(); + if( singleHistograms != nullptr ) singleHistograms->startWork(); bnStartACQ->setEnabled(false); bnStartACQ->setStyleSheet(""); @@ -1256,13 +1233,9 @@ void FSUDAQ::StopACQ(){ } if( onlineAnalyzer ) onlineAnalyzer->StopThread(); + if( singleHistograms ) singleHistograms->stopWork(); + - if( singleHistograms && histThread->isRunning()){ - histThread->Stop(); - histThread->quit(); - histThread->wait(); - singleHistograms->ClearInternalDataCount(); - } lbScalarACQStatus->setText("ACQ Off"); bnStartACQ->setEnabled(true); @@ -1755,19 +1728,14 @@ void FSUDAQ::OpenScope(){ } if( digiSettings ) digiSettings->setEnabled(!onOff); - - if( singleHistograms ){ - if( onOff) { - histThread->start(); + if( singleHistograms ) { + if( onOff ) { + singleHistograms->startWork(); }else{ - if( histThread->isRunning()){ - histThread->Stop(); - histThread->quit(); - histThread->wait(); - singleHistograms->ClearInternalDataCount(); - } + singleHistograms->stopWork(); } } + }); connect(scope, &Scope::UpdateScaler, this, &FSUDAQ::UpdateScalar); diff --git a/FSUDAQ.h b/FSUDAQ.h index 751dd93..90423ec 100644 --- a/FSUDAQ.h +++ b/FSUDAQ.h @@ -194,7 +194,7 @@ private: //@----- SingleSpectra SingleSpectra * singleHistograms; - TimingThread * histThread; + // TimingThread * histThread; //@----- Analyzer Analyzer * onlineAnalyzer; diff --git a/SingleSpectra.cpp b/SingleSpectra.cpp index 346af9f..a6de8ee 100644 --- a/SingleSpectra.cpp +++ b/SingleSpectra.cpp @@ -18,8 +18,6 @@ SingleSpectra::SingleSpectra(Digitizer ** digi, unsigned int nDigi, QString rawD isSignalSlotActive = true; setWindowTitle("Single Histograms"); - - //setWindowFlags( this->windowFlags() & ~Qt::WindowCloseButtonHint ); //====== resize window if screen too small QScreen * screen = QGuiApplication::primaryScreen(); @@ -29,7 +27,6 @@ SingleSpectra::SingleSpectra(Digitizer ** digi, unsigned int nDigi, QString rawD }else{ setGeometry(0, 0, 1000, 800); } - // setGeometry(0, 0, 1000, 800); QWidget * layoutWidget = new QWidget(this); setCentralWidget(layoutWidget); @@ -174,11 +171,10 @@ SingleSpectra::SingleSpectra(Digitizer ** digi, unsigned int nDigi, QString rawD }); - QCheckBox * chkIsFillHistogram = new QCheckBox("Fill Histograms", this); + 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; + isFillingHistograms = false; QLabel * lbSettingPath = new QLabel( settingPath , this); ctrlLayout->addWidget(lbSettingPath, 1, 0, 1, 6); @@ -237,10 +233,28 @@ SingleSpectra::SingleSpectra(Digitizer ** digi, unsigned int nDigi, QString rawD ClearInternalDataCount(); + workerThread = new QThread(this); + histWorker = new HistWorker(this); + timer = new QTimer(this); + + histWorker->moveToThread(workerThread); + + // Setup the timer to trigger every second + connect(timer, &QTimer::timeout, histWorker, &HistWorker::FillHistograms); + workerThread->start(); + } SingleSpectra::~SingleSpectra(){ DebugPrint("%s", "SingleSpectra"); + + timer->stop(); + + if( workerThread->isRunning() ){ + workerThread->quit(); + workerThread->wait(); + } + SaveSetting(); for( unsigned int i = 0; i < nDigi; i++ ){ @@ -309,82 +323,6 @@ void SingleSpectra::ChangeHistView(){ } -void SingleSpectra::FillHistograms(){ - // DebugPrint("%s", "SingleSpectra"); - if( !fillHistograms ) return; - - timespec t0, t1; - - QVector randomDigiList = generateNonRepeatedCombination(nDigi); - - // qDebug() << randomDigiList; - - for( int i = 0; i < nDigi; i++){ - int ID = randomDigiList[i]; - - QVector randomChList = generateNonRepeatedCombination(digi[ID]->GetNumInputCh()); - - // qDebug() << randomChList; - - // digiMTX[ID].lock(); - - // digi[ID]->GetData()->PrintAllData(); - - 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 = digi[ID]->GetData()->GetEnergy(ch, lastFilledIndex[ID][ch]); - - // printf(" ch: %d, last fill idx : %d | %d \n", ch, lastFilledIndex[ID][ch], data); - - hist[ID][ch]->Fill( data ); - if( digi[i]->GetDPPType() == DPPTypeCode::DPP_PSD_CODE ){ - uShort e2 = digi[ID]->GetData()->GetEnergy2(ch, lastFilledIndex[ID][ch]); - // printf("%u \n", e2); - hist[ID][ch]->Fill( e2, 1); - } - hist2D[ID]->Fill(ch, data); - } - if( histVisibility[ID][ch] ) hist[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; - } - - if( hist2DVisibility[ID] ) hist2D[ID]->UpdatePlot(); - // digiMTX[ID].unlock(); - - } -} - void SingleSpectra::SaveSetting(){ DebugPrint("%s", "SingleSpectra"); diff --git a/SingleSpectra.h b/SingleSpectra.h index 721f05c..491bb99 100644 --- a/SingleSpectra.h +++ b/SingleSpectra.h @@ -20,6 +20,7 @@ #include "Histogram1D.h" #include "Histogram2D.h" +class HistWorker; //Forward decalration //^==================================================== //^==================================================== @@ -31,8 +32,8 @@ public: ~SingleSpectra(); void ClearInternalDataCount(); - void SetFillHistograms(bool onOff) { fillHistograms = onOff;} - bool IsFillHistograms() const {return fillHistograms;} + // void SetFillHistograms(bool onOff) { fillHistograms = onOff;} + // bool IsFillHistograms() const {return fillHistograms;} void LoadSetting(); void SaveSetting(); @@ -42,20 +43,39 @@ public: QVector generateNonRepeatedCombination(int size); -public slots: - void FillHistograms(); - void ChangeHistView(); -private: + /// This should be private.... + int lastFilledIndex[MaxNDigitizer][MaxNChannels]; + int loopFilledIndex[MaxNDigitizer][MaxNChannels]; + bool histVisibility[MaxNDigitizer][MaxNChannels]; + bool hist2DVisibility[MaxNDigitizer]; + unsigned short maxFillTimePerDigi; + + bool isFillingHistograms; + Histogram1D * hist[MaxNDigitizer][MaxNChannels]; + Histogram2D * hist2D[MaxNDigitizer]; Digitizer ** digi; unsigned short nDigi; - Histogram1D * hist[MaxNDigitizer][MaxNChannels]; - Histogram2D * hist2D[MaxNDigitizer]; + void startWork(){ + printf("timer start\n"); + timer->start(maxFillTimeinMilliSec); + } + void stopWork(){ + printf("timer stop\n"); + timer->stop(); + ClearInternalDataCount(); + } + + QCheckBox * chkIsFillHistogram; + +public slots: + // void FillHistograms(); + void ChangeHistView(); + +private: - bool histVisibility[MaxNDigitizer][MaxNChannels]; - bool hist2DVisibility[MaxNDigitizer]; RComboBox * cbDivision; @@ -66,17 +86,110 @@ private: QGridLayout * histLayout; int oldBd, oldCh; - int lastFilledIndex[MaxNDigitizer][MaxNChannels]; - int loopFilledIndex[MaxNDigitizer][MaxNChannels]; - - bool fillHistograms; - QString settingPath; unsigned short maxFillTimeinMilliSec; - unsigned short maxFillTimePerDigi; bool isSignalSlotActive; + QThread * workerThread; + HistWorker * histWorker; + QTimer * timer; + }; + +//^#======================================================== HistWorker +class HistWorker : public QObject{ + Q_OBJECT +public: + HistWorker(SingleSpectra * parent): SS(parent){} + +public slots: + void FillHistograms(){ + + // printf("%s | %d %d \n", __func__, SS->chkIsFillHistogram->checkState(), SS->isFillingHistograms); + if( SS->chkIsFillHistogram->checkState() == Qt::Unchecked ) return; + if( SS->isFillingHistograms) return; + + SS->isFillingHistograms = true; + timespec t0, t1; + + QVector randomDigiList = SS->generateNonRepeatedCombination(SS->nDigi); + + // qDebug() << randomDigiList; + + for( int i = 0; i < SS->nDigi; i++){ + int ID = randomDigiList[i]; + + QVector randomChList = SS->generateNonRepeatedCombination(SS->digi[ID]->GetNumInputCh()); + + // qDebug() << randomChList; + // digiMTX[ID].lock(); + // digi[ID]->GetData()->PrintAllData(); + + clock_gettime(CLOCK_REALTIME, &t0); + for( int k = 0; k < SS->digi[ID]->GetNumInputCh(); k ++ ){ + int ch = randomChList[k]; + int lastIndex = SS->digi[ID]->GetData()->GetDataIndex(ch); + if( lastIndex < 0 ) continue; + printf("--- ch %2d | last index %d \n", ch, lastIndex); + + int loopIndex = SS->digi[ID]->GetData()->GetLoopIndex(ch); + + int temp1 = lastIndex + loopIndex * SS->digi[ID]->GetData()->GetDataSize(); + int temp2 = SS->lastFilledIndex[ID][ch] + SS->loopFilledIndex[ID][ch] * SS->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 > SS->digi[ID]->GetData()->GetDataSize() ) { //DefaultDataSize = 10k + temp2 = temp1 - SS->digi[ID]->GetData()->GetDataSize(); + SS->lastFilledIndex[ID][ch] = lastIndex; + SS->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 ++){ + SS->lastFilledIndex[ID][ch] ++; + if( SS->lastFilledIndex[ID][ch] > SS->digi[ID]->GetData()->GetDataSize() ) { + SS->lastFilledIndex[ID][ch] = 0; + SS->loopFilledIndex[ID][ch] ++; + } + + uShort data = SS->digi[ID]->GetData()->GetEnergy(ch, SS->lastFilledIndex[ID][ch]); + + // printf(" ch: %d, last fill idx : %d | %d \n", ch, lastFilledIndex[ID][ch], data); + + SS->hist[ID][ch]->Fill( data ); + if( SS->digi[i]->GetDPPType() == DPPTypeCode::DPP_PSD_CODE ){ + uShort e2 = SS->digi[ID]->GetData()->GetEnergy2(ch, SS->lastFilledIndex[ID][ch]); + // printf("%u \n", e2); + SS->hist[ID][ch]->Fill( e2, 1); + } + SS->hist2D[ID]->Fill(ch, data); + } + if( SS->histVisibility[ID][ch] ) SS->hist[ID][ch]->UpdatePlot(); + + clock_gettime(CLOCK_REALTIME, &t1); + if( t1.tv_nsec - t0.tv_nsec + (t1.tv_sec - t0.tv_sec)*1e9 > SS->maxFillTimePerDigi * 1e6 ) break; + } + + if( SS->hist2DVisibility[ID] ) SS->hist2D[ID]->UpdatePlot(); + // digiMTX[ID].unlock(); + + } + + SS->isFillingHistograms = false; + emit workDone(); + } + +signals: + void workDone(); + +private: + SingleSpectra * SS; +}; + #endif \ No newline at end of file From fbd98067da84c1ead4655b19c366d517228f1a45 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Wed, 28 Aug 2024 16:53:25 -0400 Subject: [PATCH 55/72] remove some printf, remove Rebin button in SingleSpatra class --- FSUDAQ.cpp | 2 +- SingleSpectra.cpp | 92 +---------------------------------------------- SingleSpectra.h | 6 ++-- 3 files changed, 5 insertions(+), 95 deletions(-) diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index bcdd1b6..a8ad4a8 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -1289,7 +1289,7 @@ void FSUDAQ::StopACQ(){ // bnDigiSettings->setEnabled(true); repaint(); - printf("================ end of %s \n", __func__); + // printf("================ end of %s \n", __func__); } diff --git a/SingleSpectra.cpp b/SingleSpectra.cpp index a6de8ee..f996fbe 100644 --- a/SingleSpectra.cpp +++ b/SingleSpectra.cpp @@ -81,98 +81,8 @@ SingleSpectra::SingleSpectra(Digitizer ** digi, unsigned int nDigi, QString rawD } }); - QPushButton * bnRebinDigi = new QPushButton("Rebin Energy", this); - ctrlLayout->addWidget(bnRebinDigi, 0, 6, 1, 2); - connect(bnRebinDigi, &QPushButton::clicked, this, [=](){ - int ID = cbDigi->currentIndex(); - int ch = cbCh->currentIndex(); - - int a_Bin; - float a_Min, a_Max; - - if( ch >= 0 ){ - a_Bin = hist[ID][ch]->GetNBin(); - a_Min = hist[ID][ch]->GetXMin(); - a_Max = hist[ID][ch]->GetXMax(); - }else{ - a_Bin = hist2D[ID]->GetYNBin(); - a_Min = hist2D[ID]->GetYMin(); - a_Max = hist2D[ID]->GetYMax(); - } - - //pop up a dialog for nBin and ranhe - - QDialog dialog(this); - dialog.setWindowTitle("Rebin histograms"); - - QFormLayout layout(&dialog); - - QLabel * info = new QLabel(&dialog); - info->setStyleSheet("color:red;"); - info->setText("This will also clear histogram!!"); - layout.addRow(info); - - QStringList nameList = {"Num. Bin", "x-Min", "x-Max"}; - QLineEdit* lineEdit[3]; - - for (int i = 0; i < 3; ++i) { - lineEdit[i] = new QLineEdit(&dialog); - layout.addRow(nameList[i] + " : ", lineEdit[i]); - } - lineEdit[0]->setText(QString::number(a_Bin)); - lineEdit[1]->setText(QString::number(a_Min)); - lineEdit[2]->setText(QString::number(a_Max)); - - QLabel * msg = new QLabel(&dialog); - msg->setStyleSheet("color:red;"); - layout.addRow(msg); - - QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &dialog); - layout.addRow(&buttonBox); - - double number[3]; - - QObject::connect(&buttonBox, &QDialogButtonBox::accepted, [&]() { - int OKcount = 0; - bool conversionOk = true; - for( int i = 0; i < 3; i++ ){ - number[i] = lineEdit[i]->text().toDouble(&conversionOk); - if( conversionOk ){ - OKcount++; - }else{ - msg->setText(nameList[i] + " is invalid."); - return; - } - } - - if( OKcount == 3 ) { - if( number[2] > number[1] ) { - dialog.accept(); - }else{ - msg->setText(nameList[2] + " is smaller than " + nameList[1]); - } - } - }); - QObject::connect(&buttonBox, &QDialogButtonBox::rejected, [&]() { dialog.reject();}); - - if( dialog.exec() == QDialog::Accepted ){ - if( hist2D[ID] ) { - hist2D[ID]->RebinY((int)number[0], number[1], number[2]); - hist2D[ID]->rescaleAxes(); - hist2D[ID]->UpdatePlot(); - } - for( int j = 0; j < digi[ID]->GetNumInputCh(); j++){ - if( hist[ID][j] ) { - hist[ID][j]->Rebin((int)number[0], number[1], number[2]); - hist[ID][j]->UpdatePlot(); - } - } - } - - }); - chkIsFillHistogram = new QCheckBox("Fill Histograms", this); - ctrlLayout->addWidget(chkIsFillHistogram, 0, 8); + ctrlLayout->addWidget(chkIsFillHistogram, 0, 6, 1, 2); chkIsFillHistogram->setChecked(false); isFillingHistograms = false; diff --git a/SingleSpectra.h b/SingleSpectra.h index 491bb99..d8ee115 100644 --- a/SingleSpectra.h +++ b/SingleSpectra.h @@ -59,11 +59,11 @@ public: unsigned short nDigi; void startWork(){ - printf("timer start\n"); + // printf("timer start\n"); timer->start(maxFillTimeinMilliSec); } void stopWork(){ - printf("timer stop\n"); + // printf("timer stop\n"); timer->stop(); ClearInternalDataCount(); } @@ -132,7 +132,7 @@ public slots: int ch = randomChList[k]; int lastIndex = SS->digi[ID]->GetData()->GetDataIndex(ch); if( lastIndex < 0 ) continue; - printf("--- ch %2d | last index %d \n", ch, lastIndex); + // printf("--- ch %2d | last index %d \n", ch, lastIndex); int loopIndex = SS->digi[ID]->GetData()->GetLoopIndex(ch); From a08297d5cc64afcc072e6d6975508c67d499ecee Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Wed, 28 Aug 2024 17:22:41 -0400 Subject: [PATCH 56/72] Move updateScalar into a ScalarWorker, which live in a new Thread --- FSUDAQ.cpp | 131 ++++++++++++----------------------------------------- FSUDAQ.h | 114 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 138 insertions(+), 107 deletions(-) diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index a8ad4a8..ba03401 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -33,6 +33,7 @@ FSUDAQ::FSUDAQ(QWidget *parent) : QMainWindow(parent){ nDigi = 0; scalar = nullptr; + scalarUpdateTimeMilliSec = 1000; scope = nullptr; digiSettings = nullptr; singleHistograms = nullptr; @@ -301,18 +302,18 @@ FSUDAQ::FSUDAQ(QWidget *parent) : QMainWindow(parent){ CheckElog(); - LogMsg("====== FSU DAQ is ready. ======"); - } FSUDAQ::~FSUDAQ(){ DebugPrint("%s", "FSUDAQ"); if( scalar ) { - scalarThread->Stop(); - scalarThread->quit(); - scalarThread->exit(); + scalarTimer->stop(); + if( scalarThread->isRunning() ){ + scalarThread->quit(); + scalarThread->exit(); + } CleanUpScalar(); //don't need to delete scalar, it is managed by this } @@ -761,10 +762,12 @@ void FSUDAQ::CloseDigitizers(){ scope = nullptr; } - scalarThread->Stop(); - scalarThread->quit(); - scalarThread->exit(); - CleanUpScalar(); + scalarTimer->stop(); + if( scalarThread->isRunning() ){ + scalarThread->quit(); + scalarThread->exit(); + } + if( scalar ) CleanUpScalar(); if( onlineAnalyzer ){ onlineAnalyzer->close(); @@ -867,9 +870,18 @@ void FSUDAQ::SetupScalar(){ lbScalarACQStatus = nullptr; lbTotalFileSize = nullptr; - scalarThread = new TimingThread(scalar); - scalarThread->SetWaitTimeinSec(1.0); - connect(scalarThread, &TimingThread::timeUp, this, &FSUDAQ::UpdateScalar); + // scalarThread = new TimingThread(scalar); + // scalarThread->SetWaitTimeinSec(1.0); + // connect(scalarThread, &TimingThread::timeUp, this, &FSUDAQ::UpdateScalar); + + scalarThread = new QThread(this); + scalarWorker = new ScalarWorker(this); + scalarWorker->moveToThread(scalarThread); + + scalarTimer = new QTimer(this); + connect( scalarTimer, &QTimer::timeout, scalarWorker, &ScalarWorker::UpdateScalar); + + scalarThread->start(); unsigned short maxNChannel = 0; for( unsigned int k = 0; k < nDigi; k ++ ){ @@ -1024,87 +1036,6 @@ void FSUDAQ::OpenScalar(){ scalar->show(); } -void FSUDAQ::UpdateScalar(){ - DebugPrint("%s", "FSUDAQ"); - - // printf("================== FSUDAQ::%s\n", __func__); - - if( digi == nullptr ) return; - if( scalar == nullptr ) return; - //if( !scalar->isVisible() ) return; - - // digi[0]->GetData()->PrintAllData(); - - // lbLastUpdateTime->setText("Last update: " + QDateTime::currentDateTime().toString("MM.dd hh:mm:ss")); - lbLastUpdateTime->setText(QDateTime::currentDateTime().toString("MM/dd hh:mm:ss")); - scalarCount ++; - - uint64_t totalFileSize = 0; - for( unsigned int iDigi = 0; iDigi < nDigi; iDigi++){ - // printf("======== digi-%d\n", iDigi); - if( digi[iDigi]->IsBoardDisabled() ) continue; - - uint32_t acqStatus = digi[iDigi]->GetACQStatusFromMemory(); - //printf("Digi-%d : acq on/off ? : %d \n", digi[iDigi]->GetSerialNumber(), (acqStatus >> 2) & 0x1 ); - if( ( acqStatus >> 2 ) & 0x1 ){ - if( runStatus[iDigi]->styleSheet() == "") runStatus[iDigi]->setStyleSheet("background-color : green;"); - }else{ - if( runStatus[iDigi]->styleSheet() != "") runStatus[iDigi]->setStyleSheet(""); - } - - if(digiSettings && digiSettings->isVisible() && digiSettings->GetTabID() == iDigi) digiSettings->UpdateACQStatus(acqStatus); - - // digiMTX[iDigi].lock(); - - QString blockCountStr = QString::number(digi[iDigi]->GetData()->AggCount); - blockCountStr += "/" + QString::number(readDataThread[iDigi]->GetReadCount()); - readDataThread[iDigi]->SetReadCountZero(); - lbAggCount[iDigi]->setText(blockCountStr); - lbFileSize[iDigi]->setText(QString::number(digi[iDigi]->GetData()->GetTotalFileSize()/1024./1024., 'f', 3) + " MB"); - - digi[iDigi]->GetData()->CalTriggerRate(); //this will reset NumEventDecode & AggCount - if( chkSaveData->isChecked() ) totalFileSize += digi[iDigi]->GetData()->GetTotalFileSize(); - for( int i = 0; i < digi[iDigi]->GetNumInputCh(); i++){ - QString a = ""; - 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]); - 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); - leAccept[iDigi][i]->setText(b); - - if( influx && chkInflux->isChecked() && a != "inf" ){ - influx->AddDataPoint("TrigRate,Bd="+std::to_string(digi[iDigi]->GetSerialNumber()) + ",Ch=" + QString::number(i).rightJustified(2, '0').toStdString() + " value=" + a.toStdString()); - } - - } - } - - // digiMTX[iDigi].unlock(); - // printf("============= end of FSUDAQ::%s\n", __func__); - - } - - lbTotalFileSize->setText("Total Data Size : " + QString::number(totalFileSize/1024./1024., 'f', 3) + " MB"); - - repaint(); - scalar->repaint(); - - if( influx && chkInflux->isChecked() && scalarCount >= 3){ - if( chkSaveData->isChecked() ) { - influx->AddDataPoint("RunID value=" + std::to_string(runID)); - influx->AddDataPoint("FileSize value=" + std::to_string(totalFileSize)); - } - //nflux->PrintDataPoints(); - influx->WriteData(dataBaseName.toStdString()); - influx->ClearDataPointsBuffer(); - scalarCount = 0; - } - -} - //*************************************************************** //*************************************************************** void FSUDAQ::StartACQ(){ @@ -1149,7 +1080,7 @@ void FSUDAQ::StartACQ(){ // printf("------------ Go! \n"); // for( unsigned int i = 0; i < nDigi; i++) readDataThread[i]->go(); - scalarThread->start(); + if( scalar ) scalarTimer->start(scalarUpdateTimeMilliSec); if( !scalar->isVisible() ) { scalar->show(); @@ -1158,7 +1089,7 @@ void FSUDAQ::StartACQ(){ } lbScalarACQStatus->setText("ACQ On"); - if( singleHistograms != nullptr ) singleHistograms->startWork(); + if( singleHistograms ) singleHistograms->startWork(); bnStartACQ->setEnabled(false); bnStartACQ->setStyleSheet(""); @@ -1226,11 +1157,7 @@ void FSUDAQ::StopACQ(){ digi[i]->ReadACQStatus(); } - if( scalarThread->isRunning()){ - scalarThread->Stop(); - scalarThread->quit(); - scalarThread->wait(); - } + if( scalar ) scalarTimer->stop(); if( onlineAnalyzer ) onlineAnalyzer->StopThread(); if( singleHistograms ) singleHistograms->stopWork(); @@ -1738,8 +1665,7 @@ void FSUDAQ::OpenScope(){ }); - connect(scope, &Scope::UpdateScaler, this, &FSUDAQ::UpdateScalar); - + if( scalar ) connect(scope, &Scope::UpdateScaler, scalarWorker, &ScalarWorker::UpdateScalar); connect(scope, &Scope::UpdateOtherPanels, this, [=](){ UpdateAllPanels(1); }); scope->show(); @@ -1796,7 +1722,6 @@ void FSUDAQ::OpenAnalyzer(){ if( id < 0 ) return; if( onlineAnalyzer == nullptr ) { - //onlineAnalyzer = new Analyzer(digi, nDigi); if( id == 0 ) onlineAnalyzer = new CoincidentAnalyzer(digi, nDigi, rawDataPath); if( id == 1 ) onlineAnalyzer = new SplitPole(digi, nDigi); if( id == 2 ) onlineAnalyzer = new Encore(digi, nDigi); diff --git a/FSUDAQ.h b/FSUDAQ.h index 90423ec..9899361 100644 --- a/FSUDAQ.h +++ b/FSUDAQ.h @@ -20,6 +20,8 @@ #include "ClassInfluxDB.h" #include "analyzers/Analyser.h" +class ScalarWorker; //Forward declaration + //^#===================================================== FSUDAQ class FSUDAQ : public QMainWindow{ Q_OBJECT @@ -64,7 +66,7 @@ private slots: void SetupScalar(); void CleanUpScalar(); void OpenScalar(); - void UpdateScalar(); + // void UpdateScalar(); void StartACQ(); void StopACQ(); @@ -92,7 +94,8 @@ private slots: void SetAndLockInfluxElog(); -private: +// private: +public: Digitizer ** digi; unsigned int nDigi; @@ -168,7 +171,11 @@ private: //@----- Scalar QMainWindow * scalar; QGridLayout * scalarLayout; - TimingThread * scalarThread; + QThread * scalarThread; + ScalarWorker * scalarWorker; + QTimer * scalarTimer; + + // TimingThread * scalarThread; QLineEdit *** leTrigger; // need to delete manually QLineEdit *** leAccept; // need to delete manually QPushButton * runStatus[MaxNDigitizer]; @@ -178,6 +185,8 @@ private: QLabel * lbFileSize[MaxNDigitizer]; QLabel * lbTotalFileSize; + unsigned short scalarUpdateTimeMilliSec; + //@----- Run Record QMainWindow * runRecord; QStandardItemModel *model; @@ -194,7 +203,6 @@ private: //@----- SingleSpectra SingleSpectra * singleHistograms; - // TimingThread * histThread; //@----- Analyzer Analyzer * onlineAnalyzer; @@ -202,5 +210,103 @@ private: }; +//^======================== Scalar Worker + +class ScalarWorker : public QObject{ + Q_OBJECT +public: + ScalarWorker(FSUDAQ * parent): SS(parent){} + +public slots: + void UpdateScalar(){ + + DebugPrint("%s", "FSUDAQ"); + + // printf("================== FSUDAQ::%s\n", __func__); + + if( SS->digi == nullptr ) return; + if( SS->scalar == nullptr ) return; + //if( !scalar->isVisible() ) return; + + // digi[0]->GetData()->PrintAllData(); + + // lbLastUpdateTime->setText("Last update: " + QDateTime::currentDateTime().toString("MM.dd hh:mm:ss")); + SS->lbLastUpdateTime->setText(QDateTime::currentDateTime().toString("MM/dd hh:mm:ss")); + SS->scalarCount ++; + + uint64_t totalFileSize = 0; + for( unsigned int iDigi = 0; iDigi < SS->nDigi; iDigi++){ + // printf("======== digi-%d\n", iDigi); + if( SS->digi[iDigi]->IsBoardDisabled() ) continue; + + uint32_t acqStatus = SS->digi[iDigi]->GetACQStatusFromMemory(); + //printf("Digi-%d : acq on/off ? : %d \n", digi[iDigi]->GetSerialNumber(), (acqStatus >> 2) & 0x1 ); + if( ( acqStatus >> 2 ) & 0x1 ){ + if( SS->runStatus[iDigi]->styleSheet() == "") SS->runStatus[iDigi]->setStyleSheet("background-color : green;"); + }else{ + if( SS->runStatus[iDigi]->styleSheet() != "") SS->runStatus[iDigi]->setStyleSheet(""); + } + + if(SS->digiSettings && SS->digiSettings->isVisible() && SS->digiSettings->GetTabID() == iDigi) SS->digiSettings->UpdateACQStatus(acqStatus); + + // digiMTX[iDigi].lock(); + + QString blockCountStr = QString::number(SS->digi[iDigi]->GetData()->AggCount); + blockCountStr += "/" + QString::number(SS->readDataThread[iDigi]->GetReadCount()); + SS->readDataThread[iDigi]->SetReadCountZero(); + SS->lbAggCount[iDigi]->setText(blockCountStr); + SS->lbFileSize[iDigi]->setText(QString::number(SS->digi[iDigi]->GetData()->GetTotalFileSize()/1024./1024., 'f', 3) + " MB"); + + SS->digi[iDigi]->GetData()->CalTriggerRate(); //this will reset NumEventDecode & AggCount + if( SS->chkSaveData->isChecked() ) totalFileSize += SS->digi[iDigi]->GetData()->GetTotalFileSize(); + for( int i = 0; i < SS->digi[iDigi]->GetNumInputCh(); i++){ + QString a = ""; + QString b = ""; + + if( SS->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]); + QString a = QString::number(SS->digi[iDigi]->GetData()->TriggerRate[i], 'f', 2); + QString b = QString::number(SS->digi[iDigi]->GetData()->NonPileUpRate[i], 'f', 2); + SS->leTrigger[iDigi][i]->setText(a); + SS->leAccept[iDigi][i]->setText(b); + + if( SS->influx && SS->chkInflux->isChecked() && a != "inf" ){ + SS->influx->AddDataPoint("TrigRate,Bd="+std::to_string(SS->digi[iDigi]->GetSerialNumber()) + ",Ch=" + QString::number(i).rightJustified(2, '0').toStdString() + " value=" + a.toStdString()); + } + + } + } + + // digiMTX[iDigi].unlock(); + // printf("============= end of FSUDAQ::%s\n", __func__); + + } + + SS->lbTotalFileSize->setText("Total Data Size : " + QString::number(totalFileSize/1024./1024., 'f', 3) + " MB"); + + SS->repaint(); + SS->scalar->repaint(); + + if( SS->influx && SS->chkInflux->isChecked() && SS->scalarCount >= 3){ + if( SS->chkSaveData->isChecked() ) { + SS->influx->AddDataPoint("RunID value=" + std::to_string(SS->runID)); + SS->influx->AddDataPoint("FileSize value=" + std::to_string(totalFileSize)); + } + //nflux->PrintDataPoints(); + SS->influx->WriteData(SS->dataBaseName.toStdString()); + SS->influx->ClearDataPointsBuffer(); + SS->scalarCount = 0; + } + + emit workDone(); + } + +signals: + void workDone(); + +private: + FSUDAQ * SS; +}; + #endif // MAINWINDOW_H \ No newline at end of file From a5914f8ff88d6d3f441570eaa281c1bd571136e5 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Wed, 28 Aug 2024 17:58:12 -0400 Subject: [PATCH 57/72] restructure the workers --- FSUDAQ.cpp | 89 ++++++++++++++++++++++++++++++++- FSUDAQ.h | 88 +++----------------------------- SingleSpectra.cpp | 80 +++++++++++++++++++++++++++++ SingleSpectra.h | 116 +++++++------------------------------------ analyzers/Analyser.h | 23 +++++++++ 5 files changed, 215 insertions(+), 181 deletions(-) diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index ba03401..a158977 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -31,6 +31,7 @@ FSUDAQ::FSUDAQ(QWidget *parent) : QMainWindow(parent){ digi = nullptr; nDigi = 0; + isACQStarted= false; scalar = nullptr; scalarUpdateTimeMilliSec = 1000; @@ -1002,6 +1003,88 @@ void FSUDAQ::SetupScalar(){ } +void FSUDAQ::UpdateScalar(){ + + DebugPrint("%s", "FSUDAQ"); + + // printf("================== FSUDAQ::%s\n", __func__); + + if( digi == nullptr ) return; + if( scalar == nullptr ) return; + //if( !scalar->isVisible() ) return; + + // digi[0]->GetData()->PrintAllData(); + + // lbLastUpdateTime->setText("Last update: " + QDateTime::currentDateTime().toString("MM.dd hh:mm:ss")); + lbLastUpdateTime->setText(QDateTime::currentDateTime().toString("MM/dd hh:mm:ss")); + scalarCount ++; + + uint64_t totalFileSize = 0; + for( unsigned int iDigi = 0; iDigi < nDigi; iDigi++){ + // printf("======== digi-%d\n", iDigi); + if( digi[iDigi]->IsBoardDisabled() ) continue; + + uint32_t acqStatus = digi[iDigi]->GetACQStatusFromMemory(); + //printf("Digi-%d : acq on/off ? : %d \n", digi[iDigi]->GetSerialNumber(), (acqStatus >> 2) & 0x1 ); + if( ( acqStatus >> 2 ) & 0x1 ){ + if( runStatus[iDigi]->styleSheet() == "") runStatus[iDigi]->setStyleSheet("background-color : green;"); + }else{ + if( runStatus[iDigi]->styleSheet() != "") runStatus[iDigi]->setStyleSheet(""); + } + + if(digiSettings && digiSettings->isVisible() && digiSettings->GetTabID() == iDigi) digiSettings->UpdateACQStatus(acqStatus); + + // digiMTX[iDigi].lock(); + + QString blockCountStr = QString::number(digi[iDigi]->GetData()->AggCount); + blockCountStr += "/" + QString::number(readDataThread[iDigi]->GetReadCount()); + readDataThread[iDigi]->SetReadCountZero(); + lbAggCount[iDigi]->setText(blockCountStr); + lbFileSize[iDigi]->setText(QString::number(digi[iDigi]->GetData()->GetTotalFileSize()/1024./1024., 'f', 3) + " MB"); + + digi[iDigi]->GetData()->CalTriggerRate(); //this will reset NumEventDecode & AggCount + if( chkSaveData->isChecked() ) totalFileSize += digi[iDigi]->GetData()->GetTotalFileSize(); + for( int i = 0; i < digi[iDigi]->GetNumInputCh(); i++){ + QString a = ""; + 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]); + 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); + leAccept[iDigi][i]->setText(b); + + if( influx && chkInflux->isChecked() && a != "inf" ){ + influx->AddDataPoint("TrigRate,Bd="+std::to_string(digi[iDigi]->GetSerialNumber()) + ",Ch=" + QString::number(i).rightJustified(2, '0').toStdString() + " value=" + a.toStdString()); + } + + } + } + + // digiMTX[iDigi].unlock(); + // printf("============= end of FSUDAQ::%s\n", __func__); + + } + + lbTotalFileSize->setText("Total Data Size : " + QString::number(totalFileSize/1024./1024., 'f', 3) + " MB"); + + repaint(); + scalar->repaint(); + + if( influx && chkInflux->isChecked() && scalarCount >= 3){ + if( chkSaveData->isChecked() ) { + influx->AddDataPoint("RunID value=" + std::to_string(runID)); + influx->AddDataPoint("FileSize value=" + std::to_string(totalFileSize)); + } + //nflux->PrintDataPoints(); + influx->WriteData(dataBaseName.toStdString()); + influx->ClearDataPointsBuffer(); + scalarCount = 0; + } + +} + void FSUDAQ::CleanUpScalar(){ DebugPrint("%s", "FSUDAQ"); if( scalar == nullptr) return; @@ -1120,6 +1203,7 @@ void FSUDAQ::StartACQ(){ } } + isACQStarted = true; chkSaveData->setEnabled(false); // bnDigiSettings->setEnabled(false); @@ -1214,6 +1298,7 @@ void FSUDAQ::StopACQ(){ chkSaveData->setEnabled(true); // bnDigiSettings->setEnabled(true); + isACQStarted = false; repaint(); // printf("================ end of %s \n", __func__); @@ -1730,7 +1815,7 @@ void FSUDAQ::OpenAnalyzer(){ if( id == 5 ) onlineAnalyzer = new NeutronGamma(digi, nDigi, rawDataPath); if( id >= 0 ) onlineAnalyzer->show(); - if( scalarThread->isRunning() ) onlineAnalyzer->StartThread(); + if( isACQStarted ) onlineAnalyzer->StartThread(); }else{ @@ -1746,7 +1831,7 @@ void FSUDAQ::OpenAnalyzer(){ if( id >= 0 ){ onlineAnalyzer->show(); onlineAnalyzer->activateWindow(); - if( scalarThread->isRunning() ) onlineAnalyzer->StartThread(); + if( isACQStarted ) onlineAnalyzer->StartThread(); } } diff --git a/FSUDAQ.h b/FSUDAQ.h index 9899361..750a8c3 100644 --- a/FSUDAQ.h +++ b/FSUDAQ.h @@ -49,6 +49,9 @@ public: event->accept(); } +public slots: + void UpdateScalar(); + private slots: void OpenDataPath(); @@ -66,7 +69,6 @@ private slots: void SetupScalar(); void CleanUpScalar(); void OpenScalar(); - // void UpdateScalar(); void StartACQ(); void StopACQ(); @@ -94,11 +96,11 @@ private slots: void SetAndLockInfluxElog(); -// private: -public: +private: Digitizer ** digi; unsigned int nDigi; + bool isACQStarted; QString programSettingsFilePath; QString rawDataPath; @@ -219,85 +221,7 @@ public: public slots: void UpdateScalar(){ - - DebugPrint("%s", "FSUDAQ"); - - // printf("================== FSUDAQ::%s\n", __func__); - - if( SS->digi == nullptr ) return; - if( SS->scalar == nullptr ) return; - //if( !scalar->isVisible() ) return; - - // digi[0]->GetData()->PrintAllData(); - - // lbLastUpdateTime->setText("Last update: " + QDateTime::currentDateTime().toString("MM.dd hh:mm:ss")); - SS->lbLastUpdateTime->setText(QDateTime::currentDateTime().toString("MM/dd hh:mm:ss")); - SS->scalarCount ++; - - uint64_t totalFileSize = 0; - for( unsigned int iDigi = 0; iDigi < SS->nDigi; iDigi++){ - // printf("======== digi-%d\n", iDigi); - if( SS->digi[iDigi]->IsBoardDisabled() ) continue; - - uint32_t acqStatus = SS->digi[iDigi]->GetACQStatusFromMemory(); - //printf("Digi-%d : acq on/off ? : %d \n", digi[iDigi]->GetSerialNumber(), (acqStatus >> 2) & 0x1 ); - if( ( acqStatus >> 2 ) & 0x1 ){ - if( SS->runStatus[iDigi]->styleSheet() == "") SS->runStatus[iDigi]->setStyleSheet("background-color : green;"); - }else{ - if( SS->runStatus[iDigi]->styleSheet() != "") SS->runStatus[iDigi]->setStyleSheet(""); - } - - if(SS->digiSettings && SS->digiSettings->isVisible() && SS->digiSettings->GetTabID() == iDigi) SS->digiSettings->UpdateACQStatus(acqStatus); - - // digiMTX[iDigi].lock(); - - QString blockCountStr = QString::number(SS->digi[iDigi]->GetData()->AggCount); - blockCountStr += "/" + QString::number(SS->readDataThread[iDigi]->GetReadCount()); - SS->readDataThread[iDigi]->SetReadCountZero(); - SS->lbAggCount[iDigi]->setText(blockCountStr); - SS->lbFileSize[iDigi]->setText(QString::number(SS->digi[iDigi]->GetData()->GetTotalFileSize()/1024./1024., 'f', 3) + " MB"); - - SS->digi[iDigi]->GetData()->CalTriggerRate(); //this will reset NumEventDecode & AggCount - if( SS->chkSaveData->isChecked() ) totalFileSize += SS->digi[iDigi]->GetData()->GetTotalFileSize(); - for( int i = 0; i < SS->digi[iDigi]->GetNumInputCh(); i++){ - QString a = ""; - QString b = ""; - - if( SS->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]); - QString a = QString::number(SS->digi[iDigi]->GetData()->TriggerRate[i], 'f', 2); - QString b = QString::number(SS->digi[iDigi]->GetData()->NonPileUpRate[i], 'f', 2); - SS->leTrigger[iDigi][i]->setText(a); - SS->leAccept[iDigi][i]->setText(b); - - if( SS->influx && SS->chkInflux->isChecked() && a != "inf" ){ - SS->influx->AddDataPoint("TrigRate,Bd="+std::to_string(SS->digi[iDigi]->GetSerialNumber()) + ",Ch=" + QString::number(i).rightJustified(2, '0').toStdString() + " value=" + a.toStdString()); - } - - } - } - - // digiMTX[iDigi].unlock(); - // printf("============= end of FSUDAQ::%s\n", __func__); - - } - - SS->lbTotalFileSize->setText("Total Data Size : " + QString::number(totalFileSize/1024./1024., 'f', 3) + " MB"); - - SS->repaint(); - SS->scalar->repaint(); - - if( SS->influx && SS->chkInflux->isChecked() && SS->scalarCount >= 3){ - if( SS->chkSaveData->isChecked() ) { - SS->influx->AddDataPoint("RunID value=" + std::to_string(SS->runID)); - SS->influx->AddDataPoint("FileSize value=" + std::to_string(totalFileSize)); - } - //nflux->PrintDataPoints(); - SS->influx->WriteData(SS->dataBaseName.toStdString()); - SS->influx->ClearDataPointsBuffer(); - SS->scalarCount = 0; - } - + SS->UpdateScalar(); emit workDone(); } diff --git a/SingleSpectra.cpp b/SingleSpectra.cpp index f996fbe..b66be9e 100644 --- a/SingleSpectra.cpp +++ b/SingleSpectra.cpp @@ -233,6 +233,86 @@ void SingleSpectra::ChangeHistView(){ } +void SingleSpectra::FillHistograms(){ + + // printf("%s | %d %d \n", __func__, chkIsFillHistogram->checkState(), isFillingHistograms); + if( chkIsFillHistogram->checkState() == Qt::Unchecked ) return; + if( isFillingHistograms) return; + + isFillingHistograms = true; + timespec t0, t1; + + QVector randomDigiList = generateNonRepeatedCombination(nDigi); + + // qDebug() << randomDigiList; + + for( int i = 0; i < nDigi; i++){ + int ID = randomDigiList[i]; + + QVector randomChList = generateNonRepeatedCombination(digi[ID]->GetNumInputCh()); + + // qDebug() << randomChList; + // digiMTX[ID].lock(); + // digi[ID]->GetData()->PrintAllData(); + + 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); + if( lastIndex < 0 ) continue; + // printf("--- ch %2d | last index %d \n", ch, lastIndex); + + 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 = digi[ID]->GetData()->GetEnergy(ch, lastFilledIndex[ID][ch]); + + // printf(" ch: %d, last fill idx : %d | %d \n", ch, lastFilledIndex[ID][ch], data); + + hist[ID][ch]->Fill( data ); + if( digi[i]->GetDPPType() == DPPTypeCode::DPP_PSD_CODE ){ + uShort e2 = digi[ID]->GetData()->GetEnergy2(ch, lastFilledIndex[ID][ch]); + // printf("%u \n", e2); + hist[ID][ch]->Fill( e2, 1); + } + hist2D[ID]->Fill(ch, data); + } + if( histVisibility[ID][ch] ) hist[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; + } + + if( hist2DVisibility[ID] ) hist2D[ID]->UpdatePlot(); + // digiMTX[ID].unlock(); + + } + + isFillingHistograms = false; + +} + void SingleSpectra::SaveSetting(){ DebugPrint("%s", "SingleSpectra"); diff --git a/SingleSpectra.h b/SingleSpectra.h index d8ee115..4e1be36 100644 --- a/SingleSpectra.h +++ b/SingleSpectra.h @@ -43,21 +43,9 @@ public: QVector generateNonRepeatedCombination(int size); - - /// This should be private.... - int lastFilledIndex[MaxNDigitizer][MaxNChannels]; - int loopFilledIndex[MaxNDigitizer][MaxNChannels]; - bool histVisibility[MaxNDigitizer][MaxNChannels]; - bool hist2DVisibility[MaxNDigitizer]; - unsigned short maxFillTimePerDigi; - - bool isFillingHistograms; - Histogram1D * hist[MaxNDigitizer][MaxNChannels]; - Histogram2D * hist2D[MaxNDigitizer]; - - Digitizer ** digi; - unsigned short nDigi; - +public slots: + void FillHistograms(); + void ChangeHistView(); void startWork(){ // printf("timer start\n"); timer->start(maxFillTimeinMilliSec); @@ -68,14 +56,23 @@ public: ClearInternalDataCount(); } - QCheckBox * chkIsFillHistogram; - -public slots: - // void FillHistograms(); - void ChangeHistView(); - private: + Digitizer ** digi; + unsigned short nDigi; + + int lastFilledIndex[MaxNDigitizer][MaxNChannels]; + int loopFilledIndex[MaxNDigitizer][MaxNChannels]; + bool histVisibility[MaxNDigitizer][MaxNChannels]; + bool hist2DVisibility[MaxNDigitizer]; + unsigned short maxFillTimePerDigi; + + bool isFillingHistograms; + Histogram1D * hist[MaxNDigitizer][MaxNChannels]; + Histogram2D * hist2D[MaxNDigitizer]; + + + QCheckBox * chkIsFillHistogram; RComboBox * cbDivision; @@ -106,82 +103,7 @@ public: public slots: void FillHistograms(){ - - // printf("%s | %d %d \n", __func__, SS->chkIsFillHistogram->checkState(), SS->isFillingHistograms); - if( SS->chkIsFillHistogram->checkState() == Qt::Unchecked ) return; - if( SS->isFillingHistograms) return; - - SS->isFillingHistograms = true; - timespec t0, t1; - - QVector randomDigiList = SS->generateNonRepeatedCombination(SS->nDigi); - - // qDebug() << randomDigiList; - - for( int i = 0; i < SS->nDigi; i++){ - int ID = randomDigiList[i]; - - QVector randomChList = SS->generateNonRepeatedCombination(SS->digi[ID]->GetNumInputCh()); - - // qDebug() << randomChList; - // digiMTX[ID].lock(); - // digi[ID]->GetData()->PrintAllData(); - - clock_gettime(CLOCK_REALTIME, &t0); - for( int k = 0; k < SS->digi[ID]->GetNumInputCh(); k ++ ){ - int ch = randomChList[k]; - int lastIndex = SS->digi[ID]->GetData()->GetDataIndex(ch); - if( lastIndex < 0 ) continue; - // printf("--- ch %2d | last index %d \n", ch, lastIndex); - - int loopIndex = SS->digi[ID]->GetData()->GetLoopIndex(ch); - - int temp1 = lastIndex + loopIndex * SS->digi[ID]->GetData()->GetDataSize(); - int temp2 = SS->lastFilledIndex[ID][ch] + SS->loopFilledIndex[ID][ch] * SS->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 > SS->digi[ID]->GetData()->GetDataSize() ) { //DefaultDataSize = 10k - temp2 = temp1 - SS->digi[ID]->GetData()->GetDataSize(); - SS->lastFilledIndex[ID][ch] = lastIndex; - SS->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 ++){ - SS->lastFilledIndex[ID][ch] ++; - if( SS->lastFilledIndex[ID][ch] > SS->digi[ID]->GetData()->GetDataSize() ) { - SS->lastFilledIndex[ID][ch] = 0; - SS->loopFilledIndex[ID][ch] ++; - } - - uShort data = SS->digi[ID]->GetData()->GetEnergy(ch, SS->lastFilledIndex[ID][ch]); - - // printf(" ch: %d, last fill idx : %d | %d \n", ch, lastFilledIndex[ID][ch], data); - - SS->hist[ID][ch]->Fill( data ); - if( SS->digi[i]->GetDPPType() == DPPTypeCode::DPP_PSD_CODE ){ - uShort e2 = SS->digi[ID]->GetData()->GetEnergy2(ch, SS->lastFilledIndex[ID][ch]); - // printf("%u \n", e2); - SS->hist[ID][ch]->Fill( e2, 1); - } - SS->hist2D[ID]->Fill(ch, data); - } - if( SS->histVisibility[ID][ch] ) SS->hist[ID][ch]->UpdatePlot(); - - clock_gettime(CLOCK_REALTIME, &t1); - if( t1.tv_nsec - t0.tv_nsec + (t1.tv_sec - t0.tv_sec)*1e9 > SS->maxFillTimePerDigi * 1e6 ) break; - } - - if( SS->hist2DVisibility[ID] ) SS->hist2D[ID]->UpdatePlot(); - // digiMTX[ID].unlock(); - - } - - SS->isFillingHistograms = false; + SS->FillHistograms(); emit workDone(); } diff --git a/analyzers/Analyser.h b/analyzers/Analyser.h index d8a57e9..084ae91 100644 --- a/analyzers/Analyser.h +++ b/analyzers/Analyser.h @@ -38,6 +38,8 @@ and recompile FSUDAQ to incorporate the changes and activate the custom analyzer #include "Histogram1D.h" #include "Histogram2D.h" +// class AnalyzerWorker; //Forward decalration + //^============================================== //^============================================== class Analyzer : public QMainWindow{ @@ -92,4 +94,25 @@ private: }; + +//^================================================ AnalyzerWorker + +// class ScalarWorker : public QObject{ +// Q_OBJECT +// public: +// ScalarWorker(Analyzer * parent): SS(parent){} + +// public slots: +// void UpdateScalar(){ +// SS->UpdateHistograms(); +// emit workDone(); +// } + +// signals: +// void workDone(); + +// private: +// Analyzer * SS; +// }; + #endif \ No newline at end of file From b3ace2cc84bccc5e9becd075feb184d9c4249bc4 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Thu, 29 Aug 2024 14:45:11 -0400 Subject: [PATCH 58/72] [MAJOR] Analayzer::UpdateHistograms moved to a worker that in a thread, only tested with CoincidentAnalyzer, need to change others --- FSUDAQ.cpp | 10 ++-- MultiBuilder.cpp | 102 ++++++++++++++++++++------------- MultiBuilder.h | 5 ++ SingleSpectra.cpp | 1 + analyzers/Analyser.cpp | 57 ++++++++++-------- analyzers/Analyser.h | 61 +++++++++++++------- analyzers/CoincidentAnalyzer.h | 17 +++++- 7 files changed, 158 insertions(+), 95 deletions(-) diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index a158977..6b06d4d 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -1173,6 +1173,7 @@ void FSUDAQ::StartACQ(){ lbScalarACQStatus->setText("ACQ On"); if( singleHistograms ) singleHistograms->startWork(); + if( onlineAnalyzer ) onlineAnalyzer->startWork(); bnStartACQ->setEnabled(false); bnStartACQ->setStyleSheet(""); @@ -1184,7 +1185,6 @@ void FSUDAQ::StartACQ(){ if( digiSettings ) digiSettings->EnableButtons(false); - if( onlineAnalyzer ) onlineAnalyzer->StartThread(); {//^=== elog and database if( influx && chkInflux->isChecked() ){ @@ -1242,11 +1242,9 @@ void FSUDAQ::StopACQ(){ } if( scalar ) scalarTimer->stop(); - - if( onlineAnalyzer ) onlineAnalyzer->StopThread(); if( singleHistograms ) singleHistograms->stopWork(); + if( onlineAnalyzer ) onlineAnalyzer->stopWork(); - lbScalarACQStatus->setText("ACQ Off"); bnStartACQ->setEnabled(true); @@ -1815,7 +1813,7 @@ void FSUDAQ::OpenAnalyzer(){ if( id == 5 ) onlineAnalyzer = new NeutronGamma(digi, nDigi, rawDataPath); if( id >= 0 ) onlineAnalyzer->show(); - if( isACQStarted ) onlineAnalyzer->StartThread(); + if( isACQStarted ) onlineAnalyzer->startWork(); }else{ @@ -1831,7 +1829,7 @@ void FSUDAQ::OpenAnalyzer(){ if( id >= 0 ){ onlineAnalyzer->show(); onlineAnalyzer->activateWindow(); - if( isACQStarted ) onlineAnalyzer->StartThread(); + if( isACQStarted ) onlineAnalyzer->stopWork(); } } diff --git a/MultiBuilder.cpp b/MultiBuilder.cpp index 9907a53..88d0e8d 100644 --- a/MultiBuilder.cpp +++ b/MultiBuilder.cpp @@ -7,15 +7,18 @@ MultiBuilder::MultiBuilder(Data ** multiData, std::vector type, std::vector data = multiData; typeList = type; snList = sn; + numTotCh = 0; for( uShort i = 0; i < nData; i++) { idList.push_back(i); dataSize.push_back(data[i]->GetDataSize()); + numTotCh += data[i]->GetNChannel(); } timeWindow = 100; leftOverTime = 100; breakTime = -1; timeJump = 1e8; lastEventTime = 0; + forceStop = false; ClearEvents(); @@ -29,6 +32,7 @@ MultiBuilder::MultiBuilder(Data * singleData, int type, int sn): nData(1){ DebugPrint("%s", "MultiBuilder"); data = new Data *[1]; data[0] = singleData; + numTotCh = data[0]->GetNChannel(); typeList.push_back(type); snList.push_back(sn); idList.push_back(0); @@ -37,7 +41,7 @@ MultiBuilder::MultiBuilder(Data * singleData, int type, int sn): nData(1){ breakTime = -1; timeJump = 1e8; lastEventTime = 0; - + forceStop = false; ClearEvents(); } @@ -57,6 +61,7 @@ void MultiBuilder::ClearEvents(){ loopIndex[i][j] = 0; nextIndex[i][j] = -1; chExhaused[i][j] = false; + lastBackWardIndex[i][j] = 0; } earlistDigi = -1; @@ -77,7 +82,6 @@ void MultiBuilder::PrintStat(){ if( nextIndex[i][ch] >= 0 ) printf("%d %3d %2d | %7d (%d)\n", i, snList[i], ch, nextIndex[i][ch], loopIndex[i][ch]); } } - } void MultiBuilder::PrintAllEvent(){ @@ -89,7 +93,6 @@ void MultiBuilder::PrintAllEvent(){ events[i][j].Print(); } } - } void MultiBuilder::FindEarlistTimeAndCh(bool verbose){ @@ -100,22 +103,26 @@ void MultiBuilder::FindEarlistTimeAndCh(bool verbose){ nExhaushedCh = 0; for( int i = 0; i < nData; i++){ - for( int j = 0; j < data[i]->GetNChannel(); j++ ) chExhaused[i][j] = false; + for( int j = 0; j < data[i]->GetNChannel(); j++ ) { + chExhaused[i][j] = false; + } for(unsigned int ch = 0; ch < data[i]->GetNChannel(); ch ++){ - int index = data[i]->GetDataIndex(ch); - if( index < 0 ) { - nExhaushedCh ++; - chExhaused[i][ch] = true; - continue; - } + {// check is dataIndex is valid + int index = data[i]->GetDataIndex(ch); + if( index < 0 ) { + nExhaushedCh ++; + chExhaused[i][ch] = true; + continue; + } - if( data[i]->GetTimestamp(ch, index) == 0 || - loopIndex[i][ch] * dataSize[i] > data[i]->GetLoopIndex(ch) * dataSize[i] + data[i]->GetDataIndex(ch)) { - nExhaushedCh ++; - chExhaused[i][ch] = true; - continue; + if( data[i]->GetTimestamp(ch, index) == 0 || + loopIndex[i][ch] * dataSize[i] > data[i]->GetLoopIndex(ch) * dataSize[i] + data[i]->GetDataIndex(ch)) { + nExhaushedCh ++; + chExhaused[i][ch] = true; + continue; + } } if( nextIndex[i][ch] == -1 ) nextIndex[i][ch] = 0; @@ -126,6 +133,7 @@ void MultiBuilder::FindEarlistTimeAndCh(bool verbose){ earlistDigi = i; earlistCh = ch; } + // printf(" ch : %d | time %llu | %llu\n", ch, time, earlistTime); } } @@ -147,7 +155,7 @@ void MultiBuilder::FindLatestTimeAndCh(bool verbose){ for(unsigned int ch = 0; ch < data[i]->GetNChannel(); ch ++){ - if( nextIndex[i][ch] < 0 || data[i]->GetDataIndex(ch) < 0 ) { + if( nextIndex[i][ch] < 0 || data[i]->GetDataIndex(ch) < 0 || nextIndex[i][ch] <= lastBackWardIndex[i][ch] ) { nExhaushedCh ++; chExhaused[i][ch] = true; // printf(", exhanshed. %d \n", nExhaushedCh); @@ -211,6 +219,7 @@ void MultiBuilder::FindLatestTimeOfData(bool verbose){ void MultiBuilder::BuildEvents(bool isFinal, bool skipTrace, bool verbose){ DebugPrint("%s", "MultiBuilder"); + FindEarlistTimeAmongLastData(verbose); // give lastest Time, Ch, and Digi for event building FindEarlistTimeAndCh(verbose); //Give the earliest time, ch, digi @@ -221,6 +230,8 @@ void MultiBuilder::BuildEvents(bool isFinal, bool skipTrace, bool verbose){ Hit em; do{ + if( forceStop ) break; + eventIndex ++; if( eventIndex >= MaxNEvent ) eventIndex = 0; events[eventIndex].clear(); @@ -339,13 +350,16 @@ void MultiBuilder::BuildEvents(bool isFinal, bool skipTrace, bool verbose){ } }while(nExhaushedCh < nData * MaxNChannels); + forceStop = false; + } void MultiBuilder::BuildEventsBackWard(int maxNumEvent, bool verbose){ DebugPrint("%s", "MultiBuilder"); //skip trace, and only build for maxNumEvent events max - // remember the end of DataIndex, prevent over build + // Get the last data index and loop index + for( int k = 0; k < nData; k++){ for( int i = 0; i < data[k]->GetNChannel(); i++){ nextIndex[k][i] = data[k]->GetDataIndex(i); @@ -359,12 +373,11 @@ void MultiBuilder::BuildEventsBackWard(int maxNumEvent, bool verbose){ eventBuilt = 0; Hit em; do{ + if( forceStop ) break; eventIndex ++; if( eventIndex >= MaxNEvent ) eventIndex = 0; events[eventIndex].clear(); - eventBuilt ++; - totalEventBuilt ++; em.Clear(); for( int k = 0; k < nData; k++){ @@ -375,10 +388,9 @@ void MultiBuilder::BuildEventsBackWard(int maxNumEvent, bool verbose){ for( int i = 0; i < numCh; i++){ int ch = (i + latestCh) % numCh; if( chExhaused[bd][ch] ) continue; - //if( nextIndex[bd][ch] <= lastBackWardIndex[bd][ch] || nextIndex[bd][ch] < 0){ - if( nextIndex[bd][ch] < 0){ - chExhaused[bd][ch] = true; + if( nextIndex[bd][ch] <= lastBackWardIndex[bd][ch] || nextIndex[bd][ch] <= 0){ nExhaushedCh ++; + chExhaused[bd][ch] = true; continue; } @@ -406,12 +418,27 @@ void MultiBuilder::BuildEventsBackWard(int maxNumEvent, bool verbose){ if( timeWindow == 0 ) break; } - std::sort(events[eventIndex].begin(), events[eventIndex].end(), [](const Hit& a, const Hit& b) { - return a.timestamp < b.timestamp; - }); FindLatestTimeAndCh(verbose); + if( verbose ) printf(" nExhaushedCh %d | numToCh %d \n", nExhaushedCh, numTotCh); + if( nExhaushedCh == numTotCh ) { + if( verbose ) printf("######################### no more event to be built\n"); + break; + } + if( verbose ) printf("----- next bd: %d, ch : %d, next latest Time : %llu.\n", latestDigi, latestCh, latestTime); + + if( events[eventIndex].size() > 0 ) { + eventBuilt ++; + totalEventBuilt ++; + + std::sort(events[eventIndex].begin(), events[eventIndex].end(), [](const Hit& a, const Hit& b) { + return a.timestamp < b.timestamp; + }); + }else{ + continue; + } + if( verbose ){ printf(">>>>>>>>>>>>>>>>> Event ID : %ld, total built: %ld, multiplicity : %ld\n", eventIndex, totalEventBuilt, events[eventIndex].size()); for( int i = 0; i <(int) events[eventIndex].size(); i++){ @@ -424,24 +451,19 @@ void MultiBuilder::BuildEventsBackWard(int maxNumEvent, bool verbose){ break; } } - printf("%05d, %02d | %5d | %5d %llu \n", sn, chxxx, nextIndex[bd][chxxx], events[eventIndex][i].energy, events[eventIndex][i].timestamp); + printf("%5d, %02d | %5d | %5d %llu \n", sn, chxxx, nextIndex[bd][chxxx], events[eventIndex][i].energy, events[eventIndex][i].timestamp); } - - if( nExhaushedCh == nData * MaxNChannels ) { - printf("######################### no more event to be built\n"); - break; - } - printf("----- next bd: %d, ch : %d, next latest Time : %llu.\n", latestDigi, latestCh, latestTime); - } - }while(nExhaushedCh < nData * MaxNChannels && eventBuilt < maxNumEvent); + }while(nExhaushedCh < numTotCh && eventBuilt < maxNumEvent); - // // remember the end of DataIndex, prevent over build - // for( int k = 0; k < nData; k++){ - // for( int i = 0; i < MaxRegChannel; i++){ - // lastBackWardIndex[k][i] = data[k]->DataIndex[i]; - // } - // } + forceStop = false; + + // remember the end of DataIndex, prevent over build + for( int k = 0; k < nData; k++){ + for( int i = 0; i < data[k]->GetNChannel(); i++){ + lastBackWardIndex[k][i] = data[k]->GetDataIndex(i); + } + } } diff --git a/MultiBuilder.h b/MultiBuilder.h index dd09f58..9fa8d13 100644 --- a/MultiBuilder.h +++ b/MultiBuilder.h @@ -14,6 +14,8 @@ public: MultiBuilder(Data * singleData, int type, int sn); ~MultiBuilder(); + void ForceStop(bool onOff) { forceStop = onOff;} + void SetTimeWindow(unsigned short nanosec) {timeWindow = nanosec; leftOverTime = nanosec;} unsigned short GetTimeWindow() const{return timeWindow;} @@ -48,6 +50,7 @@ private: std::vector tick2ns; const unsigned short nData; Data ** data; // assume all data has MaxNChannel (16) + int numTotCh; // number of total channel = sum digi[i]->GetNChannel() std::vector dataSize; @@ -78,6 +81,8 @@ private: int lastBackWardIndex[MaxNDigitizer][MaxNChannels]; + bool forceStop; + }; diff --git a/SingleSpectra.cpp b/SingleSpectra.cpp index b66be9e..bc08501 100644 --- a/SingleSpectra.cpp +++ b/SingleSpectra.cpp @@ -236,6 +236,7 @@ void SingleSpectra::ChangeHistView(){ void SingleSpectra::FillHistograms(){ // printf("%s | %d %d \n", __func__, chkIsFillHistogram->checkState(), isFillingHistograms); + if( this->isVisible() == false ) return; if( chkIsFillHistogram->checkState() == Qt::Unchecked ) return; if( isFillingHistograms) return; diff --git a/analyzers/Analyser.cpp b/analyzers/Analyser.cpp index 2fcc2ae..0039ecc 100644 --- a/analyzers/Analyser.cpp +++ b/analyzers/Analyser.cpp @@ -30,9 +30,9 @@ Analyzer::Analyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent ) isBuildBackward = false; mb = new MultiBuilder(dataList, typeList, snList); - buildTimerThread = new TimingThread(this); - buildTimerThread->SetWaitTimeinSec(1.0); //^Set event build interval - connect( buildTimerThread, &TimingThread::timeUp, this, &Analyzer::UpdateHistograms); + // buildTimerThread = new TimingThread(this); + // buildTimerThread->SetWaitTimeinSec(1.0); //^Set event build interval + // connect( buildTimerThread, &TimingThread::timeUp, this, &Analyzer::UpdateHistograms); QWidget * layoutWidget = new QWidget(this); setCentralWidget(layoutWidget); @@ -42,19 +42,39 @@ Analyzer::Analyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent ) // QPushButton * bnSetting = new QPushButton("Settings", this); // layout->addWidget(bnSetting); + anaThread = new QThread(this); + anaWorker = new AnalyzerWorker(this); + anaTimer = new QTimer(); + isWorking = false; + + anaWorker->moveToThread(anaThread); + + connect(anaTimer, &QTimer::timeout, anaWorker, [=](){ + if( isWorking ) return; + anaWorker->UpdateHistograms(); + }); + + // connect(anaWorker, &AnalyzerWorker::workDone, this, [=](){ + // printf(" --------- work Done\n"); + // }); + + anaThread->start(); + } Analyzer::~Analyzer(){ - if( buildTimerThread ){ - if( !buildTimerThread->isStopped() ){ - buildTimerThread->Stop(); - buildTimerThread->quit(); - buildTimerThread->wait(); - } - delete buildTimerThread; + printf("Analyzer::%s\n", __func__); + anaTimer->stop(); + + printf(" is anaThread is running %d \n", anaThread->isRunning()); + if( anaThread->isRunning() ){ + anaThread->quit(); + anaThread->wait(); } + printf("------ end of anaThread \n"); + delete influx; delete mb; delete [] dataList; @@ -144,28 +164,17 @@ void Analyzer::RedefineEventBuilder(std::vector idList){ mb = new MultiBuilder(dataList, typeList, snList); } -void Analyzer::StartThread(){ - mb->ClearEvents(); - buildTimerThread->start(); -} - -void Analyzer::StopThread(){ - // printf("%s\n", __func__); - buildTimerThread->Stop(); - buildTimerThread->quit(); - buildTimerThread->wait(); -} - void Analyzer::BuildEvents(bool verbose){ - unsigned int nData = mb->GetNumOfDigitizer(); - std::vector idList = mb->GetDigiIDList(); + // unsigned int nData = mb->GetNumOfDigitizer(); + // std::vector idList = mb->GetDigiIDList(); // for( unsigned int i = 0; i < nData; i++ ) digiMTX[idList[i]].lock(); if( isBuildBackward ){ mb->BuildEventsBackWard(maxNumEventBuilt, verbose); }else{ mb->BuildEvents(0, true, verbose); } + // mb->PrintStat(); // for( unsigned int i = 0; i < nData; i++ ) digiMTX[idList[i]].unlock(); } diff --git a/analyzers/Analyser.h b/analyzers/Analyser.h index 084ae91..e698a7e 100644 --- a/analyzers/Analyser.h +++ b/analyzers/Analyser.h @@ -38,7 +38,7 @@ and recompile FSUDAQ to incorporate the changes and activate the custom analyzer #include "Histogram1D.h" #include "Histogram2D.h" -// class AnalyzerWorker; //Forward decalration +class AnalyzerWorker; //Forward decalration //^============================================== //^============================================== @@ -56,27 +56,40 @@ public: void SetDatabase(QString IP, QString Name, QString Token); double RandomGauss(double mean, double sigma); - -public slots: - void StartThread(); - void StopThread(); void SetDatabaseButton(); - + + double GetUpdateTimeInSec() const {return waitTimeinSec;} + virtual void SetUpCanvas(); virtual void UpdateHistograms(); // where event-building, analysis, and ploting +public slots: + void startWork(){ + // printf("start timer\n"); + mb->ForceStop(false); + mb->ClearEvents(); + anaTimer->start(waitTimeinSec*1000); + } + void stopWork(){ + // printf("stop worker\n"); + anaTimer->stop(); + mb->ForceStop(true); + } + private slots: protected: QGridLayout * layout; void BuildEvents(bool verbose = false); - void SetUpdateTimeInSec(double sec = 1.0) {waitTimeinSec = sec; buildTimerThread->SetWaitTimeinSec(waitTimeinSec);} + void SetUpdateTimeInSec(double sec = 1.0) { waitTimeinSec = sec; } InfluxDB * influx; QString dataBaseIP; QString dataBaseName; QString dataBaseToken; + bool isWorking; // a flag to indicate the worker is working + private: Digitizer ** digi; unsigned short nDigi; @@ -90,29 +103,33 @@ private: MultiBuilder * mb; bool isBuildBackward; int maxNumEventBuilt; - TimingThread * buildTimerThread; + // TimingThread * buildTimerThread; + + QThread * anaThread; + AnalyzerWorker * anaWorker; + QTimer * anaTimer; }; //^================================================ AnalyzerWorker -// class ScalarWorker : public QObject{ -// Q_OBJECT -// public: -// ScalarWorker(Analyzer * parent): SS(parent){} +class AnalyzerWorker : public QObject{ + Q_OBJECT +public: + AnalyzerWorker(Analyzer * parent): SS(parent){} -// public slots: -// void UpdateScalar(){ -// SS->UpdateHistograms(); -// emit workDone(); -// } +public slots: + void UpdateHistograms(){ + SS->UpdateHistograms(); + emit workDone(); + } -// signals: -// void workDone(); +signals: + void workDone(); -// private: -// Analyzer * SS; -// }; +private: + Analyzer * SS; +}; #endif \ No newline at end of file diff --git a/analyzers/CoincidentAnalyzer.h b/analyzers/CoincidentAnalyzer.h index b34db4c..682fb29 100644 --- a/analyzers/CoincidentAnalyzer.h +++ b/analyzers/CoincidentAnalyzer.h @@ -403,16 +403,22 @@ inline void CoincidentAnalyzer::SetUpCanvas(){ inline void CoincidentAnalyzer::UpdateHistograms(){ + // printf(">>>>>>>>>>>>> CoincidentAnalyzer::%s | %d %d %d \n", __func__, this->isVisible(), chkRunAnalyzer->isChecked(), isWorking); + 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(); // call the event builder to build events + 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; + if( eventBuilt == 0 ) return; //============ Get the cut list, if any @@ -450,7 +456,7 @@ inline void CoincidentAnalyzer::UpdateHistograms(){ int xE = -1, yE = -1; unsigned long long xT = 0; for( int k = 0; k < (int) event.size(); k++ ){ - //event[k].Print(); + // event[k].Print(); if( event[k].sn == a_sn && event[k].ch == a_ch) { h1->Fill(event[k].energy); aE = event[k].energy; @@ -478,10 +484,11 @@ inline void CoincidentAnalyzer::UpdateHistograms(){ } unsigned long long ta = getTime_ns(); - if( ta - t0 > sbUpdateTime->value() * 0.9 * 1e9 ) break; + if( ta - t0 > sbUpdateTime->value() * 0.9 * GetUpdateTimeInSec() * 1e9 ) break; } + // printf("--------------- update histograms\n"); h2D->UpdatePlot(); h1->UpdatePlot(); hMulti->UpdatePlot(); @@ -502,6 +509,10 @@ inline void CoincidentAnalyzer::UpdateHistograms(){ influx->WriteData(dataBaseName.toStdString()); influx->ClearDataPointsBuffer(); } + + // printf("<<<<<<<<<<<<< end of UpdateHistorgams\n"); + + isWorking = false; } inline void CoincidentAnalyzer::SaveSettings(){ From 2abdc83549fe4d0c5a5b8a6e93fe283b3f69072f Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Thu, 29 Aug 2024 15:47:07 -0400 Subject: [PATCH 59/72] added analyzer/README.md, move the isWorking from the custom analyzer to Analyzer, so user don't need to worry --- analyzers/Analyser.cpp | 2 + analyzers/Analyser.h | 2 - analyzers/CoincidentAnalyzer.h | 34 +++++-------- analyzers/NeutronGamma.h | 68 ------------------------- analyzers/RAISOR.h | 3 +- analyzers/README.md | 93 ++++++++++++++++++++++++++++++++++ 6 files changed, 111 insertions(+), 91 deletions(-) create mode 100644 analyzers/README.md 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 From c2265f3cc6933f178390ddc60695c6cf7c726f4e Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Thu, 29 Aug 2024 16:49:52 -0400 Subject: [PATCH 60/72] remove TimingThread, Scope::UpdateScope() in Qthread via a worker. ScalarUpdateTimeinMiliSec in macro.h --- ClassDigitizer.cpp | 2 + CustomThreads.h | 59 ++++++++++++++-------------- FSUDAQ.cpp | 4 +- FSUDAQ.h | 2 - Scope.cpp | 74 +++++++++++++++++------------------ Scope.h | 29 +++++++++++++- analyzers/SplitPoleAnalyzer.h | 13 +++--- macro.h | 2 + 8 files changed, 102 insertions(+), 83 deletions(-) diff --git a/ClassDigitizer.cpp b/ClassDigitizer.cpp index bae427c..4fd7db6 100644 --- a/ClassDigitizer.cpp +++ b/ClassDigitizer.cpp @@ -606,6 +606,8 @@ void Digitizer::StopACQ(){ data->ClearBuffer(); data->ClearReferenceTime(); data->ZeroTotalFileSize(); + + ReadACQStatus(); } unsigned int Digitizer::CalByteForBuffer(bool verbose){ diff --git a/CustomThreads.h b/CustomThreads.h index 995f7ca..ea87b1d 100644 --- a/CustomThreads.h +++ b/CustomThreads.h @@ -69,7 +69,6 @@ public: digi->WriteRegister(DPP::SoftwareClear_W, 1); digi->GetData()->ClearData(); } - digi->ReadACQStatus(); digiMTX[ID].unlock(); emit sendMsg("Digi-" + QString::number(digi->GetSerialNumber()) + " ACQ off."); stop = true; @@ -112,34 +111,34 @@ private: }; //^#======================================================= Timing Thread -class TimingThread : public QThread { - Q_OBJECT -public: - TimingThread(QObject * parent = 0 ) : QThread(parent){ - waitTime = 20; // multiple of 100 mili sec - stop = false; - } - bool isStopped() const {return stop;} - void Stop() { this->stop = true;} - void SetWaitTimeinSec(float sec) {waitTime = sec * 10 ;} - float GetWaitTimeinSec() const {return waitTime/10.;} - void DoOnce() {emit timeUp();}; - void run(){ - unsigned int count = 0; - stop = false; - do{ - usleep(100000); - count ++; - if( count % waitTime == 0){ - emit timeUp(); - } - }while(!stop); - } -signals: - void timeUp(); -private: - bool stop; - unsigned int waitTime; -}; +// class TimingThread : public QThread { +// Q_OBJECT +// public: +// TimingThread(QObject * parent = 0 ) : QThread(parent){ +// waitTime = 20; // multiple of 100 mili sec +// stop = false; +// } +// bool isStopped() const {return stop;} +// void Stop() { this->stop = true;} +// void SetWaitTimeinSec(float sec) {waitTime = sec * 10 ;} +// float GetWaitTimeinSec() const {return waitTime/10.;} +// void DoOnce() {emit timeUp();}; +// void run(){ +// unsigned int count = 0; +// stop = false; +// do{ +// usleep(100000); +// count ++; +// if( count % waitTime == 0){ +// emit timeUp(); +// } +// }while(!stop); +// } +// signals: +// void timeUp(); +// private: +// bool stop; +// unsigned int waitTime; +// }; #endif diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index 6b06d4d..57eb1e9 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -34,7 +34,6 @@ FSUDAQ::FSUDAQ(QWidget *parent) : QMainWindow(parent){ isACQStarted= false; scalar = nullptr; - scalarUpdateTimeMilliSec = 1000; scope = nullptr; digiSettings = nullptr; singleHistograms = nullptr; @@ -1163,7 +1162,7 @@ void FSUDAQ::StartACQ(){ // printf("------------ Go! \n"); // for( unsigned int i = 0; i < nDigi; i++) readDataThread[i]->go(); - if( scalar ) scalarTimer->start(scalarUpdateTimeMilliSec); + if( scalar ) scalarTimer->start(ScalarUpdateinMiliSec); if( !scalar->isVisible() ) { scalar->show(); @@ -1238,7 +1237,6 @@ void FSUDAQ::StopACQ(){ if( chkSaveData->isChecked() ) digi[i]->GetData()->CloseSaveFile(); LogMsg("Digi-" + QString::number(digi[i]->GetSerialNumber()) + " ACQ is stopped." ); QCoreApplication::processEvents(); - digi[i]->ReadACQStatus(); } if( scalar ) scalarTimer->stop(); diff --git a/FSUDAQ.h b/FSUDAQ.h index 750a8c3..b892d1a 100644 --- a/FSUDAQ.h +++ b/FSUDAQ.h @@ -187,8 +187,6 @@ private: QLabel * lbFileSize[MaxNDigitizer]; QLabel * lbTotalFileSize; - unsigned short scalarUpdateTimeMilliSec; - //@----- Run Record QMainWindow * runRecord; QStandardItemModel *model; diff --git a/Scope.cpp b/Scope.cpp index d151237..556aa80 100644 --- a/Scope.cpp +++ b/Scope.cpp @@ -6,7 +6,7 @@ #include #include #include -// #include +#include QVector Scope::TrapezoidFilter(QVector data, int baseLineEndS, int riseTimeS, int flatTopS, float decayTime_ns){ DebugPrint("%s", "Scope"); @@ -41,12 +41,12 @@ QVector Scope::TrapezoidFilter(QVector data, int baseLineEndS, trapezoid.append(QPointF(data[i].x(), sn / decayTime_ns / riseTimeS)); - } - + } return trapezoid; } - +//^======================================================== +//^======================================================== Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataThread, QMainWindow * parent) : QMainWindow(parent){ DebugPrint("%s", "Scope"); this->digi = digi; @@ -64,7 +64,6 @@ Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataTh }else{ setGeometry(0, 0, 1000, 800); } - // setGeometry(0, 0, 1000, 800); enableSignalSlot = false; @@ -100,16 +99,6 @@ Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataTh xaxis->setLabelFormat("%.0f"); xaxis->setTitleText("Time [ns]"); - updateTraceThread = new TimingThread(); - updateTraceThread->SetWaitTimeinSec(ScopeUpdateMiliSec / 1000.); - connect(updateTraceThread, &TimingThread::timeUp, this, &Scope::UpdateScope); - - updateScalarThread = new TimingThread(); - updateScalarThread->SetWaitTimeinSec(2); - connect(updateScalarThread, &TimingThread::timeUp, this, [=](){ - emit UpdateScaler(); - }); - NullThePointers(); //*================================== UI @@ -226,7 +215,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 updates every " + QString::number(updateTraceThread->GetWaitTimeinSec()) + " sec.", this); + QLabel * lbinfo = new QLabel("Trace updates every " + QString::number(ScopeUpdateMiliSec / 1000.) + " sec.", this); lbinfo->setAlignment(Qt::AlignRight); layout->addWidget(lbinfo, rowID, 6); @@ -288,22 +277,35 @@ Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataTh yaxis->setRange(0, 0xFFF); } + workerThread = new QThread(this); + scopeWorker = new ScopeWorker(this); + scopeTimer = new QTimer(this); + + scopeWorker->moveToThread(workerThread); + + // Setup the timer to trigger every second + connect(scopeTimer, &QTimer::timeout, scopeWorker, [=](){ + scopeWorker->UpdateScope(); + }); + workerThread->start(); + + scalarTimer = new QTimer(this); + connect(scalarTimer, &QTimer::timeout, this, &Scope::UpdateScaler); + enableSignalSlot = true; } - Scope::~Scope(){ DebugPrint("%s", "Scope"); - updateTraceThread->Stop(); - updateTraceThread->quit(); - updateTraceThread->wait(); - delete updateTraceThread; - updateScalarThread->Stop(); - updateScalarThread->quit(); - updateScalarThread->wait(); - delete updateScalarThread; + scopeTimer->stop(); + scalarTimer->stop(); + + if( workerThread->isRunning() ){ + workerThread->quit(); + workerThread->wait(); + } for( int i = 0; i < MaxNumberOfTrace; i++) delete dataTrace[i]; delete plot; @@ -432,8 +434,8 @@ void Scope::StartScope(){ } - updateTraceThread->start(); - updateScalarThread->start(); + scopeTimer->start(ScopeUpdateMiliSec); + scalarTimer->start(ScalarUpdateinMiliSec); bnScopeStart->setEnabled(false); bnScopeStart->setStyleSheet(""); @@ -444,7 +446,7 @@ void Scope::StartScope(){ EnableControl(false); - TellACQOnOff(true); + emit TellACQOnOff(true); isACQStarted = true; @@ -455,13 +457,8 @@ void Scope::StopScope(){ if( !digi ) return; // printf("------ Scope::%s \n", __func__); - updateTraceThread->Stop(); - updateTraceThread->quit(); - updateTraceThread->exit(); - - updateScalarThread->Stop(); - updateScalarThread->quit(); - updateScalarThread->exit(); + scopeTimer->stop(); + scalarTimer->stop(); if( chkSoleRun->isChecked() ){ @@ -477,7 +474,6 @@ void Scope::StopScope(){ digiMTX[ID].lock(); digi[ID]->StopACQ(); - digi[ID]->ReadACQStatus(); digiMTX[ID].unlock(); //restore setting @@ -508,9 +504,9 @@ void Scope::StopScope(){ readDataThread[iDigi]->wait(); readDataThread[iDigi]->SetScopeMode(false); } + digiMTX[iDigi].lock(); digi[iDigi]->StopACQ(); - digi[iDigi]->ReadACQStatus(); //digi[iDigi]->GetData()->PrintAllData(); digiMTX[iDigi].unlock(); @@ -521,6 +517,8 @@ void Scope::StopScope(){ } + runStatus->setStyleSheet(""); // cheated, don;t know why digi[iDigi]->GetACQStatusFromMemory(), sometimes return ACQ on + emit UpdateOtherPanels(); bnScopeStart->setEnabled(true); @@ -533,7 +531,7 @@ void Scope::StopScope(){ EnableControl(true); - TellACQOnOff(false); + emit TellACQOnOff(false); isACQStarted = false; diff --git a/Scope.h b/Scope.h index 2f2c769..d1268db 100644 --- a/Scope.h +++ b/Scope.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -22,6 +23,8 @@ #include "CustomThreads.h" #include "CustomWidgets.h" +class ScopeWorker; //Forward declaration + //^==================================================== //^==================================================== class Scope : public QMainWindow{ @@ -87,8 +90,7 @@ private: unsigned short oldCh, oldDigi; ReadDataThread ** readDataThread; - TimingThread * updateTraceThread; - TimingThread * updateScalarThread; + // TimingThread * updateScalarThread; bool enableSignalSlot; @@ -147,8 +149,31 @@ private: //sbGateOffset -> GateOffset //sbTriggerHoldOff ->Trigger Hold Off + QThread * workerThread; + ScopeWorker * scopeWorker; + QTimer * scopeTimer; + QTimer * scalarTimer; + + }; +//^#======================================================== ScopeWorker +class ScopeWorker : public QObject{ + Q_OBJECT +public: + ScopeWorker(Scope * parent): SS(parent){} +public slots: + void UpdateScope(){ + SS->UpdateScope(); + emit workDone(); + } + +signals: + void workDone(); + +private: + Scope * SS; +}; #endif \ No newline at end of file diff --git a/analyzers/SplitPoleAnalyzer.h b/analyzers/SplitPoleAnalyzer.h index 5137997..088a1fe 100644 --- a/analyzers/SplitPoleAnalyzer.h +++ b/analyzers/SplitPoleAnalyzer.h @@ -30,8 +30,7 @@ public: RedefineEventBuilder({0}); // only build for the 0-th digitizer, otherwise, it will build event accross all digitizers tick2ns = digi[0]->GetTick2ns(); 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(3000); + mb->SetTimeWindow(3000); //========== use the influx from the Analyzer influx = new InfluxDB("https://fsunuc.physics.fsu.edu/influx/"); @@ -67,8 +66,6 @@ public slots: private: - MultiBuilder *evtbder; - // declaie histograms Histogram2D * hPID; @@ -224,7 +221,7 @@ inline void SplitPole::SetUpCanvas(){ boxLayout->addWidget(sbEventWin, 4, 1); sbEventWin->setValue(3000); connect(sbEventWin, &RSpinBox::returnPressed, this, [=](){ - evtbder->SetTimeWindow(sbEventWin->value()); + mb->SetTimeWindow(sbEventWin->value()); }); chkRunAnalyzer = new QCheckBox("Run Analyzer", this); @@ -352,7 +349,7 @@ inline void SplitPole::UpdateHistograms(){ BuildEvents(); // call the event builder to build events //============ Get events, and do analysis - long eventBuilt = evtbder->eventBuilt; + long eventBuilt = mb->eventBuilt; if( eventBuilt == 0 ) return; //============ Get the cut list, if any @@ -362,12 +359,12 @@ inline void SplitPole::UpdateHistograms(){ unsigned int count[nCut]={0}; //============ 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]; //printf("-------------- %ld\n", i); hMulti->Fill((int) event.size()); diff --git a/macro.h b/macro.h index d071d78..34c802d 100644 --- a/macro.h +++ b/macro.h @@ -11,6 +11,8 @@ #define MaxRecordLength 0x3fff * 8 #define MaxSaveFileSize 1024 * 1024 * 1024 * 2 +#define ScalarUpdateinMiliSec 1000 // msec + #define MaxDisplayTraceTimeLength 20000 //ns #define ScopeUpdateMiliSec 200 // msec #define MaxNumberOfTrace 5 // in an event From 11ae70db1849169708ede3b75eed464eb025ee3d Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Thu, 29 Aug 2024 17:15:36 -0400 Subject: [PATCH 61/72] remove scope Qtimer for scalar, use the Scope::TellACQOnOff to start/stop work for scalar, singleHostogram, and onlineAnalyzer --- FSUDAQ.cpp | 43 +++++++++++++++++++++++++------------------ Scope.cpp | 10 +++------- Scope.h | 4 ---- 3 files changed, 28 insertions(+), 29 deletions(-) diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index 57eb1e9..bb89c18 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -1714,39 +1714,46 @@ void FSUDAQ::OpenScope(){ if( scope == nullptr ) { scope = new Scope(digi, nDigi, readDataThread); connect(scope, &Scope::SendLogMsg, this, &FSUDAQ::LogMsg); + connect(scope, &Scope::CloseWindow, this, [=](){ bnStartACQ->setEnabled(true); bnStartACQ->setStyleSheet("background-color: green;"); bnStopACQ->setEnabled(false); bnStopACQ->setStyleSheet(""); }); + connect(scope, &Scope::TellACQOnOff, this, [=](bool onOff){ - if( scope ) { - if( onOff ) { + + isACQStarted = onOff; + + if( onOff ){ + if( influx && chkInflux->isChecked() && !elogName.isEmpty()) influx->AddDataPoint("SavingData,ExpName=" + elogName.toStdString() + " value=1"); + + if( scalar ){ lbScalarACQStatus->setText("ACQ On"); - if( influx && chkInflux->isChecked() && !elogName.isEmpty()) influx->AddDataPoint("SavingData,ExpName=" + elogName.toStdString() + " value=1"); - }else{ + scalarTimer->start(ScalarUpdateinMiliSec); + } + + if( singleHistograms ) singleHistograms->startWork(); + if( onlineAnalyzer ) onlineAnalyzer->startWork(); + + }else{ + if( influx && chkInflux->isChecked() && !elogName.isEmpty()) influx->AddDataPoint("SavingData,ExpName=" + elogName.toStdString() + " value=0"); + + if( scalar ){ lbScalarACQStatus->setText("ACQ Off"); - if( influx && chkInflux->isChecked() && !elogName.isEmpty()) influx->AddDataPoint("SavingData,ExpName=" + elogName.toStdString() + " value=0"); - } - if( influx && chkInflux->isChecked()){ - influx->WriteData(dataBaseName.toStdString()); - influx->ClearDataPointsBuffer(); + scalarTimer->stop(); } + + if( singleHistograms ) singleHistograms->stopWork(); + if( onlineAnalyzer ) onlineAnalyzer->stopWork(); + } - if( digiSettings ) digiSettings->setEnabled(!onOff); - if( singleHistograms ) { - if( onOff ) { - singleHistograms->startWork(); - }else{ - singleHistograms->stopWork(); - } - } + if( digiSettings ) digiSettings->EnableButtons(!onOff); }); - if( scalar ) connect(scope, &Scope::UpdateScaler, scalarWorker, &ScalarWorker::UpdateScalar); connect(scope, &Scope::UpdateOtherPanels, this, [=](){ UpdateAllPanels(1); }); scope->show(); diff --git a/Scope.cpp b/Scope.cpp index 556aa80..372e719 100644 --- a/Scope.cpp +++ b/Scope.cpp @@ -289,9 +289,6 @@ Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataTh }); workerThread->start(); - scalarTimer = new QTimer(this); - connect(scalarTimer, &QTimer::timeout, this, &Scope::UpdateScaler); - enableSignalSlot = true; } @@ -300,7 +297,7 @@ Scope::~Scope(){ DebugPrint("%s", "Scope"); scopeTimer->stop(); - scalarTimer->stop(); + // scalarTimer->stop(); if( workerThread->isRunning() ){ workerThread->quit(); @@ -435,7 +432,6 @@ void Scope::StartScope(){ } scopeTimer->start(ScopeUpdateMiliSec); - scalarTimer->start(ScalarUpdateinMiliSec); bnScopeStart->setEnabled(false); bnScopeStart->setStyleSheet(""); @@ -458,7 +454,7 @@ void Scope::StopScope(){ // printf("------ Scope::%s \n", __func__); scopeTimer->stop(); - scalarTimer->stop(); + // scalarTimer->stop(); if( chkSoleRun->isChecked() ){ @@ -517,7 +513,7 @@ void Scope::StopScope(){ } - runStatus->setStyleSheet(""); // cheated, don;t know why digi[iDigi]->GetACQStatusFromMemory(), sometimes return ACQ on + runStatus->setStyleSheet(""); // cheated, don;t know why digi[iDigi]->GetACQStatusFromMemory(), sometimes return ACQ one. emit UpdateOtherPanels(); diff --git a/Scope.h b/Scope.h index d1268db..be68607 100644 --- a/Scope.h +++ b/Scope.h @@ -54,7 +54,6 @@ signals: void CloseWindow(); void SendLogMsg(const QString &msg); void TellACQOnOff(const bool onOff); - void UpdateScaler(); void UpdateOtherPanels(); private: @@ -90,7 +89,6 @@ private: unsigned short oldCh, oldDigi; ReadDataThread ** readDataThread; - // TimingThread * updateScalarThread; bool enableSignalSlot; @@ -152,8 +150,6 @@ private: QThread * workerThread; ScopeWorker * scopeWorker; QTimer * scopeTimer; - QTimer * scalarTimer; - }; From e79f93e9ab69e2f07bf98884c4b8911ee696f121 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Fri, 30 Aug 2024 12:27:24 -0400 Subject: [PATCH 62/72] add Locale --- ClassDigitizer.cpp | 4 +++- FSUDAQ.cpp | 20 ++++++++++---------- SingleSpectra.h | 4 ++-- analyzers/Analyser.h | 4 ++-- main.cpp | 3 +++ 5 files changed, 20 insertions(+), 15 deletions(-) diff --git a/ClassDigitizer.cpp b/ClassDigitizer.cpp index 4fd7db6..061b7e8 100644 --- a/ClassDigitizer.cpp +++ b/ClassDigitizer.cpp @@ -279,7 +279,9 @@ int Digitizer::CloseDigitizer(){ isConnected = false; ret = CAEN_DGTZ_SWStopAcquisition(handle); printf("-------- Closing Digtizer Board : %d Port : %d \n", boardID, portID); - printf(" Model %s with handle %d using %s\n", BoardInfo.ModelName, handle, LinkType == CAEN_DGTZ_USB ? "USB" : "Optical Link"); + if( LinkType == CAEN_DGTZ_USB ) printf(" Model %s with handle %d using USB\n", BoardInfo.ModelName, handle); + if( LinkType == CAEN_DGTZ_OpticalLink ) printf(" Model %s with handle %d using Optical Fiber\n", BoardInfo.ModelName, handle); + if( LinkType == CAEN_DGTZ_USB_A4818 ) printf(" Model %s with handle %d using A4818\n", BoardInfo.ModelName, handle); ret |= CAEN_DGTZ_CloseDigitizer(handle); return ret; diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index bb89c18..21b8856 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -1171,8 +1171,8 @@ void FSUDAQ::StartACQ(){ } lbScalarACQStatus->setText("ACQ On"); - if( singleHistograms ) singleHistograms->startWork(); - if( onlineAnalyzer ) onlineAnalyzer->startWork(); + if( singleHistograms ) singleHistograms->startTimer(); + if( onlineAnalyzer ) onlineAnalyzer->startTimer(); bnStartACQ->setEnabled(false); bnStartACQ->setStyleSheet(""); @@ -1240,8 +1240,8 @@ void FSUDAQ::StopACQ(){ } if( scalar ) scalarTimer->stop(); - if( singleHistograms ) singleHistograms->stopWork(); - if( onlineAnalyzer ) onlineAnalyzer->stopWork(); + if( singleHistograms ) singleHistograms->stopTimer(); + if( onlineAnalyzer ) onlineAnalyzer->stopTimer(); lbScalarACQStatus->setText("ACQ Off"); @@ -1734,8 +1734,8 @@ void FSUDAQ::OpenScope(){ scalarTimer->start(ScalarUpdateinMiliSec); } - if( singleHistograms ) singleHistograms->startWork(); - if( onlineAnalyzer ) onlineAnalyzer->startWork(); + if( singleHistograms ) singleHistograms->startTimer(); + if( onlineAnalyzer ) onlineAnalyzer->startTimer(); }else{ if( influx && chkInflux->isChecked() && !elogName.isEmpty()) influx->AddDataPoint("SavingData,ExpName=" + elogName.toStdString() + " value=0"); @@ -1745,8 +1745,8 @@ void FSUDAQ::OpenScope(){ scalarTimer->stop(); } - if( singleHistograms ) singleHistograms->stopWork(); - if( onlineAnalyzer ) onlineAnalyzer->stopWork(); + if( singleHistograms ) singleHistograms->stopTimer(); + if( onlineAnalyzer ) onlineAnalyzer->stopTimer(); } @@ -1818,7 +1818,7 @@ void FSUDAQ::OpenAnalyzer(){ if( id == 5 ) onlineAnalyzer = new NeutronGamma(digi, nDigi, rawDataPath); if( id >= 0 ) onlineAnalyzer->show(); - if( isACQStarted ) onlineAnalyzer->startWork(); + if( isACQStarted ) onlineAnalyzer->startTimer(); }else{ @@ -1834,7 +1834,7 @@ void FSUDAQ::OpenAnalyzer(){ if( id >= 0 ){ onlineAnalyzer->show(); onlineAnalyzer->activateWindow(); - if( isACQStarted ) onlineAnalyzer->stopWork(); + if( isACQStarted ) onlineAnalyzer->stopTimer(); } } diff --git a/SingleSpectra.h b/SingleSpectra.h index 4e1be36..9a0d19d 100644 --- a/SingleSpectra.h +++ b/SingleSpectra.h @@ -46,11 +46,11 @@ public: public slots: void FillHistograms(); void ChangeHistView(); - void startWork(){ + void startTimer(){ // printf("timer start\n"); timer->start(maxFillTimeinMilliSec); } - void stopWork(){ + void stopTimer(){ // printf("timer stop\n"); timer->stop(); ClearInternalDataCount(); diff --git a/analyzers/Analyser.h b/analyzers/Analyser.h index 436120f..75dade6 100644 --- a/analyzers/Analyser.h +++ b/analyzers/Analyser.h @@ -64,13 +64,13 @@ public: virtual void UpdateHistograms(); // where event-building, analysis, and ploting public slots: - void startWork(){ + void startTimer(){ // printf("start timer\n"); mb->ForceStop(false); mb->ClearEvents(); anaTimer->start(waitTimeinSec*1000); } - void stopWork(){ + void stopTimer(){ // printf("stop worker\n"); anaTimer->stop(); mb->ForceStop(true); diff --git a/main.cpp b/main.cpp index bdaee58..22e28cb 100644 --- a/main.cpp +++ b/main.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "FSUDAQ.h" @@ -27,6 +28,8 @@ int main(int argc, char *argv[]){ // CustomApplication a(argc, argv); QApplication a(argc, argv); + QLocale::setDefault(QLocale::system()); + setpriority(PRIO_PROCESS, 0, -20); bool isLock = false; From 540f967d70c5397362bcabc0cda63edcdc5aa1ff Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Tue, 3 Sep 2024 15:49:15 -0400 Subject: [PATCH 63/72] ClassData.h, fine_time = -1 as default --- ClassData.h | 14 +++++++++++--- ClassDigitizer.cpp | 2 -- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ClassData.h b/ClassData.h index 0fdbe66..208f54f 100644 --- a/ClassData.h +++ b/ClassData.h @@ -311,7 +311,7 @@ inline void Data::ClearData(){ if( ch >= numInputCh) break; for( int j = 0; j < dataSize; j++){ Timestamp[ch][j] = 0; - fineTime[ch][j] = 0; + fineTime[ch][j] = -1; Energy[ch][j] = 0; Energy2[ch][j] = 0; Waveform1[ch][j].clear(); @@ -897,7 +897,11 @@ inline int Data::DecodePHADualChannelBlock(unsigned int ChannelMask, bool fastDe Energy[channel][DataIndex[channel]] = energy; Timestamp[channel][DataIndex[channel]] = timeStamp * tick2ns; - if(extra2Option == 2 ) fineTime[channel][DataIndex[channel]] = (extra2 & 0x03FF ) * tick2ns; // in ps, the tick2ns is a conversion factor + if(extra2Option == 2 ) { + fineTime[channel][DataIndex[channel]] = (extra2 & 0x03FF ) * tick2ns; // in ps, the tick2ns is a conversion factor + }else{ + fineTime[channel][DataIndex[channel]] = -1; + } PileUp[channel][DataIndex[channel]] = pileUp; NumEventsDecoded[channel] ++; @@ -1100,7 +1104,11 @@ inline int Data::DecodePSDDualChannelBlock(unsigned int ChannelMask, bool fastDe Energy2[channel][DataIndex[channel]] = Qshort; Energy[channel][DataIndex[channel]] = Qlong; Timestamp[channel][DataIndex[channel]] = timeStamp * tick2ns; - if( extraOption == 2 ) fineTime[channel][DataIndex[channel]] = (extra & 0x3FF) * tick2ns; //in ps, tick2ns is justa conversion factor + if( extraOption == 2 ) { + fineTime[channel][DataIndex[channel]] = (extra & 0x3FF) * tick2ns; //in ps, tick2ns is justa conversion factor + }else{ + fineTime[channel][DataIndex[channel]] = -1; //in ps, tick2ns is justa conversion factor + } NumEventsDecoded[channel] ++; if( !pileup){ diff --git a/ClassDigitizer.cpp b/ClassDigitizer.cpp index 061b7e8..277b551 100644 --- a/ClassDigitizer.cpp +++ b/ClassDigitizer.cpp @@ -183,7 +183,6 @@ int Digitizer::OpenDigitizer(int boardID, int portID, bool program, bool verbose /// change address 0xEF08 (5 bits), this will reflected in the 2nd word of the Board Agg. header. ret = CAEN_DGTZ_WriteRegister(handle, DPP::BoardID, (DPPType & 0xF)); - //TODO somehow the bdInfo does not work, use DPPType to set it uint32_t bdInfo = GetSettingFromMemory(DPP::BoardInfo_R); uint32_t haha = ((bdInfo >> 8 ) & 0xFF); @@ -287,7 +286,6 @@ int Digitizer::CloseDigitizer(){ return ret; } - void Digitizer::SetRegChannelMask(uint32_t mask){ DebugPrint("%s", "Digitizer"); if( softwareDisable ) return; From 06592c6aca2dce938a270f5aa6b43a17552270bf Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Tue, 3 Sep 2024 15:55:58 -0400 Subject: [PATCH 64/72] ClassData.h, fix PSD decoder verbose display --- ClassData.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/ClassData.h b/ClassData.h index 208f54f..39606c9 100644 --- a/ClassData.h +++ b/ClassData.h @@ -1133,10 +1133,16 @@ inline int Data::DecodePSDDualChannelBlock(unsigned int ChannelMask, bool fastDe //if( DataIndex[channel] >= dataSize ) ClearData(); //if( verbose >= 2 ) printf("extra : 0x%08x, Qshort : %d, Qlong : %d \n", extra, Qshort, Qlong); - if( verbose == 1 ) printf("ch : %2d, Qshort : %6d, Qlong : %6d, timestamp : %llu, fineTime : %u\n", - channel, Qshort, Qlong, timeStamp * tick2ns, (extra & 0x3FF) * tick2ns); - if( verbose >= 2 ) printf("Qshort : %6d, Qlong : %6d, timestamp : %llu, fineTime : %u\n", + if( verbose >= 1 ) { + if( extraOption == 0){ + printf("Qshort : %6d, Qlong : %6d, timestamp : %llu, baseline : %u\n", + Qshort, Qlong, timeStamp * tick2ns, (extra & 0xFFFF) * 4); + } + if( extraOption == 2){ + printf("Qshort : %6d, Qlong : %6d, timestamp : %llu, fineTime : %u\n", Qshort, Qlong, timeStamp * tick2ns, (extra & 0x3FF) * tick2ns); + } + } From 8baa37142c6f072f81cef1c97d681d4e4602a004 Mon Sep 17 00:00:00 2001 From: "carina@hades" Date: Wed, 4 Sep 2024 03:09:08 -0400 Subject: [PATCH 65/72] add some debug code in EventBuilder and fsuReader.h, ReadBatch can switch off trace --- Aux/EventBuilder.cpp | 15 +++++++++------ Aux/fsuReader.h | 14 +++++++++----- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/Aux/EventBuilder.cpp b/Aux/EventBuilder.cpp index 8265098..fe23f13 100644 --- a/Aux/EventBuilder.cpp +++ b/Aux/EventBuilder.cpp @@ -89,6 +89,8 @@ int main(int argc, char **argv) { FSUReader * readerA = new FSUReader(inFileName[0].Data(), 1, 1); readerA->ScanNumBlock(0,0); if( readerA->GetOptimumBatchSize() > batchSize ) batchSize = readerA->GetOptimumBatchSize(); + //printf("Hit count : %7ld | opt. batch size : %7ld\n", readerA->GetTotalHitCount(), readerA->GetOptimumBatchSize()); + FileInfo fileInfo = {inFileName[0].Data(), readerA->GetSN() * 1000 + readerA->GetFileOrder(), readerA->GetTotalHitCount()}; fileList.push_back(fileInfo); totalHitCount += readerA->GetTotalHitCount(); @@ -98,6 +100,7 @@ int main(int argc, char **argv) { readerB->ScanNumBlock(0,0); // if( readerB->GetOptimumBatchSize() > batchSize ) batchSize = readerB->GetOptimumBatchSize(); batchSize = readerB->GetOptimumBatchSize(); + //printf("Hit count : %7ld | opt. batch size : %7ld\n", readerB->GetTotalHitCount(), readerB->GetOptimumBatchSize()); totalHitCount += readerB->GetTotalHitCount(); fileInfo = {inFileName[i].Data(), readerB->GetSN() * 1000 + readerB->GetFileOrder(), readerB->GetTotalHitCount()}; @@ -162,9 +165,8 @@ int main(int argc, char **argv) { tree->GetBranch("trace")->SetCompressionSettings(205); } - //*======================================= Open files - printf("========================================= Open files & Build Events.\n"); + printf("========================================= Open files & reading 1st batch.\n"); const short nGroup = fileGroupList.size(); std::vector hitList[nGroup]; @@ -177,7 +179,7 @@ int main(int argc, char **argv) { fList.push_back( fileGroupList[i][j].fileName ); } reader[i] = new FSUReader(fList, 1024, debug); // 1024 is the maximum event / agg. - hitList[i] = reader[i]->ReadBatch(batchSize, debug ); + hitList[i] = reader[i]->ReadBatch(batchSize, traceOn, debug ); reader[i]->PrintHitListInfo(&hitList[i], "hitList-" + std::to_string(reader[i]->GetSN())); ID[i] = 0; if( debug ) { @@ -212,6 +214,7 @@ int main(int argc, char **argv) { std::vector events; unsigned long long hitProcessed = 0; + printf("========================================= Start Building Events....\n"); do{ @@ -226,7 +229,7 @@ int main(int argc, char **argv) { //chekc if reached the end of hitList if( ID[ig] >= hitList[ig].size() ) { - hitList[ig] = reader[ig]->ReadBatch(batchSize, debug + 1); + hitList[ig] = reader[ig]->ReadBatch(batchSize, traceOn, debug + 1); if( debug ) reader[ig]->PrintHitListInfo( &hitList[ig], "hitList-" + std::to_string(ig)); ID[ig] = 0; if( hitList[ig].size() == 0 ) continue; @@ -245,7 +248,7 @@ int main(int argc, char **argv) { //check if reached the end of hitList if( ID[ig] >= hitList[ig].size() ) { - hitList[ig] = reader[ig]->ReadBatch(batchSize, debug); + hitList[ig] = reader[ig]->ReadBatch(batchSize, traceOn, debug); if( debug ) reader[ig]->PrintHitListInfo( &hitList[ig], "hitList-" + std::to_string(ig)); ID[ig] = 0; if( hitList[ig].size() == 0 ) break; @@ -334,7 +337,7 @@ int main(int argc, char **argv) { continue; }else{ if( ID[i] >= hitList[i].size( )) { - hitList[i] = reader[i]->ReadBatch(batchSize, debug); + hitList[i] = reader[i]->ReadBatch(batchSize, traceOn, debug); ID[i] = 0; if( hitList[i].size() == 0 ) nFileFinished ++; } diff --git a/Aux/fsuReader.h b/Aux/fsuReader.h index e3b802b..6d9e3d0 100644 --- a/Aux/fsuReader.h +++ b/Aux/fsuReader.h @@ -64,7 +64,7 @@ class FSUReader{ void ClearTotalHitCount() {totalHitCount = 0;} ulong GetTotalHitCount() const{return totalHitCount;} - std::vector ReadBatch(unsigned int batchSize = 1000000, bool verbose = false); // output the sorted Hit + std::vector ReadBatch(unsigned int batchSize = 1000000, bool traceOn = false, bool verbose = false); // output the sorted Hit void PrintHit(ulong numHit = -1, ulong startIndex = 0) { for( ulong i = startIndex; i < std::min(numHit, totalHitCount); i++){ @@ -296,7 +296,7 @@ inline int FSUReader::ReadNextBlock(bool traceON, int verbose, uShort saveData){ if( inFile == NULL ) return -1; if( feof(inFile) || filePos >= inFileSize) { if( fileID >= 0 && fileID + 1 < (short) fileList.size() ){ - printf("-------------- next file\n"); + printf("-------------- next file | hit size : %zu\n", hit.size()); fileID ++; OpenFile(fileList[fileID], data->GetDataSize(), 1 ); }else{ @@ -375,7 +375,11 @@ inline int FSUReader::ReadNextBlock(bool traceON, int verbose, uShort saveData){ temp.ch = ch; temp.energy = data->GetEnergy(ch, k); temp.energy2 = data->GetEnergy2(ch, k); + temp.timestamp = data->GetTimestamp(ch, k); + // unsigned long long offset = 1000000; + // if( sn == 405 && ch == 0) temp.timestamp -= offset; + temp.fineTime = data->GetFineTime(ch, k); temp.pileUp = data->GetPileUp(ch, k); if( saveData > 1 ) { @@ -498,7 +502,7 @@ inline void FSUReader::ScanNumBlock(int verbose, uShort saveData){ } //^============================================================== -inline std::vector FSUReader::ReadBatch(unsigned int batchSize, bool verbose){ +inline std::vector FSUReader::ReadBatch(unsigned int batchSize, bool traceOn, bool verbose){ // printf("%s sn:%d. filePos : %lu\n", __func__, sn, ftell(inFile)); @@ -512,7 +516,7 @@ inline std::vector FSUReader::ReadBatch(unsigned int batchSize, bool verbos if( hit.size() == 0 ){ int res = 0; do{ - res = ReadNextBlock(true, 0, 3); + res = ReadNextBlock(traceOn, 0, 3); }while ( hit.size() < batchSize && res == 0); SortHit(); uLong t0_B = hit.at(0).timestamp; @@ -538,7 +542,7 @@ inline std::vector FSUReader::ReadBatch(unsigned int batchSize, bool verbos int res = 0; do{ - res = ReadNextBlock(true, 0, 3); + res = ReadNextBlock(traceOn, 0, 3); }while ( hit.size() < batchSize && res == 0); SortHit(); uLong t0_B = hit.at(0).timestamp; From 13b2a3d63dfb42608775c43c0f00ae67107cfa29 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Wed, 4 Sep 2024 16:26:21 -0400 Subject: [PATCH 66/72] Set PSD default is fine time. fix UI bug for PSD --- ClassDigitizer.cpp | 2 ++ DigiSettingsPanel.cpp | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ClassDigitizer.cpp b/ClassDigitizer.cpp index 277b551..1c3bb54 100644 --- a/ClassDigitizer.cpp +++ b/ClassDigitizer.cpp @@ -439,6 +439,8 @@ int Digitizer::ProgramBoard_PSD(){ ret |= CAEN_DGTZ_SetChannelDCOffset(handle, 0xF, 0xAAAA); } + ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::PSD::DPPAlgorithmControl2_G) + 0x7000 , 0x00000200 ); // use fine time + ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::DPPAlgorithmControl) + 0x7000 , 0x00100000 ); // baseline 16 sample ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::PSD::TriggerThreshold) + 0x7000 , 100 ); diff --git a/DigiSettingsPanel.cpp b/DigiSettingsPanel.cpp index 8a3f009..96fa5d2 100644 --- a/DigiSettingsPanel.cpp +++ b/DigiSettingsPanel.cpp @@ -2499,7 +2499,7 @@ void DigiSettingsPanel::SetUpChannel_PSD(){ QLabel * lb4 = new QLabel("Veto Width", this); lb4->setAlignment(Qt::AlignHCenter); tabLayout->addWidget(lb4, 0, 6); QLabel * lb5 = new QLabel("Veto Step", this); lb5->setAlignment(Qt::AlignHCenter); tabLayout->addWidget(lb5, 0, 8); } - SetUpComboBoxBit(cbVetoSource[ID][ch], "", tabLayout, ch + 1, 1, DPP::PHA::Bit_DPPAlgorithmControl2::ListVetoSource, DPP::PHA::DPPAlgorithmControl2_G, DPP::PHA::Bit_DPPAlgorithmControl2::VetoSource, 1, ch); + SetUpComboBoxBit(cbVetoSource[ID][ch], "", tabLayout, ch + 1, 1, DPP::PSD::Bit_DPPAlgorithmControl2::ListVetoSource, DPP::PSD::DPPAlgorithmControl2_G, DPP::PSD::Bit_DPPAlgorithmControl2::VetoSource, 1, ch); SetUpComboBoxBit(cbVetoMode[ID][ch], "", tabLayout, ch + 1, 3, DPP::PSD::Bit_DPPAlgorithmControl2::ListVetoMode, DPP::PSD::DPPAlgorithmControl2_G, DPP::PSD::Bit_DPPAlgorithmControl2::VetoMode, 1, ch); SetUpSpinBox(sbVetoWidth[ID][ch], "", tabLayout, ch + 1, 5, DPP::VetoWidth, ch); SetUpComboBoxBit(cbVetoStep[ID][ch], "", tabLayout, ch + 1, 7, DPP::Bit_VetoWidth::ListVetoStep, DPP::VetoWidth, DPP::Bit_VetoWidth::VetoStep, 1, ch); @@ -2510,7 +2510,7 @@ void DigiSettingsPanel::SetUpChannel_PSD(){ QLabel * lb2 = new QLabel("Extra Option [G]", this); lb2->setAlignment(Qt::AlignHCenter); tabLayout->addWidget(lb2, 0, 2); QLabel * lb3 = new QLabel("TRG-OUT Ch. Prb. [G]", this); lb3->setAlignment(Qt::AlignHCenter); tabLayout->addWidget(lb3, 0, 4); } - SetUpComboBoxBit(cbExtra2Option[ID][ch], "", tabLayout, ch + 1, 1, DPP::PHA::Bit_DPPAlgorithmControl2::ListExtra2, DPP::PHA::DPPAlgorithmControl2_G, DPP::PHA::Bit_DPPAlgorithmControl2::Extra2Option, 2, ch); + SetUpComboBoxBit(cbExtra2Option[ID][ch], "", tabLayout, ch + 1, 1, DPP::PSD::Bit_DPPAlgorithmControl2::ListExtraWordOpt, DPP::PSD::DPPAlgorithmControl2_G, DPP::PSD::Bit_DPPAlgorithmControl2::ExtraWordOption, 2, ch); SetUpComboBoxBit(cbTRGOUTChannelProbe[ID][ch], "", tabLayout, ch + 1, 3, DPP::PSD::Bit_DPPAlgorithmControl2::ListChannelProbe, DPP::PSD::DPPAlgorithmControl2_G, DPP::PSD::Bit_DPPAlgorithmControl2::ChannelProbe, 2, ch); } From dfdc5c4700adb78359ed3c85673c460202eb57a3 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Wed, 4 Sep 2024 16:39:19 -0400 Subject: [PATCH 67/72] fixed a UI issue for PSD channel, the SetUpComBoBoxBit cannot span col --- DigiSettingsPanel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DigiSettingsPanel.cpp b/DigiSettingsPanel.cpp index 96fa5d2..264a8a2 100644 --- a/DigiSettingsPanel.cpp +++ b/DigiSettingsPanel.cpp @@ -2510,8 +2510,8 @@ void DigiSettingsPanel::SetUpChannel_PSD(){ QLabel * lb2 = new QLabel("Extra Option [G]", this); lb2->setAlignment(Qt::AlignHCenter); tabLayout->addWidget(lb2, 0, 2); QLabel * lb3 = new QLabel("TRG-OUT Ch. Prb. [G]", this); lb3->setAlignment(Qt::AlignHCenter); tabLayout->addWidget(lb3, 0, 4); } - SetUpComboBoxBit(cbExtra2Option[ID][ch], "", tabLayout, ch + 1, 1, DPP::PSD::Bit_DPPAlgorithmControl2::ListExtraWordOpt, DPP::PSD::DPPAlgorithmControl2_G, DPP::PSD::Bit_DPPAlgorithmControl2::ExtraWordOption, 2, ch); - SetUpComboBoxBit(cbTRGOUTChannelProbe[ID][ch], "", tabLayout, ch + 1, 3, DPP::PSD::Bit_DPPAlgorithmControl2::ListChannelProbe, DPP::PSD::DPPAlgorithmControl2_G, DPP::PSD::Bit_DPPAlgorithmControl2::ChannelProbe, 2, ch); + SetUpComboBoxBit(cbExtra2Option[ID][ch], "", tabLayout, ch + 1, 1, DPP::PSD::Bit_DPPAlgorithmControl2::ListExtraWordOpt, DPP::PSD::DPPAlgorithmControl2_G, DPP::PSD::Bit_DPPAlgorithmControl2::ExtraWordOption, 1, ch); + SetUpComboBoxBit(cbTRGOUTChannelProbe[ID][ch], "", tabLayout, ch + 1, 3, DPP::PSD::Bit_DPPAlgorithmControl2::ListChannelProbe, DPP::PSD::DPPAlgorithmControl2_G, DPP::PSD::Bit_DPPAlgorithmControl2::ChannelProbe, 1, ch); } } From 3b3a22382b24aebc574f1cac82c181460b31242c Mon Sep 17 00:00:00 2001 From: "carina@hades" Date: Wed, 4 Sep 2024 17:50:59 -0400 Subject: [PATCH 68/72] [Major] Scalar cannot be put in Thread, becuase it update QLineEdit of the MainThread and it is not thread-safe --- CustomThreads.h | 58 ++++++++++++++++++++--------------------- FSUDAQ.cpp | 69 ++++++++++++++++++++++++++++++++----------------- FSUDAQ.h | 36 ++++++++++++++------------ 3 files changed, 93 insertions(+), 70 deletions(-) diff --git a/CustomThreads.h b/CustomThreads.h index ea87b1d..4251233 100644 --- a/CustomThreads.h +++ b/CustomThreads.h @@ -111,34 +111,34 @@ private: }; //^#======================================================= Timing Thread -// class TimingThread : public QThread { -// Q_OBJECT -// public: -// TimingThread(QObject * parent = 0 ) : QThread(parent){ -// waitTime = 20; // multiple of 100 mili sec -// stop = false; -// } -// bool isStopped() const {return stop;} -// void Stop() { this->stop = true;} -// void SetWaitTimeinSec(float sec) {waitTime = sec * 10 ;} -// float GetWaitTimeinSec() const {return waitTime/10.;} -// void DoOnce() {emit timeUp();}; -// void run(){ -// unsigned int count = 0; -// stop = false; -// do{ -// usleep(100000); -// count ++; -// if( count % waitTime == 0){ -// emit timeUp(); -// } -// }while(!stop); -// } -// signals: -// void timeUp(); -// private: -// bool stop; -// unsigned int waitTime; -// }; +class TimingThread : public QThread { + Q_OBJECT +public: + TimingThread(QObject * parent = 0 ) : QThread(parent){ + waitTime = 20; // multiple of 100 mili sec + stop = false; + } + bool isStopped() const {return stop;} + void Stop() { this->stop = true;} + void SetWaitTimeinSec(float sec) {waitTime = sec * 10 ;} + float GetWaitTimeinSec() const {return waitTime/10.;} + void DoOnce() {emit timeUp();}; + void run(){ + unsigned int count = 0; + stop = false; + do{ + usleep(100000); + count ++; + if( count % waitTime == 0){ + emit timeUp(); + } + }while(!stop); + } +signals: + void timeUp(); +private: + bool stop; + unsigned int waitTime; +}; #endif diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index 21b8856..0c6dd16 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -309,11 +309,14 @@ FSUDAQ::FSUDAQ(QWidget *parent) : QMainWindow(parent){ FSUDAQ::~FSUDAQ(){ DebugPrint("%s", "FSUDAQ"); if( scalar ) { - scalarTimer->stop(); - if( scalarThread->isRunning() ){ - scalarThread->quit(); - scalarThread->exit(); - } + scalarTimingThread->Stop(); + scalarTimingThread->quit(); + scalarTimingThread->exit(); + // scalarTimer->stop(); + // if( scalarThread->isRunning() ){ + // scalarThread->quit(); + // scalarThread->exit(); + // } CleanUpScalar(); //don't need to delete scalar, it is managed by this } @@ -762,10 +765,15 @@ void FSUDAQ::CloseDigitizers(){ scope = nullptr; } - scalarTimer->stop(); - if( scalarThread->isRunning() ){ - scalarThread->quit(); - scalarThread->exit(); + // scalarTimer->stop(); + // if( scalarThread->isRunning() ){ + // scalarThread->quit(); + // scalarThread->exit(); + // } + scalarTimingThread->Stop(); + if( scalarTimingThread->isRunning() ){ + scalarTimingThread->quit(); + scalarTimingThread->exit(); } if( scalar ) CleanUpScalar(); @@ -870,18 +878,18 @@ void FSUDAQ::SetupScalar(){ lbScalarACQStatus = nullptr; lbTotalFileSize = nullptr; - // scalarThread = new TimingThread(scalar); - // scalarThread->SetWaitTimeinSec(1.0); - // connect(scalarThread, &TimingThread::timeUp, this, &FSUDAQ::UpdateScalar); + scalarTimingThread = new TimingThread(scalar); + scalarTimingThread->SetWaitTimeinSec(ScalarUpdateinMiliSec / 1000.); + connect(scalarTimingThread, &TimingThread::timeUp, this, &FSUDAQ::UpdateScalar); - scalarThread = new QThread(this); - scalarWorker = new ScalarWorker(this); - scalarWorker->moveToThread(scalarThread); + // scalarThread = new QThread(this); + // scalarWorker = new ScalarWorker(this); + // scalarWorker->moveToThread(scalarThread); - scalarTimer = new QTimer(this); - connect( scalarTimer, &QTimer::timeout, scalarWorker, &ScalarWorker::UpdateScalar); + // scalarTimer = new QTimer(this); + // connect( scalarTimer, &QTimer::timeout, scalarWorker, &ScalarWorker::UpdateScalar); - scalarThread->start(); + // scalarThread->start(); unsigned short maxNChannel = 0; for( unsigned int k = 0; k < nDigi; k ++ ){ @@ -1068,8 +1076,8 @@ void FSUDAQ::UpdateScalar(){ lbTotalFileSize->setText("Total Data Size : " + QString::number(totalFileSize/1024./1024., 'f', 3) + " MB"); - repaint(); - scalar->repaint(); + // repaint(); + // scalar->repaint(); if( influx && chkInflux->isChecked() && scalarCount >= 3){ if( chkSaveData->isChecked() ) { @@ -1081,6 +1089,8 @@ void FSUDAQ::UpdateScalar(){ influx->ClearDataPointsBuffer(); scalarCount = 0; } + + // printf("end of %s\n", __func__); } @@ -1162,7 +1172,8 @@ void FSUDAQ::StartACQ(){ // printf("------------ Go! \n"); // for( unsigned int i = 0; i < nDigi; i++) readDataThread[i]->go(); - if( scalar ) scalarTimer->start(ScalarUpdateinMiliSec); + // if( scalar ) scalarTimer->start(ScalarUpdateinMiliSec); + if( scalar ) scalarTimingThread->start(); if( !scalar->isVisible() ) { scalar->show(); @@ -1239,7 +1250,13 @@ void FSUDAQ::StopACQ(){ QCoreApplication::processEvents(); } - if( scalar ) scalarTimer->stop(); + if( scalarTimingThread->isRunning()){ + scalarTimingThread->Stop(); + scalarTimingThread->quit(); + scalarTimingThread->wait(); + } + + // if( scalar ) scalarTimer->stop(); if( singleHistograms ) singleHistograms->stopTimer(); if( onlineAnalyzer ) onlineAnalyzer->stopTimer(); @@ -1731,7 +1748,8 @@ void FSUDAQ::OpenScope(){ if( scalar ){ lbScalarACQStatus->setText("ACQ On"); - scalarTimer->start(ScalarUpdateinMiliSec); + // scalarTimer->start(ScalarUpdateinMiliSec); + scalarTimingThread->start(); } if( singleHistograms ) singleHistograms->startTimer(); @@ -1742,7 +1760,10 @@ void FSUDAQ::OpenScope(){ if( scalar ){ lbScalarACQStatus->setText("ACQ Off"); - scalarTimer->stop(); + // scalarTimer->stop(); + scalarTimingThread->Stop(); + scalarTimingThread->quit(); + scalarTimingThread->wait(); } if( singleHistograms ) singleHistograms->stopTimer(); diff --git a/FSUDAQ.h b/FSUDAQ.h index b892d1a..42c3ab3 100644 --- a/FSUDAQ.h +++ b/FSUDAQ.h @@ -173,9 +173,11 @@ private: //@----- Scalar QMainWindow * scalar; QGridLayout * scalarLayout; - QThread * scalarThread; - ScalarWorker * scalarWorker; - QTimer * scalarTimer; + TimingThread * scalarTimingThread; + // QThread * scalarThread; + // ScalarWorker * scalarWorker; + // QTimer * scalarTimer; + // TimingThread * scalarThread; QLineEdit *** leTrigger; // need to delete manually @@ -212,23 +214,23 @@ private: //^======================== Scalar Worker -class ScalarWorker : public QObject{ - Q_OBJECT -public: - ScalarWorker(FSUDAQ * parent): SS(parent){} +// class ScalarWorker : public QObject{ +// Q_OBJECT +// public: +// ScalarWorker(FSUDAQ * parent): SS(parent){} -public slots: - void UpdateScalar(){ - SS->UpdateScalar(); - emit workDone(); - } +// public slots: +// void UpdateScalar(){ +// SS->UpdateScalar(); +// emit workDone(); +// } -signals: - void workDone(); +// signals: +// void workDone(); -private: - FSUDAQ * SS; -}; +// private: +// FSUDAQ * SS; +// }; #endif // MAINWINDOW_H \ No newline at end of file From 968259787b3d12b5d9fa0553e37d3a347630681d Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Fri, 6 Sep 2024 18:16:18 -0400 Subject: [PATCH 69/72] when open digitizer, always set no trace recording --- ClassDigitizer.h | 4 ++++ FSUDAQ.cpp | 3 +++ 2 files changed, 7 insertions(+) diff --git a/ClassDigitizer.h b/ClassDigitizer.h index 6b7652f..6087493 100644 --- a/ClassDigitizer.h +++ b/ClassDigitizer.h @@ -206,6 +206,10 @@ class Digitizer{ return returnData; } + void SetTrace(bool onOff){ + SetBits(DPP::BoardConfiguration, DPP::Bit_BoardConfig::RecordTrace, onOff, -1); + } + }; diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index 0c6dd16..6735f65 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -684,6 +684,9 @@ void FSUDAQ::OpenDigitizers(){ digi[i] = new Digitizer(portList[i].first, portList[i].second); //digi[i]->Reset(); + //===== set no trace, even when FSQDAQ segfault at scope, the digitizer will save no trace + digi[i]->SetTrace(false); + if( cbOpenMethod->currentData().toInt() == 2 ) { digi[i]->ProgramBoard(); } From b3692705ab1618acc77a8a8dc73792671e2a74d5 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Mon, 9 Sep 2024 14:00:43 -0400 Subject: [PATCH 70/72] add core dump when segfault --- .gitignore | 1 + README.md | 17 +++++++++++++++++ main.cpp | 24 +++++++++++++----------- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 91497de..84e79bb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ *.o *.fsu *.root +core.FSUDAQ* FSUDAQ_Qt6 test diff --git a/README.md b/README.md index 3bb01f4..aa95aaa 100644 --- a/README.md +++ b/README.md @@ -159,6 +159,23 @@ 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. +# Enable Core dump + +The program has abort handler to save core dump. + +first, enable the gdb in compilation by edit the FSUDAQ_Qt6.pro by commen out the following lines: +```sh +QMAKE_CXXFLAGS += -g +QMAKE_CXXFLAGS_RELEASE = -O0 +QMAKE_CFLAGS_RELEASE = -O0 +``` + +second, ensure the core dump file has unlimited size and set the core dump file name +```sh +>ulimit -c unlimited +>echo "core.%e.%p" | sudo tee /proc/sys/kernel/core_pattern +``` + # Known Issues diff --git a/main.cpp b/main.cpp index 22e28cb..e096e98 100644 --- a/main.cpp +++ b/main.cpp @@ -12,26 +12,28 @@ #include -// class CustomApplication : public QApplication{ -// public: -// CustomApplication(int &argc, char **argv) : QApplication(argc, argv) {} +#include +#include +#include -// protected: -// bool notify(QObject *receiver, QEvent *event) override{ -// qDebug() << event->type() << "Receiver:" << receiver; -// return QApplication::notify(receiver, event); -// } -// }; +void abortHandler(int signal) { + std::cerr << "Signal received: " << signal << ", aborting..." << std::endl; + std::abort(); // Calls abort to generate core dump +} int main(int argc, char *argv[]){ + std::signal(SIGSEGV, abortHandler); + + setpriority(PRIO_PROCESS, 0, -20); + // CustomApplication a(argc, argv); QApplication a(argc, argv); + // Set Locale QLocale::setDefault(QLocale::system()); - setpriority(PRIO_PROCESS, 0, -20); - + // Set Lock file bool isLock = false; int pid = 0; QFile lockFile(DAQLockFile); From d7389714351613ad8efab6df420ca15d888aff69 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Mon, 9 Sep 2024 14:22:21 -0400 Subject: [PATCH 71/72] add maskText to mask password --- FSUDAQ.cpp | 6 +++--- FSUDAQ.h | 12 ++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index 6735f65..e4a74bf 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -468,11 +468,11 @@ void FSUDAQ::LoadProgramSettings(){ LogMsg(" Raw Data Path : " + rawDataPath); LogMsg(" Influx IP : " + influxIP); LogMsg(" Database Name : " + dataBaseName); - LogMsg("Database Token : " + influxToken); + LogMsg("Database Token : " + maskText(influxToken)); LogMsg(" Elog IP : " + elogIP); LogMsg(" Elog Name : " + elogName); - LogMsg(" Elog User : " + elogUser); - LogMsg(" Elog PWD : " + elogPWD); + LogMsg(" Elog User : " + maskText(elogUser)); + LogMsg(" Elog PWD : " + maskText(elogPWD)); logMsgHTMLMode = true; //check is rawDataPath exist, if not, create one diff --git a/FSUDAQ.h b/FSUDAQ.h index 42c3ab3..07f22d7 100644 --- a/FSUDAQ.h +++ b/FSUDAQ.h @@ -209,6 +209,18 @@ private: //@----- Analyzer Analyzer * onlineAnalyzer; + QString maskText(const QString &password) { + if (password.length() <= 3) { + return password; // No masking needed for short passwords + } else if (password.length() <= 10) { + QString maskedPassword = password.left(3); + maskedPassword += QString("*").repeated(password.length() - 3); + return maskedPassword; + } else { + return password.left(3) + QString("*").repeated(7); + } + } + }; From d8c6fa224601abb22548be90603c88692a17fc46 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS_testStation" Date: Mon, 9 Sep 2024 14:38:08 -0400 Subject: [PATCH 72/72] add FSUDAQ bash script, to pipe the stout to a log file --- FSUDAQ | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100755 FSUDAQ diff --git a/FSUDAQ b/FSUDAQ new file mode 100755 index 0000000..04a3b23 --- /dev/null +++ b/FSUDAQ @@ -0,0 +1,7 @@ +#!/bin/bash + +timestamp=$(date +%Y%m%d_%H%M%S) + +outFile=program_${timestamp}.log + +stdbuf -oL ./FSUDAQ_Qt6 | tee $outFile \ No newline at end of file