diff --git a/.gitignore b/.gitignore index 11275eb..4a85c01 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ test_indep programSettings.txt EventKenshikushi EventBuilder +EventBuilderNoTrace EventBuilder_sortTime DataGenerator DataReaderScript diff --git a/Aux/EventBuilderNoTrace.cpp b/Aux/EventBuilderNoTrace.cpp new file mode 100644 index 0000000..c5fb4ed --- /dev/null +++ b/Aux/EventBuilderNoTrace.cpp @@ -0,0 +1,254 @@ +#include "fsuReader.h" + +#include "TROOT.h" +#include "TSystem.h" +#include "TClonesArray.h" +#include "TGraph.h" +#include "TFile.h" +#include "TTree.h" + +#define MAX_MULTI 100 +#define TIMEJUMP 1e8 // 0.1 sec or 10 Hz, any signal less than 10 Hz should increase the value. + +#define ORDERSHIFT 100000 + +typedef unsigned short uShort; +typedef unsigned int uInt; +typedef unsigned long uLong; +typedef unsigned long long ullong; + +struct FileInfo { + TString fileName; + unsigned int fileSize; + unsigned int SN; + unsigned long hitCount; + unsigned short DPPType; + unsigned short tick2ns; + unsigned short order; + unsigned short readerID; + + unsigned ID; // sn + 100000 * order + + void CalOrder(){ ID = ORDERSHIFT * order + SN; } + + void Print(){ + printf("%6d | %3d | %30s | %2d | %6lu | %u Bytes = %.2f MB\n", + ID, DPPType, fileName.Data(), tick2ns, hitCount, fileSize, fileSize/1024./1024.); + + } +}; + +struct GroupInfo{ + + std::vector readerIDList; + + unsigned short currentID; + +}; + +//^############################################################# +//^############################################################# +int main(int argc, char **argv) { + + printf("=========================================\n"); + printf("=== *.fsu Events Builder ===\n"); + printf("=========================================\n"); + if (argc <= 3) { + printf("Incorrect number of arguments:\n"); + printf("%s [timeWindow] [verbose] [inFile1] [inFile2] .... \n", argv[0]); + printf(" timeWindow : in ns \n"); + printf(" verbose : > 0 for debug \n"); + printf(" Output file name is contructed from inFile1 \n"); + printf("\n"); + printf(" * there is a TIMEJUMP = 1e8 ns in EventBuilder.cpp.\n"); + printf(" This control the time diff for a time jumping.\n"); + printf(" Any signal with trigger rate < 1/TIMEJUMP should increase the value.\n"); + return 1; + } + +/// File format must be YYY...Y_runXXX_AAA_BBB_CCC.fsu + /// YYY...Y = prefix + /// XXX = runID, 3 digits + /// AAA = board Serial Number, 3 digits + /// BBB = DPPtype, 3 digits + /// CCC = over size index, 3 digits + + ///============= read input + unsigned int timeWindow = atoi(argv[1]); + //float bufferSize = atof(argv[2]); + //bool traceOn = atoi(argv[3]); + bool traceOn = false; + unsigned int debug = atoi(argv[2]); + int nFile = argc - 3; + TString inFileName[nFile]; + for( int i = 0 ; i < nFile ; i++){ + inFileName[i] = argv[i+3]; + } + + /// Form outFileName; + TString outFileName = inFileName[0]; + int pos = outFileName.Index("_"); + pos = outFileName.Index("_", pos+1); + outFileName.Remove(pos); + outFileName += ".root"; + printf("-------> Out file name : %s \n", outFileName.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"); + printf(" Time Window = %u ns = %.1f us\n", timeWindow, timeWindow/1000.); + //printf(" Buffer size = %.0f event/channel\n", MaxNData * bufferSize); + printf("===================================== input files:\n"); + + ///============= sorting file by the serial number & order + std::vector fileInfo; + FSUReader ** reader = new FSUReader*[nFile]; + + // file name format is expName_runID_SN_DPP_tick2ns_order.fsu + for( int i = 0; i < nFile; i++){ + + printf("Processing %s (%d/%d) ..... \n\033[A\r", inFileName[i].Data(), i+1, nFile); + + reader[i] = new FSUReader(inFileName[i].Data(), false); + reader[i]->ScanNumBlock(false); + + FileInfo tempInfo; + tempInfo.fileName = inFileName[i]; + tempInfo.readerID = i; + tempInfo.SN = reader[i]->GetSN(); + tempInfo.hitCount = reader[i]->GetHitCount(); + tempInfo.fileSize = reader[i]->GetFileByteSize(); + tempInfo.tick2ns = reader[i]->GetTick2ns(); + tempInfo.DPPType = reader[i]->GetDPPType(); + tempInfo.order = reader[i]->GetFileOrder(); + + tempInfo.CalOrder(); + + fileInfo.push_back(tempInfo); + + } + + std::sort(fileInfo.begin(), fileInfo.end(), [](const FileInfo& a, const FileInfo& b) { + return a.ID < b.ID; + }); + + unsigned int totHitCount = 0; + + for( int i = 0 ; i < nFile; i++){ + printf("%d |", i); + fileInfo[i].Print(); + totHitCount += fileInfo[i].hitCount; + } + + printf("----- total number of block : %u.\n", totHitCount); + + //*======================================= Sort files into groups + std::vector group; + + for( int i = 0; i < nFile; i++){ + if( fileInfo[i].ID / ORDERSHIFT == 0 ){ + group.push_back(GroupInfo()); + group.back().readerIDList.push_back(fileInfo[i].readerID); // an empty struct + group.back().currentID = fileInfo[i].readerID; + }else{ + group.back().readerIDList.push_back(fileInfo[i].readerID); + } + + } + + int nGroup = group.size(); + printf("===================================== number of file Group by digitizer %d.\n", nGroup); + for( int i = 0; i < nGroup; i++){ + printf(" Digi-%d, DPPType: %d \n", reader[group[i].currentID]->GetSN(), reader[group[i].currentID]->GetDPPType()); + for( int j = 0; j< (int) group[i].readerIDList.size(); j++){ + uShort rID = group[i].readerIDList[j]; + printf(" %s \n", reader[rID]->GetFileName().c_str()); + + uLong hitCount = reader[rID]->GetHitCount(); + for( int k = 0; k < (hitCount < 10 ? hitCount : 10); k++){ + (reader[group[i].readerIDList[j]]->GetHit(k)).Print(); + } + + } + } + + // //*====================================== create tree + // TFile * outRootFile = new TFile(outFileName, "recreate"); + // TTree * tree = new TTree("tree", outFileName); + + // unsigned long long evID = -1; + // unsigned short multi = 0; + // unsigned short sn[MAX_MULTI] = {0}; /// board SN + // unsigned short bd[MAX_MULTI] = {0}; /// boardID + // unsigned short ch[MAX_MULTI] = {0}; /// chID + // unsigned short e[MAX_MULTI] = {0}; /// 15 bit + // unsigned short e2[MAX_MULTI] = {0}; /// 15 bit + // unsigned long long e_t[MAX_MULTI] = {0}; /// timestamp 47 bit + // unsigned short e_f[MAX_MULTI] = {0}; /// fine time 10 bit + + // tree->Branch("evID", &evID, "event_ID/l"); + // tree->Branch("multi", &multi, "multi/s"); + // tree->Branch("sn", sn, "sn[multi]/s"); + // tree->Branch("bd", bd, "bd[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_timestamp[multi]/s"); + + // TClonesArray * arrayTrace = nullptr; + // unsigned short traceLength[MAX_MULTI] = {0}; + // TGraph * trace = nullptr; + + // if( traceOn ) { + // arrayTrace = new TClonesArray("TGraph"); + // tree->Branch("traceLength", traceLength, "traceLength[multi]/s"); + // tree->Branch("trace", arrayTrace, 2560000); + // arrayTrace->BypassStreamer(); + // } + + + //*====================================== build events + printf("================= Building events....\n"); + + // //Find earlist time among the first file + unsigned long long t0 = -1; + unsigned short group0 = -1; + for( int gpID = 0; gpID < nGroup; gpID++){ + uShort rID = group[gpID].currentID; + unsigned long long t = reader[rID]->GetHit(0).timestamp; + if( t < t0 ) { + t0 = t; + group0 = gpID; + } + } + + printf("the eariliest time is %llu at %s\n", t0, reader[group[group0].currentID]->GetFileName().c_str()); + + do{ + + std::vector event; + + for(int i = 0; i < nGroup; i++){ + + + + + } + + }while(true); + + + + // printf("========================= finished.\n"); + // printf("total events built = %llu(%llu)\n", evID + 1, tree->GetEntriesFast()); + // printf("=======> saved to %s \n", outFileName.Data()); + + // outRootFile->Close(); + + for( int i = 0 ; i < nFile; i++) delete reader[i]; + delete [] reader; + +} + diff --git a/Aux/Makefile b/Aux/Makefile index 222bb87..7ca76cf 100644 --- a/Aux/Makefile +++ b/Aux/Makefile @@ -14,7 +14,7 @@ ROOTLIBS = `root-config --cflags --glibs` OBJS = ClassDigitizer.o MultiBuilder.o -ALL = test test_indep DataGenerator EventBuilder DataReader DumpFSU2ROOT SettingsExplorer +ALL = test test_indep DataGenerator EventBuilder EventBuilderNoTrace DataReader DumpFSU2ROOT SettingsExplorer ######################################################################### @@ -23,7 +23,7 @@ all : $(ALL) clean : /bin/rm -f $(OBJS) $(ALL) -MultiBuilder.o : ../MultiBuilder.cpp ../MultiBuilder.h +MultiBuilder.o : ../MultiBuilder.cpp ../MultiBuilder.h ../Hit.h $(CC) $(COPTS) -c ../MultiBuilder.cpp ClassDigitizer.o : ../ClassDigitizer.cpp ../ClassDigitizer.h ../RegisterAddress.h ../macro.h ../ClassData.h @@ -49,6 +49,10 @@ EventBuilder : EventBuilder.cpp ../ClassData.h MultiBuilder.o fsuReader.h @echo "--------- making EventBuilder" $(CC) $(COPTS) -o EventBuilder EventBuilder.cpp MultiBuilder.o $(ROOTLIBS) +EventBuilderNoTrace : EventBuilderNoTrace.cpp ../ClassData.h fsuReader.h ../Hit.h + @echo "--------- making EventBuilderNoTrace" + $(CC) $(COPTS) -o EventBuilderNoTrace EventBuilderNoTrace.cpp $(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/Aux/fsuReader.h b/Aux/fsuReader.h index b4bd076..89bc347 100644 --- a/Aux/fsuReader.h +++ b/Aux/fsuReader.h @@ -1,11 +1,16 @@ #include "../ClassData.h" +#include "../Hit.h" +#include class FSUReader{ public: + FSUReader(); FSUReader(std::string fileName, bool verbose = true); ~FSUReader(); + void OpenFile(std::string fileName, bool verbose = true); + void ScanNumBlock(bool verbose = true); int ReadNextBlock(bool fast = false, int verbose = 0, bool saveData = false); int ReadBlock(unsigned int ID, int verbose = 0); @@ -14,6 +19,7 @@ class FSUReader{ Data * GetData() const{return data;} + std::string GetFileName() const{return fileName;} int GetDPPType() const{return DPPType;} int GetSN() const{return sn;} int GetTick2ns() const{return tick2ns;} @@ -23,19 +29,17 @@ class FSUReader{ std::vector GetBlockTimestamp() const {return blockTimeStamp;} - std::vector GetTimestamp(int id) const {return timestamp[id];} - std::vector GetEnergy(int id) const {return energy[id];} - std::vector GetEnergy2(int id) const {return energy2[id];} - std::vector GetChannel(int id) const {return channel[id];} - std::vector GeFineTime(int id) const {return fineTime[id];} + Hit GetHit(int id) const {return hit[id];} + std::vector GetHitVector() const {return hit;} - unsigned long GetHitCount() const{ return numHit;} + unsigned long GetHitCount() const{ return hit.size();} private: FILE * inFile; Data * data; + std::string fileName; unsigned long inFileSize; unsigned int filePos; unsigned long totNumBlock; @@ -54,17 +58,7 @@ class FSUReader{ unsigned long numHit; - std::vector> channel; - std::vector> energy; - std::vector> energy2; - std::vector> timestamp; - std::vector> fineTime; - - std::vector tempChannel; - std::vector tempEnergy; - std::vector tempEnergy2; - std::vector tempTimestamp; - std::vector tempFineTime; + std::vector hit; unsigned int word[1]; /// 4 byte size_t dummy; @@ -72,15 +66,32 @@ class FSUReader{ }; +inline FSUReader::FSUReader(){ + inFile = nullptr; + data = nullptr; + + blockPos.clear(); + blockTimeStamp.clear(); + hit.clear(); + +} + inline FSUReader::FSUReader(std::string fileName, bool verbose){ + OpenFile(fileName, verbose); +} + +inline void FSUReader::OpenFile(std::string fileName, bool verbose){ inFile = fopen(fileName.c_str(), "r"); if( inFile == NULL ){ printf("Cannot open file : %s \n", fileName.c_str()); + this->fileName = ""; return; } + this->fileName = fileName; + fseek(inFile, 0L, SEEK_END); inFileSize = ftell(inFile); if(verbose) printf("%s | file size : %ld Byte = %.2f MB\n", fileName.c_str() , inFileSize, inFileSize/1024./1024.); @@ -93,10 +104,7 @@ inline FSUReader::FSUReader(std::string fileName, bool verbose){ blockTimeStamp.clear(); numHit = 0; - channel.clear(); - timestamp.clear(); - energy.clear(); - + hit.clear(); //check is the file is *.fsu or *.fsu.X size_t found = fileName.find_last_of('.'); @@ -161,6 +169,8 @@ inline int FSUReader::ReadNextBlock(bool fast, int verbose,bool saveData){ } short header = ((word[0] >> 28 ) & 0xF); + Hit temp; + if( header == 0xA ) { ///normal header unsigned int aggSize = (word[0] & 0x0FFFFFFF) * 4; ///byte @@ -176,11 +186,6 @@ inline int FSUReader::ReadNextBlock(bool fast, int verbose,bool saveData){ data->DecodeBuffer(buffer, aggSize, fast, verbose); // data will own the buffer if( saveData ){ - tempTimestamp.clear(); - tempEnergy.clear(); - tempEnergy2.clear(); - tempChannel.clear(); - tempFineTime.clear(); for( int ch = 0; ch < data->GetNChannel(); ch++){ if( data->NumEventsDecoded[ch] == 0 ) continue; @@ -190,21 +195,19 @@ inline int FSUReader::ReadNextBlock(bool fast, int verbose,bool saveData){ for( int i = start; i <= stop; i++ ){ i = i % MaxNData; - tempChannel.push_back(ch); - tempEnergy.push_back(data->Energy[ch][i]); - tempTimestamp.push_back(data->Timestamp[ch][i]); - tempEnergy2.push_back(data->Energy2[ch][i]); - tempFineTime.push_back(data->fineTime[ch][i]); - + + temp.sn = sn; + temp.ch = ch; + temp.energy = data->Energy[ch][i]; + temp.timestamp = data->Timestamp[ch][i]; + temp.energy2 = data->Energy2[ch][i]; + temp.fineTime = data->fineTime[ch][i]; + + hit.push_back(temp); + numHit ++; } } - - timestamp.push_back(tempTimestamp); - energy.push_back(tempEnergy); - energy2.push_back(tempEnergy2); - channel.push_back(tempChannel); - fineTime.push_back(tempFineTime); } data->ClearTriggerRate(); @@ -271,16 +274,19 @@ inline void FSUReader::ScanNumBlock(bool verbose){ printf("\nScan complete: number of data Block : %lu\n", totNumBlock); printf( " number of hit : %lu\n", numHit); - size_t sizeT = sizeof(std::vector) * timestamp.size(); - for (size_t i = 0; i < timestamp.size(); ++i) { - sizeT += sizeof(std::vector) + sizeof(unsigned long long) * timestamp[i].size(); - } - - printf("size of timestamp : %lu byte = %.2f kByte, = %.2f MByte\n", sizeT, sizeT/1024., sizeT/1024./1024.); + size_t sizeT = sizeof(hit[0]) * hit.size(); + printf("size of hit array : %lu byte = %.2f kByte, = %.2f MByte\n", sizeT, sizeT/1024., sizeT/1024./1024.); } rewind(inFile); blockID = 0; filePos = 0; + if(verbose) printf("\nQuick Sort hit array according to time..."); + + std::sort(hit.begin(), hit.end(), [](const Hit& a, const Hit& b) { + return a.timestamp < b.timestamp; + }); + + if(verbose) printf(".......done.\n"); } \ No newline at end of file diff --git a/Hit.h b/Hit.h new file mode 100644 index 0000000..2f3ee1c --- /dev/null +++ b/Hit.h @@ -0,0 +1,37 @@ +#ifndef Hit_H +#define Hit_H + +class Hit{ +public: + int sn; + unsigned short bd; + unsigned short ch; + unsigned short energy; + unsigned short energy2; + unsigned long long timestamp; + unsigned short fineTime; + + std::vector trace; + + Hit(){ + Clear(); + } + + void Clear(){ + sn = 0; + bd = 0; + ch = 0; + energy = 0; + energy2 = 0; + timestamp = 0; + fineTime = 0; + trace.clear(); + } + + void Print(){ + printf("(%5d, %2d) %6d %10llu, %6d, %5ld\n", sn, ch, energy, timestamp, fineTime, trace.size()); + } + +}; + +#endif \ No newline at end of file diff --git a/MultiBuilder.h b/MultiBuilder.h index 6227d16..80ea006 100644 --- a/MultiBuilder.h +++ b/MultiBuilder.h @@ -2,41 +2,10 @@ #define MuLTI_BUILDER_H #include "ClassData.h" +#include "Hit.h" #define MaxNEvent 100000 // circular, this number should be at least nDigi * MaxNChannel * MaxNData -class Hit{ -public: - int sn; - unsigned short bd; - unsigned short ch; - unsigned short energy; - unsigned short energy2; - unsigned long long timestamp; - unsigned short fineTime; - - std::vector trace; - - Hit(){ - Clear(); - } - - void Clear(){ - sn = 0; - bd = 0; - ch = 0; - energy = 0; - energy2 = 0; - timestamp = 0; - fineTime = 0; - trace.clear(); - } - - void Print(){ - printf("(%2d, %2d)[%3d] %6d %10llu, %6d, %5ld\n", bd, ch, sn, energy, timestamp, fineTime, trace.size()); - } - -}; class MultiBuilder {