#include "ClassData.h" #include "TROOT.h" #include "TSystem.h" #include "TApplication.h" #include "TCanvas.h" #include "TGraph.h" #include "TH1.h" #include "TFile.h" #include "TTree.h" #define MAX_MULTI 100 #define NTimeWinForBuffer 3 unsigned long get_time(){ unsigned long time_us; struct timeval t1; struct timezone tz; gettimeofday(&t1, &tz); time_us = (t1.tv_sec) * 1000000 + t1.tv_usec; return time_us; } TFile * outRootFile = NULL; TTree * tree = NULL; unsigned long long evID = 0; unsigned short multi = 0; unsigned short bd[MAX_MULTI] = {0}; /// boardID unsigned short ch[MAX_MULTI] = {0}; /// chID unsigned short e[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 //TODO std::vector wave[MAX_ID]; /// waveform void EventBuilder(Data * data, const unsigned int timeWin, bool isLastData = false){ ///printf("============= build Event\n"); ///data->PrintData(); /// find the last event timestamp; unsigned long long firstTimeStamp = -1; unsigned long long lastTimeStamp = 0; unsigned long long smallestLastTimeStamp = -1; for( int chI = 0; chI < MaxNChannels ; chI ++){ if( data->Timestamp[chI][0] > 0 && data->Timestamp[chI][0] < firstTimeStamp ) { firstTimeStamp = data->Timestamp[chI][0]; } unsigned short ev = data->NumEvents[chI]-1; if( data->Timestamp[chI][ev] > 0 && data->Timestamp[chI][ev] > lastTimeStamp ) { lastTimeStamp = data->Timestamp[chI][ev]; } if( data->Timestamp[chI][ev] > 0 && data->Timestamp[chI][ev] < smallestLastTimeStamp ){ smallestLastTimeStamp = data->Timestamp[chI][ev]; } } ///printf("================ time range : %llu - %llu, smallest Last %llu\n", firstTimeStamp, lastTimeStamp, smallestLastTimeStamp ); unsigned short lastEv[MaxNChannels] = {0}; /// store the last event number for each ch unsigned short exhaustedCh = 0; do { exhaustedCh = 0; bool breakFlag = false; /// find the 1st event int ch1st = -1; unsigned long long time1st = -1; for( int chI = 0; chI < MaxNChannels ; chI ++){ if( data->Timestamp[chI][lastEv[chI]] == 0 ) { exhaustedCh ++; continue; } if( data->NumEvents[chI] <= lastEv[chI] ) { breakFlag = true; exhaustedCh ++; break; } if( data->Timestamp[chI][lastEv[chI]] < time1st ) { time1st = data->Timestamp[chI][lastEv[chI]]; ch1st = chI; } } if( !isLastData && ((smallestLastTimeStamp - time1st) < NTimeWinForBuffer * timeWin) ) break; if( ch1st > MaxNChannels ) break; multi ++; bd[multi-1] = data->boardSN; ch[multi-1] = ch1st; e[multi-1] = data->Energy[ch1st][lastEv[ch1st]]; e_t[multi-1] = data->Timestamp[ch1st][lastEv[ch1st]]; e_f[multi-1] = data->fineTime[ch1st][lastEv[ch1st]]; lastEv[ch1st] ++; /// build event for( int chI = ch1st; chI < ch1st + MaxNChannels; chI ++){ unsigned short chX = chI % MaxNChannels; if( data->NumEvents[chX] == 0 ) continue; if( data->NumEvents[chX] <= lastEv[chX] ) continue; for( int ev = lastEv[chX]; ev < data->NumEvents[chX] ; ev++){ if( data->Timestamp[chX][ev] > 0 && (data->Timestamp[chX][ev] - e_t[0] ) < timeWin ) { multi ++; bd[multi-1] = data->boardSN; ch[multi-1] = chX; e[multi-1] = data->Energy[chX][ev]; e_t[multi-1] = data->Timestamp[chX][ev]; e_f[multi-1] = data->fineTime[chX][ev]; lastEv[chX] = ev + 1; if( lastEv[chX] == data->NumEvents[chX] ) exhaustedCh ++; } } } ///printf("=============== multi : %d , ev : %llu\n", multi, evID); ///for( int ev = 0; ev < multi; ev++){ /// printf("%3d, ch : %2d, %u, %llu \n", ev, ch[ev], e[ev], e_t[ev]); ///} /// ///printf("=============== Last Ev , exhaustedCh %d \n", exhaustedCh); ///for( int chI = 0; chI < MaxNChannels ; chI++){ /// if( lastEv[chI] == 0 ) continue; /// printf("%2d, %d \n", chI, lastEv[chI]); ///} ///========== Quick Sort the timestamp ??or left it to analyzer, monitor? /// fill Tree outRootFile->cd(); tree->Fill(); evID++; /// clear multi = 0; }while( exhaustedCh < MaxNChannels - 1 ); ///========== clear built data /// move the last data to the top, for( int chI = 0; chI < MaxNChannels; chI++){ if( data->NumEvents[chI] == 0 ) continue; int count = 0; for( int ev = lastEv[chI] ; ev < data->NumEvents[chI] ; ev++){ data->Energy[chI][count] = data->Energy[chI][ev]; data->Timestamp[chI][count] = data->Timestamp[chI][ev]; data->fineTime[chI][count] = data->fineTime[chI][ev]; count++; } data->NumEvents[chI] = data->NumEvents[chI] - lastEv[chI]; } } int main(int argc, char **argv) { printf("=====================================\n"); printf("=== *.fsu Events Builder ===\n"); printf("=====================================\n"); // Check that the corrent number of arguments were provided. if (argc <= 2) { printf("Incorrect number of arguments:\n"); printf("%s [outFile] [timeWindow] [inFile1] [inFile2] .... \n", argv[0]); printf(" outFile : output root file name\n"); printf(" timeWindow : number of tick, 1 tick. default = 100 \n"); return 1; } TString outFileName = argv[1]; unsigned int timeWindow = atoi(argv[2]); int nFile = argc - 3; TString inFileName[nFile]; for( int i = 0 ; i < nFile ; i++){ inFileName[i] = argv[i+3]; } printf(" Time Window = %u \n", timeWindow); /// Open input Files FILE * haha = fopen(inFileName[0], "r"); fseek(haha, 0L, SEEK_END); const size_t inFileSize = ftell(haha); printf("file size : %d Byte = %.2f MB\n", (int) inFileSize, inFileSize/1024./1024.); fclose(haha); Data * data = new Data(); data->DPPType = V1730_DPP_PHA_CODE; data->boardSN = 323; data->SetSaveWaveToMemory(true); ///============= Set Root Tree outRootFile = new TFile(outFileName, "recreate"); tree = new TTree("tree", outFileName); tree->Branch("evID", &evID, "event_ID/l"); tree->Branch("multi", &multi, "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("e_t", e_t, "e_timestamp[multi]/l"); tree->Branch("e_f", e_f, "e_timestamp[multi]/s"); ///============= Main Loop haha = fopen(inFileName[0], "r"); int countBdAgg = 0; unsigned long currentTime = 0; unsigned long oldTime = 0; do{ ///========== Get 1 aggreration oldTime = get_time(); ///printf("*********************** file pos : %d, %lu\n", (int) ftell(haha), oldTime); unsigned int word[1]; /// 4 bytes size_t dump = fread(word, 4, 1, haha); fseek(haha, -4, SEEK_CUR); unsigned int aggSize = (word[0] & 0x0FFFFFFF) * 4; ///byte short header = ((word[0] >> 28 ) & 0xF); if( header != 0xA ) break; ///printf("Board Agg. has %d word = %d bytes\n", aggSize/4, aggSize); countBdAgg ++; char * buffer = new char[aggSize]; dump = fread(buffer, aggSize, 1, haha); data->DecodeBuffer(buffer, aggSize, false, 0); currentTime = get_time(); ///printf("~~~~~~~~~~~~~~~~ time used : %lu \n", currentTime - oldTime); ///data->PrintStat(); EventBuilder(data, timeWindow); }while(!feof(haha) && ftell(haha) <= inFileSize); fclose(haha); ///printf("==================== end of loop \n"); EventBuilder(data, timeWindow, true); tree->Write(); outRootFile->Close(); printf("========================= finsihed.\n"); printf("total events built = %llu \n", evID); }