2023-12-08 17:03:52 -05:00
|
|
|
#include "../ClassData.h"
|
2024-01-12 19:12:37 -05:00
|
|
|
#include "../Hit.h"
|
|
|
|
#include <algorithm>
|
2024-01-19 03:11:10 -05:00
|
|
|
#include <filesystem>
|
2023-10-13 18:02:19 -04:00
|
|
|
|
|
|
|
class FSUReader{
|
|
|
|
|
|
|
|
public:
|
2024-01-12 19:12:37 -05:00
|
|
|
FSUReader();
|
2024-01-19 03:11:10 -05:00
|
|
|
FSUReader(std::string fileName, uShort dataSize = 100, int verbose = 1);
|
2023-10-13 18:02:19 -04:00
|
|
|
~FSUReader();
|
|
|
|
|
2024-01-19 03:11:10 -05:00
|
|
|
void OpenFile(std::string fileName, uShort dataSize, int verbose = 1);
|
2024-01-18 18:55:37 -05:00
|
|
|
bool isOpen() const{return inFile == nullptr ? false : true;}
|
2024-01-12 19:12:37 -05:00
|
|
|
|
2024-01-19 03:11:10 -05:00
|
|
|
void ScanNumBlock(int verbose = 1, uShort saveData = 0);
|
2024-01-20 01:01:10 -05:00
|
|
|
int ReadNextBlock(bool traceON = false, int verbose = 0, uShort saveData = 0); // saveData = 0 (no save), 1 (no trace), 2 (with trace);
|
2023-10-13 18:02:19 -04:00
|
|
|
int ReadBlock(unsigned int ID, int verbose = 0);
|
|
|
|
|
|
|
|
unsigned long GetTotNumBlock() const{ return totNumBlock;}
|
2024-01-18 18:55:37 -05:00
|
|
|
std::vector<unsigned int> GetBlockTimestamp() const {return blockTimeStamp;}
|
2023-10-13 18:02:19 -04:00
|
|
|
|
|
|
|
Data * GetData() const{return data;}
|
|
|
|
|
2024-01-12 19:12:37 -05:00
|
|
|
std::string GetFileName() const{return fileName;}
|
2024-01-11 11:52:40 -05:00
|
|
|
int GetDPPType() const{return DPPType;}
|
|
|
|
int GetSN() const{return sn;}
|
|
|
|
int GetTick2ns() const{return tick2ns;}
|
|
|
|
int GetNumCh() const{return numCh;}
|
|
|
|
int GetFileOrder() const{return order;}
|
2024-01-18 18:55:37 -05:00
|
|
|
int GetChMask() const{return chMask;}
|
2024-01-10 18:29:15 -05:00
|
|
|
unsigned long GetFileByteSize() const {return inFileSize;}
|
|
|
|
|
2024-01-18 23:09:50 -05:00
|
|
|
void ClearHitList() { hit.clear();}
|
2024-01-20 01:01:10 -05:00
|
|
|
Hit GetHit(unsigned int id) const {return hit[id];}
|
2024-01-18 23:09:50 -05:00
|
|
|
ulong GetHitListLength() const {return hit.size();}
|
|
|
|
|
2024-01-20 01:01:10 -05:00
|
|
|
void ClearHitCount() {hitCount = 0;}
|
|
|
|
ulong GetHitCount() const{return hitCount;}
|
2024-01-16 15:39:41 -05:00
|
|
|
std::vector<Hit> GetHitVector() const {return hit;}
|
2024-01-19 03:11:10 -05:00
|
|
|
void SortHit(int verbose = false);
|
|
|
|
|
|
|
|
std::string SaveHit2NewFile(std::string saveFolder = "./");
|
2024-01-19 19:24:51 -05:00
|
|
|
off_t GetTSFileSize() const {return tsFileSize;}
|
2024-01-12 16:59:55 -05:00
|
|
|
|
2024-01-20 01:01:10 -05:00
|
|
|
void PrintHit(ulong numHit = -1, ulong startIndex = 0) {
|
|
|
|
for( ulong i = startIndex; i < std::min(numHit, hitCount); i++){
|
|
|
|
printf("%10zu ", i); hit[i].Print();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-13 18:02:19 -04:00
|
|
|
private:
|
|
|
|
|
|
|
|
FILE * inFile;
|
|
|
|
Data * data;
|
|
|
|
|
2024-01-12 19:12:37 -05:00
|
|
|
std::string fileName;
|
2023-10-13 18:02:19 -04:00
|
|
|
unsigned long inFileSize;
|
|
|
|
unsigned int filePos;
|
|
|
|
unsigned long totNumBlock;
|
|
|
|
unsigned int blockID;
|
|
|
|
|
2024-01-18 18:55:37 -05:00
|
|
|
bool isDualBlock;
|
|
|
|
|
2024-01-11 11:52:40 -05:00
|
|
|
int sn;
|
2023-12-12 15:35:47 -05:00
|
|
|
int DPPType;
|
2024-01-11 11:52:40 -05:00
|
|
|
int tick2ns;
|
|
|
|
int order;
|
2023-12-12 15:35:47 -05:00
|
|
|
int chMask;
|
2024-01-19 03:11:10 -05:00
|
|
|
uShort numCh;
|
2023-12-12 15:35:47 -05:00
|
|
|
|
2023-10-13 18:02:19 -04:00
|
|
|
std::vector<unsigned int> blockPos;
|
2024-01-12 16:59:55 -05:00
|
|
|
std::vector<unsigned int > blockTimeStamp;
|
|
|
|
|
2024-01-20 01:01:10 -05:00
|
|
|
unsigned long hitCount;
|
2024-01-12 16:59:55 -05:00
|
|
|
|
2024-01-12 19:12:37 -05:00
|
|
|
std::vector<Hit> hit;
|
2023-10-13 18:02:19 -04:00
|
|
|
|
|
|
|
unsigned int word[1]; /// 4 byte
|
|
|
|
size_t dummy;
|
|
|
|
char * buffer;
|
|
|
|
|
2024-01-19 19:24:51 -05:00
|
|
|
off_t tsFileSize;
|
|
|
|
|
2023-10-13 18:02:19 -04:00
|
|
|
};
|
|
|
|
|
2024-01-18 18:55:37 -05:00
|
|
|
inline FSUReader::~FSUReader(){
|
|
|
|
delete data;
|
|
|
|
|
|
|
|
fclose(inFile);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2024-01-12 19:12:37 -05:00
|
|
|
inline FSUReader::FSUReader(){
|
|
|
|
inFile = nullptr;
|
|
|
|
data = nullptr;
|
|
|
|
|
|
|
|
blockPos.clear();
|
|
|
|
blockTimeStamp.clear();
|
|
|
|
hit.clear();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2024-01-19 03:11:10 -05:00
|
|
|
inline FSUReader::FSUReader(std::string fileName, uShort dataSize, int verbose){
|
2024-01-18 23:09:50 -05:00
|
|
|
OpenFile(fileName, dataSize, verbose);
|
2024-01-12 19:12:37 -05:00
|
|
|
}
|
|
|
|
|
2024-01-19 03:11:10 -05:00
|
|
|
inline void FSUReader::OpenFile(std::string fileName, uShort dataSize, int verbose){
|
2023-10-13 18:02:19 -04:00
|
|
|
|
2024-01-22 13:56:18 -05:00
|
|
|
/// File format must be YYY...Y_runXXX_AAA_BBB_TT_CCC.fsu
|
|
|
|
/// YYY...Y = prefix
|
|
|
|
/// XXX = runID, 3 digits
|
|
|
|
/// AAA = board Serial Number, 3 digits
|
|
|
|
/// BBB = DPPtype, 3 digits
|
|
|
|
/// TT = tick2ns, any digits
|
|
|
|
/// CCC = over size index, 3 digits
|
|
|
|
|
2023-10-13 18:02:19 -04:00
|
|
|
inFile = fopen(fileName.c_str(), "r");
|
|
|
|
|
|
|
|
if( inFile == NULL ){
|
2024-01-18 18:55:37 -05:00
|
|
|
printf("FSUReader::Cannot open file : %s \n", fileName.c_str());
|
2024-01-12 19:12:37 -05:00
|
|
|
this->fileName = "";
|
2023-10-13 18:02:19 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-01-12 19:12:37 -05:00
|
|
|
this->fileName = fileName;
|
|
|
|
|
2023-10-13 18:02:19 -04:00
|
|
|
fseek(inFile, 0L, SEEK_END);
|
|
|
|
inFileSize = ftell(inFile);
|
2024-01-10 18:29:15 -05:00
|
|
|
if(verbose) printf("%s | file size : %ld Byte = %.2f MB\n", fileName.c_str() , inFileSize, inFileSize/1024./1024.);
|
2023-10-13 18:02:19 -04:00
|
|
|
fseek(inFile, 0L, SEEK_SET);
|
|
|
|
filePos = 0;
|
|
|
|
|
|
|
|
totNumBlock = 0;
|
|
|
|
blockID = 0;
|
|
|
|
blockPos.clear();
|
2024-01-12 16:59:55 -05:00
|
|
|
blockTimeStamp.clear();
|
|
|
|
|
2024-01-20 01:01:10 -05:00
|
|
|
hitCount = 0;
|
2024-01-12 19:12:37 -05:00
|
|
|
hit.clear();
|
2023-12-12 15:35:47 -05:00
|
|
|
|
|
|
|
//check is the file is *.fsu or *.fsu.X
|
|
|
|
size_t found = fileName.find_last_of('.');
|
|
|
|
std::string ext = fileName.substr(found + 1);
|
|
|
|
|
|
|
|
if( ext.find("fsu") != std::string::npos ) {
|
2024-01-10 18:29:15 -05:00
|
|
|
if(verbose) printf("It is an raw data *.fsu format\n");
|
2024-01-18 18:55:37 -05:00
|
|
|
isDualBlock = false;
|
|
|
|
chMask = -1;
|
2023-12-12 15:35:47 -05:00
|
|
|
}else{
|
|
|
|
chMask = atoi(ext.c_str());
|
2024-01-18 18:55:37 -05:00
|
|
|
isDualBlock = true;
|
2024-01-10 18:29:15 -05:00
|
|
|
if(verbose) printf("It is a splitted dual block data *.fsu.X format, dual channel mask : %d \n", chMask);
|
2023-12-12 15:35:47 -05:00
|
|
|
}
|
|
|
|
|
2024-01-12 16:59:55 -05:00
|
|
|
std::string fileNameNoExt;
|
2024-01-17 18:19:50 -05:00
|
|
|
found = fileName.find_last_of(".fsu");
|
2024-01-12 16:59:55 -05:00
|
|
|
size_t found2 = fileName.find_last_of('/');
|
2024-01-17 18:19:50 -05:00
|
|
|
if( found2 == std::string::npos ){
|
|
|
|
fileNameNoExt = fileName.substr(0, found-4);
|
2024-01-12 16:59:55 -05:00
|
|
|
}else{
|
2024-01-17 18:19:50 -05:00
|
|
|
fileNameNoExt = fileName.substr(found2+1, found-4);
|
2024-01-12 16:59:55 -05:00
|
|
|
}
|
2024-01-11 11:52:40 -05:00
|
|
|
|
|
|
|
// 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());
|
|
|
|
tick2ns = atoi(tokens[4].c_str());
|
|
|
|
order = atoi(tokens[5].c_str());
|
|
|
|
|
|
|
|
DPPType = -1;
|
|
|
|
if( fileName.find("PHA") != std::string::npos ) DPPType = DPPType::DPP_PHA_CODE;
|
|
|
|
if( fileName.find("PSD") != std::string::npos ) DPPType = DPPType::DPP_PSD_CODE;
|
|
|
|
if( fileName.find("QDC") != std::string::npos ) DPPType = DPPType::DPP_QDC_CODE;
|
|
|
|
|
2024-01-19 03:11:10 -05:00
|
|
|
numCh = (DPPType == DPPType::DPP_QDC_CODE ? 64 : 16);
|
2024-01-11 11:52:40 -05:00
|
|
|
|
2024-01-18 23:09:50 -05:00
|
|
|
data = new Data(numCh, dataSize);
|
2024-01-11 11:52:40 -05:00
|
|
|
data->tick2ns = tick2ns;
|
|
|
|
data->boardSN = sn;
|
|
|
|
data->DPPType = DPPType;
|
2023-10-13 18:02:19 -04:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2024-01-20 01:01:10 -05:00
|
|
|
inline int FSUReader::ReadNextBlock(bool traceON, int verbose, uShort saveData){
|
2023-10-13 18:02:19 -04:00
|
|
|
if( inFile == NULL ) return -1;
|
|
|
|
if( feof(inFile) ) return -1;
|
|
|
|
if( filePos >= inFileSize) return -1;
|
|
|
|
|
|
|
|
dummy = fread(word, 4, 1, inFile);
|
2023-12-12 15:35:47 -05:00
|
|
|
fseek(inFile, -4, SEEK_CUR);
|
|
|
|
|
2023-10-13 18:02:19 -04:00
|
|
|
if( dummy != 1) {
|
2024-01-25 18:34:58 -05:00
|
|
|
printf("fread error, should read 4 bytes, but read %ld x 4 byte, file pos: %ld / %ld byte\n",
|
|
|
|
dummy, ftell(inFile), inFileSize);
|
2023-10-13 18:02:19 -04:00
|
|
|
return -10;
|
|
|
|
}
|
|
|
|
short header = ((word[0] >> 28 ) & 0xF);
|
2023-12-12 15:35:47 -05:00
|
|
|
|
2024-01-12 19:12:37 -05:00
|
|
|
Hit temp;
|
|
|
|
|
2023-12-12 15:35:47 -05:00
|
|
|
if( header == 0xA ) { ///normal header
|
|
|
|
|
|
|
|
unsigned int aggSize = (word[0] & 0x0FFFFFFF) * 4; ///byte
|
|
|
|
buffer = new char[aggSize];
|
|
|
|
dummy = fread(buffer, aggSize, 1, inFile);
|
|
|
|
filePos = ftell(inFile);
|
|
|
|
if( dummy != 1) {
|
2024-01-25 18:34:58 -05:00
|
|
|
printf("fread error, should read %d bytes, but read %ld x %d byte, file pos: %ld / %ld byte \n",
|
|
|
|
aggSize, dummy, aggSize, ftell(inFile), inFileSize);
|
2023-12-12 15:35:47 -05:00
|
|
|
return -30;
|
|
|
|
}
|
|
|
|
|
2024-01-20 01:01:10 -05:00
|
|
|
data->DecodeBuffer(buffer, aggSize, !traceON, verbose); // data will own the buffer
|
2024-01-12 16:59:55 -05:00
|
|
|
|
2023-12-12 15:35:47 -05:00
|
|
|
}else if( (header & 0xF ) == 0x8 ) { /// dual channel header
|
|
|
|
|
|
|
|
unsigned int dualSize = (word[0] & 0x7FFFFFFF) * 4; ///byte
|
|
|
|
buffer = new char[dualSize];
|
|
|
|
dummy = fread(buffer, dualSize, 1, inFile);
|
|
|
|
filePos = ftell(inFile);
|
|
|
|
|
|
|
|
data->buffer = buffer;
|
2024-01-20 01:01:10 -05:00
|
|
|
data->DecodeDualBlock(buffer, dualSize, DPPType, chMask, !traceON, verbose);
|
2023-12-12 15:35:47 -05:00
|
|
|
|
|
|
|
}else{
|
2023-10-13 18:02:19 -04:00
|
|
|
printf("incorrect header.\n trminate.");
|
|
|
|
return -20;
|
|
|
|
}
|
|
|
|
|
2024-01-18 18:55:37 -05:00
|
|
|
for( int ch = 0; ch < data->GetNChannel(); ch++){
|
|
|
|
if( data->NumEventsDecoded[ch] == 0 ) continue;
|
2024-01-17 18:19:50 -05:00
|
|
|
|
2024-01-20 01:01:10 -05:00
|
|
|
hitCount += data->NumEventsDecoded[ch];
|
2024-01-17 18:19:50 -05:00
|
|
|
|
2024-01-18 18:55:37 -05:00
|
|
|
if( saveData ){
|
2024-01-26 14:53:52 -05:00
|
|
|
int start = data->GetDataIndex(ch) - data->NumEventsDecoded[ch] + 1;
|
2024-01-20 01:01:10 -05:00
|
|
|
if( start < 0 ) start = start + data->GetDataSize();
|
2024-01-17 18:19:50 -05:00
|
|
|
|
2024-01-20 01:01:10 -05:00
|
|
|
for( int i = start; i < start + data->NumEventsDecoded[ch]; i++ ){
|
|
|
|
int k = i % data->GetDataSize();
|
2024-01-17 18:19:50 -05:00
|
|
|
|
|
|
|
temp.sn = sn;
|
|
|
|
temp.ch = ch;
|
2024-01-26 14:53:52 -05:00
|
|
|
temp.energy = data->GetEnergy(ch, k);
|
|
|
|
temp.energy2 = data->GetEnergy2(ch, k);
|
|
|
|
temp.timestamp = data->GetTimestamp(ch, k);
|
|
|
|
temp.fineTime = data->GetFineTime(ch, k);
|
|
|
|
temp.pileUp = data->GetPileUp(ch, k);
|
2024-01-19 03:11:10 -05:00
|
|
|
if( saveData > 1 ) {
|
2024-01-20 01:01:10 -05:00
|
|
|
temp.traceLength = data->Waveform1[ch][k].size();
|
|
|
|
temp.trace = data->Waveform1[ch][k];
|
2024-01-19 03:11:10 -05:00
|
|
|
}else{
|
|
|
|
temp.traceLength = 0;
|
|
|
|
if( temp.trace.size() > 0 ) temp.trace.clear();
|
|
|
|
}
|
2024-01-17 18:19:50 -05:00
|
|
|
|
|
|
|
hit.push_back(temp);
|
|
|
|
|
2024-01-20 01:01:10 -05:00
|
|
|
// if( data->Timestamp[ch][k] == 0 ){
|
|
|
|
// printf("-------- %lu \n", blockID);
|
|
|
|
// return 1;
|
|
|
|
// }
|
|
|
|
|
2024-01-17 18:19:50 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
data->ClearTriggerRate();
|
|
|
|
data->ClearBuffer(); // this will clear the buffer.
|
|
|
|
|
2023-10-13 18:02:19 -04:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
inline int FSUReader::ReadBlock(unsigned int ID, int verbose){
|
|
|
|
if( totNumBlock == 0 )return -1;
|
|
|
|
if( ID >= totNumBlock )return -1;
|
|
|
|
|
|
|
|
data->ClearData();
|
|
|
|
|
|
|
|
fseek( inFile, 0L, SEEK_SET);
|
|
|
|
|
|
|
|
if( verbose ) printf("Block index: %u, File Pos: %u byte\n", ID, blockPos[ID]);
|
|
|
|
|
|
|
|
fseek(inFile, blockPos[ID], SEEK_CUR);
|
|
|
|
filePos = blockPos[ID];
|
|
|
|
blockID = ID;
|
2024-01-12 16:59:55 -05:00
|
|
|
return ReadNextBlock(false, verbose, false);
|
2023-10-13 18:02:19 -04:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2024-01-19 03:11:10 -05:00
|
|
|
inline void FSUReader::SortHit(int verbose){
|
|
|
|
if( verbose) printf("\nQuick Sort hit array according to time...");
|
2024-01-18 23:09:50 -05:00
|
|
|
std::sort(hit.begin(), hit.end(), [](const Hit& a, const Hit& b) {
|
|
|
|
return a.timestamp < b.timestamp;
|
|
|
|
});
|
2024-01-19 03:11:10 -05:00
|
|
|
if( verbose) printf(".......done.\n");
|
2024-01-18 23:09:50 -05:00
|
|
|
}
|
|
|
|
|
2024-01-19 03:11:10 -05:00
|
|
|
inline void FSUReader::ScanNumBlock(int verbose, uShort saveData){
|
2023-10-13 18:02:19 -04:00
|
|
|
if( feof(inFile) ) return;
|
|
|
|
|
|
|
|
blockID = 0;
|
|
|
|
blockPos.push_back(0);
|
|
|
|
|
2023-10-18 18:33:29 -04:00
|
|
|
data->ClearData();
|
|
|
|
fseek(inFile, 0L, SEEK_SET);
|
|
|
|
filePos = 0;
|
|
|
|
|
2024-01-20 01:01:10 -05:00
|
|
|
while( ReadNextBlock(saveData < 2 ? false : true, verbose - 1, saveData) == 0 ){
|
2023-10-13 18:02:19 -04:00
|
|
|
blockPos.push_back(filePos);
|
2024-01-12 16:59:55 -05:00
|
|
|
blockTimeStamp.push_back(data->aggTime);
|
2023-10-13 18:02:19 -04:00
|
|
|
blockID ++;
|
2024-01-23 15:26:35 -05:00
|
|
|
if(verbose && blockID % 10000 == 0) printf("%u, %.2f%% %u/%lu\n\033[A\r", blockID, filePos*100./inFileSize, filePos, inFileSize);
|
2023-10-13 18:02:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
totNumBlock = blockID;
|
2024-01-12 16:59:55 -05:00
|
|
|
if(verbose) {
|
|
|
|
printf("\nScan complete: number of data Block : %lu\n", totNumBlock);
|
2024-01-20 01:01:10 -05:00
|
|
|
printf( " number of hit : %lu\n", hitCount);
|
2024-01-12 16:59:55 -05:00
|
|
|
|
2024-01-18 18:55:37 -05:00
|
|
|
if( saveData ){
|
|
|
|
size_t sizeT = sizeof(hit[0]) * hit.size();
|
|
|
|
printf("size of hit array : %lu byte = %.2f kByte, = %.2f MByte\n", sizeT, sizeT/1024., sizeT/1024./1024.);
|
|
|
|
}
|
2024-01-12 16:59:55 -05:00
|
|
|
}
|
2023-10-13 18:02:19 -04:00
|
|
|
rewind(inFile);
|
|
|
|
blockID = 0;
|
|
|
|
filePos = 0;
|
|
|
|
|
2024-01-20 01:01:10 -05:00
|
|
|
//check is the hitCount == hit.size();
|
|
|
|
if( hitCount != hit.size() ){
|
|
|
|
printf("!!!!!! the Data::dataSize is not big enough. !!!!!!!!!!!!!!!\n");
|
|
|
|
}else{
|
2024-01-25 18:34:58 -05:00
|
|
|
SortHit(verbose+1);
|
2024-01-20 01:01:10 -05:00
|
|
|
}
|
2024-01-19 03:11:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
inline std::string FSUReader::SaveHit2NewFile(std::string saveFolder){
|
|
|
|
|
2024-01-19 19:24:51 -05:00
|
|
|
// printf("FSUReader::%s\n", __func__);
|
2024-01-19 03:11:10 -05:00
|
|
|
|
|
|
|
std::string folder = "";
|
|
|
|
size_t found = fileName.find_last_of('/');
|
|
|
|
std::string outFileName = fileName;
|
|
|
|
if( found != std::string::npos ){
|
|
|
|
folder = fileName.substr(0, found + 1);
|
|
|
|
outFileName = fileName.substr(found +1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( saveFolder.empty() ) saveFolder = "./";
|
|
|
|
if( saveFolder.back() != '/') saveFolder += '/';
|
|
|
|
|
|
|
|
//checkif the saveFolder exist;
|
|
|
|
if( saveFolder != "./"){
|
|
|
|
if (!std::filesystem::exists(saveFolder)) {
|
|
|
|
if (std::filesystem::create_directory(saveFolder)) {
|
|
|
|
std::cout << "Directory created successfully." << std::endl;
|
|
|
|
} else {
|
|
|
|
std::cerr << "Failed to create directory." << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
outFileName = saveFolder + outFileName + ".ts";
|
|
|
|
|
2024-01-19 19:24:51 -05:00
|
|
|
//TODO Check if the ts file is newer than the fsu file, if yes, don't need to do unless forced.
|
|
|
|
|
2024-01-19 03:11:10 -05:00
|
|
|
FILE * outFile = fopen(outFileName.c_str(), "wb"); //overwrite binary
|
|
|
|
|
|
|
|
uint32_t header = 0xAA000000;
|
|
|
|
header += sn;
|
|
|
|
fwrite( &header, 4, 1, outFile );
|
2024-01-25 18:34:58 -05:00
|
|
|
fwrite( &hitCount, 8, 1, outFile);
|
2024-01-19 03:11:10 -05:00
|
|
|
|
2024-01-20 01:01:10 -05:00
|
|
|
for( ulong i = 0; i < hitCount; i++){
|
2024-01-19 03:11:10 -05:00
|
|
|
|
2024-01-23 15:26:35 -05:00
|
|
|
if( i% 10000 == 0 ) printf("Saving %lu/%lu Hit (%.2f%%)\n\033[A\r", i, hitCount, i*100./hitCount);
|
2024-01-19 03:11:10 -05:00
|
|
|
|
|
|
|
fwrite( &(hit[i].sn), 2, 1, outFile);
|
|
|
|
fwrite( &(hit[i].ch), 1, 1, outFile);
|
|
|
|
fwrite( &(hit[i].energy), 2, 1, outFile);
|
|
|
|
fwrite( &(hit[i].energy2), 2, 1, outFile);
|
|
|
|
fwrite( &(hit[i].timestamp), 8, 1, outFile);
|
|
|
|
fwrite( &(hit[i].fineTime), 2, 1, outFile);
|
2024-01-25 18:34:58 -05:00
|
|
|
fwrite( &(hit[i].pileUp), 1, 1, outFile);
|
2024-01-19 03:11:10 -05:00
|
|
|
fwrite( &(hit[i].traceLength), 2, 1, outFile);
|
|
|
|
|
|
|
|
for( uShort j = 0; j < hit[i].traceLength; j++){
|
|
|
|
fwrite( &(hit[i].trace[j]), 2, 1, outFile);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2024-01-19 19:24:51 -05:00
|
|
|
tsFileSize = ftello(outFile); // unsigned int = Max ~4GB
|
2024-01-19 03:11:10 -05:00
|
|
|
fclose(outFile);
|
|
|
|
|
|
|
|
printf("Saved to %s, size: ", outFileName.c_str());
|
2024-01-19 19:24:51 -05:00
|
|
|
if( tsFileSize < 1024 ) {
|
|
|
|
printf(" %ld Byte", tsFileSize);
|
|
|
|
}else if( tsFileSize < 1024*1024 ) {
|
|
|
|
printf(" %.2f kB", tsFileSize/1024.);
|
|
|
|
}else if( tsFileSize < 1024*1024*1024){
|
|
|
|
printf(" %.2f MB", tsFileSize/1024./1024.);
|
2024-01-19 03:11:10 -05:00
|
|
|
}else{
|
2024-01-19 19:24:51 -05:00
|
|
|
printf(" %.2f GB", tsFileSize/1024./1024./1024.);
|
2024-01-18 18:55:37 -05:00
|
|
|
}
|
2024-01-19 03:11:10 -05:00
|
|
|
printf("\n");
|
|
|
|
|
|
|
|
return outFileName;
|
2024-01-16 15:39:41 -05:00
|
|
|
|
|
|
|
}
|