#ifndef SOLREADER_H #define SOLREADER_H #include /// for FILE #include #include #include #include #include // time in nano-sec #include "Event.h" // this is a symblic link to SOLARIS_QT6_DAQ/Event.h #define tick2ns 8 // 1 tick = 8 ns class SolReader { private: FILE * inFile; unsigned int inFileSize; unsigned int filePos; unsigned int totNumBlock; unsigned short blockStartIdentifier; unsigned int numBlock; bool isScanned; void init(); std::vector blockPos; public: SolReader(); SolReader(std::string fileName, unsigned short dataType = 0); // dataType can auto determine from the data, but remove it will crash.... ~SolReader(); void OpenFile(std::string fileName); int ReadNextBlock(int isSkip = 0); // opt = 0, noraml, 1, fast int ReadBlock(unsigned int index, bool verbose = false); void ScanNumBlock(); unsigned int GetNumBlock() {return numBlock;} unsigned int GetTotalNumBlock() {return totNumBlock;} unsigned int GetFilePos() {return filePos;} unsigned int GetFileSize() {return inFileSize;} void RewindFile(); Event * evt; }; void SolReader::init(){ inFileSize = 0; numBlock = 0; filePos = 0; totNumBlock = 0; evt = new Event(); isScanned = false; blockPos.clear(); } SolReader::SolReader(){ init(); } SolReader::SolReader(std::string fileName, unsigned short dataType){ init(); OpenFile(fileName); evt->SetDataType(dataType); } SolReader::~SolReader(){ if( !inFile ) fclose(inFile); delete evt; } inline void SolReader::OpenFile(std::string fileName){ inFile = fopen(fileName.c_str(), "r"); if( inFile == NULL ){ printf("Cannot open file : %s \n", fileName.c_str()); }else{ fseek(inFile, 0L, SEEK_END); inFileSize = ftell(inFile); rewind(inFile); } } inline int SolReader::ReadBlock(unsigned int index, bool verbose){ if( isScanned == false) return -1; if( index >= totNumBlock )return -1; fseek(inFile, 0L, SEEK_SET); if( verbose ) printf("Block index: %u, File Pos: %u byte\n", index, blockPos[index]); fseek(inFile, blockPos[index], SEEK_CUR); numBlock = index; return ReadNextBlock(); } inline int SolReader::ReadNextBlock(int isSkip){ if( inFile == NULL ) return -1; if( feof(inFile) ) return -1; if( filePos >= inFileSize) return -1; fread(&blockStartIdentifier, 2, 1, inFile); if( (blockStartIdentifier & 0xAAA0) != 0xAAA0 ) { printf("header fail.\n"); return -2 ; } if( ( blockStartIdentifier & 0xF ) == 15 ){ evt->SetDataType(15); } evt->dataType = blockStartIdentifier & 0xF; if( evt->dataType == 0){ //======== same as the dataFormat in Digitizer if( isSkip == 0 ){ fread(&evt->channel, 1, 1, inFile); fread(&evt->energy, 2, 1, inFile); fread(&evt->timestamp, 6, 1, inFile); fread(&evt->fine_timestamp, 2, 1, inFile); fread(&evt->flags_high_priority, 1, 1, inFile); fread(&evt->flags_low_priority, 2, 1, inFile); fread(&evt->downSampling, 1, 1, inFile); fread(&evt->board_fail, 1, 1, inFile); fread(&evt->flush, 1, 1, inFile); fread(&evt->trigger_threashold, 2, 1, inFile); fread(&evt->event_size, 8, 1, inFile); fread(&evt->aggCounter, 4, 1, inFile); }else{ fseek(inFile, 31, SEEK_CUR); } fread(&evt->traceLenght, 8, 1, inFile); if( isSkip == 0){ fread(evt->analog_probes_type, 2, 1, inFile); fread(evt->digital_probes_type, 4, 1, inFile); fread(evt->analog_probes[0], evt->traceLenght*4, 1, inFile); fread(evt->analog_probes[1], evt->traceLenght*4, 1, inFile); fread(evt->digital_probes[0], evt->traceLenght, 1, inFile); fread(evt->digital_probes[1], evt->traceLenght, 1, inFile); fread(evt->digital_probes[2], evt->traceLenght, 1, inFile); fread(evt->digital_probes[3], evt->traceLenght, 1, inFile); }else{ fseek(inFile, 6 + evt->traceLenght*(12), SEEK_CUR); } }else if( evt->dataType == 1){ if( isSkip == 0 ){ fread(&evt->channel, 1, 1, inFile); fread(&evt->energy, 2, 1, inFile); fread(&evt->timestamp, 6, 1, inFile); fread(&evt->fine_timestamp, 2, 1, inFile); fread(&evt->flags_high_priority, 1, 1, inFile); fread(&evt->flags_low_priority, 2, 1, inFile); }else{ fseek(inFile, 14, SEEK_CUR); } fread(&evt->traceLenght, 8, 1, inFile); if( isSkip == 0){ fread(&evt->analog_probes_type[0], 1, 1, inFile); fread(evt->analog_probes[0], evt->traceLenght*4, 1, inFile); }else{ fseek(inFile, 1 + evt->traceLenght*4, SEEK_CUR); } }else if( evt->dataType == 2){ if( isSkip == 0 ){ fread(&evt->channel, 1, 1, inFile); fread(&evt->energy, 2, 1, inFile); fread(&evt->timestamp, 6, 1, inFile); fread(&evt->fine_timestamp, 2, 1, inFile); fread(&evt->flags_high_priority, 1, 1, inFile); fread(&evt->flags_low_priority, 2, 1, inFile); }else{ fseek(inFile, 14, SEEK_CUR); } }else if( evt->dataType == 3){ if( isSkip == 0 ){ fread(&evt->channel, 1, 1, inFile); fread(&evt->energy, 2, 1, inFile); fread(&evt->timestamp, 6, 1, inFile); }else{ fseek(inFile, 9, SEEK_CUR); } }else if( evt->dataType == 15){ fread(&evt->dataSize, 8, 1, inFile); if( isSkip == 0){ fread(evt->data, evt->dataSize, 1, inFile); }else{ fseek(inFile, evt->dataSize, SEEK_CUR); } } numBlock ++; filePos = ftell(inFile); return 0; } void SolReader::RewindFile(){ rewind(inFile); filePos = 0; numBlock = 0; } void SolReader::ScanNumBlock(){ if( inFile == NULL ) return; if( feof(inFile) ) return; numBlock = 0; blockPos.clear(); blockPos.push_back(0); while( ReadNextBlock(1) == 0){ blockPos.push_back(filePos); printf("%u, %.2f%% %u/%u\n\033[A\r", numBlock, filePos*100./inFileSize, filePos, inFileSize); } totNumBlock = numBlock; numBlock = 0; isScanned = true; printf("\nScan complete: number of data Block : %u\n", totNumBlock); rewind(inFile); filePos = 0; //for( int i = 0; i < totNumBlock; i++){ // printf("%7d | %u \n", i, blockPos[i]); //} } #endif