#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