diff --git a/Aux/EventBuilderNoTrace.cpp b/Aux/EventBuilderNoTrace.cpp index c5fb4ed..0dfa271 100644 --- a/Aux/EventBuilderNoTrace.cpp +++ b/Aux/EventBuilderNoTrace.cpp @@ -1,4 +1,5 @@ #include "fsuReader.h" +#include #include "TROOT.h" #include "TSystem.h" @@ -33,19 +34,31 @@ struct FileInfo { void Print(){ printf("%6d | %3d | %30s | %2d | %6lu | %u Bytes = %.2f MB\n", - ID, DPPType, fileName.Data(), tick2ns, hitCount, fileSize, fileSize/1024./1024.); - + ID, DPPType, fileName.Data(), tick2ns, hitCount, fileSize, fileSize/1024./1024.); } }; struct GroupInfo{ std::vector readerIDList; - - unsigned short currentID; + uInt sn; + unsigned short currentID ; // the ID of the readerIDList; + ulong hitCount ; // this is the hitCount for the currentID; + ulong hitID ; // this is the ID for the reader->GetHit(hitID); + bool finished; }; + +unsigned long long getTime_ns(){ + + std::chrono::high_resolution_clock::time_point currentTime = std::chrono::high_resolution_clock::now(); + std::chrono::nanoseconds nanoseconds = std::chrono::duration_cast(currentTime.time_since_epoch()); + return nanoseconds.count(); + +} + + //^############################################################# //^############################################################# int main(int argc, char **argv) { @@ -102,7 +115,7 @@ int main(int argc, char **argv) { printf("===================================== input files:\n"); ///============= sorting file by the serial number & order - std::vector fileInfo; + std::vector fileInfo; FSUReader ** reader = new FSUReader*[nFile]; // file name format is expName_runID_SN_DPP_tick2ns_order.fsu @@ -112,6 +125,7 @@ int main(int argc, char **argv) { reader[i] = new FSUReader(inFileName[i].Data(), false); reader[i]->ScanNumBlock(false); + // reader[i]->FillHitList(); FileInfo tempInfo; tempInfo.fileName = inFileName[i]; @@ -141,7 +155,7 @@ int main(int argc, char **argv) { totHitCount += fileInfo[i].hitCount; } - printf("----- total number of block : %u.\n", totHitCount); + printf("----- total number of hit : %u.\n", totHitCount); //*======================================= Sort files into groups std::vector group; @@ -150,7 +164,12 @@ int main(int argc, char **argv) { 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; + group.back().currentID = 0; + group.back().hitCount = fileInfo[i].hitCount; + group.back().hitID = 0; + group.back().sn = fileInfo[i].SN; + group.back().finished = false; + }else{ group.back().readerIDList.push_back(fileInfo[i].readerID); } @@ -160,92 +179,189 @@ int main(int argc, char **argv) { 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()); + printf(" Digi-%d, DPPType: %d \n", reader[group[i].readerIDList[0]]->GetSN(), reader[group[i].readerIDList[0]]->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(); + for( uLong k = 0; k < (hitCount < 5 ? hitCount : 10); k++){ + reader[rID]->GetHit(k).Print(); } - } } // //*====================================== create tree - // TFile * outRootFile = new TFile(outFileName, "recreate"); - // TTree * tree = new TTree("tree", outFileName); + 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 + 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"); + 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; + //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(); - // } + 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; - } - } + evID = 0; + std::vector event; + Hit temp; - printf("the eariliest time is %llu at %s\n", t0, reader[group[group0].currentID]->GetFileName().c_str()); + ullong t0 = -1; + uShort group0 = -1; + + uInt hitProcessed = 0; do{ - std::vector event; + event.clear(); + t0 = -1; + //// Find earliest time + // ullong torg = getTime_ns(); + for( int gpID = 0; gpID < nGroup; gpID++){ + + if( group[gpID].finished ) continue; + + //when all hit are used, go to next file or make the group.finished = true + if( group[gpID].hitID >= group[gpID].hitCount) { + + printf(" group ID : %d, reader ID : %d is finished. \n", gpID, group[gpID].readerIDList[group[gpID].currentID]); + + group[gpID].currentID ++; + + if( group[gpID].currentID >= group[gpID].readerIDList.size() ) { + group[gpID].finished = true; + printf("-----> no more file for this group, S/N : %d.\n", group[gpID].sn); + continue; + }else{ + group[gpID].hitID = 0; + uShort rID = group[gpID].readerIDList[group[gpID].currentID]; + group[gpID].hitCount = reader[rID]->GetHitCount(); + printf("-----> go to the next file, %s \n", fileInfo[rID].fileName.Data() ); + } + } + + uShort rID = group[gpID].readerIDList[group[gpID].currentID]; + ulong hitID = group[gpID].hitID; + ullong t = reader[rID]->GetHit(hitID).timestamp; + if( t < t0 ) { + t0 = t; + group0 = gpID; + } + } + if (debug ) printf("the eariliest time is %llu at Group : %u, hitID : %lu, %s\n", t0, group0, group[group0].hitID, fileInfo[group[group0].currentID].fileName.Data()); + + // ullong t1 = getTime_ns(); + // printf("Find earliest Time used : %llu ns \n", t1 - torg); + + printf("hit Porcessed %u/%u....%.2f%%\n\033[A\r", hitProcessed, totHitCount, hitProcessed*100./totHitCount); + for(int i = 0; i < nGroup; i++){ + uShort gpID = (i + group0) % nGroup; - + if( group[gpID].finished ) continue; + uShort rID = group[gpID].readerIDList[group[gpID].currentID]; + for( ulong iHit = group[gpID].hitID; iHit < group[gpID].hitCount; iHit ++ ){ + + if( reader[rID]->GetHit(iHit).timestamp - t0 <= timeWindow ) { + + event.push_back(reader[rID]->GetHit(iHit)); + group[gpID].hitID ++; + hitProcessed ++; + + }else{ + break; + } + + if( timeWindow == 0 ) break; + } + + if( timeWindow == 0 ) break; } + // ullong t2 = getTime_ns(); + // printf(" getting an event used %llu ns\n", t2 - t1); + + if( event.size() > 1) { + std::sort(event.begin(), event.end(), [](const Hit& a, const Hit& b) { + return a.timestamp < b.timestamp; + }); + } + + multi = event.size(); + + if (debug )printf("########### evID : %llu, multi : %u \n", evID, multi); + + if( multi == 0 ) break; + + // ullong t3 = getTime_ns(); + // printf(" sort event used %llu ns\n", t3 - t2); + + + for( size_t j = 0; j < multi ; j++){ + sn[j] = event[j].sn; + ch[j] = event[j].ch; + e[j] = event[j].energy; + e2[j] = event[j].energy2; + e_t[j] = event[j].timestamp; + e_f[j] = event[j].fineTime; + + if (debug )event[j].Print(); + } + + outRootFile->cd(); + tree->Fill(); + + // ullong t4 = getTime_ns(); + // printf(" Fill tree used %llu ns\n", t4 - t3); + + //check if all groups are finished + int gpCount = 0; + for( size_t i = 0; i < group.size(); i++){ + if( group[i].finished ) gpCount ++; + } + if( gpCount == (int) group.size() ) break; + + evID ++; }while(true); + tree->Write(); + printf("========================= finished.\n"); + printf("total events built = %llu(%llu)\n", evID, tree->GetEntriesFast()); + printf("=======> saved to %s \n", outFileName.Data()); - // printf("========================= finished.\n"); - // printf("total events built = %llu(%llu)\n", evID + 1, tree->GetEntriesFast()); - // printf("=======> saved to %s \n", outFileName.Data()); - - // outRootFile->Close(); + outRootFile->Close(); for( int i = 0 ; i < nFile; i++) delete reader[i]; delete [] reader; diff --git a/Aux/fsuReader.h b/Aux/fsuReader.h index 89bc347..4963767 100644 --- a/Aux/fsuReader.h +++ b/Aux/fsuReader.h @@ -30,9 +30,8 @@ class FSUReader{ std::vector GetBlockTimestamp() const {return blockTimeStamp;} Hit GetHit(int id) const {return hit[id];} - std::vector GetHitVector() const {return hit;} - unsigned long GetHitCount() const{ return hit.size();} + std::vector GetHitVector() const {return hit;} private: @@ -153,6 +152,8 @@ inline void FSUReader::OpenFile(std::string fileName, bool verbose){ inline FSUReader::~FSUReader(){ delete data; + fclose(inFile); + } inline int FSUReader::ReadNextBlock(bool fast, int verbose,bool saveData){ @@ -199,8 +200,8 @@ inline int FSUReader::ReadNextBlock(bool fast, int verbose,bool saveData){ 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.timestamp = data->Timestamp[ch][i]; temp.fineTime = data->fineTime[ch][i]; hit.push_back(temp); @@ -283,10 +284,9 @@ inline void FSUReader::ScanNumBlock(bool verbose){ 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 index 2f3ee1c..cd5acd9 100644 --- a/Hit.h +++ b/Hit.h @@ -29,7 +29,12 @@ public: } void Print(){ - printf("(%5d, %2d) %6d %10llu, %6d, %5ld\n", sn, ch, energy, timestamp, fineTime, trace.size()); + printf("(%5d, %2d) %6d %16llu, %6d, %5ld\n", sn, ch, energy, timestamp, fineTime, trace.size()); + } + + // Define operator< for sorting + bool operator<(const Hit& other) const { + return timestamp < other.timestamp; } };