completed Bin2Root2 for all bd and ch combined BIN

This commit is contained in:
Ryan@Home 2024-09-26 13:31:37 -04:00
parent 2f316e5c2f
commit 5c248984f3
2 changed files with 230 additions and 169 deletions

View File

@ -53,8 +53,6 @@ std::vector<std::pair<int, std::string>> findDataFiles(const std::string& patter
for (const auto& entry : std::filesystem::directory_iterator(".")) { for (const auto& entry : std::filesystem::directory_iterator(".")) {
if (entry.is_regular_file()) { if (entry.is_regular_file()) {
std::string filename = entry.path().filename().string(); std::string filename = entry.path().filename().string();
printf("%s\n", filename.c_str());
std::smatch match; std::smatch match;
// Check for pattern DataR_run_34_YYY.BIN // Check for pattern DataR_run_34_YYY.BIN
@ -76,6 +74,108 @@ std::vector<std::pair<int, std::string>> findDataFiles(const std::string& patter
return results; return results;
} }
std::vector<Data> hitList_A ;
std::vector<Data> hitList_B ;
BinReader * reader = nullptr;
int ReadBatch(int bufferSize){
if( hitList_A.size() == 0 ){
for( int i = 0 ; i < bufferSize; i++ ){
if( reader->ReadBlock() != 1 ){
break;
}
//<<< should apply time offset here
hitList_A.push_back(reader->data);
}
if( hitList_A.size() > 1){
std::sort(hitList_A.begin(), hitList_A.end(), [](const Data& a, const Data& b) {
return a.TimeStamp < b.TimeStamp;
});
}
}else{
hitList_A.clear();
hitList_A = hitList_B;
}
//reader next batch
hitList_B.clear();
for( int i = 0 ; i < bufferSize; i++ ){
if( reader->ReadBlock() != 1 ){
break;
}
//<<< should apply time offset here
hitList_B.push_back(reader->data);
}
if( hitList_B.size() > 1 ){
std::sort(hitList_B.begin(), hitList_B.end(), [](const Data& a, const Data& b) {
return a.TimeStamp < b.TimeStamp;
});
}
if( hitList_B.size() == 0 ) return 1;
uint64_t t0_A = hitList_A.front().TimeStamp;
uint64_t t1_A = hitList_A.back().TimeStamp;
uint64_t t0_B = hitList_B.front().TimeStamp;
if( t0_A >= t0_B ){
printf("need to increase the batch size\n");
printf("t0_A : %15lu | %zu\n", t0_A, hitList_A.size());
printf("t0_B : %15lu | %zu\n", t0_B, hitList_B.size());
return -1;
}
if( t1_A >= t0_B ){ // move the overlap part to hitsLis_A;
ulong ID_A = 0;
ulong ID_B = 0;
std::vector<Data> hitTemp;
// find the hit that is >= t0_B, save them to 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]);
}
// remove hitList_A element that is >= t0_B
hitList_A.erase(hitList_A.begin() + ID_A, hitList_A.end() );
// find the hit that is <= t1_A, save them to hitTemp
for( size_t j = 0; j < hitList_B.size(); j++){
if( hitList_B[j].TimeStamp > t1_A ) {
break;
}
hitTemp.push_back(hitList_B[j]);
ID_B = j + 1;
}
// remove hit elements that is <= t1_A
hitList_B.erase(hitList_B.begin(), hitList_B.begin() + ID_B );
// sort hitTemp
std::sort(hitTemp.begin(), hitTemp.end(), [](const Data& a, const Data& b) {
return a.TimeStamp < b.TimeStamp;
});
//push back the hitList_A
for( size_t j = 0; j < hitTemp.size(); j++){
hitList_A.push_back(hitTemp[j]);
}
}
// printf("\n");
// printf("hitList A : %zu\n", hitList_A.size());
// printf("hitList B : %zu\n", hitList_B.size());
return 1;
}
//^############################################################# //^#############################################################
//^############################################################# //^#############################################################
int main(int argc, char **argv) { int main(int argc, char **argv) {
@ -87,7 +187,6 @@ int main(int argc, char **argv) {
printf("Incorrect number of arguments:\n"); printf("Incorrect number of arguments:\n");
printf("%s [timeWindow] [RunNum] \n", argv[0]); printf("%s [timeWindow] [RunNum] \n", argv[0]);
printf(" timeWindow : in ns, -1 = no event building \n"); printf(" timeWindow : in ns, -1 = no event building \n");
printf(" time Offset File : 0 for nothing \n");
printf("\n\n"); printf("\n\n");
return 1; return 1;
@ -95,8 +194,10 @@ int main(int argc, char **argv) {
unsigned int runStartTime = getTime_us(); unsigned int runStartTime = getTime_us();
int bufferSize = 5000000;
///============= read input ///============= read input
long timeWindow = atoi(argv[1]); long timeWindow = atoi(argv[1]); // ns
short runNum = atoi(argv[2]); short runNum = atoi(argv[2]);
///============ time offset ///============ time offset
@ -112,40 +213,36 @@ int main(int argc, char **argv) {
std::vector<std::pair<int, std::string>> inFileName = findDataFiles(pattern); std::vector<std::pair<int, std::string>> inFileName = findDataFiles(pattern);
int nFile = inFileName.size(); int nFile = inFileName.size();
printf("-------> Out file name : %s \n", outFileName.Data());
printf("=========================================\n"); printf("=========================================\n");
printf(" Time Window = %ld ns = %.1f us\n", timeWindow, timeWindow/1000.); printf(" Time Window = %ld ns = %.1f us\n", timeWindow, timeWindow/1000.);
printf(" Max multiplity = %d hits/event (hard coded)\n", MAX_MULTI); printf(" Max multiplity = %d hits/event (hard coded)\n", MAX_MULTI);
printf("========================================= Number of Files : %d \n", nFile); printf(" Out file name = %s \n", outFileName.Data());
printf(" Buffer Size = %d\n", bufferSize);
printf("=============================== Number of input Files : %d \n", nFile);
for( int i = 0 ; i < nFile; i++ ){ for( int i = 0 ; i < nFile; i++ ){
printf(" %3d | %s\n", i, inFileName[i].second.c_str()); printf(" %3d | %s\n", i, inFileName[i].second.c_str());
} }
printf("========================================= Scanning files\n");
return 0; unsigned long long totalHitCount = 0;
uint16_t tempHeader;
/* for( int i = 0; i < nFile; i++){
BinReader tempReader;
unsigned long long int totalHitCount = 0; if( i == 0 ) {
tempReader.OpenFile(inFileName[i].second);
BinReader reader[nFile]; tempHeader = tempReader.data.Header;
for(int i = 0; i < nFile; i++ ){ }else{
printf(">>>>>>>> %2d | %s \n", i, inFileName[i].Data()); tempReader.OpenFile(inFileName[i].second, 0, true);
reader[i].OpenFile(inFileName[i], 0, true); tempReader.SetCustomHeader(tempHeader);
// if( timeOffsetList.size() > 1 ){ }
// for (size_t i = 1 ; timeOffsetList.size(); i++) { tempReader.ScanNumHit();
// int sn = extractDigiSN(inFileName[i].Data(), timeOffsetList[0].first); totalHitCount += tempReader.GetNumHit();
// if( sn == timeOffsetList[i].first ) reader[i].SetTimeOffset(timeOffsetList[i].second);
// }
// }
reader[i].ScanNumHit();
totalHitCount += reader[i].GetNumHit();
} }
printf("======================= total Hit Count : %llu\n", totalHitCount); printf("============================ total Num. of Hit : %llu\n", totalHitCount);
timeWindow *= 1000; // to ps
printf("========================================= Initializing tree...\n"); printf("========================================= Initializing tree...\n");
unsigned long long evID = 0; unsigned long long evID = 0;
unsigned int multi = 0; unsigned int multi = 0;
unsigned short sn[MAX_MULTI] = {0}; unsigned short sn[MAX_MULTI] = {0};
@ -154,8 +251,8 @@ int main(int argc, char **argv) {
// unsigned short e2[MAX_MULTI] = {0}; // unsigned short e2[MAX_MULTI] = {0};
unsigned long long e_t[MAX_MULTI] = {0}; unsigned long long e_t[MAX_MULTI] = {0};
// unsigned short e_f[MAX_MULTI] = {0}; // unsigned short e_f[MAX_MULTI] = {0};
unsigned short traceLength[MAX_MULTI]; // unsigned short traceLength[MAX_MULTI];
short trace[MAX_MULTI][MAX_TRACE_LENGTH]; // short trace[MAX_MULTI][MAX_TRACE_LENGTH];
TFile * outRootFile = new TFile(outFileName, "recreate"); TFile * outRootFile = new TFile(outFileName, "recreate");
TTree * tree = new TTree("tree", outFileName); TTree * tree = new TTree("tree", outFileName);
@ -166,151 +263,103 @@ int main(int argc, char **argv) {
tree->Branch("e", e, "e[multi]/s"); tree->Branch("e", e, "e[multi]/s");
// tree->Branch("e2", e2, "e2[multi]/s"); // tree->Branch("e2", e2, "e2[multi]/s");
tree->Branch("e_t", e_t, "e_t[multi]/l"); 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);
}
printf("========================================= Event Building ...\n");
//set TimeWindow to ps;
timeWindow *= 1000;
// record the first time stamp and last time stamp // record the first time stamp and last time stamp
unsigned long long tStart = 0; unsigned long long tStart = 0;
unsigned long long tEnd = 0; unsigned long long tEnd = 0;
unsigned long long t0 = -1;
short g0 = 0 ;
int nFileFinished = 0;
multi = 0;
evID = 0;
std::vector<Data> events;
long long ID[nFile]; // filled hit ID
for( int i = 0 ; i < nFile ; i++ ) {
reader[i].ReadBlock();
SetTimeOffset(&reader[i], timeOffsetList);
ID[i] = -1;
}
unsigned long long hitProcessed = 0; unsigned long long hitProcessed = 0;
do{ printf("========================================= Read File & events building...\n");
///=========================== Read file
reader = new BinReader();
int fileID = 0;
reader->OpenFile(inFileName[fileID].second);
const uint16_t header = reader->data.Header;
if( debug ) printf("################################ ev build %llu \n", evID);
events.clear();
// //find earliest time group;
t0 = -1;
for( short i = 0; i < nFile; i++){
if( debug ) printf("NNNNNNNNNNNNNNN %d | ID: %lld, %lld, %lld \n", i, ID[i], reader[i].GetHitID(), reader[i].GetNumHit() );
if( ID[i] + 1 >= reader[i].GetNumHit()) continue;
// if( ID[i] >= reader[i].GetHitID() ) reader[i].ReadBlock();
if( debug ) reader[i].data.Print();
if( reader[i].data.TimeStamp < t0 ) {
t0 = reader[i].data.TimeStamp;
g0 = i;
}
}
if( evID == 0 ) tStart = t0;
if( debug ) printf("First timestamp is %llu, file ID : %u\n", t0, g0);
for( short i = 0; i < nFile; i++){
if( ID[i] + 1 >= reader[i].GetNumHit() ) continue;
if( timeWindow >= 0 ){
int ret = 0; int ret = 0;
uint64_t t0 = -1;
std::vector<Data> event;
do{ do{
if( (long int)( reader[i].data.TimeStamp - t0) <= timeWindow ){
events.push_back(reader[i].data); if( reader->IsEndOfFile() ){
ID[i] ++; reader->CloseFile();
fileID++;
if( fileID < nFile ) {
printf("\n========= Open next file.\n");
reader->OpenFile(inFileName[fileID].second, 0, true);
reader->SetCustomHeader(header);
}else{ }else{
break; printf("\n========= no more file.\n");
// break;
} }
ret = reader[i].ReadBlock(); }
SetTimeOffset(&reader[i], timeOffsetList); ret = ReadBatch(bufferSize);
}while( ret == 1 ); if( tStart == 0 ) tStart = hitList_A[0].TimeStamp;
tEnd = hitList_A.back().TimeStamp;
//build event from hitList_A;
for( size_t i = 0; i < hitList_A.size(); i++){
if( timeWindow < 0 ){
multi = 1;
sn[0] = hitList_A[i].BoardID;
ch[0] = hitList_A[i].Channel;
e[0] = hitList_A[i].Energy;
// e2[p] = hitList_A[i].Energy_short;
e_t[0] = hitList_A[i].TimeStamp / 1000;
tree->Fill();
evID ++;
}else{ }else{
events.push_back(reader[g0].data);
ID[g0] ++; if( t0 == -1 ) {
reader[g0].ReadBlock(); t0 = hitList_A[i].TimeStamp;
SetTimeOffset(&reader[g0], timeOffsetList); event.push_back(hitList_A[i]);
break;
} }
//if( timeWindow < 0) break; if( hitList_A[i].TimeStamp - t0 < timeWindow ){
} event.push_back(hitList_A[i]);
}else{
if( events.size() > 1 ){ //fill an event
std::sort(events.begin(), events.end(), [](const Data& a, const Data& b) { multi = event.size();
return a.TimeStamp < b.TimeStamp; if( multi > MAX_MULTI ){
});
}
tEnd = events.back().TimeStamp;
hitProcessed += events.size();
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("\033[31m event %lld has size = %d > MAX_MULTI = %d \033[0m\n", evID, multi, MAX_MULTI); printf("\033[31m event %lld has size = %d > MAX_MULTI = %d \033[0m\n", evID, multi, MAX_MULTI);
// for( int k = 0 ; k < multi; k++){ // for( int k = 0 ; k < multi; k++){
// printf("%d | %d %2d %llu | %llu , %llu , %llu\n", k, events[k].BoardID, events[k].Channel, events[k].TimeStamp, (long int)( events[k].TimeStamp - t0), t0, timeWindow); // printf("%d | %d %2d %llu | %llu , %llu , %llu\n", k, events[k].BoardID, events[k].Channel, events[k].TimeStamp, (long int)( events[k].TimeStamp - t0), t0, timeWindow);
// } // }
multi = MAX_MULTI; multi = MAX_MULTI;
} }
if( debug ) printf("=================================== filling data | %u \n", multi);
for( size_t p = 0; p < multi ; p ++ ) { for( size_t p = 0; p < multi ; p ++ ) {
if( debug ) {printf("%4zu | ", p); events[p].Print();} sn[p] = event[p].BoardID;
ch[p] = event[p].Channel;
sn[p] = events[p].BoardID; e[p] = event[p].Energy;
ch[p] = events[p].Channel; // e2[p] = event[p].Energy_short;
e[p] = events[p].Energy; e_t[p] = event[p].TimeStamp / 1000;
// e2[p] = events[p].Energy_short;
e_t[p] = events[p].TimeStamp / 1000;
// e_f[p] = events[p].TimeStamp % 1000;
traceLength[p] = events[p].NSample;
if( traceOn ){
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];
}
}
}
outRootFile->cd();
tree->Fill(); tree->Fill();
// tree->Write();
multi = 0;
evID ++; evID ++;
nFileFinished = 0; // start a new event
for( int i = 0; i < nFile; i++ ){ event.clear();
// printf(" %d | %lld %lld \n", i, ID[i], reader[i].GetNumHit() ); t0 = hitList_A[i].TimeStamp;
if( ID[i] + 1 >= reader[i].GetNumHit() ) nFileFinished ++ ; event.push_back(hitList_A[i]);
}
}
hitProcessed ++;
if( hitProcessed % 10000 == 0 ) printf("hit Porcessed %llu/%llu hit....%.2f%%\n\033[A\r", hitProcessed, totalHitCount, hitProcessed*100./totalHitCount);
} }
if( debug ) printf(" >>>> nFileFinished : %d \n", nFileFinished); tree->Write();
if( fileID >= nFile ) break;
if( events.size() == 0 ) break; }while(ret == 1);
if( debug > 1 && hitProcessed > debug ) break;
}while( nFileFinished < nFile );
tree->Write(); tree->Write();
@ -318,9 +367,8 @@ int main(int argc, char **argv) {
double runTime = (runEndTime - runStartTime) * 1e-6; double runTime = (runEndTime - runStartTime) * 1e-6;
printf("######################################### finished.\n"); printf("######################################### finished.\n");
printf(" event building time = %.2f sec = %.2f min\n", runTime, runTime/60.); 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 hit processed = %llu\n", hitProcessed); printf(" total hit processed = %llu\n", hitProcessed);
printf(" total events built = %llu by event builder\n", evID);
double tDuration_sec = (tEnd - tStart) * 1e-12; double tDuration_sec = (tEnd - tStart) * 1e-12;
printf(" first timestamp = %20llu ps\n", tStart); printf(" first timestamp = %20llu ps\n", tStart);
printf(" last timestamp = %20llu ps\n", tEnd); printf(" last timestamp = %20llu ps\n", tEnd);
@ -333,6 +381,8 @@ int main(int argc, char **argv) {
info.Write("info"); info.Write("info");
outRootFile->Close(); outRootFile->Close();
delete reader;
return 0; return 0;
*/
} }

View File

@ -94,6 +94,7 @@ class BinReader{
~BinReader(); ~BinReader();
void OpenFile(TString inFileName, int64_t timeOffset = 0, bool noHeader = false); void OpenFile(TString inFileName, int64_t timeOffset = 0, bool noHeader = false);
void SetCustomHeader(uint16_t Header);
// void SetDataFormat(bool has ); // void SetDataFormat(bool has );
void CloseFile(); void CloseFile();
void UpdateFileSize(); void UpdateFileSize();
@ -135,7 +136,7 @@ BinReader::BinReader(){
} }
BinReader::~BinReader(){ BinReader::~BinReader(){
fclose(inFile); /// fclose already delete inFile; if( inFile ) fclose(inFile); /// fclose already delete inFile;
} }
BinReader::BinReader(TString inFileName, int64_t timeOffset, bool noHeader){ BinReader::BinReader(TString inFileName, int64_t timeOffset, bool noHeader){
@ -168,6 +169,11 @@ void BinReader::OpenFile(TString inFileName, int64_t timeOffset, bool noHeader){
isOpened = true; isOpened = true;
// normal format: isHeaderOK = true, isNoHeaderFormat= false, isOldFormat = false
// old format: isHeaderOK = true, isNoHeaderFormat= false, isOldFormat = true
//no header format: isHeaderOK = false, isNoHeaderFormat= true, isOldFormat = false
if( noHeader ){ if( noHeader ){
data.Header = 0x0; data.Header = 0x0;
isOldFormat = false; isOldFormat = false;
@ -207,8 +213,14 @@ void BinReader::OpenFile(TString inFileName, int64_t timeOffset, bool noHeader){
} }
}; };
void BinReader::SetCustomHeader(uint16_t Header){
data.Header = Header;
isHeaderOK = true;
}
void BinReader::CloseFile(){ void BinReader::CloseFile(){
fclose(inFile); if(inFile) fclose(inFile);
inFile = nullptr;
isOpened = false; isOpened = false;
data.Clear(); data.Clear();
inFileSize = 0; inFileSize = 0;
@ -227,6 +239,7 @@ void BinReader::UpdateFileSize(){
bool BinReader::IsEndOfFile() { bool BinReader::IsEndOfFile() {
if( endOfFile ) return true; if( endOfFile ) return true;
if( inFile == nullptr ) return true;
return feof(inFile) > 0 ? true: false; return feof(inFile) > 0 ? true: false;
} }
@ -245,8 +258,7 @@ int BinReader::ReadBlock(int skipTrace){
if( feof(inFile) ) return -1; if( feof(inFile) ) return -1;
if( endOfFile ) return -1; if( endOfFile ) return -1;
if( isNoHeaderFormat && data.Header == 0x0 ) {
if( isNoHeaderFormat ) {
FillData(&data.BoardID); FillData(&data.BoardID);
FillData(&data.Channel); FillData(&data.Channel);
FillData(&data.TimeStamp); FillData(&data.TimeStamp);
@ -332,7 +344,7 @@ void BinReader::ScanNumHit(){
printf("scan complete: number of data Block : %ld\n", numHit); printf("scan complete: number of data Block : %ld\n", numHit);
rewind(inFile); ///back to the File begining rewind(inFile); ///back to the File begining
if( !isOldFormat && isHeaderOK ){ if( isOldFormat == false && isNoHeaderFormat == false ){ // only when normal format
FillData(&data.Header); FillData(&data.Header);
} }
inFilePos = 0; inFilePos = 0;
@ -365,5 +377,4 @@ void BinReader::PrintStatus(int mod){
} }
#endif #endif