diff --git a/DataGenerator.cpp b/Aux/DataGenerator.cpp similarity index 95% rename from DataGenerator.cpp rename to Aux/DataGenerator.cpp index 28f9e18..3090b99 100644 --- a/DataGenerator.cpp +++ b/Aux/DataGenerator.cpp @@ -1,8 +1,8 @@ #include #include -#include "macro.h" -#include "ClassDigitizer.h" +#include "../macro.h" +#include "../ClassDigitizer.h" int main(){ diff --git a/DataReaderScript.cpp b/Aux/DataReaderScript.cpp similarity index 98% rename from DataReaderScript.cpp rename to Aux/DataReaderScript.cpp index ba54cd8..3d15dd6 100644 --- a/DataReaderScript.cpp +++ b/Aux/DataReaderScript.cpp @@ -4,8 +4,8 @@ This can be loaded to root and run the DataReader() ***********/ -#include "ClassData.h" -#include "MultiBuilder.h" +#include "../ClassData.h" +#include "../MultiBuilder.h" void DataReader(std::string fileName, int DPPType){ diff --git a/DumpFSU2ROOT.cpp b/Aux/DumpFSU2ROOT.cpp similarity index 98% rename from DumpFSU2ROOT.cpp rename to Aux/DumpFSU2ROOT.cpp index da6eb85..ee1b459 100644 --- a/DumpFSU2ROOT.cpp +++ b/Aux/DumpFSU2ROOT.cpp @@ -4,8 +4,8 @@ This can be loaded to root and run the DataReader() ***********/ -#include "ClassData.h" -#include "MultiBuilder.h" +#include "../ClassData.h" +#include "../MultiBuilder.h" #include "TROOT.h" #include "TFile.h" diff --git a/EventBuilder.cpp b/Aux/EventBuilder.cpp similarity index 96% rename from EventBuilder.cpp rename to Aux/EventBuilder.cpp index 8b501cc..258a331 100644 --- a/EventBuilder.cpp +++ b/Aux/EventBuilder.cpp @@ -72,14 +72,20 @@ int main(int argc, char **argv) { int snPos = inFileName[i].Index("_"); // first "_" //snPos = inFileName[i].Index("_", snPos + 1); int sn = atoi(&inFileName[i][snPos+5]); - TString typeStr = &inFileName[i][snPos+9]; + + int typePos = inFileName[i].Index("_", snPos+5); + TString typeStr = &inFileName[i][typePos+1]; typeStr.Resize(3); + printf("sn %d %s \n", sn, typeStr.Data()); + if( typeStr == "PHA" ) type[i] = DPPType::DPP_PHA_CODE; if( typeStr == "PSD" ) type[i] = DPPType::DPP_PSD_CODE; + if( typeStr == "QDC" ) type[i] = DPPType::DPP_QDC_CODE; - int order = atoi(&inFileName[i][snPos+13]); - ID[i] = sn + order * 1000; + int orderPos = inFileName[i].Index("_", typePos + 1); + int order = atoi(&inFileName[i][orderPos+1]); + ID[i] = sn + order * 100000; FILE * temp = fopen(inFileName[i].Data(), "rb"); if( temp == NULL ) { @@ -96,7 +102,7 @@ int main(int argc, char **argv) { } quickSort(&(ID[0]), &(type[0]), &(inFileName[0]), 0, nFile-1); for( int i = 0 ; i < nFile; i++){ - printf("%d | %6d | %3d | %s | %u Bytes = %.2f MB\n", i, ID[i], type[i], inFileName[i].Data(), fileSize[i], fileSize[i]/1024./1024.); + printf("%d | %6d | %3d | %30s | %u Bytes = %.2f MB\n", i, ID[i], type[i], inFileName[i].Data(), fileSize[i], fileSize[i]/1024./1024.); } //*======================================= Sort files in to group @@ -104,11 +110,11 @@ int main(int argc, char **argv) { std::vector typeList; // store the DPP type of the group std::vector> fileList; // store the file list of the group for( int i = 0; i < nFile; i++){ - if( ID[i] / 1000 == 0 ) { + if( ID[i] / 100000 == 0 ) { std::vector temp = {inFileName[i]}; fileList.push_back(temp); typeList.push_back(type[i]); - snList.push_back(ID[i]%1000); + snList.push_back(ID[i]%100000); }else{ for( int p = 0; p < (int) snList.size(); p++){ if( (ID[i] % 1000) == snList[p] ) { diff --git a/fsuReader.h b/Aux/fsuReader.h similarity index 100% rename from fsuReader.h rename to Aux/fsuReader.h diff --git a/test.cpp b/Aux/test.cpp similarity index 99% rename from test.cpp rename to Aux/test.cpp index ecf928a..6a3de5c 100644 --- a/test.cpp +++ b/Aux/test.cpp @@ -1,6 +1,6 @@ -#include "macro.h" -#include "ClassData.h" -#include "ClassDigitizer.h" +#include "../macro.h" +#include "../ClassData.h" +#include "../ClassDigitizer.h" #include #include diff --git a/test_indep.cpp b/Aux/test_indep.cpp similarity index 99% rename from test_indep.cpp rename to Aux/test_indep.cpp index 4a50e24..e8da6d3 100644 --- a/test_indep.cpp +++ b/Aux/test_indep.cpp @@ -8,8 +8,8 @@ #include "CAENDigitizer.h" #include "CAENDigitizerType.h" -#include "macro.h" -#include "RegisterAddress.h" +#include "../macro.h" +#include "../RegisterAddress.h" using namespace std; diff --git a/FSUDAQ.cpp b/FSUDAQ.cpp index a4c97a8..ad410f5 100644 --- a/FSUDAQ.cpp +++ b/FSUDAQ.cpp @@ -14,11 +14,12 @@ #include #include +#include "analyzers/CoincidentAnalyzer.h" #include "analyzers/SplitPoleAnalyzer.h" #include "analyzers/EncoreAnalyzer.h" #include "analyzers/RAISOR.h" -std::vector onlineAnalyzerList = {"Splie-Pole", "Encore", "RAISOR"}; +std::vector onlineAnalyzerList = {"Coincident","Splie-Pole", "Encore", "RAISOR"}; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ @@ -1577,17 +1578,19 @@ void MainWindow::OpenAnalyzer(){ if( onlineAnalyzer == nullptr ) { //onlineAnalyzer = new Analyzer(digi, nDigi); - if( id == 0 ) onlineAnalyzer = new SplitPole(digi, nDigi); - if( id == 1 ) onlineAnalyzer = new Encore(digi, nDigi); - if( id == 2 ) onlineAnalyzer = new RAISOR(digi, nDigi); + if( id == 0 ) onlineAnalyzer = new CoincidentAnalyzer(digi, nDigi); + 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 >= 0 ) onlineAnalyzer->show(); }else{ delete onlineAnalyzer; - if( id == 0 ) onlineAnalyzer = new SplitPole(digi, nDigi); - if( id == 1 ) onlineAnalyzer = new Encore(digi, nDigi); - if( id == 2 ) onlineAnalyzer = new RAISOR(digi, nDigi); + if( id == 0 ) onlineAnalyzer = new CoincidentAnalyzer(digi, nDigi); + 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 >= 0 ){ onlineAnalyzer->show(); diff --git a/FSUDAQ_Qt6.pro b/FSUDAQ_Qt6.pro index 17dbcb7..77038eb 100644 --- a/FSUDAQ_Qt6.pro +++ b/FSUDAQ_Qt6.pro @@ -40,9 +40,10 @@ HEADERS += ClassData.h \ qcustomplot.h \ analyzers/Isotope.h \ analyzers/Analyser.h \ + analyzers/CoincidentAnalyzer.h \ analyzers/SplitPoleAnalyzer.h \ - analyzers/EncoreAnalyzer.h - analyzers/RAISOR.h + analyzers/EncoreAnalyzer.h \ + analyzers/RAISOR.h SOURCES += ClassDigitizer.cpp \ DigiSettingsPanel.cpp \ FSUDAQ.cpp \ diff --git a/Histogram1D.h b/Histogram1D.h index f33e88c..85f3856 100644 --- a/Histogram1D.h +++ b/Histogram1D.h @@ -215,6 +215,8 @@ public: overFlow = 0; UpdatePlot(); } + + void SetXTitle(QString xTitle) { xAxis->setLabel(xTitle); } void Rebin(int xbin, double xmin, double xmax){ xMin = xmin; diff --git a/Histogram2D.h b/Histogram2D.h index 97a790e..2bbf952 100644 --- a/Histogram2D.h +++ b/Histogram2D.h @@ -179,9 +179,25 @@ public: //^=================================== + 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 UpdatePlot(){ colorMap->rescaleDataRange(); replot(); } + void UpdatePlot(){ + QCPColorGradient color; + color.clearColorStops(); + color.setColorStopAt( 0.0, QColor("white" )); + color.setColorStopAt( 1.0/entry[1][1], 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 Clear(); // Clear Data and histrogram diff --git a/Makefile_Aux b/Makefile_Aux deleted file mode 100644 index cd7b0e9..0000000 --- a/Makefile_Aux +++ /dev/null @@ -1,54 +0,0 @@ -######################################################################## -# -# -######################################################################### - -CC = g++ - -#COPTS = -fPIC -DLINUX -O2 -std=c++17 -lpthread -COPTS = -fPIC -DLINUX -g -O2 -Wall -std=c++17 -lpthread - -CAENLIBS = -lCAENDigitizer - -ROOTLIBS = `root-config --cflags --glibs` - -OBJS = ClassDigitizer.o MultiBuilder.o - -ALL = test test_indep DataGenerator EventBuilder DataReader DumpFSU2ROOT - -######################################################################### - -all : $(ALL) - -clean : - /bin/rm -f $(OBJS) $(ALL) - -MultiBuilder.o : MultiBuilder.cpp MultiBuilder.h - $(CC) $(COPTS) -c MultiBuilder.cpp - -ClassDigitizer.o : ClassDigitizer.cpp ClassDigitizer.h RegisterAddress.h macro.h ClassData.h - $(CC) $(COPTS) -c ClassDigitizer.cpp - -test : test.cpp ClassDigitizer.o - @echo "--------- making test" - $(CC) $(COPTS) -o test test.cpp ClassDigitizer.o $(CAENLIBS) $(ROOTLIBS) - -test_indep : test_indep.cpp RegisterAddress.h macro.h - @echo "--------- making test_indep" - $(CC) $(COPTS) -o test_indep test_indep.cpp $(CAENLIBS) - -DataGenerator : DataGenerator.cpp ClassDigitizer.o - @echo "--------- making DataGenerator" - $(CC) $(COPTS) -o DataGenerator DataGenerator.cpp ClassDigitizer.o $(CAENLIBS) - -DataReader : DataReaderScript.cpp ClassData.h MultiBuilder.o - @echo "--------- making DataReader" - $(CC) $(COPTS) -o DataReader DataReaderScript.cpp ClassData.h MultiBuilder.o - -EventBuilder : EventBuilder.cpp ClassData.h MultiBuilder.o - @echo "--------- making EventBuilder" - $(CC) $(COPTS) -o EventBuilder EventBuilder.cpp MultiBuilder.o $(ROOTLIBS) - -DumpFSU2ROOT : DumpFSU2ROOT.cpp ClassData.h MultiBuilder.o - @echo "--------- making DumpFSU2ROOT" - $(CC) $(COPTS) -o DumpFSU2ROOT DumpFSU2ROOT.cpp ClassData.h MultiBuilder.o $(ROOTLIBS) diff --git a/analyzers/CoincidentAnalyzer.h b/analyzers/CoincidentAnalyzer.h new file mode 100644 index 0000000..1c6263e --- /dev/null +++ b/analyzers/CoincidentAnalyzer.h @@ -0,0 +1,268 @@ +#ifndef COINCIDENTANLAYZER_H +#define COINCIDENTANLAYZER_H + +#include "Analyser.h" + +//^=========================================== +class CoincidentAnalyzer : public Analyzer{ + Q_OBJECT +public: + CoincidentAnalyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent = nullptr): Analyzer(digi, nDigi, parent){ + + this->digi = digi; + this->nDigi = nDigi; + + SetUpdateTimeInSec(1.0); + + //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); + + //========== use the influx from the Analyzer + influx = new InfluxDB("https://fsunuc.physics.fsu.edu/influx/"); + dataBaseName = "testing"; + + SetUpCanvas(); + + } + + void SetUpCanvas(); + +public slots: + void UpdateHistograms(); + +private: + + Digitizer ** digi; + unsigned int nDigi; + + MultiBuilder *evtbder; + + // declaie histograms + Histogram2D * h2D; + Histogram1D * h1; + Histogram1D * h1g; + Histogram1D * hMulti; + + QCheckBox * runAnalyzer; + RSpinBox * sbUpdateTime; + + QCheckBox * backWardBuilding; + RSpinBox * sbBackwardCount; + + RSpinBox * sbBuildWindow; + + // data source for the h2D + RComboBox * xDigi; + RComboBox * xCh; + RComboBox * yDigi; + RComboBox * yCh; + + // data source for the h1 + RComboBox * aDigi; + RComboBox * aCh; + +}; + + +inline void CoincidentAnalyzer::SetUpCanvas(){ + + setGeometry(0, 0, 1600, 1000); + + {//^====== magnet and reaction setting + QGroupBox * box = new QGroupBox("Configuration", this); + layout->addWidget(box, 0, 0); + QGridLayout * boxLayout = new QGridLayout(box); + boxLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft); + box->setLayout(boxLayout); + + runAnalyzer = new QCheckBox("Run Analyzer", this); + boxLayout->addWidget(runAnalyzer, 0, 0); + + QLabel * lbUpdateTime = new QLabel("Update Period [s]", this); + lbUpdateTime->setAlignment(Qt::AlignRight | Qt::AlignCenter); + boxLayout->addWidget(lbUpdateTime, 0, 1); + sbUpdateTime = new RSpinBox(this, 1); + sbUpdateTime->setMinimum(0.1); + sbUpdateTime->setMaximum(5); + sbUpdateTime->setValue(1); + boxLayout->addWidget(sbUpdateTime, 0, 2); + + backWardBuilding = new QCheckBox("Use Backward builder", this); + boxLayout->addWidget(backWardBuilding, 1, 0); + + QLabel * lbBKWindow = new QLabel("No. Backward Event", this); + lbBKWindow->setAlignment(Qt::AlignRight | Qt::AlignCenter); + boxLayout->addWidget(lbBKWindow, 1, 1); + sbBackwardCount = new RSpinBox(this, 0); + sbBackwardCount->setMinimum(1); + sbBackwardCount->setMaximum(9999); + sbBackwardCount->setValue(100); + boxLayout->addWidget(sbBackwardCount, 1, 2); + + backWardBuilding->setChecked(false); + sbBackwardCount->setEnabled(false); + + QLabel * lbBuildWindow = new QLabel("Event Window [tick]", this); + lbBuildWindow->setAlignment(Qt::AlignRight | Qt::AlignCenter); + boxLayout->addWidget(lbBuildWindow, 2, 1); + sbBuildWindow = new RSpinBox(this, 0); + sbBuildWindow->setMinimum(1); + sbBuildWindow->setMaximum(9999999999); + boxLayout->addWidget(sbBuildWindow, 2, 2); + + QFrame *separator = new QFrame(box); + separator->setFrameShape(QFrame::HLine); + separator->setFrameShadow(QFrame::Sunken); + boxLayout->addWidget(separator, 3, 0, 1, 4); + + QLabel * lbXDigi = new QLabel("X-Digi", this); + lbXDigi->setAlignment(Qt::AlignRight | Qt::AlignCenter); + boxLayout->addWidget(lbXDigi, 4, 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); + + QLabel * lbXCh = new QLabel("X-Ch", this); + lbXCh->setAlignment(Qt::AlignRight | Qt::AlignCenter); + boxLayout->addWidget(lbXCh, 4, 2); + xCh = new RComboBox(this); + for( int i = 0; i < digi[0]->GetNumInputCh(); i++) xCh->addItem("Ch-" + QString::number(i)); + boxLayout->addWidget(xCh, 4, 3); + + QLabel * lbYDigi = new QLabel("Y-Digi", this); + lbYDigi->setAlignment(Qt::AlignRight | Qt::AlignCenter); + boxLayout->addWidget(lbYDigi, 5, 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); + + QLabel * lbYCh = new QLabel("Y-Ch", this); + lbYCh->setAlignment(Qt::AlignRight | Qt::AlignCenter); + boxLayout->addWidget(lbYCh, 5, 2); + yCh = new RComboBox(this); + for( int i = 0; i < digi[0]->GetNumInputCh(); i++) yCh->addItem("Ch-" + QString::number(i)); + boxLayout->addWidget(yCh, 5, 3); + + QFrame *separator1 = new QFrame(box); + separator1->setFrameShape(QFrame::HLine); + separator1->setFrameShadow(QFrame::Sunken); + boxLayout->addWidget(separator1, 6, 0, 1, 4); + + + QLabel * lbaDigi = new QLabel("ID-Digi", this); + lbaDigi->setAlignment(Qt::AlignRight | Qt::AlignCenter); + 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()), i); + } + boxLayout->addWidget(yDigi, 7, 1); + + QLabel * lbaCh = new QLabel("1D-Ch", this); + lbaCh->setAlignment(Qt::AlignRight | Qt::AlignCenter); + boxLayout->addWidget(lbaCh, 7, 2); + aCh = new RComboBox(this); + for( int i = 0; i < digi[0]->GetNumInputCh(); i++) aCh->addItem("Ch-" + QString::number(i)); + boxLayout->addWidget(aCh, 7, 3); + + } + + //============ histograms + hMulti = new Histogram1D("Multiplicity", "", 10, 0, 10, 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); + //layout is inheriatge from Analyzer + layout->addWidget(h2D, 1, 0, 2, 1); + + h1 = new Histogram1D("1D Plot", "XXX", 300, 30, 70, 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("1D Plot (PID gated)", "XXX", 300, -2, 10, this); + layout->addWidget(h1g, 2, 1); + + layout->setColumnStretch(0, 1); + layout->setColumnStretch(1, 1); + +} + +inline void CoincidentAnalyzer::UpdateHistograms(){ + + if( this->isVisible() == false ) return; + if( runAnalyzer->isChecked() == false ) return; + + BuildEvents(); // call the event builder to build events + + //============ Get events, and do analysis + long eventBuilt = evtbder->eventBuilt; + if( eventBuilt == 0 ) return; + + //============ Get the cut list, if any + QList cutList = h2D->GetCutList(); + const int nCut = cutList.count(); + unsigned long long tMin[nCut] = {0xFFFFFFFFFFFFFFFF}, tMax[nCut] = {0}; + unsigned int count[nCut]={0}; + + //============ Processing data and fill histograms + long eventIndex = evtbder->eventIndex; + long eventStart = eventIndex - eventBuilt + 1; + if(eventStart < 0 ) eventStart += MaxNEvent; + + 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; + + + for( int k = 0; k < (int) event.size(); k++ ){ + //event[k].Print(); + } + + //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; + // if( cutList[p].containsPoint(QPointF(hit.eSL, hit.eSR), Qt::OddEvenFill) ){ + // if( hit.tSR < tMin[p] ) tMin[p] = hit.tSR; + // if( hit.tSR > tMax[p] ) tMax[p] = hit.tSR; + // count[p] ++; + // //printf(".... %d \n", count[p]); + // if( p == 0 ) h1g->Fill(hit.eSR); + // } + } + } + + h2D->UpdatePlot(); + h1->UpdatePlot(); + 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(); + } + +} + + +#endif \ No newline at end of file