diff --git a/.gitignore b/.gitignore index 3c019f8..7afbcaa 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,9 @@ *.d *.so *.root +*.evt +EventBuilder legacy_code nscl2pixie nscl2pixie_haha diff --git a/armory/EventBuilder.cpp b/armory/EventBuilder.cpp new file mode 100644 index 0000000..24d6c26 --- /dev/null +++ b/armory/EventBuilder.cpp @@ -0,0 +1,267 @@ +/**********************************************************/ +/* */ +/* Modified by Ryan From */ +/* */ +/* PXI SCAN CODE -- J.M. Allmond (ORNL) -- July 2016 */ +/* */ +/**********************************************************/ + +#include +#include +#include +#include +#include + +#include "TFile.h" +#include "TTree.h" +#include "TMath.h" +#include "TBenchmark.h" + +#define RAND ((float) rand() / ((unsigned int) RAND_MAX + 1)) // random number in interval (0,1) + +#define MAX_CRATES 2 +#define MAX_BOARDS_PER_CRATE 13 +#define MAX_CHANNELS_PER_BOARD 16 +#define BOARD_START 2 + +#define MAX_ID MAX_CRATES*MAX_BOARDS_PER_CRATE*MAX_CHANNELS_PER_BOARD + +#include "../mapping.h" + +#include "../armory/evtReader.h" + +unsigned long long int dataCount=0; +unsigned long long int pileUpCount=0; +unsigned long long int evtCount=0; +int tick2ns = 8; + +/////////////////////////////////// +// START OF MAIN FUNCTION // +/////////////////////////////////// +int main(int argc, char **argv) { + + printf("=====================================\n"); + printf("=== evt --> root ===\n"); + printf("=====================================\n"); + + // Check that the corrent number of arguments were provided. + if (argc <= 3) { + printf("Incorrect number of arguments:\n"); + printf("%s [outFile] [isNSCL] [timeWindow] [to File1] [to File2] .... \n", argv[0]); + printf(" outFile : output root file name\n"); + printf(" isNSCL : flag for NSCL evt file\n"); + printf(" timeWindow : number of tick, 1 tick = %d ns. default = 100 \n", tick2ns); + return 1; + } + + TString outFileName = argv[1]; + bool isNSCL = argv[2]; + int timeWindow = atoi(argv[3]); + int nFile = argc - 4; + TString inFileName[nFile]; + for( int i = 0 ; i < nFile ; i++){ + inFileName[i] = argv[i+4]; + } + + printf("====================================\n"); + + evtReader * evt = new evtReader(); + DataBlock * data = evt->data; + + printf(" Number of input file : %d \n", nFile); + printf(" out file : \033[1;31m%s\033[m\n", outFileName.Data()); + printf(" Event building time window : %d tics = %d nsec \n", timeWindow, timeWindow*tick2ns); + + + TFile * outRootFile = new TFile(outFileName, "recreate"); + outRootFile->cd(); + TTree * tree = new TTree("tree", outFileName); + + unsigned long long evID = 0; + int multi = 0; + int id[MAX_ID] = {0}; + double e[MAX_ID] = {TMath::QuietNaN()}; + unsigned long long e_t[MAX_ID] = {0}; + int cfd[MAX_ID] = {0}; + bool pileup[MAX_ID] = {0}; + int qdc[MAX_ID][8] = {0}; + int multiClover = 0 ; /// this is total multiplicity for all crystal + int runID = 0; // date-run-fileID + int multiBeam = 0; + //unsigned short pileup[MAXMULTI]; + + tree->Branch("evID", &evID, "event_ID/l"); + tree->Branch("multi", &multi, "multi/I"); + tree->Branch("detID", id, "detID[multi]/I"); + tree->Branch("e", e, "e[multi]/D"); + tree->Branch("e_t", e_t, "e_timestamp[multi]/l"); + //tree->Branch("pileup", pileup, "pileup[multi]/O"); + tree->Branch("cfd", cfd, "cfd[multi]/I"); + tree->Branch("qdc", qdc, "qdc[multi][8]/I"); + tree->Branch("multiClover", &multiClover, "multiplicity_Clover/I"); + tree->Branch("multiBeam", &multiBeam, "multiplicity_Beam/I"); + tree->Branch("runID", &runID, "runID/I"); + + int countGP = 0; //gamma-particle coincident + double totalDataSize = 0; + int outFileCount = 0; + + for( int i = 0; i < nFile; i++){ + + evt->OpenFile(inFileName[i], isNSCL); + if( evt->IsOpen() == false ) continue; + + printf("==================================================== %d / %d\n", i+1, nFile); + printf("\033[1;31m%s \033[m\n", inFileName[i].Data()); + + int pos = inFileName[i].Last('/'); + TString temp = inFileName[i]; + temp.Remove(0, pos+1); + pos = temp.Last('-'); + temp.Remove(0, pos+1); + pos = temp.Last('.'); + temp.Remove(pos); + runID = atoi(temp.Data()); + + long long int etime = -1; + long long int tdif = -1; + + while ( evt->IsEndOfFile() == false ) { //main while loop + + if ( evt->ReadBlock() == -1) break; + + if ( data->crate == 0 ) continue; + + //Set reference time for event building + if (etime == -1) { + etime = data->time; + tdif = 0; + multi = 0; + multiClover = 0; + multiBeam = 0; + }else { + tdif = data->time - etime; + } + + //Check for end of event, rewind, and break out of while loop + if (tdif > timeWindow) { + + //Gate + //if( multiClover > 2 && multiBeam ==0 ) { + // + outRootFile->cd(); + tree->Fill(); + //printf("------------------\n"); + // + // countGP++; + //} + + evID ++; + + //clear data + etime = data->time; + tdif = 0; + multi = 0; + multiClover = 0; + multiBeam = 0; + + int haha = data->crate*MAX_BOARDS_PER_CRATE*MAX_CHANNELS_PER_BOARD + (data->slot-BOARD_START)*MAX_CHANNELS_PER_BOARD + data->ch; + id[multi] = mapping[haha]; + e[multi] = data->energy; + e_t[multi] = data->time; + cfd[multi] = data->cfd_forced == 0 ? (data->cfd - 16384*(data->cfd_source == true ? 1 : 0))/2 : 0; + pileup[multi] = data->pileup; + for( int i = 0; i < 8; i++) qdc[multi][i] = data->QDCsum[i]; + + if( 0 <= id[multi] && id[multi] < 100 ) multiClover += 1; + if( id[multi] == 300 || id[multi] == 301 || id[multi] == 307 || id[multi] == 308 ) multiBeam += 1; + //printf("id: %d, multiBeam: %d, %llu, tdif %llu\n", id[multi], multiBeam, e_t[multi], tdif); + multi++ ; + }else{ + //if within time window, fill array; + int haha = data->crate*MAX_BOARDS_PER_CRATE*MAX_CHANNELS_PER_BOARD + (data->slot-BOARD_START)*MAX_CHANNELS_PER_BOARD + data->ch; + id[multi] = mapping[haha]; + e[multi] = data->energy; + e_t[multi] = data->time; + cfd[multi] = data->cfd_forced == 0 ? (data->cfd - 16384*(data->cfd_source == true ? 1 : 0))/2 : 0; + //printf(" %d , %d , %d, %d \n", data->cfd_forced, data->cfd_source, data->cfd, cfd[multi]); + pileup[multi] = data->pileup; + for( int i = 0; i < 8; i++) qdc[multi][i] = data->QDCsum[i]; + if( 0 <= id[multi] && id[multi] < 100 ) multiClover += 1; + if( id[multi] == 300 || id[multi] == 301 || id[multi] == 307 || id[multi] == 308 ) multiBeam += 1; + //printf("id: %d, multiBeam: %d, %llu, tdif %llu\n", id[multi], multiBeam, e_t[multi], tdif); + multi++ ; + + } + + // total pileups + if (data->pileup == 1) { + pileUpCount++; + } + + evt->PrintStatus(10000); + + } // end main while loop + + evt->PrintStatus(1); + printf("\n\n\n"); + printf(" total number of event built : %llu\n", evID); + //printf(" total number of Gamma - GAGG coincdient : %d (%.3f %%)\n", countGP, countGP*1.0/evID); + + outRootFile->cd(); + tree->Write(); + + totalDataSize += (evt->GetFileSize())/1024./1024./1024.; + + double rootFileSize = outRootFile->GetSize()/1024./1024./1024. ; // in GB + printf(" ----------- root file size : %.3f GB\n", rootFileSize); + printf(" ---------- total read size : %.3f GB\n", totalDataSize); + printf(" ----------- reduction rate : %.3f %%\n", rootFileSize*100./totalDataSize); + + evt->CloseFile(); + + /* + if( rootFileSize > 3.0 ) { + break; + }*/ + + ///try to open a new root file when file size > 2 GB + /*if( rootFileSize > 2.0 ) { + + outRootFile->Close(); + delete outRootFile; + delete tree; + outFileCount += 1; + + if( outFileCount > 5 ) break; + + TString outFileName2 = outFileName; + outFileName2.Insert(outFileName.Sizeof() - 6, Form("_%03d",outFileCount)); + outRootFile = new TFile( outFileName2, "recreate"); + + tree = new TTree("tree", "tree"); + tree->Branch("evID", &evID, "event_ID/l"); + tree->Branch("multi", &multi, "multi/I"); + tree->Branch("detID", id, "detID[multi]/I"); + tree->Branch("e", e, "e[multi]/D"); + tree->Branch("e_t", e_t, "e_timestamp[multi]/l"); + tree->Branch("qdc", qdc, "qdc[multi][8]/I"); + tree->Branch("multiClover", &multiClover, "multiplicity_crystal/I"); + tree->Branch("multiBeam", &multiBeam, "multiplicity_GAGG/I"); + tree->Branch("runID", &runID, "runID/I"); + + }*/ + + } + + + outRootFile->Close(); + + printf("\n\n\n==================== finished.\r\n"); + + //printf(" number of Gamma - GAGG coincdient : %d\n", countGP); + + return 0; +} + + diff --git a/armory/EventBuilder_evt.cpp b/armory/EventBuilder_evt.cpp index 18310bf..f65258e 100644 --- a/armory/EventBuilder_evt.cpp +++ b/armory/EventBuilder_evt.cpp @@ -26,11 +26,6 @@ #define MAX_ID MAX_CRATES*MAX_BOARDS_PER_CRATE*MAX_CHANNELS_PER_BOARD -#define HEADER_LENGTH 4 //unit = words with 4 bytes per word -#define MAX_SUB_LENGTH 2016 //unit = words with 4 bytes per word ; 2004 --> 40 micro-second trace + 4 word header - -#define RAWE_REBIN_FACTOR 2.0 // Rebin 32k pixie16 spectra to something smaller to fit better into 8k. - #include "../mapping.h" #include "../armory/evtReader.h" @@ -46,7 +41,7 @@ int tick2ns = 4; int main(int argc, char **argv) { printf("=====================================\n"); - printf("=== evt.to --> root ===\n"); + printf("=== evt --> root ===\n"); printf("=====================================\n"); // Check that the corrent number of arguments were provided. @@ -133,7 +128,7 @@ int main(int argc, char **argv) { if ( evt->ReadBlock() == -1) break; - if ( data->crate == 0 ) continue; + if ( data->crate == 0 ) continue; //Set reference time for event building if (etime == -1) { @@ -154,14 +149,14 @@ int main(int argc, char **argv) { // outRootFile->cd(); tree->Fill(); - //printf("------------------\n"); + //printf("------------------\n"); // // countGP++; //} evID ++; - //clear data + //clear data etime = data->time; tdif = 0; multi = 0; @@ -172,13 +167,13 @@ int main(int argc, char **argv) { id[multi] = mapping[haha]; e[multi] = data->energy; e_t[multi] = data->time; - cfd[multi] = data->cfd_forced == 0 ? (data->cfd - 16384*(data->cfd_source == true ? 1 : 0))/2 : 0; + cfd[multi] = data->cfd_forced == 0 ? (data->cfd - 16384*(data->cfd_source == true ? 1 : 0))/2 : 0; pileup[multi] = data->pileup; for( int i = 0; i < 8; i++) qdc[multi][i] = data->QDCsum[i]; if( 0 <= id[multi] && id[multi] < 100 ) multiClover += 1; if( id[multi] == 300 || id[multi] == 301 || id[multi] == 307 || id[multi] == 308 ) multiBeam += 1; - //printf("id: %d, multiBeam: %d, %llu, tdif %llu\n", id[multi], multiBeam, e_t[multi], tdif); + //printf("id: %d, multiBeam: %d, %llu, tdif %llu\n", id[multi], multiBeam, e_t[multi], tdif); multi++ ; }else{ //if within time window, fill array; @@ -187,12 +182,12 @@ int main(int argc, char **argv) { e[multi] = data->energy; e_t[multi] = data->time; cfd[multi] = data->cfd_forced == 0 ? (data->cfd - 16384*(data->cfd_source == true ? 1 : 0))/2 : 0; - //printf(" %d , %d , %d, %d \n", data->cfd_forced, data->cfd_source, data->cfd, cfd[multi]); + //printf(" %d , %d , %d, %d \n", data->cfd_forced, data->cfd_source, data->cfd, cfd[multi]); pileup[multi] = data->pileup; for( int i = 0; i < 8; i++) qdc[multi][i] = data->QDCsum[i]; if( 0 <= id[multi] && id[multi] < 100 ) multiClover += 1; if( id[multi] == 300 || id[multi] == 301 || id[multi] == 307 || id[multi] == 308 ) multiBeam += 1; - //printf("id: %d, multiBeam: %d, %llu, tdif %llu\n", id[multi], multiBeam, e_t[multi], tdif); + //printf("id: %d, multiBeam: %d, %llu, tdif %llu\n", id[multi], multiBeam, e_t[multi], tdif); multi++ ; } diff --git a/armory/MergeEVT b/armory/MergeEVT index 81c1e10..788f467 100755 Binary files a/armory/MergeEVT and b/armory/MergeEVT differ diff --git a/armory/evt2hist b/armory/evt2hist index 51bd0ed..580a48f 100755 Binary files a/armory/evt2hist and b/armory/evt2hist differ diff --git a/armory/evtReader.h b/armory/evtReader.h index 8da3310..e2abbd6 100644 --- a/armory/evtReader.h +++ b/armory/evtReader.h @@ -17,8 +17,6 @@ #define MAX_CHANNELS_PER_BOARD 16 #define BOARD_START 2 -//TODO load the file into RAM, and read from the RAM - class evtReader{ public: @@ -42,18 +40,22 @@ class evtReader{ long int inFilePosPrecent[10]; Long64_t blockIDPrecent[10]; - bool fromRAM; int * pxidata; long nWords; + + bool isNSCL; + + unsigned int rib_size[1]; + unsigned int readRingItemByte; ///============================================ Methods public: evtReader(); - evtReader(TString inFileName, bool load2RAM); + evtReader(TString inFileName, bool isNSCL); ~evtReader(); - void OpenFile(TString inFileName, bool load2RAM); + void OpenFile(TString inFileName, bool isNSCL); void CloseFile(); void UpdateFileSize(); @@ -74,6 +76,7 @@ class evtReader{ void JumptoPrecent(int precent); ///this is offset by 1 block void PrintStatus(int mod); + void SetNSCL(bool isNSCL_Evt); }; @@ -91,9 +94,13 @@ evtReader::evtReader(){ endOfFile = false; isOpened = false; - fromRAM = false; pxidata = NULL; nWords = 0; + + isNSCL = false; + rib_size[0] = 0; + readRingItemByte = 0; + } @@ -105,7 +112,7 @@ evtReader::~evtReader(){ } -evtReader::evtReader(TString inFileName, bool load2RAM = false){ +evtReader::evtReader(TString inFileName, bool isNSCL = false){ inFile = 0; data = new DataBlock(); @@ -116,14 +123,13 @@ evtReader::evtReader(TString inFileName, bool load2RAM = false){ blockID = -1; endOfFile = false; isOpened = false; - fromRAM = false; // true until loaded to RAM pxidata = NULL; nWords = 0; - OpenFile(inFileName, load2RAM); + OpenFile(inFileName, isNSCL); } -void evtReader::OpenFile(TString inFileName, bool load2RAM = false){ +void evtReader::OpenFile(TString inFileName, bool isNSCL = false){ inFile = fopen(inFileName, "r"); if( inFile == NULL ){ printf("Cannot read file : %s \n", inFileName.Data()); @@ -132,23 +138,12 @@ void evtReader::OpenFile(TString inFileName, bool load2RAM = false){ inFileSize = ftell(inFile); rewind(inFile); ///back to the File begining - //TODO load the evt file to RAM - if( load2RAM ) { - pxidata = (int *) malloc(inFileSize); - if( pxidata == NULL ){ - printf("\nError, memory not allocated.\n"); - }else{ - printf("Allocated %.3f GB of memory to buffer native PXI data\n", (float)inFileSize/(1024.0*1024.0*1024.0)); - printf("Now loading data to RAM\n"); - fread(pxidata, sizeof(pxidata), inFileSize/sizeof(pxidata), inFile); - fromRAM = true; - fclose(inFile); - inFilePos = 0; - } - } - data->Clear(); + this->isNSCL = isNSCL; + rib_size[0] = 0; + readRingItemByte = 0; + gClock.Reset(); gClock.Start("timer"); @@ -165,6 +160,8 @@ void evtReader::CloseFile(){ nBlock = 0; blockID = -1; endOfFile = false; + + isNSCL = false; }; void evtReader::UpdateFileSize(){ @@ -179,26 +176,74 @@ bool evtReader::IsEndOfFile() { return haha > 0 ? true: false; } +void evtReader::SetNSCL(bool isNSCL_Evt){ + isNSCL = isNSCL_Evt; +} + int evtReader::ReadBlock(int opt){ if( feof(inFile) ) return -1; if( endOfFile ) return -1; + + if( isNSCL && readRingItemByte == rib_size[0]) { + //============= Ring item header, [0] = size, [1] = type + unsigned int rih[2]= {0}; + do{ + if ( fread(rih, sizeof(rih), 1, inFile) != 1 ) { + endOfFile = true; + return -1; + } + inFilePos = ftell(inFile); + ///printf("%ld-------- Ring Item Header| size : %d, type : %d \n", inFilePos, rih[0], rih[1]); - unsigned int header[4]; ///read 4 header, unsigned int = 4 byte = 32 bits. + ///if the type is not 30, skip + if( rih[1] != 30 ) { + fseek(inFile, rih[0]-8, SEEK_CUR); + inFilePos = ftell(inFile); + ///printf("%ld---- skip %d bytes\n", inFilePos, rih[0]-8); + } + }while(rih[1] != 30); - if( fromRAM ){ - for( int i = 0; i < 4 ; i++){ - header[i] = pxidata[nWords]; nWords += 1; - } - }else{ - if ( fread(header, sizeof(header), 1, inFile) != 1 ) { + //=========== Ring item body header, [0] = size, [1] timestamp-low, [2] timestamp-high, [3] source ID, [4] = barrier type + unsigned int ribh[5]={0}; + if ( fread(ribh, sizeof(ribh), 1, inFile) != 1 ) { + endOfFile = true; + return -1; + } + inFilePos = ftell(inFile); + unsigned long long timestamp = ((unsigned long long)ribh[2] << 32) + ribh[1]; + ///printf("%ld - Ring Item Body Header| size : %d, timestamp : %llu \n", inFilePos, ribh[0], timestamp); + + //================================== Ring item body + + if ( fread(rib_size, sizeof(rib_size), 1, inFile) != 1 ) { endOfFile = true; return -1; } - } - blockID ++; + inFilePos = ftell(inFile); + ///printf("%ld - Size of Ring Item Body : %d \n", inFilePos, rib_size[0]); + readRingItemByte = 4; + } + + if( isNSCL){ + if(rib_size[0] > 48 && readRingItemByte < rib_size[0] ){ + fseek(inFile, 14*4, SEEK_CUR); + inFilePos = ftell(inFile); + readRingItemByte += 14 * 4; + }else{ + return -2; + } + } + + unsigned int header[4]; ///read 4 header, unsigned int = 4 byte = 32 bits. + if ( fread(header, sizeof(header), 1, inFile) != 1 ) { + endOfFile = true; + return -1; + } + readRingItemByte += sizeof(header); + blockID ++; if( opt == 0 || opt == 2){ /// see the Pixie-16 user manual, Table4-2 @@ -222,13 +267,8 @@ int evtReader::ReadBlock(int opt){ ///======== read QDCsum if( data->headerLength >= 4 ){ - if( fromRAM ){ - for( int i = 0; i < data->headerLength - 4 ; i++){ - extraHeader[i] = pxidata[nWords]; nWords += 1; - } - }else{ - fread(extraHeader, sizeof(unsigned int) * (data->headerLength-4), 1, inFile); - } + fread(extraHeader, sizeof(unsigned int) * (data->headerLength-4), 1, inFile); + readRingItemByte += (data->headerLength-4)*4; if( data->headerLength == 8 || data->headerLength == 16){ data->trailing = extraHeader[0]; data->leading = extraHeader[1]; @@ -251,13 +291,8 @@ int evtReader::ReadBlock(int opt){ } ///====== read trace if( data->eventLength > data->headerLength ){ - if( fromRAM ){ - for( int i = 0; i < data->trace_length / 2 ; i++){ - traceBlock[i] = pxidata[nWords]; nWords += 1; - } - }else{ - fread(traceBlock, sizeof(unsigned int) * ( data->trace_length / 2 ), 1, inFile); - } + fread(traceBlock, sizeof(unsigned int) * ( data->trace_length / 2 ), 1, inFile); + readRingItemByte += data->trace_length / 2 * 4; for( int i = 0; i < data->trace_length/2 ; i++){ data->trace[2*i+0] = traceBlock[i] & 0xFFFF ; data->trace[2*i+1] = (traceBlock[i] >> 16 ) & 0xFFFF ; @@ -280,37 +315,25 @@ int evtReader::ReadBlock(int opt){ }*/ } } - + if( opt == 1 ){ - + data->headerLength = (header[0] >> 12) & 0x1F; data->eventLength = (header[0] >> 17) & 0x3FFF; data->trace_length = (header[3] >> 16) & 0x7FFF; if( data->headerLength >= 4 ){ - if( fromRAM ){ - nWords += (data->headerLength-4); - }else{ - fread(extraHeader, sizeof(unsigned int) * (data->headerLength-4), 1, inFile); - } + fread(extraHeader, sizeof(unsigned int) * (data->headerLength-4), 1, inFile); } if( data->eventLength > data->headerLength ){ - if( fromRAM ){ - nWords += ( data->trace_length / 2 ); - }else{ - fread(traceBlock, sizeof(unsigned int) * ( data->trace_length / 2 ), 1, inFile); - } + fread(traceBlock, sizeof(unsigned int) * ( data->trace_length / 2 ), 1, inFile); } } - if ( fromRAM ){ - inFilePos = nWords * 32; - }else{ - inFilePos = ftell(inFile); - } - - if( opt == 2) data->Print(); + inFilePos = ftell(inFile); + if( opt == 2) data->Print(); + return 1; } diff --git a/armory/makefile b/armory/makefile index 29a7fe2..a0b18b7 100644 --- a/armory/makefile +++ b/armory/makefile @@ -1,10 +1,10 @@ CC=g++ -all: EventBuilder_evt evt2hist MergeEVT ev22txt EventBuilder +all: EventBuilder evt2hist MergeEVT ev22txt nscl2pixie #this is for eventbuild -EventBuilder_evt: ../armory/EventBuilder_evt.cpp ../armory/DataBlock.h ../armory/evtReader.h ../mapping.h - $(CC) ../armory/EventBuilder_evt.cpp -o EventBuilder_evt `root-config --cflags --glibs` +EventBuilder: ../armory/EventBuilder.cpp ../armory/DataBlock.h ../armory/evtReader.h ../mapping.h + $(CC) ../armory/EventBuilder.cpp -o EventBuilder `root-config --cflags --glibs` #this is for online root MergeEVT: ../armory/MergeEVT.cpp ../armory/DataBlock.h ../armory/evtReader.h ../mapping.h @@ -14,12 +14,14 @@ MergeEVT: ../armory/MergeEVT.cpp ../armory/DataBlock.h ../armory/evtReader.h ../ evt2hist: ../armory/evt2hist.cpp ../armory/DataBlock.h ../armory/evtReader.h ../mapping.h $(CC) ../armory/evt2hist.cpp -o evt2hist `root-config --cflags --glibs` +nscl2pixie: ../armory/nscl2pixie.c + $(CC) ../armory/nscl2pixie.c -o nscl2pixie ev22txt: ../armory/ev22txt.cpp $(CC) ../armory/ev22txt.cpp -o ev22txt -EventBuilder: ../armory/EventBuilder.cpp - $(CC) ../armory/EventBuilder.cpp -o EventBuilder `root-config --cflags --glibs` +#EventBuilder: ../armory/EventBuilder.cpp +# $(CC) ../armory/EventBuilder.cpp -o EventBuilder `root-config --cflags --glibs` clean: -rm xia2root to2root MergeEVT evt2hist pxi-time-order ev22txt EventBuilder test diff --git a/nscl2pixie.c b/armory/nscl2pixie.c similarity index 84% rename from nscl2pixie.c rename to armory/nscl2pixie.c index e77800f..cb58936 100644 --- a/nscl2pixie.c +++ b/armory/nscl2pixie.c @@ -1,5 +1,6 @@ #include #include +#include /* Ring Item structure @@ -49,6 +50,8 @@ Ring Item Body bool debug = false; +unsigned long long words = 0; + int readRingItemHeader(FILE *file, unsigned int *ri_size) { unsigned int ri_type; if (fread(ri_size, (size_t)sizeof(int), 1, file) != 1) { @@ -57,6 +60,7 @@ int readRingItemHeader(FILE *file, unsigned int *ri_size) { if (fread(&ri_type, (size_t)sizeof(int), 1, file) != 1) { return -1; } + if (ri_type != 30 ) { //non-physics item if (ri_type == 1) { @@ -100,11 +104,11 @@ int readRingItemBodyHeader(FILE *file) { } /* - std::cout << "Ring Item Body Header: " << std::endl; - std::cout << " size : " << ribh_size << std::endl; - std::cout << " timestamp : " << ribh_ts << std::endl; - std::cout << " source ID : " << ribh_sid << std::endl; - std::cout << " barrier type : " << ribh_bt << std::endl; + printf("Ring Item Body Header: \n" ); + printf(" size : %u\n" , ribh_size); + printf(" timestamp : %llu\n" , ribh_ts ); + printf(" source ID : %u\n" , ribh_sid ); + printf(" barrier type : %u\n" , ribh_bt ); */ return ribh_size; } @@ -151,22 +155,19 @@ int readNextFragment(FILE *file, unsigned int *rib_size) { if (fread(&frag_ribh_bt, (size_t)sizeof(int), 1, file) != 1) { return -1; } /* - std::cout << "Fragment Header: " << std::endl; - std::cout << " Timestamp: " << frag_ts << std::endl; - std::cout << " Source ID: " << frag_sid << std::endl; - std::cout << " Payload Size: " << frag_paysize << std::endl; - std::cout << " Barrier Type: " << frag_bt << std::endl; - - std::cout << "Fragment RIH: " << std::endl; - std::cout << " Size: " << frag_rih_size << std::endl; - std::cout << " Type: " << frag_rih_type << std::endl; - - - std::cout << "Fragment RIBH: " << std::endl; - std::cout << " Size: " << frag_ribh_size << std::endl; - std::cout << " Timestamp: " << frag_ribh_ts << std::endl; - std::cout << " Source ID: " << frag_ribh_sid << std::endl; - std::cout << " Barrier Type: " << frag_ribh_bt << std::endl; + printf("Fragment Header: \n"); + printf(" Timestamp: %llu\n", frag_ts ); + printf(" Source ID: %u\n", frag_sid ); + printf(" Payload Size: %u\n", frag_paysize); + printf(" Barrier Type: %u\n", frag_bt ); + printf("Fragment RIH: \n"); + printf(" Size: %u\n", frag_rih_size); + printf(" Type: %u\n", frag_rih_type); + printf("Fragment RIBH: \n"); + printf(" Size: %u\n", frag_ribh_size); + printf(" Timestamp: %llu\n", frag_ribh_ts ); + printf(" Source ID: %u\n", frag_ribh_sid ); + printf(" Barrier Type: %u\n", frag_ribh_bt ); */ unsigned int frag_size; //in 16 bit words not 32 bit words @@ -212,6 +213,7 @@ int readNextFragment(FILE *file, unsigned int *rib_size) { } int findNextFragment(FILE *file, unsigned int *rib_size) { + if (*rib_size > 0) { return readNextFragment(file, rib_size); } @@ -229,6 +231,7 @@ int findNextFragment(FILE *file, unsigned int *rib_size) { readRingItemBody(file, rib_size); if (*rib_size < 0) { return *rib_size; } + return readNextFragment(file, rib_size); } @@ -279,6 +282,9 @@ int main(int argc, const char **argv) { retval = copyPixieSubEvent(infile, outfile); if (retval < 0 ) { break; } ++evts; + + sleep(2); + } printf("%llu subevents copied\n", evts); diff --git a/armory/nsclEvtReader.h b/armory/nsclEvtReader.h new file mode 100644 index 0000000..078974e --- /dev/null +++ b/armory/nsclEvtReader.h @@ -0,0 +1,278 @@ +#ifndef NSCLEVTREADER_H +#define NSCLEVTREADER_H + +#include /// for FILE +#include +#include +#include +#include + +#include "TString.h" +#include "TBenchmark.h" + +#include "../armory/DataBlock.h" + +#define MAX_CRATES 2 +#define MAX_BOARDS_PER_CRATE 13 +#define MAX_CHANNELS_PER_BOARD 16 +#define BOARD_START 2 + +class NSCLEvtReader{ + + public: + DataBlock * data; + + private: + FILE * inFile; + + long int inFileSize; + long int inFilePos; /// in byte = 8 bits + bool endOfFile; + bool isOpened; + Long64_t blockID; + long int nBlock; + + TBenchmark gClock; + + unsigned int extraHeader[14]; + unsigned int traceBlock[MAX_TRACE_LENGHT/2]; + + ///==================================== Methods + public: + + NSCLEvtReader(); + NSCLEvtReader(TString inFileName); + ~NSCLEvtReader(); + + void OpenFile(TString inFileName); + void CloseFile(); + int ReadBlock(); + +}; + + +NSCLEvtReader::NSCLEvtReader(){ + inFile = 0; + data = 0; + + inFileSize = 0; + inFilePos = 0; + endOfFile = false; + isOpened = false; + + blockID = -1; + nBlock = 0; +}; + +NSCLEvtReader::NSCLEvtReader(TString inFileName){ + + inFileSize = 0; + inFilePos = 0; + endOfFile = false; + isOpened = false; + + blockID = -1; + nBlock = 0; + + OpenFile(inFileName); + +} + +NSCLEvtReader::~NSCLEvtReader(){ + + delete inFile; + delete data; +}; + +void NSCLEvtReader::OpenFile(TString inFileName){ + + inFile = fopen(inFileName, "r"); + + if( inFile == NULL ){ + printf("Cannot read file : %s \n", inFileName.Data()); + }else{ + fseek(inFile, 0L, SEEK_END); + inFileSize = ftell(inFile); + rewind(inFile); ///back to the File begining + + data = new DataBlock(); + data->Clear(); + + gClock.Reset(); + gClock.Start("timer"); + + isOpened = true; + } + +}; + +void NSCLEvtReader::CloseFile(){ + fclose(inFile); + isOpened = false; + data->Clear(); + inFileSize = 0; + inFilePos = 0; + nBlock = 0; + blockID = -1; + endOfFile = false; +}; + + +int NSCLEvtReader::ReadBlock(){ + + if( feof(inFile) ) return -1; + if( endOfFile ) return -1; + + //============= Ring item header, [0] = size, [1] = type + unsigned int rih[2]= {0}; + do{ + if ( fread(rih, sizeof(rih), 1, inFile) != 1 ) { + endOfFile = true; + return -1; + } + inFilePos = ftell(inFile); + ///printf("%ld-------- Ring Item Header| size : %d, type : %d \n", inFilePos, rih[0], rih[1]); + + ///if the type is not 30, skip + if( rih[1] != 30 ) { + fseek(inFile, rih[0]-8, SEEK_CUR); + inFilePos = ftell(inFile); + ///printf("%ld---- skip %d bytes\n", inFilePos, rih[0]-8); + } + }while(rih[1] != 30); + + //=========== Ring item body header, [0] = size, [1] timestamp-low, [2] timestamp-high, [3] source ID, [4] = barrier type + unsigned int ribh[5]={0}; + if ( fread(ribh, sizeof(ribh), 1, inFile) != 1 ) { + endOfFile = true; + return -1; + } + inFilePos = ftell(inFile); + unsigned long long timestamp = ((unsigned long long)ribh[2] << 32) + ribh[1]; + ///printf("%ld - Ring Item Body Header| size : %d, timestamp : %llu \n", inFilePos, ribh[0], timestamp); + + //================================== Ring item body + unsigned int rib_size[1] = {0}; + if ( fread(rib_size, sizeof(rib_size), 1, inFile) != 1 ) { + endOfFile = true; + return -1; + } + inFilePos = ftell(inFile); + ///printf("%ld - Size of Ring Item Body : %d \n", inFilePos, rib_size[0]); + + unsigned int readRingItemByte = 4; + + while( rib_size[0] > 48 && readRingItemByte < rib_size[0] ){ /// Ring Item Body size must be > 48 byte, so that + + ///skip to raw data + fseek(inFile, 14*4, SEEK_CUR); + inFilePos = ftell(inFile); + readRingItemByte += 14 * 4; + + /** + unsigned int fh[5] = {0}; /// fragment header + if ( fread(fh, sizeof(fh), 1, inFile) != 1 ) { + endOfFile = true; + return -1; + } + inFilePos = ftell(inFile); + readRingItemByte += sizeof(fh); + timestamp = ((unsigned long long)fh[1] << 32) + fh[0]; + ///printf("%ld - Fragment Header | payload size : %d, timestamp : %llu\n", inFilePos, fh[3], timestamp); + + unsigned int fp[9] = {0}; /// fragment payload + if ( fread(fp, sizeof(fp), 1, inFile) != 1 ) { + endOfFile = true; + return -1; + } + inFilePos = ftell(inFile); + readRingItemByte += sizeof(fp); + timestamp = ((unsigned long long)fp[4] << 32) + fp[3]; + ///printf("%ld ------ Fragment Payload \n", inFilePos); + ///printf(" header size : %d \n", fp[0]); + ///printf(" type : %d \n", fp[1]); + ///printf(" Body Header size : %d \n", fp[2]); + ///printf(" timestamp : %llu \n", timestamp); + ///printf(" source id : %d \n", fp[5]); + ///printf(" barrier type : %d \n", fp[6]); + ///printf(" Body size : %d \n", fp[7]); + ///printf(" Deivce Info : %d \n", fp[8]); + */ + + ///================== Raw Data Pixie + + unsigned int header[4]; + if ( fread(header, sizeof(header), 1, inFile) != 1 ) { + endOfFile = true; + return -1; + } + inFilePos = ftell(inFile); + readRingItemByte += sizeof(header); + blockID ++; + + data->eventID = blockID; + data->ch = header[0] & 0xF ; + data->slot = (header[0] >> 4) & 0xF; + data->crate = (header[0] >> 8) & 0xF; + data->headerLength = (header[0] >> 12) & 0x1F; + data->eventLength = (header[0] >> 17) & 0x3FFF; + data->pileup = header[0] >> 31 ; + data->time = ((ULong64_t)(header[2] & 0xFFFF) << 32) + header[1]; + data->cfd_forced = header[2] >> 16 & 0x8000; + data->cfd_source = header[2] >> 16 & 0x4000; + data->cfd = header[2] >> 16 & 0x3FFF; // 0x3FFF for 250MHz , 0x7FFF for 100MHz + data->energy = (header[3] & 0xFFFF ); + data->trace_length = (header[3] >> 16) & 0x7FFF; + data->trace_out_of_range = header[3] >> 31; + + data->ClearQDC(); + data->ClearTrace(); + + ///======== read QDCsum + if( data->headerLength >= 4 ){ + fread(extraHeader, sizeof(unsigned int) * (data->headerLength-4), 1, inFile); + inFilePos = ftell(inFile); + readRingItemByte += (data->headerLength-4)*4; + + if( data->headerLength == 8 || data->headerLength == 16){ + data->trailing = extraHeader[0]; + data->leading = extraHeader[1]; + data->gap = extraHeader[2]; + data->baseline = extraHeader[3]; + } + if( data->headerLength == 12 || data->headerLength == 16){ + for( int i = 0; i < 8; i++){ + int startID = 0; + if( data->headerLength > 12) startID = 4; ///the 1st 4 words + data->QDCsum[i] = extraHeader[i+startID]; + } + } + }else{ + for( int i = 0 ; i < 8; i++){ data->QDCsum[i] = 0;} + data->trailing = 0; + data->leading = 0; + data->gap = 0; + data->baseline = 0; + } + + ///====== read trace + if( data->eventLength > data->headerLength ){ + fread(traceBlock, sizeof(unsigned int) * ( data->trace_length / 2 ), 1, inFile); + inFilePos = ftell(inFile); + readRingItemByte += data->trace_length / 2 * 4; + for( int i = 0; i < data->trace_length/2 ; i++){ + data->trace[2*i+0] = traceBlock[i] & 0xFFFF ; + data->trace[2*i+1] = (traceBlock[i] >> 16 ) & 0xFFFF ; + } + } + + ///printf("%ld--------- ring item body size : %d, readed size : %d \n",inFilePos, rib_size[0], readRingItemByte); + } + + ///if( rib_size[0] == readRingItemByte ) printf("=======================================\n"); + + return 1; + +}; + +#endif diff --git a/script.C b/script.C index 9216510..99743b8 100644 --- a/script.C +++ b/script.C @@ -1,4 +1,10 @@ -{ +#include "armory/evtReader.h" + +evtReader * evt = new evtReader("run-0238-00.evt", true); + +void script() { + + /* TChain * chain = new TChain("tree"); chain->Add("root_data/run-0238-[0-4][0-9].root"); @@ -6,5 +12,12 @@ chain->GetListOfFiles()->Print(); chain->Process("peachCake.C+"); + */ + + + //gROOT->ProcessLine("armory/nsclEvtReader.h"); + + + evt->ReadBlock(2); }