From 15e2768eeb73f47e24146b326746702e4df45ee7 Mon Sep 17 00:00:00 2001 From: "Ryan@SOLARIS-DAQ" Date: Tue, 28 Mar 2023 15:28:36 -0400 Subject: [PATCH] finished the EventBuilder --- .gitignore | 5 + Mapping.h | 42 -------- armory/Event.h | 1 + armory/EventBuilder.cpp | 173 ++++++++++++++++++++++++++++++ armory/Makefile | 11 ++ SolReader.h => armory/SolReader.h | 34 +++--- expName.sh | 5 - working/Mapping.h | 70 ++++++++++++ working/expName.sh | 5 + working/script.C | 75 +++++++++++++ 10 files changed, 358 insertions(+), 63 deletions(-) create mode 100644 .gitignore delete mode 100644 Mapping.h create mode 120000 armory/Event.h create mode 100644 armory/EventBuilder.cpp create mode 100644 armory/Makefile rename SolReader.h => armory/SolReader.h (86%) delete mode 100644 expName.sh create mode 100644 working/Mapping.h create mode 100644 working/expName.sh create mode 100644 working/script.C diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..343089b --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +working/Logs +working/Settings + +EventBuilder +*.root \ No newline at end of file diff --git a/Mapping.h b/Mapping.h deleted file mode 100644 index a8362a6..0000000 --- a/Mapping.h +++ /dev/null @@ -1,42 +0,0 @@ -//^=============================================================================== -//^ This is mapping file for SOLARIS -//^ This file is used to constructe the SOLARIS panel in the SOLARIS DAQ -//^ If this file is modified, please Close Digitizer and Open again -//^------------------------------------------------------------------------------- -//^ -//^ Array : 0 - 199 -//^ Recoil : 200 - 299 -//^ -//^ -//^=============================================================================== - -#define NARRAY 60 -#define NRDT 10 - -#define PARITYARRAY 1 -#define PARITYRDT 1 - -#define NDIGITIZER 2 -#define NCHANNEL 64 // number of channel per digitizer - -int mapping[NDIGITIZER][NCHANNEL] = { -{ -//* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // this line is an indicator DON'T Remove - 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, /// 0 - 15 - 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, /// 16 - 31 - 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, /// 32 - 47 - 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, -1 /// 48 - 63 -//*------------- end of a digitizer // this line is an indicator DON'T Remove -}, -{ -//* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // this line is an indicator DON'T Remove - 21, 21, 21, 22, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 26, /// 0 - 15 - 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, /// 16 - 31 - 31, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 36, 36, /// 32 - 47 - 37, 37, 37, 38, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, -1 /// 48 - 63 -//*------------- end of a digitizer // this line is an indicator DON'T Remove -} -}; - -//& if all array is arrange like this, no need kind mapping. it is always e, xf, xn - diff --git a/armory/Event.h b/armory/Event.h new file mode 120000 index 0000000..a57f30c --- /dev/null +++ b/armory/Event.h @@ -0,0 +1 @@ +/home/solaris/SOLARIS_QT6_DAQ/Event.h \ No newline at end of file diff --git a/armory/EventBuilder.cpp b/armory/EventBuilder.cpp new file mode 100644 index 0000000..5ac3fd5 --- /dev/null +++ b/armory/EventBuilder.cpp @@ -0,0 +1,173 @@ +#include "SolReader.h" +#include +#include + +#include "TFile.h" +#include "TTree.h" +#include "TMath.h" +#include "TString.h" +#include "TClonesArray.h" +#include "TVector.h" + +#define MAX_ID 64 +#define MAX_TRACE_LEN 2500 + +SolReader ** reader; +Event ** evt; + +unsigned long totNumEvent = 0; + +void findEarliestTime(const int &nFile, int &fileID){ + + unsigned long firstTime = 0; + for(int i = 0; i < nFile; i++){ + if( reader[i]->GetNumBlock() + 1 >= reader[i]->GetTotalNumBlock() ) continue; + if( firstTime == 0 ) { + firstTime = evt[i]->timestamp; + fileID = i; + continue; + } + if( evt[i]->timestamp <= firstTime) { + firstTime = evt[i]->timestamp; + fileID = i; + } + } + +} + +unsigned long long evID = 0; +int multi = 0; +int bd[MAX_ID] = {0}; +int ch[MAX_ID] = {0}; +int e[MAX_ID] = {0}; +unsigned long long e_t[MAX_ID] = {0}; +int traceLen[MAX_ID] = {0}; +int trace[MAX_ID][MAX_TRACE_LEN] = {0}; + +void fillData(int &fileID, const bool &saveTrace){ + bd[multi] = fileID; + ch[multi] = evt[fileID]->channel; + e[multi] = evt[fileID]->energy; + e_t[multi] = evt[fileID]->timestamp; + + if( saveTrace ){ + traceLen[multi] = evt[fileID]->traceLenght; + for( int i = 0; i < TMath::Min(traceLen[multi], MAX_TRACE_LEN); i++){ + trace[multi][i] = evt[fileID]->analog_probes[0][i]; + } + } + + multi++; + reader[fileID]->ReadNextBlock(); +} + +void printEvent(){ + printf("==================== evID : %llu\n", evID); + for( int i = 0; i < multi; i++){ + printf(" %2d | %d %d | %llu %d \n", i, bd[i], ch[i], e_t[i], e[i] ); + } + printf("==========================================\n"); +} + +int main(int argc, char ** argv){ + + printf("=====================================\n"); + printf("=== sol --> root ===\n"); + printf("=====================================\n"); + + if( argc <= 3){ + printf("%s [outfile] [timeWindow] [saveTrace] [sol-1] [sol-2] ... \n", argv[0]); + printf(" outfile : output root file name\n"); + printf(" timeWindow : number of tick, 1 tick = %d ns.\n", tick2ns); + printf(" saveTrace : 1 = save trace, 0 = no trace\n"); + printf(" sol-X : the sol file(s)\n"); + return -1; + } + + TString outFileName = argv[1]; + int timeWindow = atoi(argv[2]); + const bool saveTrace = atoi(argv[3]); + + const int nFile = argc - 4; + TString inFileName[nFile]; + for( int i = 0 ; i < nFile ; i++){ + inFileName[i] = argv[i+4]; + } + + printf(" out file : \033[1;33m%s\033[m\n", outFileName.Data()); + printf(" Event building time window : %d tics = %d nsec \n", timeWindow, timeWindow*tick2ns); + printf(" Save Trace ? %s \n", saveTrace ? "Yes" : "No"); + printf(" Number of input file : %d \n", nFile); + for( int i = 0; i < nFile; i++){ + printf(" %2d| %s \n", i, inFileName[i].Data()); + } + printf("------------------------------------\n"); + + TFile * outRootFile = new TFile(outFileName, "recreate"); + outRootFile->cd(); + + TTree * tree = new TTree("tree", outFileName); + + tree->Branch("evID", &evID, "event_ID/l"); + tree->Branch("multi", &multi, "multi/I"); + tree->Branch("bd", bd, "board[multi]/I"); + tree->Branch("ch", ch, "channel[multi]/I"); + tree->Branch("e", e, "energy[multi]/I"); + tree->Branch("e_t", e_t, "energy_timestamp[multi]/l"); + + if( saveTrace){ + tree->Branch("tl", traceLen, "traceLen[multi]/I"); + tree->Branch("trace", trace, Form("trace[multi][%d]/I", MAX_TRACE_LEN)); + } + + + reader = new SolReader*[nFile]; + evt = new Event *[nFile]; + + for( int i = 0 ; i < nFile ; i++){ + reader[i] = new SolReader(inFileName[i].Data()); + evt[i] = reader[i]->evt; + reader[i]->ScanNumBlock(); + + totNumEvent += reader[i]->GetTotalNumBlock(); + reader[i]->ReadNextBlock(); // read the first block + } + + //^=========================================== + int fileID = 0; + findEarliestTime(nFile, fileID); + fillData(fileID, saveTrace); + + unsigned count = 1; + while(count < totNumEvent){ + + findEarliestTime(nFile, fileID); + + if( evt[fileID]->timestamp - e_t[0] < timeWindow ){ + + fillData(fileID, saveTrace); + + }else{ + + outRootFile->cd(); + tree->Fill(); + evID ++; + + multi = 0; + fillData(fileID, saveTrace); + } + + count ++; + } + + outRootFile->cd(); + tree->Write(); + + + //^############## delete new + for( int i = 0; i < nFile; i++) delete reader[i]; + delete [] reader; + outRootFile->Close(); + + return 0; +} \ No newline at end of file diff --git a/armory/Makefile b/armory/Makefile new file mode 100644 index 0000000..ab42e06 --- /dev/null +++ b/armory/Makefile @@ -0,0 +1,11 @@ +CC=g++ +ROOTFLAG=`root-config --cflags --glibs` + +all: EventBuilder + +EventBuilder: EventBuilder.cpp SolReader.h + $(CC) EventBuilder.cpp -o EventBuilder ${ROOTFLAG} + + +clean: + -rm EventBuilder \ No newline at end of file diff --git a/SolReader.h b/armory/SolReader.h similarity index 86% rename from SolReader.h rename to armory/SolReader.h index 0beada2..48ba535 100644 --- a/SolReader.h +++ b/armory/SolReader.h @@ -8,7 +8,9 @@ #include #include // time in nano-sec -#include "../SOLARIS_QT6_DAQ/Event.h" +#include "Event.h" // this is a symblic link to SOLARIS_QT6_DAQ/Event.h + +#define tick2ns 8 // 1 tick = 8 ns class SolReader { private: @@ -27,12 +29,12 @@ class SolReader { public: SolReader(); - SolReader(std::string fileName, unsigned short dataType); + SolReader(std::string fileName, unsigned short dataType = 0); // dataType can auto determine from the data, but remove it will crash.... ~SolReader(); void OpenFile(std::string fileName); - int ReadNextBlock(int opt = 0); // opt = 0, noraml, 1, fast - int ReadBlock(unsigned int index); + int ReadNextBlock(int isSkip = 0); // opt = 0, noraml, 1, fast + int ReadBlock(unsigned int index, bool verbose = false); void ScanNumBlock(); @@ -64,7 +66,7 @@ SolReader::SolReader(){ init(); } -SolReader::SolReader(std::string fileName, unsigned short dataType = 0){ +SolReader::SolReader(std::string fileName, unsigned short dataType){ init(); OpenFile(fileName); evt->SetDataType(dataType); @@ -86,12 +88,12 @@ inline void SolReader::OpenFile(std::string fileName){ } } -inline int SolReader::ReadBlock(unsigned int index){ +inline int SolReader::ReadBlock(unsigned int index, bool verbose){ if( isScanned == false) return -1; if( index >= totNumBlock )return -1; fseek(inFile, 0L, SEEK_SET); - printf("-----------%u, %u\n", index, blockPos[index]); + if( verbose ) printf("Block index: %u, File Pos: %u byte\n", index, blockPos[index]); fseek(inFile, blockPos[index], SEEK_CUR); @@ -100,7 +102,7 @@ inline int SolReader::ReadBlock(unsigned int index){ return ReadNextBlock(); } -inline int SolReader::ReadNextBlock(int opt){ +inline int SolReader::ReadNextBlock(int isSkip){ if( inFile == NULL ) return -1; if( feof(inFile) ) return -1; if( filePos >= inFileSize) return -1; @@ -117,8 +119,8 @@ inline int SolReader::ReadNextBlock(int opt){ } evt->dataType = blockStartIdentifier & 0xF; - if( evt->dataType == 0){ - if( opt == 0 ){ + if( evt->dataType == 0){ //======== same as the dataFormat in Digitizer + if( isSkip == 0 ){ fread(&evt->channel, 1, 1, inFile); fread(&evt->energy, 2, 1, inFile); fread(&evt->timestamp, 6, 1, inFile); @@ -135,7 +137,7 @@ inline int SolReader::ReadNextBlock(int opt){ fseek(inFile, 31, SEEK_CUR); } fread(&evt->traceLenght, 8, 1, inFile); - if( opt == 0){ + if( isSkip == 0){ fread(evt->analog_probes_type, 2, 1, inFile); fread(evt->digital_probes_type, 4, 1, inFile); fread(evt->analog_probes[0], evt->traceLenght*4, 1, inFile); @@ -148,7 +150,7 @@ inline int SolReader::ReadNextBlock(int opt){ fseek(inFile, 6 + evt->traceLenght*(12), SEEK_CUR); } }else if( evt->dataType == 1){ - if( opt == 0 ){ + if( isSkip == 0 ){ fread(&evt->channel, 1, 1, inFile); fread(&evt->energy, 2, 1, inFile); fread(&evt->timestamp, 6, 1, inFile); @@ -159,14 +161,14 @@ inline int SolReader::ReadNextBlock(int opt){ fseek(inFile, 14, SEEK_CUR); } fread(&evt->traceLenght, 8, 1, inFile); - if( opt == 0){ + if( isSkip == 0){ fread(&evt->analog_probes_type[0], 1, 1, inFile); fread(evt->analog_probes[0], evt->traceLenght*4, 1, inFile); }else{ fseek(inFile, 1 + evt->traceLenght*4, SEEK_CUR); } }else if( evt->dataType == 2){ - if( opt == 0 ){ + if( isSkip == 0 ){ fread(&evt->channel, 1, 1, inFile); fread(&evt->energy, 2, 1, inFile); fread(&evt->timestamp, 6, 1, inFile); @@ -177,7 +179,7 @@ inline int SolReader::ReadNextBlock(int opt){ fseek(inFile, 14, SEEK_CUR); } }else if( evt->dataType == 3){ - if( opt == 0 ){ + if( isSkip == 0 ){ fread(&evt->channel, 1, 1, inFile); fread(&evt->energy, 2, 1, inFile); fread(&evt->timestamp, 6, 1, inFile); @@ -186,7 +188,7 @@ inline int SolReader::ReadNextBlock(int opt){ } }else if( evt->dataType == 15){ fread(&evt->dataSize, 8, 1, inFile); - if( opt == 0){ + if( isSkip == 0){ fread(evt->data, evt->dataSize, 1, inFile); }else{ fseek(inFile, evt->dataSize, SEEK_CUR); diff --git a/expName.sh b/expName.sh deleted file mode 100644 index 99216c8..0000000 --- a/expName.sh +++ /dev/null @@ -1,5 +0,0 @@ -expName=Master -rawDataPath=/mnt/data0/Master -runID=-1 -elogID=-1 -//------------end of file. diff --git a/working/Mapping.h b/working/Mapping.h new file mode 100644 index 0000000..5689e7d --- /dev/null +++ b/working/Mapping.h @@ -0,0 +1,70 @@ +#ifndef MAPPING_H +#define MAPPING_H + +//^=============================================================================== +//^ This is mapping file for SOLARIS +//^ This file is used to constructe the SOLARIS panel in the SOLARIS DAQ +//^ If this file is modified, please Close Digitizer and Open again +//^------------------------------------------------------------------------------- +//^ +//^ Array : 0 - 99 +//^ Recoil : 100 - 199 +//^ +//^ line comment is '//^' +//^ +//^=============================================================================== + +#include +#include + +//#define NARRAY 60 +//#define NRDT 10 + +#define PARITYARRAY 1 +#define PARITYRDT 1 + +//#define NDIGITIZER 4 +//#define NCHANNEL 64 // number of channel per digitizer + +std::vector detName = {"Array", "Recoil"}; //*= The comment "//*=" is an indicator DON't Remove +std::vector detMaxID = { 100, 200}; //*# The comment "//*#" is an indicator DON't Remove + +//!The mapping[i] must match as the IP setting in the DAQ + +std::vector> mapping = { +{ +//* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // this line is an indicator DON'T Remove + 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, -1, /// 0 - 15 + 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, -1, /// 16 - 31 + 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, -1, /// 32 - 47 + 15, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, -1 /// 48 - 63 +//*------------- end of a digitizer // this line is an indicator DON'T Remove +}, +//^{ +//^//* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // this line is an indicator DON'T Remove +//^ 20, 20, 20, 21, 21, 21, 22, 22, 22, 23, 23, 23, 24, 24, 24, -1, /// 0 - 15 +//^ 25, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, -1, /// 16 - 31 +//^ 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34, 34, -1, /// 32 - 47 +//^ 35, 35, 35, 36, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 39, -1 /// 48 - 63 +//^//*------------- end of a digitizer // this line is an indicator DON'T Remove +//^}, +//^{ +//^//* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // this line is an indicator DON'T Remove +//^ 40, 40, 40, 41, 41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 44, -1, /// 0 - 15 +//^ 45, 45, 45, 46, 46, 46, 47, 47, 47, 48, 48, 48, 49, 49, 49, -1, /// 16 - 31 +//^ 50, 50, 50, 51, 51, 51, 52, 52, 52, 53, 53, 53, 54, 54, 54, -1, /// 32 - 47 +//^ 55, 55, 55, 56, 56, 56, 57, 57, 57, 58, 58, 58, 59, 59, 59, -1 /// 48 - 63 +//^//*------------- end of a digitizer // this line is an indicator DON'T Remove +//^}, +{ +//* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // this line is an indicator DON'T Remove + 100, 101, 102, 103, 104, 105, 106, 107, -1, -1, -1, -1, -1, -1, -1, -1, /// 0 - 15 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /// 16 - 31 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /// 32 - 47 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /// 48 - 63 +//*------------- end of a digitizer // this line is an indicator DON'T Remove +} +}; + +//& if all array is arrange like this, no need kind mapping. it is always e, xf, xn +#endif diff --git a/working/expName.sh b/working/expName.sh new file mode 100644 index 0000000..3168bb7 --- /dev/null +++ b/working/expName.sh @@ -0,0 +1,5 @@ +expName=Master +rawDataPath=/mnt/data0/Master +runID=1 +elogID=14 +//------------end of file. \ No newline at end of file diff --git a/working/script.C b/working/script.C new file mode 100644 index 0000000..47ec58c --- /dev/null +++ b/working/script.C @@ -0,0 +1,75 @@ +#include "../armory/SolReader.h" +#include "TH1.h" +#include "TH2.h" +#include "TCanvas.h" + +void script(){ + + SolReader * reader = new SolReader("../data_raw/Master_001_01_21233_000.sol"); + Event * evt = reader->evt; + + printf("========== file size: %u Byte\n", reader->GetFileSize()); + + reader->ScanNumBlock(); + + if( reader->GetTotalNumBlock() == 0 ) return; + + unsigned long startTime, endTime; + reader->ReadBlock(0); + startTime = evt->timestamp; + reader->ReadBlock(reader->GetTotalNumBlock() - 1); + endTime = evt->timestamp; + + double duration = double(endTime - startTime)*8./1e9; + printf("============== %lu ns = %.4f sec.\n", (endTime - startTime)*8, duration); + printf(" avarge rate (16ch): %f Hz\n", reader->GetTotalNumBlock()/duration/16); + reader->RewindFile(); + + + TCanvas * canvas = new TCanvas("c1", "c1", 600, 600); + + TH1F * h1 = new TH1F("h1", "h1", 1000, startTime, endTime); + TH2F * h2 = new TH2F("h2", "h2", 1000, startTime, endTime, 1000, 0, reader->GetTotalNumBlock()); + + uint64_t tOld = startTime; + + for( int i = 0; i < reader->GetTotalNumBlock() ; i++){ + //for( int i = 0; i < 8 ; i++){ + + reader->ReadNextBlock(); + + if( i < 8 ){ + printf("########################## nBlock : %u, %u/%u\n", reader->GetNumBlock(), + reader->GetFilePos(), + reader->GetFileSize()); + evt->PrintAll(); + evt->PrintAllTrace(); + } + + h1->Fill(evt->timestamp); + h2->Fill(evt->timestamp, i); + + if( i > 0 ){ + if( evt->timestamp < tOld) printf("-------- time not sorted."); + tOld = evt->timestamp; + } + + } + + + h2->Draw(); + + //printf("reader traceLength : %lu \n", evt->traceLenght); + + /* + for( int i = 0; i < evt->traceLenght; i++){ + + printf("%4d| %d\n", i, evt->analog_probes[0][i]); + + } + */ + + evt = NULL; + delete reader; + +} \ No newline at end of file