2024-01-19 03:11:50 -05:00
|
|
|
#include "../Hit.h"
|
|
|
|
#include "../macro.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string>
|
|
|
|
#include <sstream>
|
|
|
|
#include <cmath>
|
|
|
|
#include <cstring> ///memset
|
|
|
|
#include <iostream> ///cout
|
|
|
|
#include <sstream>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <bitset>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
class FSUTSReader{
|
|
|
|
|
|
|
|
public:
|
|
|
|
FSUTSReader();
|
2024-01-19 19:45:41 -05:00
|
|
|
FSUTSReader(std::string fileName, int verbose = 1);
|
2024-01-19 03:11:50 -05:00
|
|
|
~FSUTSReader();
|
|
|
|
|
2024-01-19 19:45:41 -05:00
|
|
|
void OpenFile(std::string fileName, int verbose = 1);
|
2024-01-19 03:11:50 -05:00
|
|
|
bool isOpen() const{return inFile == nullptr ? false : true;}
|
|
|
|
|
2024-01-19 19:45:41 -05:00
|
|
|
void ScanFile(int verbose = 1);
|
2024-01-19 19:24:51 -05:00
|
|
|
int ReadNextHit(bool withTrace = true, int verbose = 0);
|
|
|
|
int ReadHitAt(unsigned int ID, bool withTrace = true, int verbose = 0);
|
2024-01-19 03:11:50 -05:00
|
|
|
|
2024-01-19 19:45:41 -05:00
|
|
|
unsigned int GetHitID() const {return hitIndex;}
|
2024-01-20 01:01:10 -05:00
|
|
|
unsigned long GetNumHit() const {return hitCount;}
|
2024-01-25 18:34:58 -05:00
|
|
|
unsigned long GetNumHitFromHeader() const {return hitCount0;}
|
2024-01-19 03:11:50 -05:00
|
|
|
|
2024-01-19 19:45:41 -05:00
|
|
|
std::string GetFileName() const {return fileName;}
|
2024-01-19 03:11:50 -05:00
|
|
|
unsigned long GetFileByteSize() const {return inFileSize;}
|
2024-01-22 13:56:18 -05:00
|
|
|
unsigned int GetFilePos() const {return filePos;}
|
2024-01-19 19:45:41 -05:00
|
|
|
int GetFileOrder() const {return order;}
|
|
|
|
uShort GetSN() const {return sn;}
|
|
|
|
ullong GetT0() const {return t0;}
|
|
|
|
|
2024-01-19 19:24:51 -05:00
|
|
|
Hit* GetHit() const{return hit;}
|
|
|
|
|
2024-01-19 03:11:50 -05:00
|
|
|
private:
|
|
|
|
|
|
|
|
FILE * inFile;
|
|
|
|
|
|
|
|
std::string fileName;
|
|
|
|
unsigned long inFileSize;
|
|
|
|
unsigned int filePos;
|
2024-01-20 01:01:10 -05:00
|
|
|
unsigned long hitCount;
|
2024-01-25 18:34:58 -05:00
|
|
|
unsigned long hitCount0; // hit count from file
|
2024-01-19 03:11:50 -05:00
|
|
|
|
2024-01-19 19:45:41 -05:00
|
|
|
uShort sn;
|
|
|
|
int order;
|
2024-01-19 03:11:50 -05:00
|
|
|
|
2024-01-19 19:24:51 -05:00
|
|
|
Hit* hit;
|
|
|
|
unsigned int hitIndex;
|
|
|
|
std::vector<unsigned int> hitStartPos;
|
2024-01-19 03:11:50 -05:00
|
|
|
|
2024-01-19 19:45:41 -05:00
|
|
|
unsigned long long t0;
|
|
|
|
|
2024-01-19 03:11:50 -05:00
|
|
|
uint32_t header;
|
|
|
|
size_t dummy;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
inline FSUTSReader::~FSUTSReader(){
|
|
|
|
|
|
|
|
fclose(inFile);
|
|
|
|
|
2024-01-19 19:24:51 -05:00
|
|
|
delete hit;
|
|
|
|
|
2024-01-19 03:11:50 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
inline FSUTSReader::FSUTSReader(){
|
|
|
|
inFile = nullptr;
|
|
|
|
|
2024-01-19 19:24:51 -05:00
|
|
|
hitStartPos.clear();
|
|
|
|
hit = nullptr;
|
2024-01-19 03:11:50 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
inline FSUTSReader::FSUTSReader(std::string fileName, int verbose){
|
|
|
|
OpenFile(fileName, verbose);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void FSUTSReader::OpenFile(std::string fileName, int verbose){
|
|
|
|
|
|
|
|
inFile = fopen(fileName.c_str(), "r");
|
|
|
|
|
|
|
|
if( inFile == NULL ){
|
|
|
|
printf("FSUTSReader::Cannot open file : %s \n", fileName.c_str());
|
|
|
|
this->fileName = "";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this->fileName = fileName;
|
|
|
|
|
2024-01-19 19:45:41 -05:00
|
|
|
std::string fileNameNoExt;
|
|
|
|
size_t found = fileName.find_last_of(".fsu.ts");
|
|
|
|
size_t found2 = fileName.find_last_of('/');
|
|
|
|
if( found2 == std::string::npos ){
|
|
|
|
fileNameNoExt = fileName.substr(0, found-7);
|
|
|
|
}else{
|
|
|
|
fileNameNoExt = fileName.substr(found2+1, found-7);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Split the string by underscores
|
|
|
|
std::istringstream iss(fileNameNoExt);
|
|
|
|
std::vector<std::string> tokens;
|
|
|
|
std::string token;
|
|
|
|
|
|
|
|
while (std::getline(iss, token, '_')) { tokens.push_back(token); }
|
|
|
|
sn = atoi(tokens[2].c_str());
|
|
|
|
order = atoi(tokens[5].c_str());
|
|
|
|
|
2024-01-19 03:11:50 -05:00
|
|
|
fseek(inFile, 0L, SEEK_END);
|
|
|
|
inFileSize = ftell(inFile);
|
2024-01-22 13:56:18 -05:00
|
|
|
if(verbose) printf("###### %50s | %11ld Byte = %.2f MB\n", fileName.c_str() , inFileSize, inFileSize/1024./1024.);
|
2024-01-19 03:11:50 -05:00
|
|
|
fseek(inFile, 0L, SEEK_SET);
|
|
|
|
filePos = 0;
|
|
|
|
|
2024-01-20 01:01:10 -05:00
|
|
|
hitCount = 0;
|
2024-01-19 19:24:51 -05:00
|
|
|
hitIndex = -1;
|
|
|
|
hitStartPos.clear();
|
|
|
|
hit = new Hit();
|
|
|
|
hit->Clear();
|
2024-01-19 03:11:50 -05:00
|
|
|
|
|
|
|
//check is the file is .ts file by checking the 1st 4 byte
|
|
|
|
|
|
|
|
dummy = fread(&header, 4, 1, inFile);
|
2024-01-19 19:24:51 -05:00
|
|
|
printf(" header : 0x%8X.", header);
|
2024-01-19 03:11:50 -05:00
|
|
|
if( (header >> 24) != 0xAA ){
|
|
|
|
printf(" This is not a time-sorted fsu (*.fsu.ts) file. Abort.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
sn = (header & 0xFFFFFF);
|
2024-01-19 19:24:51 -05:00
|
|
|
hit->sn = sn;
|
2024-01-25 18:34:58 -05:00
|
|
|
printf(" S/N : %u, ", sn);
|
|
|
|
|
|
|
|
dummy = fread(&hitCount0, 8, 1, inFile);
|
|
|
|
printf(" hitCount : %lu \n", hitCount0);
|
2024-01-19 03:11:50 -05:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2024-01-19 19:24:51 -05:00
|
|
|
inline int FSUTSReader::ReadNextHit(bool withTrace, int verbose){
|
2024-01-19 03:11:50 -05:00
|
|
|
if( inFile == NULL ) return -1;
|
|
|
|
if( feof(inFile) ) return -1;
|
|
|
|
if( filePos >= inFileSize) return -1;
|
|
|
|
|
2024-01-19 19:24:51 -05:00
|
|
|
hitIndex ++;
|
|
|
|
|
2024-03-02 00:33:08 -05:00
|
|
|
hit->sn = sn;
|
|
|
|
|
|
|
|
uint16_t temp = 0;
|
|
|
|
dummy = fread(&temp, 2, 1, inFile); // [0:7] ch [8] pileUp [14] hasTrace [15] hasEnergy2
|
|
|
|
|
|
|
|
hit->ch = (temp & 0xFF);
|
|
|
|
hit->pileUp = ((temp>>8) & 0x1);
|
|
|
|
bool hasEnergy2 = ((temp>>15) & 0x1);
|
|
|
|
bool hasTrace = ((temp>>14) & 0x1);
|
|
|
|
|
2024-01-19 19:24:51 -05:00
|
|
|
dummy = fread(&(hit->energy), 2, 1, inFile);
|
2024-03-02 00:33:08 -05:00
|
|
|
if( hasEnergy2 ) dummy = fread(&(hit->energy2), 2, 1, inFile);
|
|
|
|
dummy = fread(&(hit->timestamp), 6, 1, inFile);
|
2024-01-19 19:24:51 -05:00
|
|
|
dummy = fread(&(hit->fineTime), 2, 1, inFile);
|
2024-03-02 00:33:08 -05:00
|
|
|
if( hasTrace ) {
|
|
|
|
dummy = fread(&(hit->traceLength), 2, 1, inFile);
|
|
|
|
if( hit->trace.size() > 0 ) hit->trace.clear();
|
|
|
|
}
|
2024-01-19 19:24:51 -05:00
|
|
|
|
|
|
|
if( withTrace && hit->traceLength > 0 ){
|
|
|
|
for(uShort j = 0; j < hit->traceLength; j++){
|
2024-01-19 03:11:50 -05:00
|
|
|
short temp;
|
|
|
|
fread( &temp, 2, 1, inFile);
|
2024-01-19 19:24:51 -05:00
|
|
|
hit->trace.push_back(temp);
|
2024-01-19 03:11:50 -05:00
|
|
|
}
|
2024-01-19 19:24:51 -05:00
|
|
|
}else{
|
|
|
|
unsigned int jumpByte = hit->traceLength * 2;
|
|
|
|
fseek(inFile, jumpByte, SEEK_CUR);
|
|
|
|
hit->traceLength = 0;
|
2024-01-19 03:11:50 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
filePos = ftell(inFile);
|
|
|
|
|
2024-01-19 19:24:51 -05:00
|
|
|
// if(verbose) printf("Block index: %u, current file Pos: %u byte \n", hitIndex, filePos);
|
|
|
|
|
|
|
|
if(verbose >= 2) hit->Print();
|
|
|
|
if(verbose >= 3) hit->PrintTrace();
|
2024-01-19 03:11:50 -05:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2024-01-19 19:24:51 -05:00
|
|
|
inline int FSUTSReader::ReadHitAt(unsigned int ID, bool withTrace, int verbose){
|
2024-01-20 01:01:10 -05:00
|
|
|
if( hitCount == 0 ) return -1;
|
|
|
|
if( ID >= hitCount ) return -1;
|
2024-01-19 03:11:50 -05:00
|
|
|
|
2024-01-19 19:24:51 -05:00
|
|
|
fseek(inFile, 0L, SEEK_SET);
|
2024-01-19 03:11:50 -05:00
|
|
|
|
2024-01-19 19:24:51 -05:00
|
|
|
if( verbose ) printf("Block index: %u, File Pos: %u byte\n", ID, hitStartPos[ID]);
|
2024-01-19 03:11:50 -05:00
|
|
|
|
2024-01-19 19:24:51 -05:00
|
|
|
fseek(inFile, hitStartPos[ID], SEEK_CUR);
|
|
|
|
filePos = hitStartPos[ID];
|
|
|
|
hitIndex = ID - 1;
|
|
|
|
return ReadNextHit(withTrace, verbose);
|
2024-01-19 03:11:50 -05:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void FSUTSReader::ScanFile(int verbose){
|
|
|
|
if( feof(inFile) ) return;
|
|
|
|
|
2024-01-19 19:24:51 -05:00
|
|
|
hitStartPos.clear();
|
2024-01-19 03:11:50 -05:00
|
|
|
fseek(inFile, 0L, SEEK_SET);
|
|
|
|
dummy = fread(&header, 4, 1, inFile);
|
2024-01-25 18:34:58 -05:00
|
|
|
dummy = fread(&hitCount0, 8, 1, inFile);
|
2024-01-19 03:11:50 -05:00
|
|
|
filePos = ftell(inFile);
|
2024-01-19 19:24:51 -05:00
|
|
|
hitStartPos.push_back(filePos);
|
|
|
|
hitIndex = -1;
|
|
|
|
|
|
|
|
while( ReadNextHit(false, verbose-1) == 0 ){ // no trace
|
|
|
|
hitStartPos.push_back(filePos);
|
|
|
|
|
2024-01-19 19:45:41 -05:00
|
|
|
if( hitIndex == 0 ) t0 = hit->timestamp;
|
|
|
|
|
2024-01-19 19:24:51 -05:00
|
|
|
if(verbose > 1 ) printf("hitIndex : %u, Pos : %u - %u\n" , hitIndex, hitStartPos[hitIndex], hitStartPos[hitIndex+1]);
|
2024-01-19 03:11:50 -05:00
|
|
|
|
2024-01-25 18:34:58 -05:00
|
|
|
if(verbose && hitIndex%10000 == 0 ) printf(" %u, %.2f%% %u/%lu byte \n\033[A\r", hitIndex, filePos*100./inFileSize, filePos, inFileSize);
|
2024-01-19 03:11:50 -05:00
|
|
|
}
|
|
|
|
|
2024-01-20 01:01:10 -05:00
|
|
|
hitCount = hitIndex + 1;
|
2024-01-25 18:34:58 -05:00
|
|
|
if(verbose) {
|
|
|
|
printf("\n-----> Scan complete\n");
|
|
|
|
printf(" number of hit : %lu\n", hitCount);
|
|
|
|
printf(" first timestamp : %16llu\n", t0);
|
|
|
|
printf(" last timestamp : %16llu\n", hit->timestamp);
|
|
|
|
double dt = (hit->timestamp - t0)*1e-9;
|
|
|
|
printf(" duration : %.2f sec = %.2f min\n", dt, dt/60.);
|
|
|
|
}
|
2024-01-19 03:11:50 -05:00
|
|
|
|
2024-01-25 18:34:58 -05:00
|
|
|
fseek(inFile, 0L, SEEK_SET);
|
|
|
|
fseek(inFile, hitStartPos[0], SEEK_CUR);
|
|
|
|
filePos = hitStartPos[0];
|
|
|
|
hitIndex = -1;
|
2024-01-19 03:11:50 -05:00
|
|
|
}
|