Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
Ryan Tang | 4eab257a01 | ||
Ryan Tang | 554247e046 | ||
8ce3b4f274 | |||
800fb4e55d | |||
5c248984f3 | |||
2f316e5c2f | |||
76582e2a51 | |||
d5f5ee232d |
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -5,4 +5,5 @@
|
||||||
|
|
||||||
data
|
data
|
||||||
|
|
||||||
Bin2Root
|
Bin2Root
|
||||||
|
Bin2Root2
|
50
Bin2Root.cpp
50
Bin2Root.cpp
|
@ -16,7 +16,7 @@ inline unsigned int getTime_us(){
|
||||||
#include "TMacro.h"
|
#include "TMacro.h"
|
||||||
|
|
||||||
#define MAX_TRACE_LENGTH 2000
|
#define MAX_TRACE_LENGTH 2000
|
||||||
#define MAX_MULTI 100
|
#define MAX_MULTI 500
|
||||||
#define NMINARG 5
|
#define NMINARG 5
|
||||||
#define debug 0 // for > 1 number of hit to debug
|
#define debug 0 // for > 1 number of hit to debug
|
||||||
|
|
||||||
|
@ -88,6 +88,15 @@ int extractDigiSN(const std::string& str, int n = 1) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SetTimeOffset(BinReader * reader, std::vector<std::pair<int, int64_t>>& timeOffsetList){
|
||||||
|
int bd = reader->data.BoardID;
|
||||||
|
for( size_t i = 0 ; i < timeOffsetList.size(); i++){
|
||||||
|
if( bd == timeOffsetList[i].first) reader->data.TimeStamp += timeOffsetList[i].second ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//^#############################################################
|
//^#############################################################
|
||||||
//^#############################################################
|
//^#############################################################
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
@ -107,9 +116,6 @@ int main(int argc, char **argv) {
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf(" Time offset file format :\n");
|
printf(" Time offset file format :\n");
|
||||||
printf("[board SN] [time offset(int64_t)]\n");
|
printf("[board SN] [time offset(int64_t)]\n");
|
||||||
printf("\n");
|
|
||||||
printf(" file name should be this format CH0@V1725_324_Data_run_196.bin\n");
|
|
||||||
printf(" so that the serial number is between the 1st and 2nd underscore\n");
|
|
||||||
printf("\n\n");
|
printf("\n\n");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -170,13 +176,13 @@ int main(int argc, char **argv) {
|
||||||
BinReader reader[nFile];
|
BinReader reader[nFile];
|
||||||
for(int i = 0; i < nFile; i++ ){
|
for(int i = 0; i < nFile; i++ ){
|
||||||
printf(">>>>>>>> %2d | %s \n", i, inFileName[i].Data());
|
printf(">>>>>>>> %2d | %s \n", i, inFileName[i].Data());
|
||||||
reader[i].OpenFile(inFileName[i]);
|
reader[i].OpenFile(inFileName[i], 0, true);
|
||||||
if( timeOffsetList.size() > 1 ){
|
// if( timeOffsetList.size() > 1 ){
|
||||||
for (size_t i = 1 ; timeOffsetList.size(); i++) {
|
// for (size_t i = 1 ; timeOffsetList.size(); i++) {
|
||||||
int sn = extractDigiSN(inFileName[i].Data(), timeOffsetList[0].first);
|
// int sn = extractDigiSN(inFileName[i].Data(), timeOffsetList[0].first);
|
||||||
if( sn == timeOffsetList[i].first ) reader[i].SetTimeOffset(timeOffsetList[i].second);
|
// if( sn == timeOffsetList[i].first ) reader[i].SetTimeOffset(timeOffsetList[i].second);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
reader[i].ScanNumHit();
|
reader[i].ScanNumHit();
|
||||||
totalHitCount += reader[i].GetNumHit();
|
totalHitCount += reader[i].GetNumHit();
|
||||||
}
|
}
|
||||||
|
@ -190,9 +196,9 @@ int main(int argc, char **argv) {
|
||||||
unsigned short sn[MAX_MULTI] = {0};
|
unsigned short sn[MAX_MULTI] = {0};
|
||||||
unsigned short ch[MAX_MULTI] = {0};
|
unsigned short ch[MAX_MULTI] = {0};
|
||||||
unsigned short e[MAX_MULTI] = {0};
|
unsigned short e[MAX_MULTI] = {0};
|
||||||
unsigned short e2[MAX_MULTI] = {0};
|
// unsigned short e2[MAX_MULTI] = {0};
|
||||||
unsigned long long e_t[MAX_MULTI] = {0};
|
unsigned long long e_t[MAX_MULTI] = {0};
|
||||||
unsigned short e_f[MAX_MULTI] = {0};
|
// unsigned short e_f[MAX_MULTI] = {0};
|
||||||
unsigned short traceLength[MAX_MULTI];
|
unsigned short traceLength[MAX_MULTI];
|
||||||
short trace[MAX_MULTI][MAX_TRACE_LENGTH];
|
short trace[MAX_MULTI][MAX_TRACE_LENGTH];
|
||||||
|
|
||||||
|
@ -203,9 +209,9 @@ int main(int argc, char **argv) {
|
||||||
tree->Branch("sn", sn, "sn[multi]/s");
|
tree->Branch("sn", sn, "sn[multi]/s");
|
||||||
tree->Branch("ch", ch, "ch[multi]/s");
|
tree->Branch("ch", ch, "ch[multi]/s");
|
||||||
tree->Branch("e", e, "e[multi]/s");
|
tree->Branch("e", e, "e[multi]/s");
|
||||||
tree->Branch("e2", e2, "e2[multi]/s");
|
// tree->Branch("e2", e2, "e2[multi]/s");
|
||||||
tree->Branch("e_t", e_t, "e_t[multi]/l");
|
tree->Branch("e_t", e_t, "e_t[multi]/l");
|
||||||
tree->Branch("e_f", e_f, "e_f[multi]/s");
|
// tree->Branch("e_f", e_f, "e_f[multi]/s");
|
||||||
tree->Branch("traceLength", traceLength, "traceLength[multi]/s");
|
tree->Branch("traceLength", traceLength, "traceLength[multi]/s");
|
||||||
|
|
||||||
if( traceOn ) {
|
if( traceOn ) {
|
||||||
|
@ -232,6 +238,7 @@ int main(int argc, char **argv) {
|
||||||
long long ID[nFile]; // filled hit ID
|
long long ID[nFile]; // filled hit ID
|
||||||
for( int i = 0 ; i < nFile ; i++ ) {
|
for( int i = 0 ; i < nFile ; i++ ) {
|
||||||
reader[i].ReadBlock();
|
reader[i].ReadBlock();
|
||||||
|
SetTimeOffset(&reader[i], timeOffsetList);
|
||||||
ID[i] = -1;
|
ID[i] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,6 +270,7 @@ int main(int argc, char **argv) {
|
||||||
if( ID[i] + 1 >= reader[i].GetNumHit() ) continue;
|
if( ID[i] + 1 >= reader[i].GetNumHit() ) continue;
|
||||||
|
|
||||||
if( timeWindow >= 0 ){
|
if( timeWindow >= 0 ){
|
||||||
|
int ret = 0;
|
||||||
do{
|
do{
|
||||||
if( (long int)( reader[i].data.TimeStamp - t0) <= timeWindow ){
|
if( (long int)( reader[i].data.TimeStamp - t0) <= timeWindow ){
|
||||||
events.push_back(reader[i].data);
|
events.push_back(reader[i].data);
|
||||||
|
@ -270,11 +278,14 @@ int main(int argc, char **argv) {
|
||||||
}else{
|
}else{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}while( reader[i].ReadBlock() == 1 );
|
ret = reader[i].ReadBlock();
|
||||||
|
SetTimeOffset(&reader[i], timeOffsetList);
|
||||||
|
}while( ret == 1 );
|
||||||
}else{
|
}else{
|
||||||
events.push_back(reader[g0].data);
|
events.push_back(reader[g0].data);
|
||||||
ID[g0] ++;
|
ID[g0] ++;
|
||||||
reader[g0].ReadBlock();
|
reader[g0].ReadBlock();
|
||||||
|
SetTimeOffset(&reader[g0], timeOffsetList);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,6 +306,9 @@ int main(int argc, char **argv) {
|
||||||
multi = events.size() ;
|
multi = events.size() ;
|
||||||
if( events.size() >= MAX_MULTI ) {
|
if( events.size() >= MAX_MULTI ) {
|
||||||
printf("\033[31m event %lld has size = %d > MAX_MULTI = %d \033[0m\n", evID, multi, MAX_MULTI);
|
printf("\033[31m event %lld has size = %d > MAX_MULTI = %d \033[0m\n", evID, multi, MAX_MULTI);
|
||||||
|
// for( int k = 0 ; k < multi; k++){
|
||||||
|
// printf("%d | %d %2d %llu | %llu , %llu , %llu\n", k, events[k].BoardID, events[k].Channel, events[k].TimeStamp, (long int)( events[k].TimeStamp - t0), t0, timeWindow);
|
||||||
|
// }
|
||||||
multi = MAX_MULTI;
|
multi = MAX_MULTI;
|
||||||
}
|
}
|
||||||
if( debug ) printf("=================================== filling data | %u \n", multi);
|
if( debug ) printf("=================================== filling data | %u \n", multi);
|
||||||
|
@ -305,9 +319,9 @@ int main(int argc, char **argv) {
|
||||||
sn[p] = events[p].BoardID;
|
sn[p] = events[p].BoardID;
|
||||||
ch[p] = events[p].Channel;
|
ch[p] = events[p].Channel;
|
||||||
e[p] = events[p].Energy;
|
e[p] = events[p].Energy;
|
||||||
e2[p] = events[p].Energy_short;
|
// e2[p] = events[p].Energy_short;
|
||||||
e_t[p] = events[p].TimeStamp / 1000;
|
e_t[p] = events[p].TimeStamp / 1000;
|
||||||
e_f[p] = events[p].TimeStamp % 1000;
|
// e_f[p] = events[p].TimeStamp % 1000;
|
||||||
|
|
||||||
traceLength[p] = events[p].NSample;
|
traceLength[p] = events[p].NSample;
|
||||||
if( traceOn ){
|
if( traceOn ){
|
||||||
|
|
434
Bin2Root2.cpp
Normal file
434
Bin2Root2.cpp
Normal file
|
@ -0,0 +1,434 @@
|
||||||
|
/********************************************
|
||||||
|
*
|
||||||
|
* This Bin2Root2.cpp is specially designed for CAEN CoMPASS output
|
||||||
|
*
|
||||||
|
* that all boards and channels are combined together.
|
||||||
|
*
|
||||||
|
* The data file name has format DataR_run_XXX_YYY.BIN
|
||||||
|
* where XXX is run number, YYY from 1 when data size > 1 GB
|
||||||
|
* The first file of the run is DataR_run_XXX.BIN
|
||||||
|
*
|
||||||
|
* In this case, only the first .BIN file has header.
|
||||||
|
*
|
||||||
|
* Also, the timestamp is not fully sorted.
|
||||||
|
*
|
||||||
|
* Timeoffset is hardcoded.
|
||||||
|
*
|
||||||
|
* Created by Ryan Tang, goluckyryan@gmail.com
|
||||||
|
* last edit @ 2024-09-25
|
||||||
|
*
|
||||||
|
*********************************************/
|
||||||
|
|
||||||
|
#include "BinReader.h"
|
||||||
|
#include <sys/time.h> /** struct timeval, select() */
|
||||||
|
|
||||||
|
inline unsigned int getTime_us(){
|
||||||
|
unsigned int time_us;
|
||||||
|
struct timeval t1;
|
||||||
|
struct timezone tz;
|
||||||
|
gettimeofday(&t1, &tz);
|
||||||
|
time_us = (t1.tv_sec) * 1000 * 1000 + t1.tv_usec;
|
||||||
|
return time_us;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "TFile.h"
|
||||||
|
#include "TTree.h"
|
||||||
|
#include "TMacro.h"
|
||||||
|
|
||||||
|
#define MAX_MULTI 100
|
||||||
|
#define debug 0 // for > 1 number of hit to debug
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <utility>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
//^================================================
|
||||||
|
///============ time offset
|
||||||
|
// std::vector<uint64_t> timeOffsetList = {100863280000, 100562004000, 320120000, 0}; //in ps // run34
|
||||||
|
|
||||||
|
std::vector<double> timeOffsetListSec = {0.0008849, 0.000359944, 0.000268992, 0.0}; // run 29
|
||||||
|
|
||||||
|
std::vector<uint64_t> timeOffsetList = {0, 0, 0, 0}; // in ps
|
||||||
|
|
||||||
|
int bufferSize = 10000000;
|
||||||
|
|
||||||
|
//^================================================
|
||||||
|
|
||||||
|
std::vector<std::pair<int, std::string>> findDataFiles(const std::string& patternPrefix) {
|
||||||
|
std::vector<std::pair<int, std::string>> results;
|
||||||
|
std::regex pattern1(patternPrefix + "_" + R"_((\d{1,3})\.BIN)_");
|
||||||
|
std::regex pattern2(patternPrefix + R"(\.BIN)");
|
||||||
|
|
||||||
|
for (const auto& entry : std::filesystem::directory_iterator(".")) {
|
||||||
|
if (entry.is_regular_file()) {
|
||||||
|
std::string filename = entry.path().filename().string();
|
||||||
|
std::smatch match;
|
||||||
|
|
||||||
|
// Check for pattern DataR_run_34_YYY.BIN
|
||||||
|
if (std::regex_match(filename, match, pattern1)) {
|
||||||
|
int yyy = std::stoi(match[1].str());
|
||||||
|
results.emplace_back(yyy, filename);
|
||||||
|
}
|
||||||
|
// Check for pattern DataR_run_34.BIN
|
||||||
|
else if (std::regex_match(filename, pattern2)) {
|
||||||
|
results.emplace_back(0, filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(results.begin(), results.end(), [](const std::pair<int, std::string>& a, const std::pair<int, std::string>& b) {
|
||||||
|
return a.first < b.first;
|
||||||
|
});
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvertTimeOffset(){
|
||||||
|
|
||||||
|
double tMax = 0;
|
||||||
|
for( size_t i = 0; i < timeOffsetListSec.size(); i++ ) {
|
||||||
|
if( tMax < timeOffsetListSec[i] ) tMax = timeOffsetListSec[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("############ Time Offset \n");
|
||||||
|
for( size_t i = 0; i < timeOffsetList.size(); i++ ) {
|
||||||
|
timeOffsetList[i] = uint64_t( ( tMax - timeOffsetListSec[i] ) * 1e12);
|
||||||
|
printf("%zu | %lu ps = %.3f msec\n", i, timeOffsetList[i],timeOffsetList[i] / 1e9);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Data> hitList_A ;
|
||||||
|
std::vector<Data> hitList_B ;
|
||||||
|
BinReader * reader = nullptr;
|
||||||
|
|
||||||
|
int ReadBatch(int bufferSize){
|
||||||
|
|
||||||
|
printf("Reading Batch %d \n", bufferSize);
|
||||||
|
|
||||||
|
if( hitList_A.size() == 0 ){
|
||||||
|
for( int i = 0 ; i < bufferSize; i++ ){
|
||||||
|
if( reader->ReadBlock() != 1 ){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
int bd = reader->data.BoardID;
|
||||||
|
if( bd < timeOffsetList.size() ) reader->data.TimeStamp += timeOffsetList[bd];
|
||||||
|
hitList_A.push_back(reader->data);
|
||||||
|
}
|
||||||
|
if( hitList_A.size() > 1){
|
||||||
|
std::sort(hitList_A.begin(), hitList_A.end(), [](const Data& a, const Data& b) {
|
||||||
|
return a.TimeStamp < b.TimeStamp;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
hitList_A.clear();
|
||||||
|
hitList_A = hitList_B;
|
||||||
|
}
|
||||||
|
|
||||||
|
//reader next batch
|
||||||
|
hitList_B.clear();
|
||||||
|
for( int i = 0 ; i < bufferSize; i++ ){
|
||||||
|
if( reader->ReadBlock() != 1 ){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
int bd = reader->data.BoardID;
|
||||||
|
if( bd < timeOffsetList.size() ) reader->data.TimeStamp += timeOffsetList[bd];
|
||||||
|
hitList_B.push_back(reader->data);
|
||||||
|
}
|
||||||
|
if( hitList_B.size() > 1 ){
|
||||||
|
std::sort(hitList_B.begin(), hitList_B.end(), [](const Data& a, const Data& b) {
|
||||||
|
return a.TimeStamp < b.TimeStamp;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if( hitList_B.size() == 0 ) {
|
||||||
|
printf("hitList_B is empty. end of ReadBatch\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t t0_A = hitList_A.front().TimeStamp;
|
||||||
|
uint64_t t1_A = hitList_A.back().TimeStamp;
|
||||||
|
uint64_t t0_B = hitList_B.front().TimeStamp;
|
||||||
|
|
||||||
|
if( t0_A >= t0_B ){
|
||||||
|
printf("need to increase the batch size\n");
|
||||||
|
printf("t0_A : %15lu | %zu\n", t0_A, hitList_A.size());
|
||||||
|
printf("t0_B : %15lu | %zu\n", t0_B, hitList_B.size());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( t1_A >= t0_B ){ // move the overlap part to hitsLis_A;
|
||||||
|
|
||||||
|
ulong ID_A = 0;
|
||||||
|
ulong ID_B = 0;
|
||||||
|
std::vector<Data> hitTemp;
|
||||||
|
|
||||||
|
// find the hit that is >= t0_B, save them to hitTemp
|
||||||
|
for( size_t j = 0; j < hitList_A.size() ; j++){
|
||||||
|
if( hitList_A[j].TimeStamp < t0_B ) continue;;
|
||||||
|
if( ID_A == 0 ) ID_A = j;
|
||||||
|
hitTemp.push_back(hitList_A[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove hitList_A element that is >= t0_B
|
||||||
|
hitList_A.erase(hitList_A.begin() + ID_A, hitList_A.end() );
|
||||||
|
|
||||||
|
// find the hit that is <= t1_A, save them to hitTemp
|
||||||
|
for( size_t j = 0; j < hitList_B.size(); j++){
|
||||||
|
if( hitList_B[j].TimeStamp > t1_A ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
hitTemp.push_back(hitList_B[j]);
|
||||||
|
ID_B = j + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove hit elements that is <= t1_A
|
||||||
|
hitList_B.erase(hitList_B.begin(), hitList_B.begin() + ID_B );
|
||||||
|
|
||||||
|
// sort hitTemp
|
||||||
|
std::sort(hitTemp.begin(), hitTemp.end(), [](const Data& a, const Data& b) {
|
||||||
|
return a.TimeStamp < b.TimeStamp;
|
||||||
|
});
|
||||||
|
|
||||||
|
//push back the hitList_A
|
||||||
|
for( size_t j = 0; j < hitTemp.size(); j++){
|
||||||
|
hitList_A.push_back(hitTemp[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
unsigned long dtA = (hitList_A.back().TimeStamp - hitList_A.front().TimeStamp)/ 1000;
|
||||||
|
unsigned long dtB = (hitList_B.back().TimeStamp - hitList_B.front().TimeStamp)/ 1000;
|
||||||
|
|
||||||
|
printf("hitList A | size %zu | timeRange %ld ns = %.3f sec\n", hitList_A.size(), dtA/100, dtA/1e12 );
|
||||||
|
printf("hitList B | size %zu | timeRange %ld ns = %.3f sec\n", hitList_B.size(), dtB/100, dtB/1e12 );
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//^#############################################################
|
||||||
|
//^#############################################################
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
printf("=========================================\n");
|
||||||
|
printf("=== CoMPASS Binary to root ===\n");
|
||||||
|
printf("=========================================\n");
|
||||||
|
if (argc < 3) {
|
||||||
|
printf("Incorrect number of arguments:\n");
|
||||||
|
printf("%s [timeWindow] [RunNum] \n", argv[0]);
|
||||||
|
printf(" timeWindow : in ns, -1 = no event building \n");
|
||||||
|
printf("\n\n");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int runStartTime = getTime_us();
|
||||||
|
|
||||||
|
///============= read input
|
||||||
|
long timeWindow = atoi(argv[1]); // ns
|
||||||
|
short runNum = atoi(argv[2]);
|
||||||
|
|
||||||
|
///=========== Form outFileName;
|
||||||
|
TString outFileName = Form("run%03d_%s.root", runNum, (timeWindow < 0 ? "single" : std::to_string(timeWindow).c_str()) );
|
||||||
|
|
||||||
|
///=========== Find all BIN file with runNum
|
||||||
|
std::string pattern = "DataR_run_" + std::to_string(runNum);
|
||||||
|
printf("Searching file with pattern %s....\n", pattern.c_str());
|
||||||
|
|
||||||
|
std::vector<std::pair<int, std::string>> inFileName = findDataFiles(pattern);
|
||||||
|
int nFile = inFileName.size();
|
||||||
|
|
||||||
|
printf("=========================================\n");
|
||||||
|
printf(" Time Window = %ld ns = %.1f us\n", timeWindow, timeWindow/1000.);
|
||||||
|
printf(" Max multiplity = %d hits/event (hard coded)\n", MAX_MULTI);
|
||||||
|
printf(" Out file name = %s \n", outFileName.Data());
|
||||||
|
printf(" Buffer Size = %d\n", bufferSize);
|
||||||
|
|
||||||
|
ConvertTimeOffset();
|
||||||
|
|
||||||
|
printf("=============================== Number of input Files : %d \n", nFile);
|
||||||
|
for( int i = 0 ; i < nFile; i++ ){
|
||||||
|
printf(" %3d | %s\n", i, inFileName[i].second.c_str());
|
||||||
|
}
|
||||||
|
printf("========================================= Scanning files\n");
|
||||||
|
unsigned long long totalHitCount = 0;
|
||||||
|
uint16_t tempHeader;
|
||||||
|
for( int i = 0; i < nFile; i++){
|
||||||
|
BinReader tempReader;
|
||||||
|
if( i == 0 ) {
|
||||||
|
tempReader.OpenFile(inFileName[i].second);
|
||||||
|
tempHeader = tempReader.data.Header;
|
||||||
|
}else{
|
||||||
|
tempReader.OpenFile(inFileName[i].second, 0, true);
|
||||||
|
tempReader.SetCustomHeader(tempHeader);
|
||||||
|
}
|
||||||
|
tempReader.ScanNumHit();
|
||||||
|
totalHitCount += tempReader.GetNumHit();
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("============================ total Num. of Hit : %llu\n", totalHitCount);
|
||||||
|
|
||||||
|
timeWindow *= 1000; // to ps
|
||||||
|
|
||||||
|
printf("========================================= Initializing tree...\n");
|
||||||
|
unsigned long long evID = 0;
|
||||||
|
unsigned int multi = 0;
|
||||||
|
unsigned short sn[MAX_MULTI] = {0};
|
||||||
|
unsigned short ch[MAX_MULTI] = {0};
|
||||||
|
unsigned short e[MAX_MULTI] = {0};
|
||||||
|
// unsigned short e2[MAX_MULTI] = {0};
|
||||||
|
unsigned long long e_t[MAX_MULTI] = {0};
|
||||||
|
// unsigned short e_f[MAX_MULTI] = {0};
|
||||||
|
// unsigned short traceLength[MAX_MULTI];
|
||||||
|
// short trace[MAX_MULTI][MAX_TRACE_LENGTH];
|
||||||
|
|
||||||
|
TFile * outRootFile = new TFile(outFileName, "recreate");
|
||||||
|
TTree * tree = new TTree("tree", outFileName);
|
||||||
|
tree->Branch("evID", &evID, "event_ID/l");
|
||||||
|
tree->Branch("multi", &multi, "multi/i");
|
||||||
|
tree->Branch("sn", sn, "sn[multi]/s");
|
||||||
|
tree->Branch("ch", ch, "ch[multi]/s");
|
||||||
|
tree->Branch("e", e, "e[multi]/s");
|
||||||
|
// tree->Branch("e2", e2, "e2[multi]/s");
|
||||||
|
tree->Branch("e_t", e_t, "e_t[multi]/l");
|
||||||
|
|
||||||
|
|
||||||
|
// record the first time stamp and last time stamp
|
||||||
|
unsigned long long tStart = 0;
|
||||||
|
unsigned long long tEnd = 0;
|
||||||
|
unsigned long long hitProcessed = 0;
|
||||||
|
|
||||||
|
printf("========================================= Read File & events building...\n");
|
||||||
|
///=========================== Read file
|
||||||
|
reader = new BinReader();
|
||||||
|
int fileID = 0;
|
||||||
|
reader->OpenFile(inFileName[fileID].second);
|
||||||
|
const uint16_t header = reader->data.Header;
|
||||||
|
|
||||||
|
int ret = 0;
|
||||||
|
bool windowOpen = false;
|
||||||
|
uint64_t t0 = 0;
|
||||||
|
|
||||||
|
std::vector<Data> event;
|
||||||
|
|
||||||
|
do{
|
||||||
|
|
||||||
|
if( reader->IsEndOfFile() ){
|
||||||
|
reader->CloseFile();
|
||||||
|
fileID++;
|
||||||
|
if( fileID < nFile ) {
|
||||||
|
printf("\n========= Open next file.\n");
|
||||||
|
reader->OpenFile(inFileName[fileID].second, 0, true);
|
||||||
|
reader->SetCustomHeader(header);
|
||||||
|
}else{
|
||||||
|
printf("\n========= no more file.\n");
|
||||||
|
// break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = ReadBatch(bufferSize);
|
||||||
|
if( hitList_A.size() > 0 ) {
|
||||||
|
unsigned long dtA = (hitList_A.back().TimeStamp - hitList_A.front().TimeStamp)/ 1000;
|
||||||
|
printf("hitList A | size %zu | timeRange %ld ns = %.3f sec\n", hitList_A.size(), dtA/100, dtA/1e12 );
|
||||||
|
if( tStart == 0 ) tStart = hitList_A[0].TimeStamp;
|
||||||
|
tEnd = hitList_A.back().TimeStamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
//build event from hitList_A;
|
||||||
|
for( size_t i = 0; i < hitList_A.size(); i++){
|
||||||
|
|
||||||
|
if( timeWindow < 0 ){
|
||||||
|
|
||||||
|
multi = 1;
|
||||||
|
sn[0] = hitList_A[i].BoardID;
|
||||||
|
ch[0] = hitList_A[i].Channel;
|
||||||
|
e[0] = hitList_A[i].Energy;
|
||||||
|
// e2[p] = hitList_A[i].Energy_short;
|
||||||
|
e_t[0] = hitList_A[i].TimeStamp / 1000;
|
||||||
|
tree->Fill();
|
||||||
|
evID ++;
|
||||||
|
|
||||||
|
}else{
|
||||||
|
|
||||||
|
// if( t0 == -1 ) {
|
||||||
|
if( !windowOpen && (hitList_A[i].BoardID == 0 && hitList_A[i].Channel == 15 ) ){ // for MUSICS, use the grid to open time window
|
||||||
|
t0 = hitList_A[i].TimeStamp;
|
||||||
|
windowOpen = true;
|
||||||
|
event.push_back(hitList_A[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !windowOpen ) continue;
|
||||||
|
|
||||||
|
if( hitList_A[i].TimeStamp - t0 < timeWindow ){
|
||||||
|
event.push_back(hitList_A[i]);
|
||||||
|
}else{
|
||||||
|
|
||||||
|
//fill an event
|
||||||
|
multi = event.size();
|
||||||
|
if( multi > MAX_MULTI ){
|
||||||
|
printf("\033[31m event %lld has size = %d > MAX_MULTI = %d \033[0m\n", evID, multi, MAX_MULTI);
|
||||||
|
// for( int k = 0 ; k < multi; k++){
|
||||||
|
// printf("%d | %d %2d %llu | %llu , %llu , %llu\n", k, events[k].BoardID, events[k].Channel, events[k].TimeStamp, (long int)( events[k].TimeStamp - t0), t0, timeWindow);
|
||||||
|
// }
|
||||||
|
multi = MAX_MULTI;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( size_t p = 0; p < multi ; p ++ ) {
|
||||||
|
sn[p] = event[p].BoardID;
|
||||||
|
ch[p] = event[p].Channel;
|
||||||
|
e[p] = event[p].Energy;
|
||||||
|
// e2[p] = event[p].Energy_short;
|
||||||
|
e_t[p] = event[p].TimeStamp / 1000;
|
||||||
|
}
|
||||||
|
tree->Fill();
|
||||||
|
evID ++;
|
||||||
|
|
||||||
|
// start a new event
|
||||||
|
event.clear();
|
||||||
|
// t0 = hitList_A[i].TimeStamp;
|
||||||
|
// event.push_back(hitList_A[i]);
|
||||||
|
t0 = 0; // for MUSICS
|
||||||
|
windowOpen = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hitProcessed ++;
|
||||||
|
if( hitProcessed % 10000 == 0 ) printf("hit Porcessed %llu/%llu hit....%.2f%%\n\033[A\r", hitProcessed, totalHitCount, hitProcessed*100./totalHitCount);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
tree->Write();
|
||||||
|
if( fileID >= nFile ) break;
|
||||||
|
}while(ret == 1);
|
||||||
|
|
||||||
|
tree->Write();
|
||||||
|
|
||||||
|
unsigned int runEndTime = getTime_us();
|
||||||
|
double runTime = (runEndTime - runStartTime) * 1e-6;
|
||||||
|
printf("######################################### finished.\n");
|
||||||
|
printf(" event building time = %.2f sec = %.2f min\n", runTime, runTime/60.);
|
||||||
|
printf(" total events built = %llu by event builder (%llu in tree)\n", evID, tree->GetEntriesFast());
|
||||||
|
printf(" total hit processed = %llu\n", hitProcessed);
|
||||||
|
double tDuration_sec = (tEnd - tStart) * 1e-12;
|
||||||
|
printf(" first timestamp = %20llu ps\n", tStart);
|
||||||
|
printf(" last timestamp = %20llu ps\n", tEnd);
|
||||||
|
printf(" total data duration = %.2f sec = %.2f min\n", tDuration_sec, tDuration_sec/60.);
|
||||||
|
printf("========================================> saved to %s \n", outFileName.Data());
|
||||||
|
|
||||||
|
TMacro info;
|
||||||
|
info.AddLine(Form("tStart= %20llu ns",tStart));
|
||||||
|
info.AddLine(Form(" tEnd= %20llu ns",tEnd));
|
||||||
|
info.Write("info");
|
||||||
|
outRootFile->Close();
|
||||||
|
|
||||||
|
delete reader;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
42
BinReader.h
42
BinReader.h
|
@ -45,14 +45,14 @@ struct Data{
|
||||||
printf("header : 0x%X \n", Header);
|
printf("header : 0x%X \n", Header);
|
||||||
printf(" Board : %u , Channel : %u\n", BoardID, Channel);
|
printf(" Board : %u , Channel : %u\n", BoardID, Channel);
|
||||||
if( Header & 4 ) {
|
if( Header & 4 ) {
|
||||||
printf("Energy : %5u, Energy2 : %5u, TimeStamp : %16llu ps\n", Energy, Energy_short, TimeStamp);
|
printf("Energy : %5u, Energy2 : %5u, TimeStamp : %16lu ps\n", Energy, Energy_short, TimeStamp);
|
||||||
}else{
|
}else{
|
||||||
printf("Energy : %5u, TimeStamp : %16llu ps\n", Energy, TimeStamp);
|
printf("Energy : %5u, TimeStamp : %16lu ps\n", Energy, TimeStamp);
|
||||||
}
|
}
|
||||||
printf(" Flag : 0x%08X\n", Flags);
|
printf(" Flag : 0x%08X\n", Flags);
|
||||||
if( (Header & 0x8 ) >= 1 ){ /// is waevform exist
|
if( (Header & 0x8 ) >= 1 ){ /// is waevform exist
|
||||||
printf(" Wave form code : %d , nSample : %d\n", WaveformCode, NSample);
|
printf(" Wave form code : %d , nSample : %d\n", WaveformCode, NSample);
|
||||||
for( int i = 0 ; i < NSample ; i++){
|
for( unsigned int i = 0 ; i < NSample ; i++){
|
||||||
printf("%4d | %d \n", i, Trace[i]);
|
printf("%4d | %d \n", i, Trace[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,7 @@ class BinReader{
|
||||||
~BinReader();
|
~BinReader();
|
||||||
|
|
||||||
void OpenFile(TString inFileName, int64_t timeOffset = 0, bool noHeader = false);
|
void OpenFile(TString inFileName, int64_t timeOffset = 0, bool noHeader = false);
|
||||||
|
void SetCustomHeader(uint16_t Header);
|
||||||
// void SetDataFormat(bool has );
|
// void SetDataFormat(bool has );
|
||||||
void CloseFile();
|
void CloseFile();
|
||||||
void UpdateFileSize();
|
void UpdateFileSize();
|
||||||
|
@ -112,7 +113,7 @@ class BinReader{
|
||||||
void PrintStatus(int mod);
|
void PrintStatus(int mod);
|
||||||
|
|
||||||
void SetTimeOffset(int64_t timeOffset) { this->timeOffset = timeOffset; }
|
void SetTimeOffset(int64_t timeOffset) { this->timeOffset = timeOffset; }
|
||||||
|
|
||||||
};
|
};
|
||||||
//========================== implementation
|
//========================== implementation
|
||||||
|
|
||||||
|
@ -135,7 +136,7 @@ BinReader::BinReader(){
|
||||||
}
|
}
|
||||||
|
|
||||||
BinReader::~BinReader(){
|
BinReader::~BinReader(){
|
||||||
fclose(inFile); /// fclose already delete inFile;
|
if( inFile ) fclose(inFile); /// fclose already delete inFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
BinReader::BinReader(TString inFileName, int64_t timeOffset, bool noHeader){
|
BinReader::BinReader(TString inFileName, int64_t timeOffset, bool noHeader){
|
||||||
|
@ -167,6 +168,11 @@ void BinReader::OpenFile(TString inFileName, int64_t timeOffset, bool noHeader){
|
||||||
gClock.Start("timer");
|
gClock.Start("timer");
|
||||||
|
|
||||||
isOpened = true;
|
isOpened = true;
|
||||||
|
|
||||||
|
// normal format: isHeaderOK = true, isNoHeaderFormat= false, isOldFormat = false
|
||||||
|
// old format: isHeaderOK = true, isNoHeaderFormat= false, isOldFormat = true
|
||||||
|
//no header format: isHeaderOK = false, isNoHeaderFormat= true, isOldFormat = false
|
||||||
|
|
||||||
|
|
||||||
if( noHeader ){
|
if( noHeader ){
|
||||||
data.Header = 0x0;
|
data.Header = 0x0;
|
||||||
|
@ -202,12 +208,19 @@ void BinReader::OpenFile(TString inFileName, int64_t timeOffset, bool noHeader){
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf(" Header format. 0x%04x\n", data.Header);
|
||||||
isHeaderOK = true;
|
isHeaderOK = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void BinReader::SetCustomHeader(uint16_t Header){
|
||||||
|
data.Header = Header;
|
||||||
|
isHeaderOK = true;
|
||||||
|
}
|
||||||
|
|
||||||
void BinReader::CloseFile(){
|
void BinReader::CloseFile(){
|
||||||
fclose(inFile);
|
if(inFile) fclose(inFile);
|
||||||
|
inFile = nullptr;
|
||||||
isOpened = false;
|
isOpened = false;
|
||||||
data.Clear();
|
data.Clear();
|
||||||
inFileSize = 0;
|
inFileSize = 0;
|
||||||
|
@ -226,6 +239,7 @@ void BinReader::UpdateFileSize(){
|
||||||
|
|
||||||
bool BinReader::IsEndOfFile() {
|
bool BinReader::IsEndOfFile() {
|
||||||
if( endOfFile ) return true;
|
if( endOfFile ) return true;
|
||||||
|
if( inFile == nullptr ) return true;
|
||||||
return feof(inFile) > 0 ? true: false;
|
return feof(inFile) > 0 ? true: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,8 +258,7 @@ int BinReader::ReadBlock(int skipTrace){
|
||||||
if( feof(inFile) ) return -1;
|
if( feof(inFile) ) return -1;
|
||||||
if( endOfFile ) return -1;
|
if( endOfFile ) return -1;
|
||||||
|
|
||||||
|
if( isNoHeaderFormat && data.Header == 0x0 ) {
|
||||||
if( isNoHeaderFormat ) {
|
|
||||||
FillData(&data.BoardID);
|
FillData(&data.BoardID);
|
||||||
FillData(&data.Channel);
|
FillData(&data.Channel);
|
||||||
FillData(&data.TimeStamp);
|
FillData(&data.TimeStamp);
|
||||||
|
@ -269,14 +282,14 @@ int BinReader::ReadBlock(int skipTrace){
|
||||||
FillData(&data.TimeStamp);
|
FillData(&data.TimeStamp);
|
||||||
if( timeOffset != 0 ) data.TimeStamp += timeOffset;
|
if( timeOffset != 0 ) data.TimeStamp += timeOffset;
|
||||||
|
|
||||||
if( (data.Header & 0x3) != 0 ) FillData(&data.Energy);
|
if( (data.Header & 0x3) ) FillData(&data.Energy);
|
||||||
|
|
||||||
if( (data.Header & 0x2) == 1 ) {
|
if( (data.Header & 0x2) ) {
|
||||||
uint64_t dummy = 0;
|
uint64_t dummy = 0;
|
||||||
FillData(&dummy);
|
FillData(&dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( (data.Header & 0x4 ) != 0 ) FillData(&data.Energy_short);
|
if( (data.Header & 0x4 ) ) FillData(&data.Energy_short);
|
||||||
|
|
||||||
FillData(&data.Flags);
|
FillData(&data.Flags);
|
||||||
|
|
||||||
|
@ -286,13 +299,13 @@ int BinReader::ReadBlock(int skipTrace){
|
||||||
}
|
}
|
||||||
|
|
||||||
/// check is wave form exist
|
/// check is wave form exist
|
||||||
if( (data.Header & 0x8) == 1){
|
if( (data.Header & 0x8) ){
|
||||||
FillData(&data.WaveformCode);
|
FillData(&data.WaveformCode);
|
||||||
FillData(&data.NSample);
|
FillData(&data.NSample);
|
||||||
if( skipTrace == 0 ){
|
if( skipTrace == 0 ){
|
||||||
// if ( fread(data.Trace, sizeof(data.Trace), 1, inFile) != 1 ) endOfFile = IsEndOfFile();
|
// if ( fread(data.Trace, sizeof(data.Trace), 1, inFile) != 1 ) endOfFile = IsEndOfFile();
|
||||||
|
|
||||||
for( int i = 0; i < data.NSample; i++ ){
|
for( unsigned int i = 0; i < data.NSample; i++ ){
|
||||||
uint16_t haha;
|
uint16_t haha;
|
||||||
size_t dummy = fread(&haha, 2, 1, inFile);
|
size_t dummy = fread(&haha, 2, 1, inFile);
|
||||||
data.Trace.push_back(haha);
|
data.Trace.push_back(haha);
|
||||||
|
@ -331,7 +344,7 @@ void BinReader::ScanNumHit(){
|
||||||
printf("scan complete: number of data Block : %ld\n", numHit);
|
printf("scan complete: number of data Block : %ld\n", numHit);
|
||||||
|
|
||||||
rewind(inFile); ///back to the File begining
|
rewind(inFile); ///back to the File begining
|
||||||
if( !isOldFormat && isHeaderOK ){
|
if( isOldFormat == false && isNoHeaderFormat == false ){ // only when normal format
|
||||||
FillData(&data.Header);
|
FillData(&data.Header);
|
||||||
}
|
}
|
||||||
inFilePos = 0;
|
inFilePos = 0;
|
||||||
|
@ -364,5 +377,4 @@ void BinReader::PrintStatus(int mod){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
6
Makefile
6
Makefile
|
@ -10,7 +10,7 @@ COPTS = -fPIC -DLINUX -O2 -std=c++17 -lpthread
|
||||||
|
|
||||||
ROOTLIBS = `root-config --cflags --glibs`
|
ROOTLIBS = `root-config --cflags --glibs`
|
||||||
|
|
||||||
ALL = Bin2Root
|
ALL = Bin2Root Bin2Root2
|
||||||
|
|
||||||
#########################################################################
|
#########################################################################
|
||||||
|
|
||||||
|
@ -22,3 +22,7 @@ clean :
|
||||||
Bin2Root : Bin2Root.cpp BinReader.h
|
Bin2Root : Bin2Root.cpp BinReader.h
|
||||||
@echo "--------- making Bin2Root"
|
@echo "--------- making Bin2Root"
|
||||||
$(CC) $(COPTS) -o Bin2Root Bin2Root.cpp $(ROOTLIBS)
|
$(CC) $(COPTS) -o Bin2Root Bin2Root.cpp $(ROOTLIBS)
|
||||||
|
|
||||||
|
Bin2Root2 : Bin2Root2.cpp BinReader.h
|
||||||
|
@echo "--------- making Bin2Root2"
|
||||||
|
$(CC) $(COPTS) -o Bin2Root2 Bin2Root2.cpp $(ROOTLIBS)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
123 456
|
0 0
|
||||||
86 49
|
1 0
|
||||||
19267 0
|
2 0
|
||||||
|
3 0
|
Loading…
Reference in New Issue
Block a user