From 60da1a4bd663a50d46c7879cc5cb96027f73eb29 Mon Sep 17 00:00:00 2001 From: "Calem@RAISOR" Date: Thu, 5 Sep 2024 15:03:31 -0500 Subject: [PATCH] first set of commits --- Aux/EventBuilder.cpp | 189 ++++++++++++++++--------- Aux/fsuReader.h | 325 +++++++++++-------------------------------- Hit.h | 38 ++++- 3 files changed, 237 insertions(+), 315 deletions(-) diff --git a/Aux/EventBuilder.cpp b/Aux/EventBuilder.cpp index f572582..8183b1b 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{ @@ -19,6 +20,9 @@ struct FileInfo{ }; +#define NMINARG 5 +#define debug 0 + //^############################################################# //^############################################################# int main(int argc, char **argv) { @@ -26,16 +30,16 @@ 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] [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(" batchSize : the size of hit in a batch \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 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; @@ -46,11 +50,12 @@ 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 batchSize = atoi(argv[4]); - int nFile = argc - 5; + // 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]; - 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]; @@ -59,17 +64,26 @@ 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 += ".root"; - printf("-------> Out file name : %s \n", outFileName.Data()); + outFileName += "_" + ( timeWindow >= 0 ? std::to_string(timeWindow) : "single"); + + TString outFileFullName; + if( format == 0 ){ + outFileFullName = outFileName + ".root"; + }else{ + 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()); 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(" Batch size = %d events/file\n", batchSize); - 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 @@ -79,15 +93,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, 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()}; + 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); @@ -104,25 +121,21 @@ 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); - //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 @@ -132,24 +145,37 @@ 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_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; + } - if( traceOn ) { - arrayTrace = new TClonesArray("TGraph"); - tree->Branch("trace", arrayTrace, 2560000); - arrayTrace->BypassStreamer(); } //*======================================= Open files @@ -165,9 +191,9 @@ 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())); + reader[i]->PrintHitListInfo(&hitList[i], "hitList-" + std::to_string(reader[i]->GetSN())); ID[i] = 0; if( debug ) { @@ -216,6 +242,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 +261,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; } @@ -258,15 +286,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 ? 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 ) { - 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();} @@ -279,17 +307,38 @@ 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]); + 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]; + } + } + } + + 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 ++; @@ -324,29 +373,35 @@ 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; + printf("####################################### end of %s\n", argv[0]); + return 0; } diff --git a/Aux/fsuReader.h b/Aux/fsuReader.h index a45b545..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,32 +60,25 @@ 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(); } } - 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,13 +87,13 @@ 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); } } - - //void SaveAsCAENCoMPASSFormat(); + unsigned long GetOptimumBatchSize() const {return optBufferSize;} private: @@ -127,7 +120,7 @@ class FSUReader{ std::vector blockPos; std::vector blockTimeStamp; - unsigned long hitCount; + unsigned long totalHitCount; std::vector hit; @@ -137,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; @@ -146,6 +146,7 @@ inline FSUReader::~FSUReader(){ } +//^============================================================== inline FSUReader::FSUReader(){ inFile = nullptr; data = nullptr; @@ -159,6 +160,7 @@ inline FSUReader::FSUReader(){ } +//^============================================================== inline FSUReader::FSUReader(std::string fileName, uInt dataSize, int verbose){ inFile = nullptr; data = nullptr; @@ -172,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; @@ -186,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 @@ -221,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); @@ -277,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) { @@ -332,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; @@ -373,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; @@ -390,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) { @@ -398,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; @@ -421,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()); @@ -443,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)); @@ -472,8 +512,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 +541,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; @@ -509,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 (); } @@ -552,8 +596,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 +609,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()); } @@ -576,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/Hit.h b/Hit.h index 1683ef4..2154f9e 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,42 @@ public: // Define operator< for sorting bool operator<(const Hit& other) const { return timestamp < other.timestamp; + } + + + void WriteHitsToCAENBinary(FILE * file, uint32_t header){ + if( file == nullptr ) return; + + 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; + 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( (header & 0x4) ) dummy = fwrite(&energy2, 2, 1, file); + + dummy = fwrite(&flag, 4, 1, file); + + if( traceLength > 0 && (header & 0x8) ){ + 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"); + } };