merge from origin master
This commit is contained in:
commit
f68d26de65
12
.gitignore
vendored
12
.gitignore
vendored
|
@ -3,6 +3,8 @@
|
||||||
*.root
|
*.root
|
||||||
*.bin
|
*.bin
|
||||||
|
|
||||||
|
core.*
|
||||||
|
|
||||||
FSUDAQr
|
FSUDAQr
|
||||||
FSUDAQ_Qt6
|
FSUDAQ_Qt6
|
||||||
test
|
test
|
||||||
|
@ -22,16 +24,20 @@ DAQLock.dat
|
||||||
DumpFSU2ROOT
|
DumpFSU2ROOT
|
||||||
SettingsExplorer
|
SettingsExplorer
|
||||||
AggSeparator
|
AggSeparator
|
||||||
|
FSU2CAEN
|
||||||
|
Bin2Root
|
||||||
|
|
||||||
data
|
data
|
||||||
|
Data
|
||||||
splitpole.C
|
raw_binary
|
||||||
splitpole.h
|
|
||||||
|
|
||||||
*.d
|
*.d
|
||||||
*.pcm
|
*.pcm
|
||||||
|
|
||||||
*.txt
|
*.txt
|
||||||
|
*.tar
|
||||||
|
*.tar.gz
|
||||||
|
*.BIN
|
||||||
|
|
||||||
*~
|
*~
|
||||||
*.autosave
|
*.autosave
|
||||||
|
|
58
.vscode/settings.json
vendored
58
.vscode/settings.json
vendored
|
@ -82,39 +82,36 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"mainWindow.C": "cpp",
|
"*.C": "cpp",
|
||||||
"Scope.C": "cpp",
|
"*.pro": "makefile",
|
||||||
"new": "cpp",
|
"regex": "cpp",
|
||||||
"allocator": "cpp",
|
|
||||||
"array": "cpp",
|
|
||||||
"istream": "cpp",
|
|
||||||
"ostream": "cpp",
|
|
||||||
"sstream": "cpp",
|
|
||||||
"limits": "cpp",
|
|
||||||
"atomic": "cpp",
|
|
||||||
"bit": "cpp",
|
|
||||||
"*.tcc": "cpp",
|
|
||||||
"bitset": "cpp",
|
|
||||||
"cctype": "cpp",
|
"cctype": "cpp",
|
||||||
"chrono": "cpp",
|
|
||||||
"clocale": "cpp",
|
"clocale": "cpp",
|
||||||
"cmath": "cpp",
|
"cmath": "cpp",
|
||||||
"codecvt": "cpp",
|
|
||||||
"compare": "cpp",
|
|
||||||
"concepts": "cpp",
|
|
||||||
"condition_variable": "cpp",
|
|
||||||
"cstdarg": "cpp",
|
"cstdarg": "cpp",
|
||||||
"cstddef": "cpp",
|
"cstddef": "cpp",
|
||||||
"cstdint": "cpp",
|
|
||||||
"cstdio": "cpp",
|
"cstdio": "cpp",
|
||||||
"cstdlib": "cpp",
|
"cstdlib": "cpp",
|
||||||
"cstring": "cpp",
|
"cstring": "cpp",
|
||||||
"ctime": "cpp",
|
"ctime": "cpp",
|
||||||
"cwchar": "cpp",
|
"cwchar": "cpp",
|
||||||
"cwctype": "cpp",
|
"cwctype": "cpp",
|
||||||
|
"array": "cpp",
|
||||||
|
"atomic": "cpp",
|
||||||
|
"bit": "cpp",
|
||||||
|
"*.tcc": "cpp",
|
||||||
|
"bitset": "cpp",
|
||||||
|
"charconv": "cpp",
|
||||||
|
"chrono": "cpp",
|
||||||
|
"codecvt": "cpp",
|
||||||
|
"compare": "cpp",
|
||||||
|
"concepts": "cpp",
|
||||||
|
"condition_variable": "cpp",
|
||||||
|
"cstdint": "cpp",
|
||||||
"deque": "cpp",
|
"deque": "cpp",
|
||||||
"list": "cpp",
|
"list": "cpp",
|
||||||
"map": "cpp",
|
"map": "cpp",
|
||||||
|
"set": "cpp",
|
||||||
"string": "cpp",
|
"string": "cpp",
|
||||||
"unordered_map": "cpp",
|
"unordered_map": "cpp",
|
||||||
"unordered_set": "cpp",
|
"unordered_set": "cpp",
|
||||||
|
@ -129,38 +126,35 @@
|
||||||
"optional": "cpp",
|
"optional": "cpp",
|
||||||
"random": "cpp",
|
"random": "cpp",
|
||||||
"ratio": "cpp",
|
"ratio": "cpp",
|
||||||
|
"source_location": "cpp",
|
||||||
"string_view": "cpp",
|
"string_view": "cpp",
|
||||||
"system_error": "cpp",
|
"system_error": "cpp",
|
||||||
"tuple": "cpp",
|
"tuple": "cpp",
|
||||||
"type_traits": "cpp",
|
"type_traits": "cpp",
|
||||||
"utility": "cpp",
|
"utility": "cpp",
|
||||||
|
"format": "cpp",
|
||||||
|
"fstream": "cpp",
|
||||||
"future": "cpp",
|
"future": "cpp",
|
||||||
"initializer_list": "cpp",
|
"initializer_list": "cpp",
|
||||||
"iomanip": "cpp",
|
"iomanip": "cpp",
|
||||||
"iosfwd": "cpp",
|
"iosfwd": "cpp",
|
||||||
"iostream": "cpp",
|
"iostream": "cpp",
|
||||||
|
"istream": "cpp",
|
||||||
|
"limits": "cpp",
|
||||||
"mutex": "cpp",
|
"mutex": "cpp",
|
||||||
|
"new": "cpp",
|
||||||
"numbers": "cpp",
|
"numbers": "cpp",
|
||||||
|
"ostream": "cpp",
|
||||||
"semaphore": "cpp",
|
"semaphore": "cpp",
|
||||||
|
"shared_mutex": "cpp",
|
||||||
"span": "cpp",
|
"span": "cpp",
|
||||||
|
"sstream": "cpp",
|
||||||
"stdexcept": "cpp",
|
"stdexcept": "cpp",
|
||||||
"stop_token": "cpp",
|
"stop_token": "cpp",
|
||||||
"streambuf": "cpp",
|
"streambuf": "cpp",
|
||||||
"thread": "cpp",
|
"thread": "cpp",
|
||||||
"cinttypes": "cpp",
|
"cinttypes": "cpp",
|
||||||
"typeinfo": "cpp",
|
"typeinfo": "cpp",
|
||||||
"variant": "cpp",
|
"variant": "cpp"
|
||||||
"qmainwindow": "cpp",
|
|
||||||
"qchartview": "cpp",
|
|
||||||
"qthread": "cpp",
|
|
||||||
"qrandomgenerator": "cpp",
|
|
||||||
"source_location": "cpp",
|
|
||||||
"splitpole.C": "cpp",
|
|
||||||
"forward_list": "cpp",
|
|
||||||
"fstream": "cpp",
|
|
||||||
"Analyzer.C": "cpp",
|
|
||||||
"process_Run.C": "cpp",
|
|
||||||
"EncoreAnalyzer.C": "cpp",
|
|
||||||
"qfiledialog": "cpp"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -20,7 +20,7 @@ struct FileInfo{
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NMINARG 5
|
#define NMINARG 4
|
||||||
#define debug 0
|
#define debug 0
|
||||||
|
|
||||||
//^#############################################################
|
//^#############################################################
|
||||||
|
@ -32,14 +32,13 @@ int main(int argc, char **argv) {
|
||||||
printf("=========================================\n");
|
printf("=========================================\n");
|
||||||
if (argc < NMINARG) {
|
if (argc < NMINARG) {
|
||||||
printf("Incorrect number of arguments:\n");
|
printf("Incorrect number of arguments:\n");
|
||||||
printf("%s [timeWindow] [withTrace] [format] [inFile1] [inFile2] .... \n", argv[0]);
|
printf("%s [timeWindow] [withTrace] [inFile1] [inFile2] .... \n", argv[0]);
|
||||||
printf(" timeWindow : in ns, -1 = no event building \n");
|
printf(" timeWindow : in ns, -1 = no event building \n");
|
||||||
printf(" withTrace : 0 for no trace, 1 for trace \n");
|
printf(" withTrace : 0 for no trace, 1 for trace \n");
|
||||||
printf(" format : 0 for root, 1 for CoMPASS binary \n");
|
|
||||||
printf(" Output file name is contructed from inFile1 \n");
|
printf(" Output file name is contructed from inFile1 \n");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf(" Example: %s -1 0 0 '\\ls -1 *001*.fsu' (no event build, no trace, no verbose)\n", argv[0]);
|
printf(" Example: %s -1 0 '\\ls -1 *001*.fsu' (no event build, no trace, no verbose)\n", argv[0]);
|
||||||
printf(" %s 100 0 0 '\\ls -1 *001*.fsu' (event build with 100 ns, no trace, no verbose)\n", argv[0]);
|
printf(" %s 100 0 '\\ls -1 *001*.fsu' (event build with 100 ns, no trace, no verbose)\n", argv[0]);
|
||||||
printf("\n\n");
|
printf("\n\n");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -51,7 +50,7 @@ int main(int argc, char **argv) {
|
||||||
long timeWindow = atoi(argv[1]);
|
long timeWindow = atoi(argv[1]);
|
||||||
bool traceOn = atoi(argv[2]);
|
bool traceOn = atoi(argv[2]);
|
||||||
// unsigned int debug = atoi(argv[3]);
|
// unsigned int debug = atoi(argv[3]);
|
||||||
unsigned short format = atoi(argv[3]);
|
// unsigned short format = atoi(argv[3]);
|
||||||
unsigned int batchSize = 2* DEFAULT_HALFBUFFERSIZE;
|
unsigned int batchSize = 2* DEFAULT_HALFBUFFERSIZE;
|
||||||
int nFile = argc - NMINARG + 1;
|
int nFile = argc - NMINARG + 1;
|
||||||
TString inFileName[nFile];
|
TString inFileName[nFile];
|
||||||
|
@ -67,13 +66,9 @@ int main(int argc, char **argv) {
|
||||||
outFileName += "_" + ( timeWindow >= 0 ? std::to_string(timeWindow) : "single");
|
outFileName += "_" + ( timeWindow >= 0 ? std::to_string(timeWindow) : "single");
|
||||||
|
|
||||||
TString outFileFullName;
|
TString outFileFullName;
|
||||||
if( format == 0 ){
|
|
||||||
outFileFullName = outFileName + ".root";
|
outFileFullName = outFileName + ".root";
|
||||||
}else{
|
|
||||||
outFileFullName = outFileName + ".bin";
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t header = 0; // for caen bin
|
// uint16_t header = 0; // for caen bin
|
||||||
|
|
||||||
printf("-------> Out file name : %s \n", outFileFullName.Data());
|
printf("-------> Out file name : %s \n", outFileFullName.Data());
|
||||||
printf("========================================= Number of Files : %d \n", nFile);
|
printf("========================================= Number of Files : %d \n", nFile);
|
||||||
|
@ -94,6 +89,8 @@ int main(int argc, char **argv) {
|
||||||
FSUReader * readerA = new FSUReader(inFileName[0].Data(), 1, 1);
|
FSUReader * readerA = new FSUReader(inFileName[0].Data(), 1, 1);
|
||||||
readerA->ScanNumBlock(0,0);
|
readerA->ScanNumBlock(0,0);
|
||||||
if( readerA->GetOptimumBatchSize() > batchSize ) batchSize = readerA->GetOptimumBatchSize();
|
if( readerA->GetOptimumBatchSize() > batchSize ) batchSize = readerA->GetOptimumBatchSize();
|
||||||
|
//printf("Hit count : %7ld | opt. batch size : %7ld\n", readerA->GetTotalHitCount(), readerA->GetOptimumBatchSize());
|
||||||
|
|
||||||
FileInfo fileInfo = {inFileName[0].Data(), readerA->GetSN() * 1000 + readerA->GetFileOrder(), readerA->GetTotalHitCount()};
|
FileInfo fileInfo = {inFileName[0].Data(), readerA->GetSN() * 1000 + readerA->GetFileOrder(), readerA->GetTotalHitCount()};
|
||||||
fileList.push_back(fileInfo);
|
fileList.push_back(fileInfo);
|
||||||
totalHitCount += readerA->GetTotalHitCount();
|
totalHitCount += readerA->GetTotalHitCount();
|
||||||
|
@ -101,7 +98,9 @@ int main(int argc, char **argv) {
|
||||||
for( int i = 1; i < nFile; i++){
|
for( int i = 1; i < nFile; i++){
|
||||||
FSUReader * readerB = new FSUReader(inFileName[i].Data(), 1, 1);
|
FSUReader * readerB = new FSUReader(inFileName[i].Data(), 1, 1);
|
||||||
readerB->ScanNumBlock(0,0);
|
readerB->ScanNumBlock(0,0);
|
||||||
if( readerB->GetOptimumBatchSize() > batchSize ) batchSize = readerB->GetOptimumBatchSize();
|
// if( readerB->GetOptimumBatchSize() > batchSize ) batchSize = readerB->GetOptimumBatchSize();
|
||||||
|
batchSize = readerB->GetOptimumBatchSize();
|
||||||
|
//printf("Hit count : %7ld | opt. batch size : %7ld\n", readerB->GetTotalHitCount(), readerB->GetOptimumBatchSize());
|
||||||
|
|
||||||
totalHitCount += readerB->GetTotalHitCount();
|
totalHitCount += readerB->GetTotalHitCount();
|
||||||
fileInfo = {inFileName[i].Data(), readerB->GetSN() * 1000 + readerB->GetFileOrder(), readerB->GetTotalHitCount()};
|
fileInfo = {inFileName[i].Data(), readerB->GetSN() * 1000 + readerB->GetFileOrder(), readerB->GetTotalHitCount()};
|
||||||
|
@ -147,9 +146,6 @@ int main(int argc, char **argv) {
|
||||||
unsigned short traceLength[MAX_MULTI];
|
unsigned short traceLength[MAX_MULTI];
|
||||||
short trace[MAX_MULTI][MAX_TRACE_LENGTH];
|
short trace[MAX_MULTI][MAX_TRACE_LENGTH];
|
||||||
|
|
||||||
FILE * caen = nullptr;
|
|
||||||
|
|
||||||
if( format == 0 ){
|
|
||||||
// //*====================================== create tree
|
// //*====================================== create tree
|
||||||
outRootFile = new TFile(outFileFullName, "recreate");
|
outRootFile = new TFile(outFileFullName, "recreate");
|
||||||
tree = new TTree("tree", outFileFullName);
|
tree = new TTree("tree", outFileFullName);
|
||||||
|
@ -168,18 +164,9 @@ int main(int argc, char **argv) {
|
||||||
tree->Branch("trace", trace,"trace[multi][MAX_TRACE_LENGTH]/S");
|
tree->Branch("trace", trace,"trace[multi][MAX_TRACE_LENGTH]/S");
|
||||||
tree->GetBranch("trace")->SetCompressionSettings(205);
|
tree->GetBranch("trace")->SetCompressionSettings(205);
|
||||||
}
|
}
|
||||||
}else{
|
|
||||||
|
|
||||||
caen = fopen(outFileFullName.Data(), "wb");
|
|
||||||
if( caen == nullptr ){
|
|
||||||
perror("Failed to open file");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//*======================================= Open files
|
//*======================================= Open files
|
||||||
printf("========================================= Open files & Build Events.\n");
|
printf("========================================= Open files & reading 1st batch.\n");
|
||||||
|
|
||||||
const short nGroup = fileGroupList.size();
|
const short nGroup = fileGroupList.size();
|
||||||
std::vector<Hit> hitList[nGroup];
|
std::vector<Hit> hitList[nGroup];
|
||||||
|
@ -192,7 +179,7 @@ int main(int argc, char **argv) {
|
||||||
fList.push_back( fileGroupList[i][j].fileName );
|
fList.push_back( fileGroupList[i][j].fileName );
|
||||||
}
|
}
|
||||||
reader[i] = new FSUReader(fList, 1024, debug); // 1024 is the maximum event / agg.
|
reader[i] = new FSUReader(fList, 1024, debug); // 1024 is the maximum event / agg.
|
||||||
hitList[i] = reader[i]->ReadBatch(batchSize, debug );
|
hitList[i] = reader[i]->ReadBatch(batchSize, traceOn, debug );
|
||||||
reader[i]->PrintHitListInfo(&hitList[i], "hitList-" + std::to_string(reader[i]->GetSN()));
|
reader[i]->PrintHitListInfo(&hitList[i], "hitList-" + std::to_string(reader[i]->GetSN()));
|
||||||
ID[i] = 0;
|
ID[i] = 0;
|
||||||
if( debug ) {
|
if( debug ) {
|
||||||
|
@ -227,6 +214,7 @@ int main(int argc, char **argv) {
|
||||||
std::vector<Hit> events;
|
std::vector<Hit> events;
|
||||||
|
|
||||||
unsigned long long hitProcessed = 0;
|
unsigned long long hitProcessed = 0;
|
||||||
|
printf("========================================= Start Building Events....\n");
|
||||||
|
|
||||||
do{
|
do{
|
||||||
|
|
||||||
|
@ -241,7 +229,7 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
//chekc if reached the end of hitList
|
//chekc if reached the end of hitList
|
||||||
if( ID[ig] >= hitList[ig].size() ) {
|
if( ID[ig] >= hitList[ig].size() ) {
|
||||||
hitList[ig] = reader[ig]->ReadBatch(batchSize, debug + 1);
|
hitList[ig] = reader[ig]->ReadBatch(batchSize, traceOn, debug + 1);
|
||||||
if( debug ) reader[ig]->PrintHitListInfo( &hitList[ig], "hitList-" + std::to_string(ig));
|
if( debug ) reader[ig]->PrintHitListInfo( &hitList[ig], "hitList-" + std::to_string(ig));
|
||||||
ID[ig] = 0;
|
ID[ig] = 0;
|
||||||
if( hitList[ig].size() == 0 ) continue;
|
if( hitList[ig].size() == 0 ) continue;
|
||||||
|
@ -251,8 +239,8 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
do{
|
do{
|
||||||
|
|
||||||
if( (long int)(hitList[ig].at(ID[ig]).timestamp - t0) <= timeWindow ){
|
if( (long int)(hitList[ig][ID[ig]].timestamp - t0) <= timeWindow ){
|
||||||
events.push_back(hitList[ig].at(ID[ig]));
|
events.push_back(hitList[ig][ID[ig]]);
|
||||||
ID[ig] ++;
|
ID[ig] ++;
|
||||||
}else{
|
}else{
|
||||||
break;
|
break;
|
||||||
|
@ -260,7 +248,7 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
//check if reached the end of hitList
|
//check if reached the end of hitList
|
||||||
if( ID[ig] >= hitList[ig].size() ) {
|
if( ID[ig] >= hitList[ig].size() ) {
|
||||||
hitList[ig] = reader[ig]->ReadBatch(batchSize, debug);
|
hitList[ig] = reader[ig]->ReadBatch(batchSize, traceOn, debug);
|
||||||
if( debug ) reader[ig]->PrintHitListInfo( &hitList[ig], "hitList-" + std::to_string(ig));
|
if( debug ) reader[ig]->PrintHitListInfo( &hitList[ig], "hitList-" + std::to_string(ig));
|
||||||
ID[ig] = 0;
|
ID[ig] = 0;
|
||||||
if( hitList[ig].size() == 0 ) break;
|
if( hitList[ig].size() == 0 ) break;
|
||||||
|
@ -291,6 +279,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 po = 0 ; po < 10 ; po ++){
|
||||||
|
events[po].Print();
|
||||||
|
}
|
||||||
multi = MAX_MULTI;
|
multi = MAX_MULTI;
|
||||||
}
|
}
|
||||||
if( debug ) printf("=================================== filling data | %u \n", multi);
|
if( debug ) printf("=================================== filling data | %u \n", multi);
|
||||||
|
@ -318,26 +309,9 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( format == 0 ){
|
|
||||||
outRootFile->cd();
|
outRootFile->cd();
|
||||||
tree->Fill();
|
tree->Fill();
|
||||||
// tree->Write();
|
// tree->Write();
|
||||||
}else{
|
|
||||||
if( caen ) {
|
|
||||||
|
|
||||||
if( header == 0 ){
|
|
||||||
header = 0xCAE1; // default to have the energy only
|
|
||||||
if( events[0].energy2 > 0 ) header += 0x4;
|
|
||||||
if( events[0].traceLength > 0 && traceOn ) header += 0x8;
|
|
||||||
size_t dummy = fwrite(&header, 2, 1, caen);
|
|
||||||
if( dummy != 1 ) printf("file write error.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
for( size_t gg = 0; gg < events.size(); gg++ ){
|
|
||||||
events[gg].WriteHitsToCAENBinary(caen, header);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
multi = 0;
|
multi = 0;
|
||||||
evID ++;
|
evID ++;
|
||||||
|
@ -363,7 +337,7 @@ int main(int argc, char **argv) {
|
||||||
continue;
|
continue;
|
||||||
}else{
|
}else{
|
||||||
if( ID[i] >= hitList[i].size( )) {
|
if( ID[i] >= hitList[i].size( )) {
|
||||||
hitList[i] = reader[i]->ReadBatch(batchSize, debug);
|
hitList[i] = reader[i]->ReadBatch(batchSize, traceOn, debug);
|
||||||
ID[i] = 0;
|
ID[i] = 0;
|
||||||
if( hitList[i].size() == 0 ) nFileFinished ++;
|
if( hitList[i].size() == 0 ) nFileFinished ++;
|
||||||
}
|
}
|
||||||
|
@ -373,7 +347,7 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
}while( nFileFinished < nGroup);
|
}while( nFileFinished < nGroup);
|
||||||
|
|
||||||
if( format == 0 ) tree->Write();
|
tree->Write();
|
||||||
|
|
||||||
uInt runEndTime = getTime_us();
|
uInt runEndTime = getTime_us();
|
||||||
double runTime = (runEndTime - runStartTime) * 1e-6;
|
double runTime = (runEndTime - runStartTime) * 1e-6;
|
||||||
|
@ -387,15 +361,12 @@ int main(int argc, char **argv) {
|
||||||
printf(" total data duration = %.2f sec = %.2f min\n", tDuration_sec, tDuration_sec/60.);
|
printf(" total data duration = %.2f sec = %.2f min\n", tDuration_sec, tDuration_sec/60.);
|
||||||
printf("========================================> saved to %s \n", outFileFullName.Data());
|
printf("========================================> saved to %s \n", outFileFullName.Data());
|
||||||
|
|
||||||
if( format == 0 ){
|
|
||||||
TMacro info;
|
TMacro info;
|
||||||
info.AddLine(Form("tStart= %20llu ns",tStart));
|
info.AddLine(Form("tStart= %20llu ns",tStart));
|
||||||
info.AddLine(Form(" tEnd= %20llu ns",tEnd));
|
info.AddLine(Form(" tEnd= %20llu ns",tEnd));
|
||||||
info.Write("info");
|
info.Write("info");
|
||||||
outRootFile->Close();
|
outRootFile->Close();
|
||||||
}else{
|
|
||||||
fclose(caen);
|
|
||||||
}
|
|
||||||
|
|
||||||
for( int i = 0; i < nGroup; i++) delete reader[i];
|
for( int i = 0; i < nGroup; i++) delete reader[i];
|
||||||
delete [] reader;
|
delete [] reader;
|
||||||
|
|
305
Aux/FSU2CAEN.cpp
Normal file
305
Aux/FSU2CAEN.cpp
Normal file
|
@ -0,0 +1,305 @@
|
||||||
|
#include "fsuReader.h"
|
||||||
|
|
||||||
|
struct FileInfo{
|
||||||
|
std::string fileName;
|
||||||
|
int fileevID;
|
||||||
|
unsigned long hitCount;
|
||||||
|
int sn;
|
||||||
|
int numCh;
|
||||||
|
int runNum;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define minNARG 3
|
||||||
|
|
||||||
|
//^#############################################################
|
||||||
|
//^#############################################################
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
printf("=========================================\n");
|
||||||
|
printf("=== *.fsu to CoMPASS bin ===\n");
|
||||||
|
printf("=========================================\n");
|
||||||
|
if (argc < minNARG) {
|
||||||
|
printf("Incorrect number of arguments:\n");
|
||||||
|
printf("%s [tar] [inFile1] [inFile2] .... \n", argv[0]);
|
||||||
|
printf(" tar : output tar, 0 = no, 1 = yes \n");
|
||||||
|
printf("\n");
|
||||||
|
printf(" Example: %s 0 '\\ls -1 *001*.fsu'\n", argv[0]);
|
||||||
|
printf("\n\n");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int debug = false;
|
||||||
|
uInt runStartTime = getTime_us();
|
||||||
|
|
||||||
|
///============= read input
|
||||||
|
// long timeWindow = atoi(argv[1]);
|
||||||
|
// bool traceOn = atoi(argv[2]);
|
||||||
|
bool tarFlag = atoi(argv[1]);
|
||||||
|
unsigned int batchSize = 2* DEFAULT_HALFBUFFERSIZE;
|
||||||
|
int nFile = argc - minNARG + 1;
|
||||||
|
std::string inFileName[nFile];
|
||||||
|
for( int i = 0 ; i < nFile ; i++){ inFileName[i] = argv[i+ minNARG - 1];}
|
||||||
|
|
||||||
|
printf("========================================= Number of Files : %d \n", nFile);
|
||||||
|
for( int i = 0; i < nFile; i++) printf("%2d | %s \n", i, inFileName[i].c_str());
|
||||||
|
printf("=========================================\n");
|
||||||
|
printf(" Batch size = %d events/file\n", batchSize);
|
||||||
|
// printf(" Out file name = %s \n", outFileName.c_str());
|
||||||
|
printf(" Is tar output = %s \n", tarFlag ? "Yes" : "No");
|
||||||
|
printf("========================================= Grouping files\n");
|
||||||
|
|
||||||
|
std::vector<std::vector<FileInfo>> fileGroupList; // fileName and evID = SN * 1000 + index
|
||||||
|
std::vector<FileInfo> fileList;
|
||||||
|
|
||||||
|
unsigned long long int totalHitCount = 0;
|
||||||
|
|
||||||
|
FSUReader * readerA = new FSUReader(inFileName[0], 1, 1);
|
||||||
|
readerA->ScanNumBlock(0,0);
|
||||||
|
if( readerA->GetOptimumBatchSize() > batchSize ) batchSize = readerA->GetOptimumBatchSize();
|
||||||
|
FileInfo fileInfo = {inFileName[0], readerA->GetSN() * 1000 + readerA->GetFileOrder(), readerA->GetTotalHitCount(), readerA->GetSN(), readerA->GetNumCh(), readerA->GetRunNum()};
|
||||||
|
fileList.push_back(fileInfo);
|
||||||
|
totalHitCount += readerA->GetTotalHitCount();
|
||||||
|
|
||||||
|
for( int i = 1; i < nFile; i++){
|
||||||
|
FSUReader * readerB = new FSUReader(inFileName[i], 1, 1);
|
||||||
|
readerB->ScanNumBlock(0,0);
|
||||||
|
if( readerB->GetOptimumBatchSize() > batchSize ) batchSize = readerB->GetOptimumBatchSize();
|
||||||
|
|
||||||
|
totalHitCount += readerB->GetTotalHitCount();
|
||||||
|
fileInfo = {inFileName[i], readerB->GetSN() * 1000 + readerB->GetFileOrder(), readerB->GetTotalHitCount(), readerB->GetSN(), readerB->GetNumCh(), readerB->GetRunNum()};
|
||||||
|
|
||||||
|
if( readerA->GetSN() == readerB->GetSN() ){
|
||||||
|
fileList.push_back(fileInfo);
|
||||||
|
}else{
|
||||||
|
fileGroupList.push_back(fileList);
|
||||||
|
fileList.clear();
|
||||||
|
fileList.push_back(fileInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete readerA;
|
||||||
|
readerA = readerB;
|
||||||
|
}
|
||||||
|
fileGroupList.push_back(fileList);
|
||||||
|
delete readerA;
|
||||||
|
|
||||||
|
printf("======================= total Hit Count : %llu\n", totalHitCount);
|
||||||
|
|
||||||
|
for( size_t i = 0; i < fileGroupList.size(); i++){
|
||||||
|
printf("group ----- %ld \n", i);
|
||||||
|
|
||||||
|
//sort by evID
|
||||||
|
std::sort(fileGroupList[i].begin(), fileGroupList[i].end(), [](const FileInfo & a, const FileInfo & b) {
|
||||||
|
return a.fileevID < b.fileevID;
|
||||||
|
});
|
||||||
|
|
||||||
|
for( size_t j = 0; j < fileGroupList[i].size(); j++){
|
||||||
|
printf("%3ld | %8d | %9lu| %s \n", j, fileGroupList[i][j].fileevID, fileGroupList[i][j].hitCount, fileGroupList[i][j].fileName.c_str() );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//*====================================== format output files
|
||||||
|
|
||||||
|
const short numFileGroup = fileGroupList.size();
|
||||||
|
|
||||||
|
FILE ** outFile[numFileGroup];
|
||||||
|
|
||||||
|
std::vector<std::string> outFileName[numFileGroup];
|
||||||
|
std::vector<uint16_t> header[numFileGroup];
|
||||||
|
std::vector<unsigned int> flags[numFileGroup];
|
||||||
|
|
||||||
|
for( int i = 0; i < numFileGroup; i++ ){
|
||||||
|
outFile[i] = new FILE * [fileGroupList[i][0].numCh];
|
||||||
|
for( int ch = 0; ch < fileGroupList[i][0].numCh; ch++ ){
|
||||||
|
std::string dudu = "Data_CH" + std::to_string(ch) + "@DIGI_" + std::to_string(fileGroupList[i][0].sn) + "_run_" + std::to_string(fileGroupList[i][0].runNum) + ".BIN";
|
||||||
|
// printf("|%s| \n", dudu.c_str());
|
||||||
|
outFile[i][ch] = fopen(dudu.c_str(), "wb");
|
||||||
|
outFileName[i].push_back(dudu);
|
||||||
|
header[i].push_back(0);
|
||||||
|
flags[i].push_back(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// std::string temp = inFileName[0];
|
||||||
|
// size_t pos = temp.find('_');
|
||||||
|
// pos = temp.find('_', pos + 1);
|
||||||
|
// std::string outFile_prefix = temp.substr(0, pos);
|
||||||
|
// std::string outFileName = outFile_prefix + ".BIN";
|
||||||
|
|
||||||
|
//*======================================= Open files
|
||||||
|
printf("========================================= Open files & Build Events.\n");
|
||||||
|
|
||||||
|
const short nGroup = fileGroupList.size();
|
||||||
|
std::vector<Hit> hitList[nGroup];
|
||||||
|
|
||||||
|
FSUReader ** reader = new FSUReader * [nGroup];
|
||||||
|
ulong evID[nGroup];
|
||||||
|
for( short i = 0; i < nGroup; i++){
|
||||||
|
std::vector<std::string> fList;
|
||||||
|
for( size_t j = 0; j < fileGroupList[i].size(); j++){
|
||||||
|
fList.push_back( fileGroupList[i][j].fileName );
|
||||||
|
}
|
||||||
|
reader[i] = new FSUReader(fList, 600, debug);
|
||||||
|
hitList[i] = reader[i]->ReadBatch(batchSize, debug );
|
||||||
|
reader[i]->PrintHitListInfo(&hitList[i], "hitList-" + std::to_string(reader[i]->GetSN()));
|
||||||
|
evID[i] = 0;
|
||||||
|
if( debug ) {
|
||||||
|
|
||||||
|
for( size_t p = 0; p < 10; p ++ ){
|
||||||
|
if( hitList[i].size() <= p ) break;
|
||||||
|
hitList[i][p].Print();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long long tStart = 0;
|
||||||
|
unsigned long long tEnd = 0;
|
||||||
|
|
||||||
|
unsigned long long t0 = -1;
|
||||||
|
short g0 = 0 ;
|
||||||
|
int nFileFinished = 0;
|
||||||
|
unsigned long long hitProcessed = 0;
|
||||||
|
|
||||||
|
do{
|
||||||
|
|
||||||
|
// find the earlist time
|
||||||
|
t0 = -1;
|
||||||
|
for( short i = 0; i < nGroup; i++){
|
||||||
|
|
||||||
|
if( hitList[i].size() == 0 ) continue;
|
||||||
|
|
||||||
|
//chekc if reached the end of hitList
|
||||||
|
if( evID[i] >= hitList[i].size() ) {
|
||||||
|
hitList[i] = reader[i]->ReadBatch(batchSize, debug + 1);
|
||||||
|
if( debug ) reader[i]->PrintHitListInfo( &hitList[i], "hitList-" + std::to_string(i));
|
||||||
|
evID[i] = 0;
|
||||||
|
if( hitList[i].size() == 0 ) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( hitList[i][evID[i]].timestamp < t0 ) {
|
||||||
|
t0 = hitList[i][evID[i]].timestamp;
|
||||||
|
g0 = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set file header
|
||||||
|
int p_ch = hitList[g0][evID[g0]].ch; // present ch
|
||||||
|
|
||||||
|
if( header[g0][p_ch] == 0 ) {
|
||||||
|
header[g0][p_ch] = 0xCAE1;
|
||||||
|
if( hitList[g0][evID[g0]].energy2 > 0 ) header[g0][p_ch] += 4;
|
||||||
|
if( hitList[g0][evID[g0]].traceLength > 0 ) header[g0][p_ch] += 8;
|
||||||
|
if( hitList[g0][evID[g0]].pileUp ) flags[g0][p_ch] += 0x8000;
|
||||||
|
if( hitList[g0][evID[g0]].fineTime > 0 ) flags[g0][p_ch] += 0x4000;
|
||||||
|
|
||||||
|
fwrite(&(header[g0][p_ch]), 2, 1, outFile[g0][p_ch]);
|
||||||
|
}
|
||||||
|
|
||||||
|
hitList[g0][evID[g0]].WriteHitsToCAENBinary(outFile[g0][p_ch], header[g0][p_ch]);
|
||||||
|
|
||||||
|
// fwrite(&(hitList[g0][evID[g0]].sn), 2, 1, outFile);
|
||||||
|
// fwrite(&(hitList[g0][evID[g0]].ch), 2, 1, outFile);
|
||||||
|
// unsigned psTimestamp = hitList[g0][evID[g0]].timestamp * 1000 + hitList[g0][evID[g0]].fineTime;
|
||||||
|
// fwrite(&(psTimestamp), 8, 1, outFile);
|
||||||
|
// fwrite(&(hitList[g0][evID[g0]].energy), 2, 1, outFile);
|
||||||
|
// if( hitList[g0][evID[g0]].energy2 > 0 ) fwrite(&(hitList[g0][evID[g0]].energy2), 2, 1, outFile);
|
||||||
|
// fwrite(&(flags), 4, 1, outFile);
|
||||||
|
// if( hitList[g0][evID[g0]].traceLength > 0 ){
|
||||||
|
// char waveCode = 1;
|
||||||
|
// fwrite(&(waveCode), 1, 1, outFile);
|
||||||
|
// fwrite(&(hitList[g0][evID[g0]].traceLength), 4, 1, outFile);
|
||||||
|
|
||||||
|
// for( int i = 0; i < hitList[g0][evID[g0]].traceLength; i++ ){
|
||||||
|
// fwrite(&(hitList[g0][evID[g0]].trace[i]), 2, 1, outFile);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
evID[g0]++;
|
||||||
|
if( hitProcessed == 0) tStart = hitList[g0][evID[g0]].timestamp;
|
||||||
|
hitProcessed ++;
|
||||||
|
if( hitProcessed % 10000 == 0 ) printf("hit Porcessed %llu/%llu hit....%.2f%%\n\033[A\r", hitProcessed, totalHitCount, hitProcessed*100./totalHitCount);
|
||||||
|
|
||||||
|
if( hitProcessed == totalHitCount -1 ) tEnd = hitList[g0][evID[g0]].timestamp;
|
||||||
|
|
||||||
|
//*=============
|
||||||
|
nFileFinished = 0;
|
||||||
|
for( int i = 0 ; i < nGroup; i++) {
|
||||||
|
if( hitList[i].size() == 0 ) {
|
||||||
|
nFileFinished ++;
|
||||||
|
continue;
|
||||||
|
}else{
|
||||||
|
if( evID[i] >= hitList[i].size( )) {
|
||||||
|
hitList[i] = reader[i]->ReadBatch(batchSize, debug);
|
||||||
|
evID[i] = 0;
|
||||||
|
if( hitList[i].size() == 0 ) nFileFinished ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( debug > 1 ) printf("========== nFileFinished : %d\n", nFileFinished);
|
||||||
|
|
||||||
|
}while( nFileFinished < nGroup);
|
||||||
|
|
||||||
|
uInt 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 hit = %llu \n", hitProcessed);
|
||||||
|
double tDuration_sec = (tEnd - tStart) * 1e-9;
|
||||||
|
printf(" first timestamp = %20llu ns\n", tStart);
|
||||||
|
printf(" last timestamp = %20llu ns\n", tEnd);
|
||||||
|
printf(" total data duration = %.2f sec = %.2f min\n", tDuration_sec, tDuration_sec/60.);
|
||||||
|
|
||||||
|
for( int i = 0; i < nGroup; i++) delete reader[i];
|
||||||
|
delete [] reader;
|
||||||
|
|
||||||
|
//============================== delete empty files and close FILE
|
||||||
|
std::vector<std::string> nonEmptyFileList;
|
||||||
|
|
||||||
|
printf("================= Removing Empty Files ....\n");
|
||||||
|
printf("============================> saved to ....");
|
||||||
|
|
||||||
|
if( tarFlag == false ) printf("\n");
|
||||||
|
|
||||||
|
for( int i = 0; i < numFileGroup; i++ ){
|
||||||
|
for( int ch = 0; ch < fileGroupList[i][0].numCh; ch++){
|
||||||
|
if( ftell(outFile[i][ch]) == 0 ){
|
||||||
|
int dummy = std::system(("rm -f " + outFileName[i][ch]).c_str());
|
||||||
|
// printf("Remove %s.\n", outFileName[i][ch].c_str());
|
||||||
|
}else{
|
||||||
|
nonEmptyFileList.push_back(outFileName[i][ch]);
|
||||||
|
if( tarFlag == false ) printf("%s\n", outFileName[i][ch].c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( tarFlag ){
|
||||||
|
std::string tarFileName = "run_" + std::to_string(fileGroupList[0][0].runNum) + ".tar.gz";
|
||||||
|
|
||||||
|
printf("%s\n", tarFileName.c_str());
|
||||||
|
printf("============================> tar.gz the BIN\n");
|
||||||
|
std::string command = "tar -czf " + tarFileName + " ";
|
||||||
|
for( size_t i = 0; i < nonEmptyFileList.size(); i++ ){
|
||||||
|
command += nonEmptyFileList[i] + " ";
|
||||||
|
}
|
||||||
|
int result = std::system(command.c_str());
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
printf("Archive created successfully: %s\n", tarFileName.c_str());
|
||||||
|
for( size_t i = 0; i < nonEmptyFileList.size(); i++ ){
|
||||||
|
int dummy = std::system(("rm -f " + nonEmptyFileList[i]).c_str());
|
||||||
|
// printf("Remove %s.\n", nonEmptyFileList[i].c_str());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("Error creating archive\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("============================================== end of program\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
18
Aux/Makefile
18
Aux/Makefile
|
@ -5,8 +5,8 @@
|
||||||
|
|
||||||
CC = g++
|
CC = g++
|
||||||
|
|
||||||
#COPTS = -fPIC -DLINUX -O2 -std=c++17 -lpthread
|
COPTS = -fPIC -DLINUX -O2 -std=c++17 -lpthread
|
||||||
COPTS = -fPIC -DLINUX -g -O0 -Wall -std=c++17 -lpthread
|
# COPTS = -fPIC -DLINUX -g -O0 -Wall -std=c++17 -lpthread
|
||||||
|
|
||||||
CAENLIBS = -lCAENDigitizer -lCAENVME
|
CAENLIBS = -lCAENDigitizer -lCAENVME
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ ROOTLIBS = `root-config --cflags --glibs`
|
||||||
|
|
||||||
OBJS = ClassDigitizer.o MultiBuilder.o ClassInfluxDB.o
|
OBJS = ClassDigitizer.o MultiBuilder.o ClassInfluxDB.o
|
||||||
|
|
||||||
ALL = test EventBuilder DataReader DumpFSU2ROOT SettingsExplorer
|
ALL = test EventBuilder DataReader DumpFSU2ROOT SettingsExplorer FSU2CAEN
|
||||||
|
|
||||||
#########################################################################
|
#########################################################################
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ ClassInfluxDB.o : ../ClassInfluxDB.cpp ../ClassInfluxDB.h
|
||||||
|
|
||||||
test : test.cpp ../ClassDigitizer.o ../MultiBuilder.o ../ClassInfluxDB.o
|
test : test.cpp ../ClassDigitizer.o ../MultiBuilder.o ../ClassInfluxDB.o
|
||||||
@echo "--------- making test"
|
@echo "--------- making test"
|
||||||
$(CC) $(COPTS) -o test test.cpp ../ClassDigitizer.o ../MultiBuilder.o ../ClassInfluxDB.o $(CAENLIBS) $(ROOTLIBS) -lcurl
|
$(CC) -fPIC -DLINUX -O0 -std=c++17 -lpthread -g -o test test.cpp ../ClassDigitizer.o ../MultiBuilder.o ../ClassInfluxDB.o $(CAENLIBS) $(ROOTLIBS) -lcurl
|
||||||
|
|
||||||
# test_indep : test_indep.cpp ../RegisterAddress.h ../macro.h
|
# test_indep : test_indep.cpp ../RegisterAddress.h ../macro.h
|
||||||
# @echo "--------- making test_indep"
|
# @echo "--------- making test_indep"
|
||||||
|
@ -44,17 +44,13 @@ DataReader : DataReaderScript.cpp ../ClassData.h MultiBuilder.o
|
||||||
@echo "--------- making DataReader"
|
@echo "--------- making DataReader"
|
||||||
$(CC) $(COPTS) -o DataReader DataReaderScript.cpp ../ClassData.h MultiBuilder.o
|
$(CC) $(COPTS) -o DataReader DataReaderScript.cpp ../ClassData.h MultiBuilder.o
|
||||||
|
|
||||||
# EventBuilder_old : EventBuilder_old.cpp ../ClassData.h MultiBuilder.o fsuReader.h
|
|
||||||
# @echo "--------- making EventBuilder"
|
|
||||||
# $(CC) $(COPTS) -o EventBuilder_old EventBuilder_old.cpp MultiBuilder.o $(ROOTLIBS)
|
|
||||||
|
|
||||||
EventBuilder : EventBuilder.cpp ../ClassData.h fsuReader.h ../Hit.h
|
EventBuilder : EventBuilder.cpp ../ClassData.h fsuReader.h ../Hit.h
|
||||||
@echo "--------- making EventBuilder"
|
@echo "--------- making EventBuilder"
|
||||||
$(CC) $(COPTS) -o EventBuilder EventBuilder.cpp $(ROOTLIBS)
|
$(CC) $(COPTS) -o EventBuilder EventBuilder.cpp $(ROOTLIBS)
|
||||||
|
|
||||||
# EventBuilderNoTrace : EventBuilderNoTrace.cpp ../ClassData.h fsuReader.h ../Hit.h
|
FSU2CAEN : FSU2CAEN.cpp ../ClassData.h fsuReader.h ../Hit.h
|
||||||
# @echo "--------- making EventBuilderNoTrace"
|
@echo "--------- making FSU2CAEN"
|
||||||
# $(CC) $(COPTS) -o EventBuilderNoTrace EventBuilderNoTrace.cpp $(ROOTLIBS)
|
$(CC) $(COPTS) -o FSU2CAEN FSU2CAEN.cpp
|
||||||
|
|
||||||
DumpFSU2ROOT : DumpFSU2ROOT.cpp ../ClassData.h MultiBuilder.o
|
DumpFSU2ROOT : DumpFSU2ROOT.cpp ../ClassData.h MultiBuilder.o
|
||||||
@echo "--------- making DumpFSU2ROOT"
|
@echo "--------- making DumpFSU2ROOT"
|
||||||
|
|
|
@ -37,18 +37,16 @@ With this approach, it is guaranteed that the output hitList_A is always time-so
|
||||||
This defines the EventBuilder. The arguments are
|
This defines the EventBuilder. The arguments are
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./EventBuilder [timeWindow] [withTrace] [verbose] [batchSize] [inFile1] [inFile2] ....
|
./EventBuilder [timeWindow] [withTrace] [inFile1] [inFile2] ....
|
||||||
timeWindow : in ns, -1 = no event building
|
timeWindow : in ns, -1 = no event building
|
||||||
withTrace : 0 for no trace, 1 for trace
|
withTrace : 0 for no trace, 1 for trace
|
||||||
verbose : > 0 for debug
|
|
||||||
batchSize : the size of hit in a batch
|
|
||||||
Output file name is contructed from inFile1
|
Output file name is contructed from inFile1
|
||||||
```
|
```
|
||||||
|
|
||||||
as an example,
|
as an example,
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
/EventBuilder 0 0 0 1000000 '\ls -1 test_001*.fsu'
|
/EventBuilder 0 0'\ls -1 test_001*.fsu'
|
||||||
```
|
```
|
||||||
|
|
||||||
setting the timeWindow to be -1, will split out a timesorted Hit.
|
setting the timeWindow to be -1, will split out a timesorted Hit.
|
||||||
|
@ -115,6 +113,16 @@ Evenbuilder output is standard information, an example structure is
|
||||||
*............................................................................*
|
*............................................................................*
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# FSU2CAEN.cpp
|
||||||
|
|
||||||
|
This convert the *.fsu to Data_CHXX@DIGI_YYYYY_run_ZZ.BIN. the BIN is CoMPASS format and could be useful for couple with existing analysis routine.
|
||||||
|
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./FSU2CAEN [tarFlag] [inFile1] [inFile2] ....
|
||||||
|
targFlag : if 1, tar ball all output files.
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
# SettingsExplorer.cpp
|
# SettingsExplorer.cpp
|
||||||
|
|
||||||
|
|
|
@ -64,13 +64,14 @@ void keyPressCommand(){
|
||||||
if( RegList[i].GetRWType() == RW::ReadONLY ) typeStr = "R ";
|
if( RegList[i].GetRWType() == RW::ReadONLY ) typeStr = "R ";
|
||||||
if( RegList[i].GetRWType() == RW::WriteONLY ) typeStr = " W";
|
if( RegList[i].GetRWType() == RW::WriteONLY ) typeStr = " W";
|
||||||
|
|
||||||
|
unsigned int value = digi->GetSettingFromMemory(RegList[i], 0);
|
||||||
|
|
||||||
printf("%2d | 0x%04X %30s %s 0x%08X = %u\n", i,
|
printf("%2d | 0x%04X %30s %s 0x%08X = %10u\n", i,
|
||||||
RegList[i].GetAddress(),
|
RegList[i].GetAddress(),
|
||||||
RegList[i].GetNameChar(),
|
RegList[i].GetNameChar(),
|
||||||
typeStr.c_str(),
|
typeStr.c_str(),
|
||||||
digi->GetSettingFromMemory(RegList[i], 0),
|
value,
|
||||||
digi->GetSettingFromMemory(RegList[i], 0));
|
value);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string input = "-1";
|
std::string input = "-1";
|
||||||
|
@ -143,12 +144,15 @@ void keyPressCommand(){
|
||||||
|
|
||||||
RegList[i].ActualAddress(ch);
|
RegList[i].ActualAddress(ch);
|
||||||
|
|
||||||
printf("%2d | 0x%04X %30s %s 0x%08X = %u\n", i,
|
unsigned int value = digi->GetSettingFromMemory(RegList[i], ch);
|
||||||
|
|
||||||
|
printf("%2d | 0x%04X %30s %s 0x%08X = %10u : %d\n", i,
|
||||||
RegList[i].GetAddress(),
|
RegList[i].GetAddress(),
|
||||||
RegList[i].GetNameChar(),
|
RegList[i].GetNameChar(),
|
||||||
typeStr.c_str(),
|
typeStr.c_str(),
|
||||||
digi->GetSettingFromMemory(RegList[i], ch),
|
value,
|
||||||
digi->GetSettingFromMemory(RegList[i], ch));
|
value,
|
||||||
|
value * abs(RegList[i].GetPartialStep()));
|
||||||
}
|
}
|
||||||
|
|
||||||
do{
|
do{
|
||||||
|
|
274
Aux/SplitPolePlotter.C
Normal file
274
Aux/SplitPolePlotter.C
Normal file
|
@ -0,0 +1,274 @@
|
||||||
|
#ifndef SPLITPOLEPLOTTER
|
||||||
|
#define SPLITPOLEPLOTTER
|
||||||
|
|
||||||
|
#include "TFile.h"
|
||||||
|
#include "TChain.h"
|
||||||
|
#include "TH1F.h"
|
||||||
|
#include "TTreeReader.h"
|
||||||
|
#include "TTreeReaderValue.h"
|
||||||
|
#include "TTreeReaderArray.h"
|
||||||
|
#include "TClonesArray.h"
|
||||||
|
#include "TGraph.h"
|
||||||
|
#include "TCutG.h"
|
||||||
|
#include "TH2.h"
|
||||||
|
#include "TCanvas.h"
|
||||||
|
#include "TStyle.h"
|
||||||
|
#include "TStopwatch.h"
|
||||||
|
#include "TMath.h"
|
||||||
|
|
||||||
|
#include "vector"
|
||||||
|
#include "../analyzers/SplitPoleHit.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace ChMap{
|
||||||
|
|
||||||
|
const short ScinR = 0;
|
||||||
|
const short ScinL = 1;
|
||||||
|
const short dFR = 9;
|
||||||
|
const short dFL = 8;
|
||||||
|
const short dBR = 11;
|
||||||
|
const short dBL = 10;
|
||||||
|
const short Cathode = 7;
|
||||||
|
const short AnodeF = 13;
|
||||||
|
const short AnodeB = 15;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const double c = 299.792458; // mm/ns
|
||||||
|
const double pi = M_PI;
|
||||||
|
const double deg2rad = pi/180.;
|
||||||
|
|
||||||
|
SplitPoleHit hit;
|
||||||
|
|
||||||
|
TH2F * PID;
|
||||||
|
TH2F * coin;
|
||||||
|
|
||||||
|
TH1F * hMulti;
|
||||||
|
|
||||||
|
TH1F * hF;
|
||||||
|
TH1F * hB;
|
||||||
|
TH1F * hXavg;
|
||||||
|
|
||||||
|
TH2F * hFocal;
|
||||||
|
|
||||||
|
TH2F * hXavg_Q;
|
||||||
|
TH2F * hXavg_Theta;
|
||||||
|
|
||||||
|
TH2F * hRay;
|
||||||
|
TH1F * hEx;
|
||||||
|
|
||||||
|
TH2F * hEx_Multi;
|
||||||
|
|
||||||
|
ULong64_t t1, t2;
|
||||||
|
|
||||||
|
#define XMIN -200
|
||||||
|
#define XMAX 200
|
||||||
|
|
||||||
|
//^###########################################
|
||||||
|
|
||||||
|
void SplitPolePlotter(TChain *tree, TCutG * pidCut = nullptr, double rhoOffset = 0, double rhoScaling = 1, bool isFSUDAQ = true){
|
||||||
|
|
||||||
|
printf("#####################################################################\n");
|
||||||
|
printf("################# SplitPolePlotter.C ####################\n");
|
||||||
|
printf("#####################################################################\n");
|
||||||
|
|
||||||
|
TObjArray * fileList = tree->GetListOfFiles();
|
||||||
|
printf("\033[0;31m========================================== Number of Files : %2d\n",fileList->GetEntries());
|
||||||
|
fileList->Print();
|
||||||
|
printf("========================================== Number of Files : %2d\033[0m\n",fileList->GetEntries());
|
||||||
|
|
||||||
|
printf("///////////////////////////////////////////////////////////////////\n");
|
||||||
|
printf(" Total Number of entries : %llu \n", tree->GetEntries());
|
||||||
|
printf("///////////////////////////////////////////////////////////////////\n");
|
||||||
|
|
||||||
|
if( tree->GetEntries() == 0 ) {
|
||||||
|
printf("========= no events. Abort.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*====================================================== histograms
|
||||||
|
|
||||||
|
coin = new TH2F("hCoin", "Coincident ", 16, 0, 16, 16, 0, 16);
|
||||||
|
hMulti = new TH1F("hMulti", "Multiplicity", 16, 0, 16);
|
||||||
|
|
||||||
|
if( isFSUDAQ ){
|
||||||
|
PID = new TH2F("hPID", "PID; Scin_X ; AnodeB", 200, 0, 20000, 100, 0, 40000);
|
||||||
|
hXavg_Q = new TH2F("hXavg_Q", "Xavg vs Q ", 200, XMIN, XMAX, 200, 0, 40000);
|
||||||
|
}else{
|
||||||
|
PID = new TH2F("hPID", "PID; Scin_X ; AnodeB", 200, 0, 4000, 100, 0, 5000);
|
||||||
|
hXavg_Q = new TH2F("hXavg_Q", "Xavg vs Q ", 200, XMIN, XMAX, 200, 0, 5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
hF = new TH1F("hF", "Front delay line position", 600, XMIN, XMAX);
|
||||||
|
hB = new TH1F("hB", "Back delay line position", 600, XMIN, XMAX);
|
||||||
|
hXavg = new TH1F("hAvg", "Xavg", 600, XMIN, XMAX);
|
||||||
|
|
||||||
|
hFocal = new TH2F("hFocal", "Front vs Back ", 200, XMIN, XMAX, 200, XMIN, XMAX);
|
||||||
|
hXavg_Theta = new TH2F("hXavg_Theta", "Xavg vs Theta ", 200, XMIN, XMAX, 200, 0.5, 1.4);
|
||||||
|
|
||||||
|
hRay = new TH2F("hRay", "Ray plot", 400, XMIN, XMAX, 400, -50, 50);
|
||||||
|
|
||||||
|
hEx = new TH1F("hEx", "Ex; Ex [MeV]; count/10 keV", 600, -1, 5);
|
||||||
|
|
||||||
|
hEx_Multi = new TH2F("hEx_Multi", "Ex vs Multi; Ex; Multi", 600, -1, 5, 16, 0, 16);
|
||||||
|
|
||||||
|
hit.SetMassTablePath("../analyzers/mass20.txt");
|
||||||
|
hit.CalConstants("12C", "d", "p", 16, 18); // 80MeV, 5 deg
|
||||||
|
hit.CalZoffset(0.750); // 1.41 T
|
||||||
|
|
||||||
|
t1 = 0;
|
||||||
|
t2 = 0;
|
||||||
|
|
||||||
|
|
||||||
|
//*====================================================== Tree Reader
|
||||||
|
TTreeReader reader(tree);
|
||||||
|
|
||||||
|
TTreeReaderValue<ULong64_t> evID = {reader, "evID"};
|
||||||
|
TTreeReaderValue<UInt_t> multi = {reader, "multi"};
|
||||||
|
TTreeReaderArray<UShort_t> sn = {reader, "sn"};
|
||||||
|
TTreeReaderArray<UShort_t> ch = {reader, "ch"};
|
||||||
|
TTreeReaderArray<UShort_t> e = {reader, "e"};
|
||||||
|
TTreeReaderArray<UShort_t> e2 = {reader, "e2"};
|
||||||
|
TTreeReaderArray<ULong64_t> e_t = {reader, "e_t"};
|
||||||
|
TTreeReaderArray<UShort_t> e_f = {reader, "e_f"};
|
||||||
|
|
||||||
|
ULong64_t NumEntries = tree->GetEntries();
|
||||||
|
|
||||||
|
//^###########################################################
|
||||||
|
//^ * Process
|
||||||
|
//^###########################################################
|
||||||
|
printf("############################################### Processing...\n");
|
||||||
|
fflush(stdout); // flush out any printf
|
||||||
|
|
||||||
|
ULong64_t processedEntries = 0;
|
||||||
|
float Frac = 0.1;
|
||||||
|
TStopwatch StpWatch;
|
||||||
|
StpWatch.Start();
|
||||||
|
|
||||||
|
while (reader.Next()) {
|
||||||
|
|
||||||
|
// if( processedEntries > 10 ) break;
|
||||||
|
// printf("============== %5llu | multi : %d (%zu) \n", processedEntries, multi.Get()[0], sn.GetSize());
|
||||||
|
// for( int i = 0; i < multi.Get()[0]; i++ ){
|
||||||
|
// printf(" %d | %5d %2d %7d %10llu\n", i, sn[i], ch[i], e[i], e_t[i]);
|
||||||
|
// }
|
||||||
|
|
||||||
|
hit.ClearData();
|
||||||
|
hMulti->Fill(*multi);
|
||||||
|
|
||||||
|
// if( *multi != 9 ) continue;
|
||||||
|
|
||||||
|
for( int i = 0; i < *multi; i++){
|
||||||
|
|
||||||
|
t2 = e_t[i];
|
||||||
|
if( t2 < t1 ) printf("entry %lld-%d, timestamp is not in order. %llu, %llu\n", processedEntries, i, t2, t1);
|
||||||
|
if( i == 0 ) t1 = e_t[i];
|
||||||
|
|
||||||
|
// if( e[i] == 65535 ) continue;
|
||||||
|
|
||||||
|
if( ch[i] == ChMap::ScinR ) {hit.eSR = e[i]; hit.tSR = e_t[i] + e_f[i]/1000;}
|
||||||
|
if( ch[i] == ChMap::ScinL ) {hit.eSL = e[i]; hit.tSL = e_t[i] + e_f[i]/1000;}
|
||||||
|
if( ch[i] == ChMap::dFR ) {hit.eFR = e[i]; hit.tFR = e_t[i] + e_f[i]/1000;}
|
||||||
|
if( ch[i] == ChMap::dFL ) {hit.eFL = e[i]; hit.tFL = e_t[i] + e_f[i]/1000;}
|
||||||
|
if( ch[i] == ChMap::dBR ) {hit.eBR = e[i]; hit.tBR = e_t[i] + e_f[i]/1000;}
|
||||||
|
if( ch[i] == ChMap::dBL ) {hit.eBL = e[i]; hit.tBL = e_t[i] + e_f[i]/1000;}
|
||||||
|
if( ch[i] == ChMap::Cathode ) {hit.eCath = e[i]; hit.tCath = e_t[i] + e_f[i]/1000;}
|
||||||
|
if( ch[i] == ChMap::AnodeF ) {hit.eAF = e[i]; hit.tAF = e_t[i] + e_f[i]/1000;}
|
||||||
|
if( ch[i] == ChMap::AnodeB ) {hit.eAB = e[i]; hit.tAB = e_t[i] + e_f[i]/1000;}
|
||||||
|
|
||||||
|
for( int j = i+1; j < sn.GetSize(); j++){
|
||||||
|
coin->Fill(ch[i], ch[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int dQ = hit.eAB; // delta Q
|
||||||
|
unsigned int Qt = hit.eSL; // total Q
|
||||||
|
|
||||||
|
if( Qt > 0 && dQ > 0 ) {
|
||||||
|
PID->Fill(Qt, dQ);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============== PID gate cut
|
||||||
|
if( pidCut ){
|
||||||
|
if( !pidCut->IsInside(Qt, dQ) ) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
hit.CalData(2);
|
||||||
|
|
||||||
|
if( hit.theta > 1.2 || 0.5 > hit.theta ) continue;
|
||||||
|
|
||||||
|
if( (!TMath::IsNaN(hit.x1) || !TMath::IsNaN(hit.x2)) ) {
|
||||||
|
hFocal->Fill(hit.x1, hit.x2);
|
||||||
|
hF->Fill(hit.x1);
|
||||||
|
hB->Fill(hit.x2);
|
||||||
|
hXavg->Fill(hit.xAvg);
|
||||||
|
|
||||||
|
hXavg_Q->Fill(hit.xAvg, dQ);
|
||||||
|
hXavg_Theta->Fill( hit.xAvg, hit.theta);
|
||||||
|
|
||||||
|
for( int i = 0; i < 400; i++){
|
||||||
|
double z = -50 + 100/400.*i;
|
||||||
|
|
||||||
|
double x = (z/42.8625 + 0.5)* ( hit.x2-hit.x1) + hit.x1;
|
||||||
|
|
||||||
|
hRay->Fill(x,z);
|
||||||
|
}
|
||||||
|
|
||||||
|
double ex = hit.Rho2Ex( ((hit.xAvg - rhoOffset)/1000/rhoScaling + hit.GetRho0() ) );
|
||||||
|
//if( XMIN < hit.xAvg && hit.xAvg < XMAX) printf("x1 : %6.2f, x2 : %6.2f, xAvg %6.2f cm , ex : %f \n", hit.x1, hit.x2, hit.xAvg, ex);
|
||||||
|
hEx->Fill(ex);
|
||||||
|
|
||||||
|
hEx_Multi->Fill(ex, *multi);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*============================================ Progress Bar
|
||||||
|
processedEntries ++;
|
||||||
|
if (processedEntries >= NumEntries*Frac - 1 ) {
|
||||||
|
TString msg; msg.Form("%llu", NumEntries/1000);
|
||||||
|
int len = msg.Sizeof();
|
||||||
|
printf(" %3.0f%% (%*llu/%llu k) processed in %6.1f sec | expect %6.1f sec\n",
|
||||||
|
Frac*100, len, processedEntries/1000,NumEntries/1000,StpWatch.RealTime(), StpWatch.RealTime()/Frac);
|
||||||
|
fflush(stdout);
|
||||||
|
StpWatch.Start(kFALSE);
|
||||||
|
Frac += 0.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//^###########################################################
|
||||||
|
//^ * Plot
|
||||||
|
//^###########################################################
|
||||||
|
TCanvas * canvas = new TCanvas("cc", "Split-Pole", 2500, 1000);
|
||||||
|
|
||||||
|
gStyle->SetOptStat("neiou");
|
||||||
|
|
||||||
|
canvas->Divide(5, 2);
|
||||||
|
|
||||||
|
canvas->cd(1); {
|
||||||
|
PID->Draw("colz");
|
||||||
|
if( pidCut ) pidCut->Draw("same");
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas->cd(2); hRay->Draw("colz");
|
||||||
|
|
||||||
|
canvas->cd(3); hF->Draw();
|
||||||
|
canvas->cd(4); hB->Draw();
|
||||||
|
|
||||||
|
canvas->cd(5); hXavg_Q->Draw("colz");
|
||||||
|
|
||||||
|
canvas->cd(6); hXavg->Draw("colz");
|
||||||
|
|
||||||
|
canvas->cd(7); hEx->Draw();
|
||||||
|
|
||||||
|
//canvas->cd(8); coin->Draw("colz");
|
||||||
|
canvas->cd(8); hEx_Multi->Draw("colz");
|
||||||
|
|
||||||
|
canvas->cd(9); canvas->cd(9)->SetLogy(); hMulti->Draw();
|
||||||
|
|
||||||
|
canvas->cd(10); hXavg_Theta->Draw("colz");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
194
Aux/SplitPolePlotter_MT.C
Normal file
194
Aux/SplitPolePlotter_MT.C
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
#include <TROOT.h>
|
||||||
|
#include "TTreeReader.h"
|
||||||
|
#include "TTreeReaderValue.h"
|
||||||
|
#include "TTreeReaderArray.h"
|
||||||
|
#include <ROOT/TTreeProcessorMP.hxx>
|
||||||
|
#include <ROOT/TTreeProcessorMT.hxx>
|
||||||
|
#include "ROOT/TProcessExecutor.hxx"
|
||||||
|
#include "ROOT/TThreadedObject.hxx"
|
||||||
|
|
||||||
|
#include "TH2F.h"
|
||||||
|
#include "TH1F.h"
|
||||||
|
#include "TCutG.h"
|
||||||
|
#include "TCanvas.h"
|
||||||
|
|
||||||
|
#include "SplitPolePlotter.C"
|
||||||
|
#include "../analyzers/SplitPoleHit.h"
|
||||||
|
|
||||||
|
|
||||||
|
void SplotPolePlotter_MT(TChain * chain, const int nThread, TCutG * pidCut = nullptr, double rhoOffset = 0, double rhoScaling = 1, bool isFSUDAQ = true){
|
||||||
|
|
||||||
|
//^====================== Thread Object, destoryed when merge
|
||||||
|
ROOT::TThreadedObject<TH2F> pCoin("hCoin", "Coincident ", 16, 0, 16, 16, 0, 16);
|
||||||
|
ROOT::TThreadedObject<TH1F> phMulti("hMulti", "Multiplicity", 16, 0, 16);
|
||||||
|
ROOT::TThreadedObject<TH2F> pPID("hPID", "PID; Scin_X ; AnodeB", 200, 0, 20000, 100, 0, isFSUDAQ ? 40000 : 5000);
|
||||||
|
ROOT::TThreadedObject<TH2F> phXavg_Q("hXavg_Q", "Xavg vs Q ", 200, XMIN, XMAX, 200, 0, isFSUDAQ ? 40000 : 5000);
|
||||||
|
ROOT::TThreadedObject<TH1F> phF("hF", "Front delay line position", 600, XMIN, XMAX);
|
||||||
|
ROOT::TThreadedObject<TH1F> phB("hB", "Back delay line position", 600, XMIN, XMAX);
|
||||||
|
ROOT::TThreadedObject<TH1F> phXavg("hAvg", "Xavg", 600, XMIN, XMAX);
|
||||||
|
ROOT::TThreadedObject<TH2F> phFocal("hFocal", "Front vs Back ", 200, XMIN, XMAX, 200, XMIN, XMAX);
|
||||||
|
ROOT::TThreadedObject<TH2F> phXavg_Theta("hXavg_Theta", "Xavg vs Theta ", 200, XMIN, XMAX, 200, 0.5, 1.4);
|
||||||
|
ROOT::TThreadedObject<TH2F> phRay("hRay", "Ray plot", 400, XMIN, XMAX, 400, -50, 50);
|
||||||
|
ROOT::TThreadedObject<TH1F> phEx("hEx", "Ex; Ex [MeV]; count/10 keV", 600, -1, 5);
|
||||||
|
ROOT::TThreadedObject<TH2F> phEx_Multi("hEx_Multi", "Ex vs Multi; Ex; Multi", 600, -1, 5, 16, 0, 16);
|
||||||
|
|
||||||
|
|
||||||
|
//^==================== TTreeProcessorMT
|
||||||
|
ROOT::EnableImplicitMT(nThread);
|
||||||
|
|
||||||
|
std::vector<std::string_view> fileList_view;
|
||||||
|
std::vector<std::string> fileList;
|
||||||
|
for( int k = 0; k < chain->GetNtrees(); k++){
|
||||||
|
fileList_view.push_back(chain->GetListOfFiles()->At(k)->GetTitle());
|
||||||
|
fileList.push_back(chain->GetListOfFiles()->At(k)->GetTitle());
|
||||||
|
}
|
||||||
|
ROOT::TTreeProcessorMT tp(fileList_view, "tree");
|
||||||
|
// tp.SetTasksPerWorkerHint(1);
|
||||||
|
|
||||||
|
std::mutex mutex;
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
//^======================= Define process
|
||||||
|
auto ProcessTask = [&](TTreeReader &reader){
|
||||||
|
|
||||||
|
TTreeReaderValue<ULong64_t> evID = {reader, "evID"};
|
||||||
|
TTreeReaderValue<UInt_t> multi = {reader, "multi"};
|
||||||
|
TTreeReaderArray<UShort_t> sn = {reader, "sn"};
|
||||||
|
TTreeReaderArray<UShort_t> ch = {reader, "ch"};
|
||||||
|
TTreeReaderArray<UShort_t> e = {reader, "e"};
|
||||||
|
TTreeReaderArray<UShort_t> e2 = {reader, "e2"};
|
||||||
|
TTreeReaderArray<ULong64_t> e_t = {reader, "e_t"};
|
||||||
|
TTreeReaderArray<UShort_t> e_f = {reader, "e_f"};
|
||||||
|
|
||||||
|
mutex.lock();
|
||||||
|
count++;
|
||||||
|
printf("-------------- Thread_ID: %d \n", count);
|
||||||
|
mutex.unlock();
|
||||||
|
|
||||||
|
SplitPoleHit hit;
|
||||||
|
hit.SetMassTablePath("../analyzers/mass20.txt");
|
||||||
|
hit.CalConstants("12C", "d", "p", 16, 18); // 80MeV, 5 deg
|
||||||
|
hit.CalZoffset(0.750); // 1.41 T
|
||||||
|
|
||||||
|
|
||||||
|
while (reader.Next()) {
|
||||||
|
|
||||||
|
hit.ClearData();
|
||||||
|
|
||||||
|
phMulti->Fill(*multi);
|
||||||
|
|
||||||
|
// if( *multi != 9 ) continue;
|
||||||
|
|
||||||
|
for( int i = 0; i < *multi; i++){
|
||||||
|
|
||||||
|
// t2 = e_t[i];
|
||||||
|
// if( t2 < t1 ) printf("entry %lld-%d, timestamp is not in order. %llu, %llu\n", processedEntries, i, t2, t1);
|
||||||
|
if( i == 0 ) t1 = e_t[i];
|
||||||
|
// if( e[i] == 65535 ) continue;
|
||||||
|
|
||||||
|
if( ch[i] == ChMap::ScinR ) {hit.eSR = e[i]; hit.tSR = e_t[i] + e_f[i]/1000;}
|
||||||
|
if( ch[i] == ChMap::ScinL ) {hit.eSL = e[i]; hit.tSL = e_t[i] + e_f[i]/1000;}
|
||||||
|
if( ch[i] == ChMap::dFR ) {hit.eFR = e[i]; hit.tFR = e_t[i] + e_f[i]/1000;}
|
||||||
|
if( ch[i] == ChMap::dFL ) {hit.eFL = e[i]; hit.tFL = e_t[i] + e_f[i]/1000;}
|
||||||
|
if( ch[i] == ChMap::dBR ) {hit.eBR = e[i]; hit.tBR = e_t[i] + e_f[i]/1000;}
|
||||||
|
if( ch[i] == ChMap::dBL ) {hit.eBL = e[i]; hit.tBL = e_t[i] + e_f[i]/1000;}
|
||||||
|
if( ch[i] == ChMap::Cathode ) {hit.eCath = e[i]; hit.tCath = e_t[i] + e_f[i]/1000;}
|
||||||
|
if( ch[i] == ChMap::AnodeF ) {hit.eAF = e[i]; hit.tAF = e_t[i] + e_f[i]/1000;}
|
||||||
|
if( ch[i] == ChMap::AnodeB ) {hit.eAB = e[i]; hit.tAB = e_t[i] + e_f[i]/1000;}
|
||||||
|
|
||||||
|
for( int j = i+1; j < sn.GetSize(); j++){
|
||||||
|
pCoin->Fill(ch[i], ch[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int dQ = hit.eAB; // delta Q
|
||||||
|
unsigned int Qt = hit.eSL; // total Q
|
||||||
|
|
||||||
|
if( Qt > 0 && dQ > 0 ) {
|
||||||
|
pPID->Fill(Qt, dQ);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============== PID gate cut
|
||||||
|
if( pidCut ){
|
||||||
|
if( !pidCut->IsInside(Qt, dQ) ) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
hit.CalData(2);
|
||||||
|
|
||||||
|
if( hit.theta > 1.2 || 0.5 > hit.theta ) continue;
|
||||||
|
|
||||||
|
if( (!TMath::IsNaN(hit.x1) || !TMath::IsNaN(hit.x2)) ) {
|
||||||
|
phFocal->Fill(hit.x1, hit.x2);
|
||||||
|
phF->Fill(hit.x1);
|
||||||
|
phB->Fill(hit.x2);
|
||||||
|
phXavg->Fill(hit.xAvg);
|
||||||
|
phXavg_Q->Fill(hit.xAvg, dQ);
|
||||||
|
phXavg_Theta->Fill( hit.xAvg, hit.theta);
|
||||||
|
|
||||||
|
for( int i = 0; i < 400; i++){
|
||||||
|
double z = -50 + 100/400.*i;
|
||||||
|
|
||||||
|
double x = (z/42.8625 + 0.5)* ( hit.x2-hit.x1) + hit.x1;
|
||||||
|
|
||||||
|
phRay->Fill(x,z);
|
||||||
|
}
|
||||||
|
|
||||||
|
double ex = hit.Rho2Ex( ((hit.xAvg - rhoOffset)/1000/rhoScaling + hit.GetRho0() ) );
|
||||||
|
//if( XMIN < hit.xAvg && hit.xAvg < XMAX) printf("x1 : %6.2f, x2 : %6.2f, xAvg %6.2f cm , ex : %f \n", hit.x1, hit.x2, hit.xAvg, ex);
|
||||||
|
|
||||||
|
phEx->Fill(ex);
|
||||||
|
phEx_Multi->Fill(ex, *multi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
//^============================ Run TP
|
||||||
|
tp.Process(ProcessTask);
|
||||||
|
|
||||||
|
//^============================ Merge all ThreadedObject
|
||||||
|
auto coin = pCoin.Merge();
|
||||||
|
auto hMulti= phMulti.Merge();
|
||||||
|
auto hEx = phEx.Merge();
|
||||||
|
auto hEx_Multi = phEx_Multi.Merge();
|
||||||
|
auto PID = pPID.Merge();
|
||||||
|
auto hFocal = phFocal.Merge();
|
||||||
|
auto hF = phF.Merge();
|
||||||
|
auto hB = phB.Merge();
|
||||||
|
auto hXavg = phXavg.Merge();
|
||||||
|
auto hXavg_Q = phXavg_Q.Merge();
|
||||||
|
auto hXavg_Theta = phXavg_Theta.Merge();
|
||||||
|
auto hRay = phRay.Merge();
|
||||||
|
|
||||||
|
//^============================== Plot
|
||||||
|
gStyle->SetOptStat("neiou");
|
||||||
|
|
||||||
|
TCanvas * canvas = new TCanvas("cc", "Split-Pole", 2500, 1000);
|
||||||
|
canvas->Divide(5, 2);
|
||||||
|
|
||||||
|
canvas->cd(1); {
|
||||||
|
PID->DrawCopy("colz");
|
||||||
|
if( pidCut ) pidCut->Draw("same");
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas->cd(2); hRay->DrawCopy("colz");
|
||||||
|
|
||||||
|
canvas->cd(3); hF->DrawCopy();
|
||||||
|
canvas->cd(4); hB->DrawCopy();
|
||||||
|
|
||||||
|
canvas->cd(5); hXavg_Q->DrawCopy("colz");
|
||||||
|
|
||||||
|
canvas->cd(6); hXavg->DrawCopy("colz");
|
||||||
|
|
||||||
|
canvas->cd(7); hEx->DrawCopy();
|
||||||
|
|
||||||
|
//canvas->cd(8); coin->DrawCopy("colz");
|
||||||
|
canvas->cd(8); hEx_Multi->DrawCopy("colz");
|
||||||
|
|
||||||
|
canvas->cd(9); canvas->cd(9)->SetLogy(); hMulti->DrawCopy();
|
||||||
|
|
||||||
|
canvas->cd(10); hXavg_Theta->DrawCopy("colz");
|
||||||
|
|
||||||
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
#define DEFAULT_HALFBUFFERSIZE 500000
|
#define DEFAULT_HALFBUFFERSIZE 5000000
|
||||||
|
|
||||||
class FSUReader{
|
class FSUReader{
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ class FSUReader{
|
||||||
int GetNumCh() const{return numCh;}
|
int GetNumCh() const{return numCh;}
|
||||||
int GetFileOrder() const{return order;}
|
int GetFileOrder() const{return order;}
|
||||||
int GetChMask() const{return chMask;}
|
int GetChMask() const{return chMask;}
|
||||||
|
int GetRunNum() const{return runNum;}
|
||||||
unsigned long GetFileByteSize() const {return inFileSize;}
|
unsigned long GetFileByteSize() const {return inFileSize;}
|
||||||
|
|
||||||
void ClearHitList() { hit.clear();}
|
void ClearHitList() { hit.clear();}
|
||||||
|
@ -63,7 +64,7 @@ class FSUReader{
|
||||||
void ClearTotalHitCount() {totalHitCount = 0;}
|
void ClearTotalHitCount() {totalHitCount = 0;}
|
||||||
ulong GetTotalHitCount() const{return totalHitCount;}
|
ulong GetTotalHitCount() const{return totalHitCount;}
|
||||||
|
|
||||||
std::vector<Hit> ReadBatch(unsigned int batchSize = 1000000, bool verbose = false); // output the sorted Hit
|
std::vector<Hit> ReadBatch(unsigned int batchSize = 1000000, bool traceOn = false, bool verbose = false); // output the sorted Hit
|
||||||
|
|
||||||
void PrintHit(ulong numHit = -1, ulong startIndex = 0) {
|
void PrintHit(ulong numHit = -1, ulong startIndex = 0) {
|
||||||
for( ulong i = startIndex; i < std::min(numHit, totalHitCount); i++){
|
for( ulong i = startIndex; i < std::min(numHit, totalHitCount); i++){
|
||||||
|
@ -116,6 +117,7 @@ class FSUReader{
|
||||||
uShort order;
|
uShort order;
|
||||||
uShort chMask;
|
uShort chMask;
|
||||||
uShort numCh;
|
uShort numCh;
|
||||||
|
uShort runNum;
|
||||||
|
|
||||||
std::vector<unsigned int> blockPos;
|
std::vector<unsigned int> blockPos;
|
||||||
std::vector<unsigned int > blockTimeStamp;
|
std::vector<unsigned int > blockTimeStamp;
|
||||||
|
@ -262,14 +264,17 @@ inline void FSUReader::OpenFile(std::string fileName, uInt dataSize, int verbose
|
||||||
std::string token;
|
std::string token;
|
||||||
|
|
||||||
while (std::getline(iss, token, '_')) { tokens.push_back(token); }
|
while (std::getline(iss, token, '_')) { tokens.push_back(token); }
|
||||||
sn = atoi(tokens[2].c_str());
|
short token_size = tokens.size();
|
||||||
tick2ns = atoi(tokens[4].c_str());
|
// for( short i = 0; i < token_size; i ++ ) printf("%d | %s\n", i, tokens[i].c_str());
|
||||||
order = atoi(tokens[5].c_str());
|
runNum = atoi(tokens[token_size-5].c_str());
|
||||||
|
sn = atoi(tokens[token_size-4].c_str());
|
||||||
|
tick2ns = atoi(tokens[token_size-2].c_str());
|
||||||
|
order = atoi(tokens[token_size-1].c_str());
|
||||||
|
|
||||||
DPPType = 0;
|
DPPType = 0;
|
||||||
if( fileName.find("PHA") != std::string::npos ) DPPType = DPPTypeCode::DPP_PHA_CODE;
|
if( fileName.find("PHA") != std::string::npos ) { printf("Using PHA decode.\n"); DPPType = DPPTypeCode::DPP_PHA_CODE;}
|
||||||
if( fileName.find("PSD") != std::string::npos ) DPPType = DPPTypeCode::DPP_PSD_CODE;
|
if( fileName.find("PSD") != std::string::npos ) { printf("Using PSD decode.\n"); DPPType = DPPTypeCode::DPP_PSD_CODE;}
|
||||||
if( fileName.find("QDC") != std::string::npos ) DPPType = DPPTypeCode::DPP_QDC_CODE;
|
if( fileName.find("QDC") != std::string::npos ) { printf("Using QDC decode.\n"); DPPType = DPPTypeCode::DPP_QDC_CODE;}
|
||||||
if( DPPType == 0 ){
|
if( DPPType == 0 ){
|
||||||
fclose(inFile);
|
fclose(inFile);
|
||||||
inFile = nullptr;
|
inFile = nullptr;
|
||||||
|
@ -291,7 +296,7 @@ inline int FSUReader::ReadNextBlock(bool traceON, int verbose, uShort saveData){
|
||||||
if( inFile == NULL ) return -1;
|
if( inFile == NULL ) return -1;
|
||||||
if( feof(inFile) || filePos >= inFileSize) {
|
if( feof(inFile) || filePos >= inFileSize) {
|
||||||
if( fileID >= 0 && fileID + 1 < (short) fileList.size() ){
|
if( fileID >= 0 && fileID + 1 < (short) fileList.size() ){
|
||||||
printf("-------------- next file\n");
|
printf("-------------- next file | hit size : %zu\n", hit.size());
|
||||||
fileID ++;
|
fileID ++;
|
||||||
OpenFile(fileList[fileID], data->GetDataSize(), 1 );
|
OpenFile(fileList[fileID], data->GetDataSize(), 1 );
|
||||||
}else{
|
}else{
|
||||||
|
@ -370,7 +375,11 @@ inline int FSUReader::ReadNextBlock(bool traceON, int verbose, uShort saveData){
|
||||||
temp.ch = ch;
|
temp.ch = ch;
|
||||||
temp.energy = data->GetEnergy(ch, k);
|
temp.energy = data->GetEnergy(ch, k);
|
||||||
temp.energy2 = data->GetEnergy2(ch, k);
|
temp.energy2 = data->GetEnergy2(ch, k);
|
||||||
|
|
||||||
temp.timestamp = data->GetTimestamp(ch, k);
|
temp.timestamp = data->GetTimestamp(ch, k);
|
||||||
|
// unsigned long long offset = 1000000;
|
||||||
|
// if( sn == 405 && ch == 0) temp.timestamp -= offset;
|
||||||
|
|
||||||
temp.fineTime = data->GetFineTime(ch, k);
|
temp.fineTime = data->GetFineTime(ch, k);
|
||||||
temp.pileUp = data->GetPileUp(ch, k);
|
temp.pileUp = data->GetPileUp(ch, k);
|
||||||
if( saveData > 1 ) {
|
if( saveData > 1 ) {
|
||||||
|
@ -381,6 +390,8 @@ inline int FSUReader::ReadNextBlock(bool traceON, int verbose, uShort saveData){
|
||||||
if( temp.trace.size() > 0 ) temp.trace.clear();
|
if( temp.trace.size() > 0 ) temp.trace.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// temp.Print();
|
||||||
|
|
||||||
hit.push_back(temp);
|
hit.push_back(temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -491,7 +502,7 @@ inline void FSUReader::ScanNumBlock(int verbose, uShort saveData){
|
||||||
}
|
}
|
||||||
|
|
||||||
//^==============================================================
|
//^==============================================================
|
||||||
inline std::vector<Hit> FSUReader::ReadBatch(unsigned int batchSize, bool verbose){
|
inline std::vector<Hit> FSUReader::ReadBatch(unsigned int batchSize, bool traceOn, bool verbose){
|
||||||
|
|
||||||
// printf("%s sn:%d. filePos : %lu\n", __func__, sn, ftell(inFile));
|
// printf("%s sn:%d. filePos : %lu\n", __func__, sn, ftell(inFile));
|
||||||
|
|
||||||
|
@ -505,7 +516,7 @@ inline std::vector<Hit> FSUReader::ReadBatch(unsigned int batchSize, bool verbos
|
||||||
if( hit.size() == 0 ){
|
if( hit.size() == 0 ){
|
||||||
int res = 0;
|
int res = 0;
|
||||||
do{
|
do{
|
||||||
res = ReadNextBlock(true, 0, 3);
|
res = ReadNextBlock(traceOn, 0, 3);
|
||||||
}while ( hit.size() < batchSize && res == 0);
|
}while ( hit.size() < batchSize && res == 0);
|
||||||
SortHit();
|
SortHit();
|
||||||
uLong t0_B = hit.at(0).timestamp;
|
uLong t0_B = hit.at(0).timestamp;
|
||||||
|
@ -531,7 +542,7 @@ inline std::vector<Hit> FSUReader::ReadBatch(unsigned int batchSize, bool verbos
|
||||||
|
|
||||||
int res = 0;
|
int res = 0;
|
||||||
do{
|
do{
|
||||||
res = ReadNextBlock(true, 0, 3);
|
res = ReadNextBlock(traceOn, 0, 3);
|
||||||
}while ( hit.size() < batchSize && res == 0);
|
}while ( hit.size() < batchSize && res == 0);
|
||||||
SortHit();
|
SortHit();
|
||||||
uLong t0_B = hit.at(0).timestamp;
|
uLong t0_B = hit.at(0).timestamp;
|
||||||
|
|
|
@ -81,7 +81,7 @@ int main(int argc, char **argv) {
|
||||||
tempInfo.fileName = inFileName[i];
|
tempInfo.fileName = inFileName[i];
|
||||||
tempInfo.readerID = i;
|
tempInfo.readerID = i;
|
||||||
tempInfo.SN = reader[i]->GetSN();
|
tempInfo.SN = reader[i]->GetSN();
|
||||||
tempInfo.hitCount = reader[i]->GetHitCount();
|
tempInfo.hitCount = reader[i]->GetTotalHitCount();
|
||||||
tempInfo.fileSize = reader[i]->GetFileByteSize();
|
tempInfo.fileSize = reader[i]->GetFileByteSize();
|
||||||
tempInfo.tick2ns = reader[i]->GetTick2ns();
|
tempInfo.tick2ns = reader[i]->GetTick2ns();
|
||||||
tempInfo.DPPType = reader[i]->GetDPPType();
|
tempInfo.DPPType = reader[i]->GetDPPType();
|
||||||
|
@ -208,7 +208,7 @@ int main(int argc, char **argv) {
|
||||||
}else{
|
}else{
|
||||||
group[gpID].hitID = 0;
|
group[gpID].hitID = 0;
|
||||||
uShort rID = group[gpID].readerIDList[group[gpID].currentID];
|
uShort rID = group[gpID].readerIDList[group[gpID].currentID];
|
||||||
group[gpID].hitCount = reader[rID]->GetHitCount();
|
group[gpID].hitCount = reader[rID]->GetTotalHitCount();
|
||||||
printf("-----> go to the next file, %s \n", fileInfo[rID].fileName.c_str() );
|
printf("-----> go to the next file, %s \n", fileInfo[rID].fileName.c_str() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,7 @@ int main(int argc, char **argv) {
|
||||||
tempInfo.fileName = outFileName;
|
tempInfo.fileName = outFileName;
|
||||||
tempInfo.readerID = i;
|
tempInfo.readerID = i;
|
||||||
tempInfo.SN = reader[i]->GetSN();
|
tempInfo.SN = reader[i]->GetSN();
|
||||||
tempInfo.hitCount = reader[i]->GetHitCount();
|
tempInfo.hitCount = reader[i]->GetTotalHitCount();
|
||||||
tempInfo.fileSize = reader[i]->GetTSFileSize();
|
tempInfo.fileSize = reader[i]->GetTSFileSize();
|
||||||
tempInfo.tick2ns = reader[i]->GetTick2ns();
|
tempInfo.tick2ns = reader[i]->GetTick2ns();
|
||||||
tempInfo.DPPType = reader[i]->GetDPPType();
|
tempInfo.DPPType = reader[i]->GetDPPType();
|
||||||
|
|
166
Aux/script.C
166
Aux/script.C
|
@ -1,90 +1,114 @@
|
||||||
#include "fsuReader.h"
|
#include "fsuReader.h"
|
||||||
#include "../MultiBuilder.cpp"
|
// #include "../MultiBuilder.cpp"
|
||||||
|
|
||||||
|
#include "SplitPolePlotter.C"
|
||||||
|
#include "SplitPolePlotter_MT.C"
|
||||||
|
|
||||||
void script(){
|
void script(){
|
||||||
|
|
||||||
FSUReader * reader = new FSUReader("~/ExpData/testing/.fsu", 16);
|
TChain * chain = new TChain("tree");
|
||||||
Data * data = reader->GetData();
|
// chain->Add("raw_binary/run_13/run013_3000.root");
|
||||||
data->tick2ns = 4;
|
// chain->Add("data/run*_3000.root");
|
||||||
|
chain->Add("data/12C_dp_*_3000.root");
|
||||||
|
|
||||||
reader->ScanNumBlock();
|
// TFile * pidCutFile = new TFile("cut_proton.root");
|
||||||
|
TFile * pidCutFile = new TFile("cut_proton_FSU.root");
|
||||||
|
TCutG * pidCut = (TCutG *) pidCutFile->Get("protons");
|
||||||
|
|
||||||
// for( int i = 0; i < 500 ; i++ ) reader->ReadNextBlock(0, 0);
|
// SplitPolePlotter(chain, pidCut, 123.307, 2.75, false); // for CoMPASS data
|
||||||
|
// SplitPolePlotter(chain, pidCut, 123.307, 2.75, true); // faster then MT?
|
||||||
|
|
||||||
|
SplotPolePlotter_MT(chain, 5, pidCut, 123.307, 2.75, true);
|
||||||
|
|
||||||
|
|
||||||
|
//^=====================================================
|
||||||
|
|
||||||
|
// FSUReader * reader = new FSUReader("data/12C_dp_002_19555_PSD_4_000.fsu", 10000, 2);
|
||||||
|
|
||||||
|
// reader->ScanNumBlock(1, 0);
|
||||||
|
|
||||||
|
// reader->ReadNextBlock(0, 9);
|
||||||
|
|
||||||
|
// for( int i = 0; i < 10 ; i++ ) reader->ReadNextBlock(0, 9);
|
||||||
|
|
||||||
|
// std::vector<Hit> hitList = reader->ReadBatch(10, true);
|
||||||
|
|
||||||
|
// for ( int i = 0; i < 10 ; i ++) hitList[i].Print();
|
||||||
|
|
||||||
|
// // int ch = 5;
|
||||||
|
// // std::vector<unsigned long long > tList;
|
||||||
|
// // int nEvent = 0;
|
||||||
|
// // for( int i = 0; i < data->TotNumNonPileUpEvents[ch]; i++){
|
||||||
|
// // tList.push_back(data->Timestamp[ch][i]);
|
||||||
|
// // printf("%3d | %d %llu \n", i, data->Energy[ch][i], data->Timestamp[ch][i]);
|
||||||
|
// // nEvent ++;
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // std::sort(tList.begin(), tList.end());
|
||||||
|
|
||||||
|
// // unsigned long long dTime = tList.back() - tList.front();
|
||||||
|
// // double sec = dTime * data->tick2ns / 1e9;
|
||||||
|
|
||||||
|
// // printf("=========== %llu, %llu = %llu | %f sec | %f Hz\n", tList.back(), tList.front(), dTime, sec, nEvent/sec );
|
||||||
|
|
||||||
|
// //data->PrintStat(0);
|
||||||
|
|
||||||
|
|
||||||
|
// data->ClearData();
|
||||||
|
// data->ClearTriggerRate();
|
||||||
|
|
||||||
|
|
||||||
|
// MultiBuilder * mb = new MultiBuilder(data, reader->GetDPPType(), 334);
|
||||||
|
// mb->SetTimeWindow(10000);
|
||||||
|
|
||||||
|
// unsigned long totNumBlock = reader->GetTotNumBlock();
|
||||||
|
|
||||||
|
// int lastDataIndex = 0;
|
||||||
|
// int lastLoopIndex = 0;
|
||||||
|
|
||||||
|
// for( unsigned long i = 0; i < 2; i++){
|
||||||
|
|
||||||
|
// reader->ReadNextBlock();
|
||||||
|
|
||||||
|
// // int maxDataIndex = 0;
|
||||||
|
// // int maxLoopIndex = 0;
|
||||||
|
|
||||||
|
// // for( int ch = 0; ch < 16 ; ch++){
|
||||||
|
// // if( data->DataIndex[ch] > maxDataIndex ) maxDataIndex = data->DataIndex[ch];
|
||||||
|
// // if( data->LoopIndex[ch] > maxLoopIndex ) maxLoopIndex = data->LoopIndex[ch];
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // if( (maxLoopIndex * MaxNData + maxDataIndex) - (lastLoopIndex * MaxNData + lastDataIndex) > MaxNData * 0.05){
|
||||||
|
|
||||||
|
// // printf("Agg ID : %lu \n", i );
|
||||||
|
|
||||||
|
// // data->PrintStat();
|
||||||
|
// // data->PrintAllData();
|
||||||
|
|
||||||
|
// // mb->BuildEvents();
|
||||||
|
// // mb->PrintAllEvent();
|
||||||
|
// // mb->PrintStat();
|
||||||
|
|
||||||
|
// // lastDataIndex = maxDataIndex;
|
||||||
|
// // lastLoopIndex = maxLoopIndex;
|
||||||
|
// // }
|
||||||
|
|
||||||
// int ch = 5;
|
|
||||||
// std::vector<unsigned long long > tList;
|
|
||||||
// int nEvent = 0;
|
|
||||||
// for( int i = 0; i < data->TotNumNonPileUpEvents[ch]; i++){
|
|
||||||
// tList.push_back(data->Timestamp[ch][i]);
|
|
||||||
// printf("%3d | %d %llu \n", i, data->Energy[ch][i], data->Timestamp[ch][i]);
|
|
||||||
// nEvent ++;
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// std::sort(tList.begin(), tList.end());
|
|
||||||
|
|
||||||
// unsigned long long dTime = tList.back() - tList.front();
|
|
||||||
// double sec = dTime * data->tick2ns / 1e9;
|
|
||||||
|
|
||||||
// printf("=========== %llu, %llu = %llu | %f sec | %f Hz\n", tList.back(), tList.front(), dTime, sec, nEvent/sec );
|
|
||||||
|
|
||||||
//data->PrintStat(0);
|
|
||||||
|
|
||||||
|
|
||||||
data->ClearData();
|
|
||||||
data->ClearTriggerRate();
|
|
||||||
|
|
||||||
|
|
||||||
MultiBuilder * mb = new MultiBuilder(data, reader->GetDPPType(), 334);
|
|
||||||
mb->SetTimeWindow(10000);
|
|
||||||
|
|
||||||
unsigned long totNumBlock = reader->GetTotNumBlock();
|
|
||||||
|
|
||||||
int lastDataIndex = 0;
|
|
||||||
int lastLoopIndex = 0;
|
|
||||||
|
|
||||||
for( unsigned long i = 0; i < 2; i++){
|
|
||||||
|
|
||||||
reader->ReadNextBlock();
|
|
||||||
|
|
||||||
// int maxDataIndex = 0;
|
|
||||||
// int maxLoopIndex = 0;
|
|
||||||
|
|
||||||
// for( int ch = 0; ch < 16 ; ch++){
|
|
||||||
// if( data->DataIndex[ch] > maxDataIndex ) maxDataIndex = data->DataIndex[ch];
|
|
||||||
// if( data->LoopIndex[ch] > maxLoopIndex ) maxLoopIndex = data->LoopIndex[ch];
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if( (maxLoopIndex * MaxNData + maxDataIndex) - (lastLoopIndex * MaxNData + lastDataIndex) > MaxNData * 0.05){
|
|
||||||
|
|
||||||
// printf("Agg ID : %lu \n", i );
|
|
||||||
|
|
||||||
// data->PrintStat();
|
// data->PrintStat();
|
||||||
// data->PrintAllData();
|
// data->PrintAllData();
|
||||||
|
|
||||||
// mb->BuildEvents();
|
|
||||||
|
// //mb->BuildEvents(true);
|
||||||
|
|
||||||
|
// mb->BuildEventsBackWard(300);
|
||||||
|
|
||||||
// mb->PrintAllEvent();
|
// mb->PrintAllEvent();
|
||||||
// mb->PrintStat();
|
// mb->PrintStat();
|
||||||
|
|
||||||
// lastDataIndex = maxDataIndex;
|
|
||||||
// lastLoopIndex = maxLoopIndex;
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
// delete mb;
|
||||||
|
// delete reader;
|
||||||
|
|
||||||
data->PrintStat();
|
|
||||||
data->PrintAllData();
|
|
||||||
|
|
||||||
|
|
||||||
//mb->BuildEvents(true);
|
|
||||||
|
|
||||||
mb->BuildEventsBackWard(300);
|
|
||||||
|
|
||||||
mb->PrintAllEvent();
|
|
||||||
mb->PrintStat();
|
|
||||||
|
|
||||||
|
|
||||||
delete mb;
|
|
||||||
delete reader;
|
|
||||||
|
|
||||||
}
|
}
|
130
Aux/test.cpp
130
Aux/test.cpp
|
@ -321,82 +321,82 @@ int TestDigitizerRaw(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Compare_CAEN_Decoder(){
|
||||||
|
|
||||||
|
std::unique_ptr<Digitizer> digi = std::make_unique<Digitizer>(0, 49093, false, true);
|
||||||
|
Data * data = digi->GetData();
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
int handle = digi->GetHandle();
|
||||||
|
CAEN_DGTZ_DPP_PSD_Event_t *Events[16]; /// events buffer
|
||||||
|
uint32_t NumEvents[16];
|
||||||
|
|
||||||
|
uint32_t AllocatedSize = 0;
|
||||||
|
|
||||||
|
ret |= CAEN_DGTZ_MallocDPPEvents(handle, reinterpret_cast<void**>(&Events), &AllocatedSize) ;
|
||||||
|
printf("allowcated %d byte for Events\n", AllocatedSize);
|
||||||
|
|
||||||
|
|
||||||
|
printf("======================== start ACQ \n");
|
||||||
|
digi->StartACQ();
|
||||||
|
|
||||||
|
int ch = 0;
|
||||||
|
for( int i = 0; i < 5; i ++ ){
|
||||||
|
usleep(1000*1000); // every 1 second
|
||||||
|
|
||||||
|
digi->ReadData();
|
||||||
|
// data->CopyBuffer(cpBuffer, bufferSize);
|
||||||
|
data->DecodeBuffer(false, 4);
|
||||||
|
|
||||||
|
if( data->nByte > 0 ){
|
||||||
|
ret = (CAEN_DGTZ_ErrorCode) CAEN_DGTZ_GetDPPEvents(handle, data->buffer, data->nByte, reinterpret_cast<void**>(&Events), NumEvents);
|
||||||
|
if (ret) {
|
||||||
|
printf("Error when getting events from data %d\n", ret);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("============ %u\n", NumEvents[0]);
|
||||||
|
|
||||||
|
for( int ev = 0; ev < NumEvents[0]; ev++ ){
|
||||||
|
|
||||||
|
printf("-------- ev %d\n", ev);
|
||||||
|
printf( " Format : 0x%04x\n", Events[ch][ev].Format);
|
||||||
|
printf( "TimeTag : 0x%08x\n", Events[ch][ev].TimeTag);
|
||||||
|
printf(" E_short : 0x%04x\n", Events[ch][ev].ChargeShort);
|
||||||
|
printf(" E_long : 0x%04x\n", (Events[ch][ev].ChargeLong & 0xffff));
|
||||||
|
printf("Baseline : 0x%04x\n", (Events[ch][ev].Baseline & 0xffff));
|
||||||
|
printf(" Pur : 0x%04x\n", Events[ch][ev].Pur);
|
||||||
|
printf(" Extra : 0x%08x\n", Events[ch][ev].Extras);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
digi->StopACQ();
|
||||||
|
|
||||||
|
printf("======================== ACQ Stopped.\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
//^======================================
|
//^======================================
|
||||||
int main(int argc, char* argv[]){
|
int main(int argc, char* argv[]){
|
||||||
|
|
||||||
TestDigitizerRaw();
|
Compare_CAEN_Decoder();
|
||||||
|
|
||||||
// CheckBufferSize(5, 4);
|
// Data * data = digi->GetData();
|
||||||
|
|
||||||
//GetOneAgg();
|
// MultiBuilder * builder = new MultiBuilder(data, DPPType::DPP_PHA_CODE, digi->GetSerialNumber());
|
||||||
|
// builder->SetTimeWindow(100);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// digi->WriteRegister(DPP::QDC::PreTrigger, 60, -1);
|
|
||||||
|
|
||||||
// digi->WriteRegister(DPP::QDC::TriggerThreshold_sub2, 17, -1);
|
|
||||||
// digi->SetBits(DPP::QDC::DPPAlgorithmControl, DPP::QDC::Bit_DPPAlgorithmControl::ChargeSensitivity, 0, -1);
|
|
||||||
// digi->SetBits(DPP::QDC::DPPAlgorithmControl, DPP::QDC::Bit_DPPAlgorithmControl::InputSmoothingFactor, 4, -1);
|
|
||||||
// digi->SetBits(DPP::QDC::DPPAlgorithmControl, DPP::QDC::Bit_DPPAlgorithmControl::BaselineAvg, 2, -1);
|
|
||||||
|
|
||||||
// digi->WriteRegister(DPP::QDC::GateWidth, 608/16, -1);
|
|
||||||
|
|
||||||
// digi->WriteRegister(DPP::QDC::GroupEnableMask, 0x01);
|
|
||||||
|
|
||||||
// digi->WriteRegister(DPP::QDC::NumberEventsPerAggregate, 10, -1);
|
|
||||||
// digi->WriteRegister(DPP::AggregateOrganization, 0, -1);
|
|
||||||
// digi->WriteRegister(DPP::MaxAggregatePerBlockTransfer, 100, -1);
|
|
||||||
|
|
||||||
// digi->SetBits(DPP::QDC::DPPAlgorithmControl, DPP::QDC::Bit_DPPAlgorithmControl::Polarity, 0, -1);
|
|
||||||
|
|
||||||
/*
|
|
||||||
digi->SetBits(DPP::BoardConfiguration, DPP::Bit_BoardConfig::EnableExtra2, 1, -1);
|
|
||||||
digi->SetBits(DPP::BoardConfiguration, DPP::Bit_BoardConfig::RecordTrace, 0, -1);
|
|
||||||
|
|
||||||
Data * data = digi->GetData();
|
|
||||||
|
|
||||||
MultiBuilder * builder = new MultiBuilder(data, DPPType::DPP_PHA_CODE, digi->GetSerialNumber());
|
|
||||||
builder->SetTimeWindow(100);
|
|
||||||
|
|
||||||
//remove("haha_*.fsu");
|
|
||||||
//data->OpenSaveFile("haha");
|
|
||||||
|
|
||||||
digi->StartACQ();
|
|
||||||
|
|
||||||
for( int i = 0; i < 5; i ++ ){
|
|
||||||
usleep(1000*1000);
|
|
||||||
digi->ReadData();
|
|
||||||
data->DecodeBuffer(true, 0);
|
|
||||||
//data->DecodeBuffer(false, 2);
|
|
||||||
//data->SaveData();
|
|
||||||
//data->PrintStat();
|
|
||||||
|
|
||||||
data->PrintAllData(true);
|
|
||||||
|
|
||||||
//builder->BuildEvents(false, true, true);
|
|
||||||
builder->BuildEventsBackWard(20, true);
|
|
||||||
|
|
||||||
builder->PrintStat();
|
|
||||||
// int index = data->NumEventsDecoded[0];
|
|
||||||
// printf("-------------- %ld \n", data->Waveform1[0][index].size());
|
|
||||||
|
|
||||||
}
|
|
||||||
digi->StopACQ();
|
|
||||||
|
|
||||||
//data->CloseSaveFile();
|
|
||||||
builder->BuildEvents(true, true, true);
|
|
||||||
|
|
||||||
data->PrintAllData();
|
|
||||||
|
|
||||||
builder->PrintAllEvent(); // TODO
|
|
||||||
*/
|
|
||||||
|
|
||||||
// digi->CloseDigitizer();
|
|
||||||
// delete digi;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//*********************************
|
//*********************************
|
||||||
//*********************************
|
//*********************************
|
||||||
|
|
||||||
|
|
45
ClassData.h
45
ClassData.h
|
@ -90,6 +90,7 @@ class Data{
|
||||||
|
|
||||||
unsigned short GetNChannel() const {return numInputCh;}
|
unsigned short GetNChannel() const {return numInputCh;}
|
||||||
|
|
||||||
|
void PrintBuffer();
|
||||||
void CopyBuffer( const char * buffer, const unsigned int size);
|
void CopyBuffer( const char * buffer, const unsigned int size);
|
||||||
|
|
||||||
void DecodeBuffer(bool fastDecode, int verbose = 0); /// fastDecode will not save waveform
|
void DecodeBuffer(bool fastDecode, int verbose = 0); /// fastDecode will not save waveform
|
||||||
|
@ -310,7 +311,7 @@ inline void Data::ClearData(){
|
||||||
if( ch >= numInputCh) break;
|
if( ch >= numInputCh) break;
|
||||||
for( int j = 0; j < dataSize; j++){
|
for( int j = 0; j < dataSize; j++){
|
||||||
Timestamp[ch][j] = 0;
|
Timestamp[ch][j] = 0;
|
||||||
fineTime[ch][j] = 0;
|
fineTime[ch][j] = -1;
|
||||||
Energy[ch][j] = 0;
|
Energy[ch][j] = 0;
|
||||||
Energy2[ch][j] = 0;
|
Energy2[ch][j] = 0;
|
||||||
Waveform1[ch][j].clear();
|
Waveform1[ch][j].clear();
|
||||||
|
@ -330,6 +331,8 @@ inline void Data::ClearData(){
|
||||||
tempDigiWaveform3.clear();
|
tempDigiWaveform3.clear();
|
||||||
tempDigiWaveform4.clear();
|
tempDigiWaveform4.clear();
|
||||||
|
|
||||||
|
outFileIndex = 0;
|
||||||
|
|
||||||
ClearNumEventsDecoded();
|
ClearNumEventsDecoded();
|
||||||
ClearTriggerRate();
|
ClearTriggerRate();
|
||||||
|
|
||||||
|
@ -344,7 +347,10 @@ inline void Data::ClearBuffer(){
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Data::CopyBuffer(const char * buffer, const unsigned int size){
|
inline void Data::CopyBuffer(const char * buffer, const unsigned int size){
|
||||||
|
if( this->buffer ) delete this->buffer;
|
||||||
|
this->buffer = (char*) malloc(size);
|
||||||
std::memcpy(this->buffer, buffer, size);
|
std::memcpy(this->buffer, buffer, size);
|
||||||
|
this->nByte = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Data::ClearReferenceTime(){
|
inline void Data::ClearReferenceTime(){
|
||||||
|
@ -557,12 +563,21 @@ inline void Data::PrintChData(unsigned short ch, unsigned int maxRowDisplay) con
|
||||||
|
|
||||||
//^#######################################################
|
//^#######################################################
|
||||||
//^####################################################### Decode
|
//^####################################################### Decode
|
||||||
|
inline void Data::PrintBuffer(){
|
||||||
|
if( buffer == NULL || nByte == 0 ) return;
|
||||||
|
printf("============== Received nByte : %u\n", nByte);
|
||||||
|
for( unsigned int i = 0; i < nByte/4; i++ ) {
|
||||||
|
ReadBuffer(i, 2);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline unsigned int Data::ReadBuffer(unsigned int nWord, int verbose){
|
inline unsigned int Data::ReadBuffer(unsigned int nWord, int verbose){
|
||||||
if( buffer == NULL ) return 0;
|
if( buffer == NULL ) return 0;
|
||||||
|
|
||||||
unsigned int word = 0;
|
unsigned int word = 0;
|
||||||
for( int i = 0 ; i < 4 ; i++) word += ((buffer[i + 4 * nWord] & 0xFF) << 8*i);
|
for( int i = 0 ; i < 4 ; i++) word += ((buffer[i + 4 * nWord] & 0xFF) << 8*i);
|
||||||
if( verbose >= 2) printf("%6d | 0x%08X | ", nWord, word);
|
if( verbose >= 2) printf("%6d | 0x%08X |", nWord, word);
|
||||||
return word;
|
return word;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -882,7 +897,11 @@ inline int Data::DecodePHADualChannelBlock(unsigned int ChannelMask, bool fastDe
|
||||||
|
|
||||||
Energy[channel][DataIndex[channel]] = energy;
|
Energy[channel][DataIndex[channel]] = energy;
|
||||||
Timestamp[channel][DataIndex[channel]] = timeStamp * tick2ns;
|
Timestamp[channel][DataIndex[channel]] = timeStamp * tick2ns;
|
||||||
if(extra2Option == 2 ) fineTime[channel][DataIndex[channel]] = (extra2 & 0x03FF );
|
if(extra2Option == 2 ) {
|
||||||
|
fineTime[channel][DataIndex[channel]] = (extra2 & 0x03FF ) * tick2ns; // in ps, the tick2ns is a conversion factor
|
||||||
|
}else{
|
||||||
|
fineTime[channel][DataIndex[channel]] = -1;
|
||||||
|
}
|
||||||
PileUp[channel][DataIndex[channel]] = pileUp;
|
PileUp[channel][DataIndex[channel]] = pileUp;
|
||||||
NumEventsDecoded[channel] ++;
|
NumEventsDecoded[channel] ++;
|
||||||
|
|
||||||
|
@ -1085,7 +1104,11 @@ inline int Data::DecodePSDDualChannelBlock(unsigned int ChannelMask, bool fastDe
|
||||||
Energy2[channel][DataIndex[channel]] = Qshort;
|
Energy2[channel][DataIndex[channel]] = Qshort;
|
||||||
Energy[channel][DataIndex[channel]] = Qlong;
|
Energy[channel][DataIndex[channel]] = Qlong;
|
||||||
Timestamp[channel][DataIndex[channel]] = timeStamp * tick2ns;
|
Timestamp[channel][DataIndex[channel]] = timeStamp * tick2ns;
|
||||||
if( extraOption == 2 ) fineTime[channel][DataIndex[channel]] = extra & 0x3FF;
|
if( extraOption == 2 ) {
|
||||||
|
fineTime[channel][DataIndex[channel]] = (extra & 0x3FF) * tick2ns; //in ps, tick2ns is justa conversion factor
|
||||||
|
}else{
|
||||||
|
fineTime[channel][DataIndex[channel]] = -1; //in ps, tick2ns is justa conversion factor
|
||||||
|
}
|
||||||
|
|
||||||
NumEventsDecoded[channel] ++;
|
NumEventsDecoded[channel] ++;
|
||||||
if( !pileup){
|
if( !pileup){
|
||||||
|
@ -1110,10 +1133,16 @@ inline int Data::DecodePSDDualChannelBlock(unsigned int ChannelMask, bool fastDe
|
||||||
//if( DataIndex[channel] >= dataSize ) ClearData();
|
//if( DataIndex[channel] >= dataSize ) ClearData();
|
||||||
|
|
||||||
//if( verbose >= 2 ) printf("extra : 0x%08x, Qshort : %d, Qlong : %d \n", extra, Qshort, Qlong);
|
//if( verbose >= 2 ) printf("extra : 0x%08x, Qshort : %d, Qlong : %d \n", extra, Qshort, Qlong);
|
||||||
if( verbose == 1 ) printf("ch : %2d, Qshort : %6d, Qlong : %6d, timestamp : %llu\n",
|
if( verbose >= 1 ) {
|
||||||
channel, Qshort, Qlong, timeStamp * tick2ns);
|
if( extraOption == 0){
|
||||||
if( verbose >= 2 ) printf("Qshort : %6d, Qlong : %6d, timestamp : %llu\n",
|
printf("Qshort : %6d, Qlong : %6d, timestamp : %llu, baseline : %u\n",
|
||||||
Qshort, Qlong, timeStamp * tick2ns);
|
Qshort, Qlong, timeStamp * tick2ns, (extra & 0xFFFF) * 4);
|
||||||
|
}
|
||||||
|
if( extraOption == 2){
|
||||||
|
printf("Qshort : %6d, Qlong : %6d, timestamp : %llu, fineTime : %u\n",
|
||||||
|
Qshort, Qlong, timeStamp * tick2ns, (extra & 0x3FF) * tick2ns);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -183,7 +183,6 @@ int Digitizer::OpenDigitizer(int boardID, int portID, bool program, bool verbose
|
||||||
/// change address 0xEF08 (5 bits), this will reflected in the 2nd word of the Board Agg. header.
|
/// change address 0xEF08 (5 bits), this will reflected in the 2nd word of the Board Agg. header.
|
||||||
ret = CAEN_DGTZ_WriteRegister(handle, DPP::BoardID, (DPPType & 0xF));
|
ret = CAEN_DGTZ_WriteRegister(handle, DPP::BoardID, (DPPType & 0xF));
|
||||||
|
|
||||||
|
|
||||||
//TODO somehow the bdInfo does not work, use DPPType to set it
|
//TODO somehow the bdInfo does not work, use DPPType to set it
|
||||||
uint32_t bdInfo = GetSettingFromMemory(DPP::BoardInfo_R);
|
uint32_t bdInfo = GetSettingFromMemory(DPP::BoardInfo_R);
|
||||||
uint32_t haha = ((bdInfo >> 8 ) & 0xFF);
|
uint32_t haha = ((bdInfo >> 8 ) & 0xFF);
|
||||||
|
@ -258,6 +257,7 @@ int Digitizer::OpenDigitizer(int boardID, int portID, bool program, bool verbose
|
||||||
ErrorMsg("end of OpenDigitizer");
|
ErrorMsg("end of OpenDigitizer");
|
||||||
|
|
||||||
softwareDisable = false;
|
softwareDisable = false;
|
||||||
|
AcqRun = false;
|
||||||
|
|
||||||
if( isConnected ) isDummy = false;
|
if( isConnected ) isDummy = false;
|
||||||
|
|
||||||
|
@ -278,16 +278,18 @@ int Digitizer::CloseDigitizer(){
|
||||||
isConnected = false;
|
isConnected = false;
|
||||||
ret = CAEN_DGTZ_SWStopAcquisition(handle);
|
ret = CAEN_DGTZ_SWStopAcquisition(handle);
|
||||||
printf("-------- Closing Digtizer Board : %d Port : %d \n", boardID, portID);
|
printf("-------- Closing Digtizer Board : %d Port : %d \n", boardID, portID);
|
||||||
printf(" Model %s with handle %d using %s\n", BoardInfo.ModelName, handle, LinkType == CAEN_DGTZ_USB ? "USB" : "Optical Link");
|
if( LinkType == CAEN_DGTZ_USB ) printf(" Model %s with handle %d using USB\n", BoardInfo.ModelName, handle);
|
||||||
|
if( LinkType == CAEN_DGTZ_OpticalLink ) printf(" Model %s with handle %d using Optical Fiber\n", BoardInfo.ModelName, handle);
|
||||||
|
if( LinkType == CAEN_DGTZ_USB_A4818 ) printf(" Model %s with handle %d using A4818\n", BoardInfo.ModelName, handle);
|
||||||
ret |= CAEN_DGTZ_CloseDigitizer(handle);
|
ret |= CAEN_DGTZ_CloseDigitizer(handle);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Digitizer::SetRegChannelMask(uint32_t mask){
|
void Digitizer::SetRegChannelMask(uint32_t mask){
|
||||||
DebugPrint("%s", "Digitizer");
|
DebugPrint("%s", "Digitizer");
|
||||||
if( softwareDisable ) return;
|
if( softwareDisable ) return;
|
||||||
|
if( AcqRun ) return;
|
||||||
if( !isConnected ) return;
|
if( !isConnected ) return;
|
||||||
regChannelMask = mask;
|
regChannelMask = mask;
|
||||||
ret |= CAEN_DGTZ_SetChannelEnableMask(handle, regChannelMask);
|
ret |= CAEN_DGTZ_SetChannelEnableMask(handle, regChannelMask);
|
||||||
|
@ -309,6 +311,7 @@ bool Digitizer::GetInputChannelOnOff(unsigned ch) {
|
||||||
void Digitizer::SetRegChannelOnOff(unsigned short ch, bool onOff){
|
void Digitizer::SetRegChannelOnOff(unsigned short ch, bool onOff){
|
||||||
DebugPrint("%s", "Digitizer");
|
DebugPrint("%s", "Digitizer");
|
||||||
if( softwareDisable ) return;
|
if( softwareDisable ) return;
|
||||||
|
if( AcqRun ) return;
|
||||||
if( !isConnected ) return;
|
if( !isConnected ) return;
|
||||||
regChannelMask = ((regChannelMask & ~( 1 << ch) ) | ( onOff << ch)) ;
|
regChannelMask = ((regChannelMask & ~( 1 << ch) ) | ( onOff << ch)) ;
|
||||||
SetRegChannelMask(regChannelMask);
|
SetRegChannelMask(regChannelMask);
|
||||||
|
@ -316,6 +319,8 @@ void Digitizer::SetRegChannelOnOff(unsigned short ch, bool onOff){
|
||||||
|
|
||||||
void Digitizer::ProgramBoard(){
|
void Digitizer::ProgramBoard(){
|
||||||
DebugPrint("%s", "Digitizer");
|
DebugPrint("%s", "Digitizer");
|
||||||
|
if( softwareDisable ) return;
|
||||||
|
if( AcqRun ) return;
|
||||||
if( DPPType == DPPTypeCode::DPP_PHA_CODE ) ProgramBoard_PHA();
|
if( DPPType == DPPTypeCode::DPP_PHA_CODE ) ProgramBoard_PHA();
|
||||||
if( DPPType == DPPTypeCode::DPP_PSD_CODE ) ProgramBoard_PSD();
|
if( DPPType == DPPTypeCode::DPP_PSD_CODE ) ProgramBoard_PSD();
|
||||||
if( DPPType == DPPTypeCode::DPP_QDC_CODE ) ProgramBoard_QDC();
|
if( DPPType == DPPTypeCode::DPP_QDC_CODE ) ProgramBoard_QDC();
|
||||||
|
@ -323,7 +328,6 @@ void Digitizer::ProgramBoard(){
|
||||||
|
|
||||||
int Digitizer::ProgramBoard_PHA(){
|
int Digitizer::ProgramBoard_PHA(){
|
||||||
DebugPrint("%s", "Digitizer");
|
DebugPrint("%s", "Digitizer");
|
||||||
if( softwareDisable ) return 0;
|
|
||||||
|
|
||||||
printf("===== Digitizer::%s\n", __func__);
|
printf("===== Digitizer::%s\n", __func__);
|
||||||
|
|
||||||
|
@ -402,8 +406,6 @@ int Digitizer::ProgramBoard_PHA(){
|
||||||
}
|
}
|
||||||
|
|
||||||
int Digitizer::ProgramBoard_PSD(){
|
int Digitizer::ProgramBoard_PSD(){
|
||||||
if( softwareDisable ) return 0;
|
|
||||||
|
|
||||||
printf("===== Digitizer::%s\n", __func__);
|
printf("===== Digitizer::%s\n", __func__);
|
||||||
|
|
||||||
//ret = CAEN_DGTZ_Reset(handle);
|
//ret = CAEN_DGTZ_Reset(handle);
|
||||||
|
@ -437,6 +439,12 @@ int Digitizer::ProgramBoard_PSD(){
|
||||||
ret |= CAEN_DGTZ_SetChannelDCOffset(handle, 0xF, 0xAAAA);
|
ret |= CAEN_DGTZ_SetChannelDCOffset(handle, 0xF, 0xAAAA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::PSD::DPPAlgorithmControl2_G) + 0x7000 , 0x00000200 ); // use fine time
|
||||||
|
|
||||||
|
ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::DPPAlgorithmControl) + 0x7000 , 0x00100000 ); // baseline 16 sample
|
||||||
|
|
||||||
|
ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::PSD::TriggerThreshold) + 0x7000 , 100 );
|
||||||
|
|
||||||
ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::PreTrigger) + 0x7000 , 20 );
|
ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::PreTrigger) + 0x7000 , 20 );
|
||||||
ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::RecordLength_G) + 0x7000 , 80 );
|
ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::RecordLength_G) + 0x7000 , 80 );
|
||||||
|
|
||||||
|
@ -461,8 +469,6 @@ int Digitizer::ProgramBoard_PSD(){
|
||||||
}
|
}
|
||||||
|
|
||||||
int Digitizer::ProgramBoard_QDC(){
|
int Digitizer::ProgramBoard_QDC(){
|
||||||
if( softwareDisable ) return 0;
|
|
||||||
|
|
||||||
printf("===== Digitizer::%s\n", __func__);
|
printf("===== Digitizer::%s\n", __func__);
|
||||||
Reset();
|
Reset();
|
||||||
|
|
||||||
|
@ -568,14 +574,13 @@ void Digitizer::StartACQ(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AcqRun = true;
|
|
||||||
data->ClearTriggerRate();
|
data->ClearTriggerRate();
|
||||||
data->ClearData();
|
data->ClearData();
|
||||||
|
|
||||||
if( DPPType == DPPTypeCode::DPP_QDC_CODE ) SetOptimialAggOrg();
|
if( DPPType == DPPTypeCode::DPP_QDC_CODE ) SetOptimialAggOrg();
|
||||||
|
|
||||||
printf(" ACQ mode : %s (%d), TRG-OUT mode : %s (%d) \n", acqStr.c_str(), acqID, trgOutStr.c_str(), trgOutID);
|
printf(" ACQ mode : %s (%d), TRG-OUT mode : %s (%d) \n", acqStr.c_str(), acqID, trgOutStr.c_str(), trgOutID);
|
||||||
|
|
||||||
|
AcqRun = true;
|
||||||
usleep(1000); // wait for 1 msec to start/Arm ACQ;
|
usleep(1000); // wait for 1 msec to start/Arm ACQ;
|
||||||
|
|
||||||
ret = CAEN_DGTZ_SWStartAcquisition(handle);
|
ret = CAEN_DGTZ_SWStartAcquisition(handle);
|
||||||
|
@ -603,6 +608,8 @@ void Digitizer::StopACQ(){
|
||||||
data->ClearBuffer();
|
data->ClearBuffer();
|
||||||
data->ClearReferenceTime();
|
data->ClearReferenceTime();
|
||||||
data->ZeroTotalFileSize();
|
data->ZeroTotalFileSize();
|
||||||
|
|
||||||
|
ReadACQStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Digitizer::CalByteForBuffer(bool verbose){
|
unsigned int Digitizer::CalByteForBuffer(bool verbose){
|
||||||
|
@ -667,7 +674,7 @@ unsigned int Digitizer::CalByteForBufferCAEN(){
|
||||||
uint32_t AllocatedSize;
|
uint32_t AllocatedSize;
|
||||||
ret = CAEN_DGTZ_MallocReadoutBuffer(handle, &BufferCAEN, &AllocatedSize);
|
ret = CAEN_DGTZ_MallocReadoutBuffer(handle, &BufferCAEN, &AllocatedSize);
|
||||||
|
|
||||||
delete BufferCAEN;
|
if( BufferCAEN) delete BufferCAEN;
|
||||||
return AllocatedSize;
|
return AllocatedSize;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -723,6 +730,7 @@ void Digitizer::ReadAndPrintACQStatue(){
|
||||||
//===========================================================
|
//===========================================================
|
||||||
void Digitizer::WriteRegister (Reg registerAddress, uint32_t value, int ch, bool isSave2MemAndFile){
|
void Digitizer::WriteRegister (Reg registerAddress, uint32_t value, int ch, bool isSave2MemAndFile){
|
||||||
if( softwareDisable ) return;
|
if( softwareDisable ) return;
|
||||||
|
if( AcqRun ) return;
|
||||||
printf("WRITE|%30s[0x%04X](digi-%d,ch-%02d) [0x%04X]: 0x%08X \n", registerAddress.GetNameChar(), registerAddress.GetAddress(),GetSerialNumber(), ch, registerAddress.ActualAddress(ch), value);
|
printf("WRITE|%30s[0x%04X](digi-%d,ch-%02d) [0x%04X]: 0x%08X \n", registerAddress.GetNameChar(), registerAddress.GetAddress(),GetSerialNumber(), ch, registerAddress.ActualAddress(ch), value);
|
||||||
|
|
||||||
if( !isConnected ) {
|
if( !isConnected ) {
|
||||||
|
@ -769,6 +777,7 @@ void Digitizer::WriteRegister (Reg registerAddress, uint32_t value, int ch, bool
|
||||||
uint32_t Digitizer::ReadRegister(Reg registerAddress, unsigned short ch, bool isSave2MemAndFile, std::string str ){
|
uint32_t Digitizer::ReadRegister(Reg registerAddress, unsigned short ch, bool isSave2MemAndFile, std::string str ){
|
||||||
DebugPrint("%s", "Digitizer");
|
DebugPrint("%s", "Digitizer");
|
||||||
if( softwareDisable ) return 0;
|
if( softwareDisable ) return 0;
|
||||||
|
if( AcqRun ) return 0;
|
||||||
if( !isConnected ) return 0;
|
if( !isConnected ) return 0;
|
||||||
if( registerAddress.GetRWType() == RW::WriteONLY ) return 0;
|
if( registerAddress.GetRWType() == RW::WriteONLY ) return 0;
|
||||||
// if( registerAddress == DPP::QDC::RecordLength_W ) return 0;
|
// if( registerAddress == DPP::QDC::RecordLength_W ) return 0;
|
||||||
|
@ -857,8 +866,8 @@ Reg Digitizer::FindRegister(uint32_t address){
|
||||||
|
|
||||||
void Digitizer::ReadAllSettingsFromBoard(bool force){
|
void Digitizer::ReadAllSettingsFromBoard(bool force){
|
||||||
if( softwareDisable ) return;
|
if( softwareDisable ) return;
|
||||||
if( !isConnected ) return;
|
|
||||||
if( AcqRun ) return;
|
if( AcqRun ) return;
|
||||||
|
if( !isConnected ) return;
|
||||||
if( isSettingFilledinMemeory && !force) return;
|
if( isSettingFilledinMemeory && !force) return;
|
||||||
|
|
||||||
printf("===== Digitizer(%d)::%s \n", GetSerialNumber(), __func__);
|
printf("===== Digitizer(%d)::%s \n", GetSerialNumber(), __func__);
|
||||||
|
@ -917,6 +926,7 @@ void Digitizer::ReadAllSettingsFromBoard(bool force){
|
||||||
void Digitizer::ProgramSettingsToBoard(){
|
void Digitizer::ProgramSettingsToBoard(){
|
||||||
DebugPrint("%s", "Digitizer");
|
DebugPrint("%s", "Digitizer");
|
||||||
if( softwareDisable ) return;
|
if( softwareDisable ) return;
|
||||||
|
if( AcqRun ) return;
|
||||||
if( !isConnected || isDummy ) return;
|
if( !isConnected || isDummy ) return;
|
||||||
|
|
||||||
printf("========== %s \n", __func__);
|
printf("========== %s \n", __func__);
|
||||||
|
@ -1005,6 +1015,7 @@ void Digitizer::ProgramSettingsToBoard(){
|
||||||
}
|
}
|
||||||
|
|
||||||
void Digitizer::SetSettingToMemory(Reg registerAddress, unsigned int value, unsigned short ch ){
|
void Digitizer::SetSettingToMemory(Reg registerAddress, unsigned int value, unsigned short ch ){
|
||||||
|
if( AcqRun ) return;
|
||||||
DebugPrint("%s", "Digitizer");
|
DebugPrint("%s", "Digitizer");
|
||||||
unsigned short index = registerAddress.Index(ch);
|
unsigned short index = registerAddress.Index(ch);
|
||||||
if( index > SETTINGSIZE ) return;
|
if( index > SETTINGSIZE ) return;
|
||||||
|
@ -1300,6 +1311,7 @@ void Digitizer::ErrorMsg(std::string header){
|
||||||
void Digitizer::SetDPPAlgorithmControl(uint32_t bit, int ch){
|
void Digitizer::SetDPPAlgorithmControl(uint32_t bit, int ch){
|
||||||
DebugPrint("%s", "Digitizer");
|
DebugPrint("%s", "Digitizer");
|
||||||
if( softwareDisable ) return;
|
if( softwareDisable ) return;
|
||||||
|
if( AcqRun ) return;
|
||||||
WriteRegister( DPP::DPPAlgorithmControl, bit, ch);
|
WriteRegister( DPP::DPPAlgorithmControl, bit, ch);
|
||||||
if( ret != 0 ) ErrorMsg(__func__);
|
if( ret != 0 ) ErrorMsg(__func__);
|
||||||
}
|
}
|
||||||
|
@ -1307,6 +1319,7 @@ void Digitizer::SetDPPAlgorithmControl(uint32_t bit, int ch){
|
||||||
unsigned int Digitizer::ReadBits(Reg address, unsigned int bitLength, unsigned int bitSmallestPos, int ch ){
|
unsigned int Digitizer::ReadBits(Reg address, unsigned int bitLength, unsigned int bitSmallestPos, int ch ){
|
||||||
DebugPrint("%s", "Digitizer");
|
DebugPrint("%s", "Digitizer");
|
||||||
if( softwareDisable ) return 0;
|
if( softwareDisable ) return 0;
|
||||||
|
if( AcqRun ) return 0;
|
||||||
int tempCh = ch;
|
int tempCh = ch;
|
||||||
if (ch < 0 && address < 0x8000 ) tempCh = 0; /// take ch-0
|
if (ch < 0 && address < 0x8000 ) tempCh = 0; /// take ch-0
|
||||||
uint32_t bit = ReadRegister(address, tempCh);
|
uint32_t bit = ReadRegister(address, tempCh);
|
||||||
|
@ -1317,6 +1330,7 @@ unsigned int Digitizer::ReadBits(Reg address, unsigned int bitLength, unsigned i
|
||||||
void Digitizer::SetBits(Reg address, unsigned int bitValue, unsigned int bitLength, unsigned int bitSmallestPos, int ch){
|
void Digitizer::SetBits(Reg address, unsigned int bitValue, unsigned int bitLength, unsigned int bitSmallestPos, int ch){
|
||||||
DebugPrint("%s", "Digitizer");
|
DebugPrint("%s", "Digitizer");
|
||||||
if( softwareDisable ) return;
|
if( softwareDisable ) return;
|
||||||
|
if( AcqRun ) return;
|
||||||
///printf("address : 0x%X, value : 0x%X, len : %d, pos : %d, ch : %d \n", address, bitValue, bitLength, bitSmallestPos, ch);
|
///printf("address : 0x%X, value : 0x%X, len : %d, pos : %d, ch : %d \n", address, bitValue, bitLength, bitSmallestPos, ch);
|
||||||
uint32_t bit ;
|
uint32_t bit ;
|
||||||
uint32_t bitmask = (uint(pow(2, bitLength)-1) << bitSmallestPos);
|
uint32_t bitmask = (uint(pow(2, bitLength)-1) << bitSmallestPos);
|
||||||
|
@ -1361,7 +1375,6 @@ void Digitizer::SetOptimialAggOrg(){
|
||||||
printf(" Record Length (bit) : %u = %u sample = %u ns\n", RecordLen, RecordLen*8, RecordLen*8*16);
|
printf(" Record Length (bit) : %u = %u sample = %u ns\n", RecordLen, RecordLen*8, RecordLen*8*16);
|
||||||
printf("==============================================================\n");
|
printf("==============================================================\n");
|
||||||
|
|
||||||
|
|
||||||
int eventSize = 6 + 2 * Ex + traceOn * RecordLen * 8; // sample
|
int eventSize = 6 + 2 * Ex + traceOn * RecordLen * 8; // sample
|
||||||
printf(" estimated event size : %d sample \n", eventSize);
|
printf(" estimated event size : %d sample \n", eventSize);
|
||||||
double maxAggOrg = log2( MemorySizekSample * 1024 / eventSize / EventAgg );
|
double maxAggOrg = log2( MemorySizekSample * 1024 / eventSize / EventAgg );
|
||||||
|
|
|
@ -206,6 +206,10 @@ class Digitizer{
|
||||||
return returnData;
|
return returnData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetTrace(bool onOff){
|
||||||
|
SetBits(DPP::BoardConfiguration, DPP::Bit_BoardConfig::RecordTrace, onOff, -1);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,6 @@ public:
|
||||||
digi->WriteRegister(DPP::SoftwareClear_W, 1);
|
digi->WriteRegister(DPP::SoftwareClear_W, 1);
|
||||||
digi->GetData()->ClearData();
|
digi->GetData()->ClearData();
|
||||||
}
|
}
|
||||||
digi->ReadACQStatus();
|
|
||||||
digiMTX[ID].unlock();
|
digiMTX[ID].unlock();
|
||||||
emit sendMsg("Digi-" + QString::number(digi->GetSerialNumber()) + " ACQ off.");
|
emit sendMsg("Digi-" + QString::number(digi->GetSerialNumber()) + " ACQ off.");
|
||||||
stop = true;
|
stop = true;
|
||||||
|
@ -119,6 +118,7 @@ public:
|
||||||
waitTime = 20; // multiple of 100 mili sec
|
waitTime = 20; // multiple of 100 mili sec
|
||||||
stop = false;
|
stop = false;
|
||||||
}
|
}
|
||||||
|
bool isStopped() const {return stop;}
|
||||||
void Stop() { this->stop = true;}
|
void Stop() { this->stop = true;}
|
||||||
void SetWaitTimeinSec(float sec) {waitTime = sec * 10 ;}
|
void SetWaitTimeinSec(float sec) {waitTime = sec * 10 ;}
|
||||||
float GetWaitTimeinSec() const {return waitTime/10.;}
|
float GetWaitTimeinSec() const {return waitTime/10.;}
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QScreen>
|
||||||
|
|
||||||
#define ComBoxMixed "Mixed"
|
#define ComBoxMixed "Mixed"
|
||||||
// bit = 0, bit = 1
|
// bit = 0, bit = 1
|
||||||
|
@ -38,7 +40,16 @@ DigiSettingsPanel::DigiSettingsPanel(Digitizer ** digi, unsigned int nDigi, QStr
|
||||||
enableSignalSlot = false;
|
enableSignalSlot = false;
|
||||||
|
|
||||||
setWindowTitle("Digitizer Settings");
|
setWindowTitle("Digitizer Settings");
|
||||||
|
|
||||||
|
//====== resize window if screen too small
|
||||||
|
QScreen * screen = QGuiApplication::primaryScreen();
|
||||||
|
QRect screenGeo = screen->geometry();
|
||||||
|
if( screenGeo.width() < 1700 || screenGeo.height() < 850) {
|
||||||
|
setGeometry(0, 0, screenGeo.width() - 100, screenGeo.height() - 100);
|
||||||
|
}else{
|
||||||
setGeometry(0, 0, 1700, 850);
|
setGeometry(0, 0, 1700, 850);
|
||||||
|
}
|
||||||
|
// setGeometry(0, 0, 1700, 850);
|
||||||
|
|
||||||
tabWidget = new QTabWidget(this);
|
tabWidget = new QTabWidget(this);
|
||||||
setCentralWidget(tabWidget);
|
setCentralWidget(tabWidget);
|
||||||
|
@ -185,9 +196,9 @@ DigiSettingsPanel::DigiSettingsPanel(Digitizer ** digi, unsigned int nDigi, QStr
|
||||||
|
|
||||||
{//^======================= Buttons
|
{//^======================= Buttons
|
||||||
|
|
||||||
QWidget * buttonsWidget = new QWidget(tab);
|
buttonsWidget[iDigi] = new QWidget(tab);
|
||||||
tabLayout_V1->addWidget(buttonsWidget);
|
tabLayout_V1->addWidget(buttonsWidget[iDigi]);
|
||||||
QGridLayout * buttonLayout = new QGridLayout(buttonsWidget);
|
QGridLayout * buttonLayout = new QGridLayout(buttonsWidget[iDigi]);
|
||||||
buttonLayout->setSpacing(2);
|
buttonLayout->setSpacing(2);
|
||||||
|
|
||||||
int rowID = 0 ;
|
int rowID = 0 ;
|
||||||
|
@ -258,7 +269,7 @@ DigiSettingsPanel::DigiSettingsPanel(Digitizer ** digi, unsigned int nDigi, QStr
|
||||||
// connect(bnSaveSettingsToText, &QPushButton::clicked, this, [=](){ SaveSetting(1);});
|
// connect(bnSaveSettingsToText, &QPushButton::clicked, this, [=](){ SaveSetting(1);});
|
||||||
|
|
||||||
//checkBox, to coupled or decouple the setting file.
|
//checkBox, to coupled or decouple the setting file.
|
||||||
chkCoupledSettingFile = new QCheckBox("Update Setting", this);
|
chkCoupledSettingFile = new QCheckBox("Live Setting Update", this);
|
||||||
buttonLayout->addWidget(chkCoupledSettingFile, rowID, 2);
|
buttonLayout->addWidget(chkCoupledSettingFile, rowID, 2);
|
||||||
chkCoupledSettingFile->setCheckState(Qt::CheckState::Unchecked);
|
chkCoupledSettingFile->setCheckState(Qt::CheckState::Unchecked);
|
||||||
connect(chkCoupledSettingFile, &QCheckBox::stateChanged, this, [=](int state){
|
connect(chkCoupledSettingFile, &QCheckBox::stateChanged, this, [=](int state){
|
||||||
|
@ -358,7 +369,8 @@ DigiSettingsPanel::DigiSettingsPanel(Digitizer ** digi, unsigned int nDigi, QStr
|
||||||
//If any digitizer is running ACQ, disable the panel.
|
//If any digitizer is running ACQ, disable the panel.
|
||||||
for( unsigned int iDigi = 0; iDigi < nDigi; iDigi ++){
|
for( unsigned int iDigi = 0; iDigi < nDigi; iDigi ++){
|
||||||
if( digi[iDigi]->IsRunning() ) {
|
if( digi[iDigi]->IsRunning() ) {
|
||||||
this->setEnabled(false);
|
// this->setEnabled(false);
|
||||||
|
EnableButtons(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1366,6 +1378,7 @@ void DigiSettingsPanel::SetUpChannelMask(unsigned int digiID){
|
||||||
|
|
||||||
connect(bnChEnableMask[digiID][i], &QPushButton::clicked, this, [=](){
|
connect(bnChEnableMask[digiID][i], &QPushButton::clicked, this, [=](){
|
||||||
if( !enableSignalSlot) return;
|
if( !enableSignalSlot) return;
|
||||||
|
if( digi[digiID]->IsRunning() ) return;
|
||||||
|
|
||||||
if( bnChEnableMask[digiID][i]->styleSheet() == "" ){
|
if( bnChEnableMask[digiID][i]->styleSheet() == "" ){
|
||||||
bnChEnableMask[digiID][i]->setStyleSheet("background-color : green;");
|
bnChEnableMask[digiID][i]->setStyleSheet("background-color : green;");
|
||||||
|
@ -2486,7 +2499,7 @@ void DigiSettingsPanel::SetUpChannel_PSD(){
|
||||||
QLabel * lb4 = new QLabel("Veto Width", this); lb4->setAlignment(Qt::AlignHCenter); tabLayout->addWidget(lb4, 0, 6);
|
QLabel * lb4 = new QLabel("Veto Width", this); lb4->setAlignment(Qt::AlignHCenter); tabLayout->addWidget(lb4, 0, 6);
|
||||||
QLabel * lb5 = new QLabel("Veto Step", this); lb5->setAlignment(Qt::AlignHCenter); tabLayout->addWidget(lb5, 0, 8);
|
QLabel * lb5 = new QLabel("Veto Step", this); lb5->setAlignment(Qt::AlignHCenter); tabLayout->addWidget(lb5, 0, 8);
|
||||||
}
|
}
|
||||||
SetUpComboBoxBit(cbVetoSource[ID][ch], "", tabLayout, ch + 1, 1, DPP::PHA::Bit_DPPAlgorithmControl2::ListVetoSource, DPP::PHA::DPPAlgorithmControl2_G, DPP::PHA::Bit_DPPAlgorithmControl2::VetoSource, 1, ch);
|
SetUpComboBoxBit(cbVetoSource[ID][ch], "", tabLayout, ch + 1, 1, DPP::PSD::Bit_DPPAlgorithmControl2::ListVetoSource, DPP::PSD::DPPAlgorithmControl2_G, DPP::PSD::Bit_DPPAlgorithmControl2::VetoSource, 1, ch);
|
||||||
SetUpComboBoxBit(cbVetoMode[ID][ch], "", tabLayout, ch + 1, 3, DPP::PSD::Bit_DPPAlgorithmControl2::ListVetoMode, DPP::PSD::DPPAlgorithmControl2_G, DPP::PSD::Bit_DPPAlgorithmControl2::VetoMode, 1, ch);
|
SetUpComboBoxBit(cbVetoMode[ID][ch], "", tabLayout, ch + 1, 3, DPP::PSD::Bit_DPPAlgorithmControl2::ListVetoMode, DPP::PSD::DPPAlgorithmControl2_G, DPP::PSD::Bit_DPPAlgorithmControl2::VetoMode, 1, ch);
|
||||||
SetUpSpinBox(sbVetoWidth[ID][ch], "", tabLayout, ch + 1, 5, DPP::VetoWidth, ch);
|
SetUpSpinBox(sbVetoWidth[ID][ch], "", tabLayout, ch + 1, 5, DPP::VetoWidth, ch);
|
||||||
SetUpComboBoxBit(cbVetoStep[ID][ch], "", tabLayout, ch + 1, 7, DPP::Bit_VetoWidth::ListVetoStep, DPP::VetoWidth, DPP::Bit_VetoWidth::VetoStep, 1, ch);
|
SetUpComboBoxBit(cbVetoStep[ID][ch], "", tabLayout, ch + 1, 7, DPP::Bit_VetoWidth::ListVetoStep, DPP::VetoWidth, DPP::Bit_VetoWidth::VetoStep, 1, ch);
|
||||||
|
@ -2497,8 +2510,8 @@ void DigiSettingsPanel::SetUpChannel_PSD(){
|
||||||
QLabel * lb2 = new QLabel("Extra Option [G]", this); lb2->setAlignment(Qt::AlignHCenter); tabLayout->addWidget(lb2, 0, 2);
|
QLabel * lb2 = new QLabel("Extra Option [G]", this); lb2->setAlignment(Qt::AlignHCenter); tabLayout->addWidget(lb2, 0, 2);
|
||||||
QLabel * lb3 = new QLabel("TRG-OUT Ch. Prb. [G]", this); lb3->setAlignment(Qt::AlignHCenter); tabLayout->addWidget(lb3, 0, 4);
|
QLabel * lb3 = new QLabel("TRG-OUT Ch. Prb. [G]", this); lb3->setAlignment(Qt::AlignHCenter); tabLayout->addWidget(lb3, 0, 4);
|
||||||
}
|
}
|
||||||
SetUpComboBoxBit(cbExtra2Option[ID][ch], "", tabLayout, ch + 1, 1, DPP::PHA::Bit_DPPAlgorithmControl2::ListExtra2, DPP::PHA::DPPAlgorithmControl2_G, DPP::PHA::Bit_DPPAlgorithmControl2::Extra2Option, 2, ch);
|
SetUpComboBoxBit(cbExtra2Option[ID][ch], "", tabLayout, ch + 1, 1, DPP::PSD::Bit_DPPAlgorithmControl2::ListExtraWordOpt, DPP::PSD::DPPAlgorithmControl2_G, DPP::PSD::Bit_DPPAlgorithmControl2::ExtraWordOption, 1, ch);
|
||||||
SetUpComboBoxBit(cbTRGOUTChannelProbe[ID][ch], "", tabLayout, ch + 1, 3, DPP::PSD::Bit_DPPAlgorithmControl2::ListChannelProbe, DPP::PSD::DPPAlgorithmControl2_G, DPP::PSD::Bit_DPPAlgorithmControl2::ChannelProbe, 2, ch);
|
SetUpComboBoxBit(cbTRGOUTChannelProbe[ID][ch], "", tabLayout, ch + 1, 3, DPP::PSD::Bit_DPPAlgorithmControl2::ListChannelProbe, DPP::PSD::DPPAlgorithmControl2_G, DPP::PSD::Bit_DPPAlgorithmControl2::ChannelProbe, 1, ch);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3620,6 +3633,20 @@ void DigiSettingsPanel::SyncCheckBox(QCheckBox *(&chk)[][MaxRegChannel+1]){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DigiSettingsPanel::EnableButtons(bool enable){
|
||||||
|
for( int i = 0; i < nDigi; i++ ){
|
||||||
|
if( !enable ) {
|
||||||
|
leSaveFilePath[i]->setText("changing setting is disabled due to ACQ is running.");
|
||||||
|
leSaveFilePath[i]->setStyleSheet("color:red;");
|
||||||
|
}else{
|
||||||
|
leSaveFilePath[i]->setText((QString::fromStdString(digi[i]->GetSettingFileName())));
|
||||||
|
leSaveFilePath[i]->setStyleSheet("");
|
||||||
|
|
||||||
|
}
|
||||||
|
buttonsWidget[i]->setEnabled(enable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DigiSettingsPanel::SyncAllChannelsTab_PHA(){
|
void DigiSettingsPanel::SyncAllChannelsTab_PHA(){
|
||||||
DebugPrint("%s", "DigiSettingsPanel");
|
DebugPrint("%s", "DigiSettingsPanel");
|
||||||
SyncSpinBox(sbRecordLength);
|
SyncSpinBox(sbRecordLength);
|
||||||
|
@ -3836,16 +3863,16 @@ void DigiSettingsPanel::UpdateSettings_PSD(){
|
||||||
chkRejOverRange[ID][ch]->setChecked( Digitizer::ExtractBits(dpp, DPP::Bit_DPPAlgorithmControl_PSD::RejectOverRange));
|
chkRejOverRange[ID][ch]->setChecked( Digitizer::ExtractBits(dpp, DPP::Bit_DPPAlgorithmControl_PSD::RejectOverRange));
|
||||||
chkTestPule[ID][ch]->setChecked( Digitizer::ExtractBits(dpp, DPP::Bit_DPPAlgorithmControl_PSD::InternalTestPulse));
|
chkTestPule[ID][ch]->setChecked( Digitizer::ExtractBits(dpp, DPP::Bit_DPPAlgorithmControl_PSD::InternalTestPulse));
|
||||||
|
|
||||||
|
chkDisableOppositePulse[ID][ch]->setChecked( Digitizer::ExtractBits(dpp, DPP::Bit_DPPAlgorithmControl_PSD::DisableOppositePolarityInhibitZeroCrossingOnCFD));
|
||||||
|
chkDisableSelfTrigger[ID][ch]->setChecked( Digitizer::ExtractBits(dpp, DPP::Bit_DPPAlgorithmControl_PSD::DisableSelfTrigger));
|
||||||
|
chkRejPileUp[ID][ch]->setChecked( Digitizer::ExtractBits(dpp, DPP::Bit_DPPAlgorithmControl_PSD::RejectPileup));
|
||||||
|
chkPileUpInGate[ID][ch]->setChecked( Digitizer::ExtractBits(dpp, DPP::Bit_DPPAlgorithmControl_PSD::PileupWithinGate));
|
||||||
|
chkDisableTriggerHysteresis[ID][ch]->setChecked( Digitizer::ExtractBits(dpp, DPP::Bit_DPPAlgorithmControl_PSD::DisableTriggerHysteresis));
|
||||||
|
|
||||||
uint32_t dpp2 = digi[ID]->GetSettingFromMemory(DPP::PSD::DPPAlgorithmControl2_G, ch);
|
uint32_t dpp2 = digi[ID]->GetSettingFromMemory(DPP::PSD::DPPAlgorithmControl2_G, ch);
|
||||||
|
|
||||||
chkDisableOppositePulse[ID][ch]->setChecked( Digitizer::ExtractBits(dpp2, DPP::Bit_DPPAlgorithmControl_PSD::DisableOppositePolarityInhibitZeroCrossingOnCFD));
|
chkMarkSaturation[ID][ch]->setChecked( Digitizer::ExtractBits(dpp, DPP::PSD::Bit_DPPAlgorithmControl2::MarkSaturation));
|
||||||
chkDisableSelfTrigger[ID][ch]->setChecked( Digitizer::ExtractBits(dpp2, DPP::Bit_DPPAlgorithmControl_PSD::DisableSelfTrigger));
|
chkResetTimestampByTRGIN[ID][ch]->setChecked( Digitizer::ExtractBits(dpp, DPP::PSD::Bit_DPPAlgorithmControl2::ResetTimestampByTRGIN));
|
||||||
chkRejPileUp[ID][ch]->setChecked( Digitizer::ExtractBits(dpp2, DPP::Bit_DPPAlgorithmControl_PSD::RejectPileup));
|
|
||||||
chkPileUpInGate[ID][ch]->setChecked( Digitizer::ExtractBits(dpp2, DPP::Bit_DPPAlgorithmControl_PSD::PileupWithinGate));
|
|
||||||
chkDisableTriggerHysteresis[ID][ch]->setChecked( Digitizer::ExtractBits(dpp2, DPP::Bit_DPPAlgorithmControl_PSD::DisableTriggerHysteresis));
|
|
||||||
chkMarkSaturation[ID][ch]->setChecked( Digitizer::ExtractBits(dpp2, DPP::PSD::Bit_DPPAlgorithmControl2::MarkSaturation));
|
|
||||||
chkResetTimestampByTRGIN[ID][ch]->setChecked( Digitizer::ExtractBits(dpp2, DPP::PSD::Bit_DPPAlgorithmControl2::ResetTimestampByTRGIN));
|
|
||||||
|
|
||||||
|
|
||||||
UpdateComboBoxBit(cbLocalTriggerValid[ID][ch], dpp2, DPP::PSD::Bit_DPPAlgorithmControl2::LocalTrigValidMode);
|
UpdateComboBoxBit(cbLocalTriggerValid[ID][ch], dpp2, DPP::PSD::Bit_DPPAlgorithmControl2::LocalTrigValidMode);
|
||||||
UpdateComboBoxBit(cbAdditionLocalTrigValid[ID][ch], dpp2, DPP::PSD::Bit_DPPAlgorithmControl2::AdditionLocalTrigValid);
|
UpdateComboBoxBit(cbAdditionLocalTrigValid[ID][ch], dpp2, DPP::PSD::Bit_DPPAlgorithmControl2::AdditionLocalTrigValid);
|
||||||
|
|
|
@ -33,6 +33,8 @@ public slots:
|
||||||
void SaveSetting(int opt);
|
void SaveSetting(int opt);
|
||||||
void LoadSetting();
|
void LoadSetting();
|
||||||
|
|
||||||
|
void EnableButtons(bool enable);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void SendLogMsg(const QString &msg);
|
void SendLogMsg(const QString &msg);
|
||||||
void UpdateOtherPanels();
|
void UpdateOtherPanels();
|
||||||
|
@ -69,7 +71,6 @@ private:
|
||||||
void SyncComboBox(RComboBox *(&cb)[][MaxRegChannel+1]);
|
void SyncComboBox(RComboBox *(&cb)[][MaxRegChannel+1]);
|
||||||
void SyncCheckBox(QCheckBox *(&chk)[][MaxRegChannel+1]);
|
void SyncCheckBox(QCheckBox *(&chk)[][MaxRegChannel+1]);
|
||||||
|
|
||||||
|
|
||||||
void SyncAllChannelsTab_PHA();
|
void SyncAllChannelsTab_PHA();
|
||||||
void UpdateSettings_PHA();
|
void UpdateSettings_PHA();
|
||||||
void SyncAllChannelsTab_PSD();
|
void SyncAllChannelsTab_PSD();
|
||||||
|
@ -102,6 +103,8 @@ private:
|
||||||
|
|
||||||
QLineEdit * leSaveFilePath[MaxNDigitizer];
|
QLineEdit * leSaveFilePath[MaxNDigitizer];
|
||||||
|
|
||||||
|
QWidget * buttonsWidget[MaxNDigitizer];
|
||||||
|
|
||||||
QPushButton * bnRefreshSetting; // read setting from board
|
QPushButton * bnRefreshSetting; // read setting from board
|
||||||
QPushButton * bnProgramPreDefined;
|
QPushButton * bnProgramPreDefined;
|
||||||
QPushButton * bnClearBuffer;
|
QPushButton * bnClearBuffer;
|
||||||
|
|
7
FSUDAQ
Executable file
7
FSUDAQ
Executable file
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
timestamp=$(date +%Y%m%d_%H%M%S)
|
||||||
|
|
||||||
|
outFile=program_${timestamp}.log
|
||||||
|
|
||||||
|
stdbuf -oL ./FSUDAQ_Qt6 | tee $outFile
|
554
FSUDAQ.cpp
554
FSUDAQ.cpp
File diff suppressed because it is too large
Load Diff
73
FSUDAQ.h
73
FSUDAQ.h
|
@ -1,5 +1,5 @@
|
||||||
#ifndef MAINWINDOW_H
|
#ifndef FSUDAQ_H
|
||||||
#define MAINWINDOW_H
|
#define FSUDAQ_H
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
@ -20,12 +20,14 @@
|
||||||
#include "ClassInfluxDB.h"
|
#include "ClassInfluxDB.h"
|
||||||
#include "analyzers/Analyser.h"
|
#include "analyzers/Analyser.h"
|
||||||
|
|
||||||
//^#===================================================== MainWindow
|
class ScalarWorker; //Forward declaration
|
||||||
class MainWindow : public QMainWindow{
|
|
||||||
|
//^#===================================================== FSUDAQ
|
||||||
|
class FSUDAQ : public QMainWindow{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
MainWindow(QWidget *parent = nullptr);
|
FSUDAQ(QWidget *parent = nullptr);
|
||||||
~MainWindow();
|
~FSUDAQ();
|
||||||
|
|
||||||
void closeEvent(QCloseEvent * event){
|
void closeEvent(QCloseEvent * event){
|
||||||
if( scope ) {
|
if( scope ) {
|
||||||
|
@ -36,9 +38,9 @@ public:
|
||||||
delete digiSettings;
|
delete digiSettings;
|
||||||
digiSettings = nullptr;
|
digiSettings = nullptr;
|
||||||
}
|
}
|
||||||
if( canvas ) {
|
if( singleHistograms ) {
|
||||||
delete canvas;
|
delete singleHistograms;
|
||||||
canvas = nullptr;
|
singleHistograms = nullptr;
|
||||||
}
|
}
|
||||||
if( onlineAnalyzer ) {
|
if( onlineAnalyzer ) {
|
||||||
delete onlineAnalyzer;
|
delete onlineAnalyzer;
|
||||||
|
@ -47,6 +49,9 @@ public:
|
||||||
event->accept();
|
event->accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void UpdateScalar();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void OpenDataPath();
|
void OpenDataPath();
|
||||||
|
@ -64,7 +69,6 @@ private slots:
|
||||||
void SetupScalar();
|
void SetupScalar();
|
||||||
void CleanUpScalar();
|
void CleanUpScalar();
|
||||||
void OpenScalar();
|
void OpenScalar();
|
||||||
void UpdateScalar();
|
|
||||||
|
|
||||||
void StartACQ();
|
void StartACQ();
|
||||||
void StopACQ();
|
void StopACQ();
|
||||||
|
@ -76,7 +80,7 @@ private slots:
|
||||||
|
|
||||||
void OpenDigiSettings();
|
void OpenDigiSettings();
|
||||||
|
|
||||||
void OpenCanvas();
|
void OpenSingleHistograms();
|
||||||
|
|
||||||
void OpenAnalyzer();
|
void OpenAnalyzer();
|
||||||
|
|
||||||
|
@ -96,6 +100,7 @@ private:
|
||||||
|
|
||||||
Digitizer ** digi;
|
Digitizer ** digi;
|
||||||
unsigned int nDigi;
|
unsigned int nDigi;
|
||||||
|
bool isACQStarted;
|
||||||
|
|
||||||
QString programSettingsFilePath;
|
QString programSettingsFilePath;
|
||||||
QString rawDataPath;
|
QString rawDataPath;
|
||||||
|
@ -145,6 +150,9 @@ private:
|
||||||
QLineEdit * leElogIP;
|
QLineEdit * leElogIP;
|
||||||
QLineEdit * leElogName;
|
QLineEdit * leElogName;
|
||||||
|
|
||||||
|
QCheckBox * chkInflux;
|
||||||
|
QCheckBox * chkElog;
|
||||||
|
|
||||||
//@----- log msg
|
//@----- log msg
|
||||||
QPlainTextEdit * logInfo;
|
QPlainTextEdit * logInfo;
|
||||||
void LogMsg(QString msg);
|
void LogMsg(QString msg);
|
||||||
|
@ -165,7 +173,13 @@ private:
|
||||||
//@----- Scalar
|
//@----- Scalar
|
||||||
QMainWindow * scalar;
|
QMainWindow * scalar;
|
||||||
QGridLayout * scalarLayout;
|
QGridLayout * scalarLayout;
|
||||||
TimingThread * scalarThread;
|
TimingThread * scalarTimingThread;
|
||||||
|
// QThread * scalarThread;
|
||||||
|
// ScalarWorker * scalarWorker;
|
||||||
|
// QTimer * scalarTimer;
|
||||||
|
|
||||||
|
|
||||||
|
// TimingThread * scalarThread;
|
||||||
QLineEdit *** leTrigger; // need to delete manually
|
QLineEdit *** leTrigger; // need to delete manually
|
||||||
QLineEdit *** leAccept; // need to delete manually
|
QLineEdit *** leAccept; // need to delete manually
|
||||||
QPushButton * runStatus[MaxNDigitizer];
|
QPushButton * runStatus[MaxNDigitizer];
|
||||||
|
@ -190,14 +204,45 @@ private:
|
||||||
DigiSettingsPanel * digiSettings;
|
DigiSettingsPanel * digiSettings;
|
||||||
|
|
||||||
//@----- SingleSpectra
|
//@----- SingleSpectra
|
||||||
SingleSpectra * canvas;
|
SingleSpectra * singleHistograms;
|
||||||
TimingThread * histThread;
|
|
||||||
|
|
||||||
//@----- Analyzer
|
//@----- Analyzer
|
||||||
Analyzer * onlineAnalyzer;
|
Analyzer * onlineAnalyzer;
|
||||||
|
|
||||||
|
QString maskText(const QString &password) {
|
||||||
|
if (password.length() <= 3) {
|
||||||
|
return password; // No masking needed for short passwords
|
||||||
|
} else if (password.length() <= 10) {
|
||||||
|
QString maskedPassword = password.left(3);
|
||||||
|
maskedPassword += QString("*").repeated(password.length() - 3);
|
||||||
|
return maskedPassword;
|
||||||
|
} else {
|
||||||
|
return password.left(3) + QString("*").repeated(7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//^======================== Scalar Worker
|
||||||
|
|
||||||
|
// class ScalarWorker : public QObject{
|
||||||
|
// Q_OBJECT
|
||||||
|
// public:
|
||||||
|
// ScalarWorker(FSUDAQ * parent): SS(parent){}
|
||||||
|
|
||||||
|
// public slots:
|
||||||
|
// void UpdateScalar(){
|
||||||
|
// SS->UpdateScalar();
|
||||||
|
// emit workDone();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// signals:
|
||||||
|
// void workDone();
|
||||||
|
|
||||||
|
// private:
|
||||||
|
// FSUDAQ * SS;
|
||||||
|
// };
|
||||||
|
|
||||||
|
|
||||||
#endif // MAINWINDOW_H
|
#endif // MAINWINDOW_H
|
|
@ -11,9 +11,9 @@ QT += core widgets charts printsupport
|
||||||
LIBS += -lCAENDigitizer -lcurl
|
LIBS += -lCAENDigitizer -lcurl
|
||||||
|
|
||||||
#==== for enable GDB debug
|
#==== for enable GDB debug
|
||||||
#QMAKE_CXXFLAGS += -g
|
QMAKE_CXXFLAGS += -g
|
||||||
#QMAKE_CXXFLAGS_RELEASE = -O0
|
QMAKE_CXXFLAGS_RELEASE = -O0
|
||||||
#QMAKE_CFLAGS_RELEASE = -O0
|
QMAKE_CFLAGS_RELEASE = -O0
|
||||||
|
|
||||||
# You can make your code fail to compile if you use deprecated APIs.
|
# You can make your code fail to compile if you use deprecated APIs.
|
||||||
# In order to do so, uncomment the following line.
|
# In order to do so, uncomment the following line.
|
||||||
|
@ -25,34 +25,37 @@ LIBS += -lCAENDigitizer -lcurl
|
||||||
# Input
|
# Input
|
||||||
HEADERS += ClassData.h \
|
HEADERS += ClassData.h \
|
||||||
ClassDigitizer.h \
|
ClassDigitizer.h \
|
||||||
|
ClassInfluxDB.h\
|
||||||
CustomThreads.h \
|
CustomThreads.h \
|
||||||
CustomWidgets.h \
|
CustomWidgets.h \
|
||||||
Histogram1D.h \
|
|
||||||
Histogram2D.h \
|
|
||||||
DigiSettingsPanel.h \
|
DigiSettingsPanel.h \
|
||||||
FSUDAQ.h \
|
FSUDAQ.h \
|
||||||
macro.h \
|
Histogram1D.h \
|
||||||
RegisterAddress.h \
|
Histogram2D.h \
|
||||||
ClassInfluxDB.h\
|
|
||||||
Scope.h \
|
|
||||||
SingleSpectra.h \
|
|
||||||
Hit.h \
|
Hit.h \
|
||||||
|
macro.h \
|
||||||
MultiBuilder.h \
|
MultiBuilder.h \
|
||||||
qcustomplot.h \
|
qcustomplot.h \
|
||||||
analyzers/Isotope.h \
|
RegisterAddress.h \
|
||||||
|
Scope.h \
|
||||||
|
SingleSpectra.h \
|
||||||
analyzers/Analyser.h \
|
analyzers/Analyser.h \
|
||||||
|
analyzers/BeamTune.h\
|
||||||
analyzers/CoincidentAnalyzer.h \
|
analyzers/CoincidentAnalyzer.h \
|
||||||
analyzers/SplitPoleAnalyzer.h \
|
analyzers/Cross.h\
|
||||||
analyzers/EncoreAnalyzer.h \
|
analyzers/EncoreAnalyzer.h \
|
||||||
|
analyzers/Isotope.h \
|
||||||
|
analyzers/MCP.h \
|
||||||
|
analyzers/MCPandPSD.h \
|
||||||
|
analyzers/PID.h \
|
||||||
analyzers/RAISOR1.h \
|
analyzers/RAISOR1.h \
|
||||||
analyzers/RAISOR2.h \
|
analyzers/RAISOR2.h \
|
||||||
analyzers/TEST.h \
|
analyzers/SplitPoleAnalyzer.h \
|
||||||
analyzers/MCPandPSD.h \
|
|
||||||
analyzers/MCP.h \
|
|
||||||
analyzers/Cross.h\
|
|
||||||
analyzers/Target.h\
|
analyzers/Target.h\
|
||||||
analyzers/BeamTune.h\
|
analyzers/TEST.h \
|
||||||
analyzers/PID.h
|
analyzers/MUSICAnalyzer.h \
|
||||||
|
analyzers/NeutronGamma.h
|
||||||
|
|
||||||
SOURCES += ClassDigitizer.cpp \
|
SOURCES += ClassDigitizer.cpp \
|
||||||
DigiSettingsPanel.cpp \
|
DigiSettingsPanel.cpp \
|
||||||
FSUDAQ.cpp \
|
FSUDAQ.cpp \
|
||||||
|
|
|
@ -15,6 +15,8 @@ public:
|
||||||
// DebugPrint("%s", "Histogram1D");
|
// DebugPrint("%s", "Histogram1D");
|
||||||
isLogY = false;
|
isLogY = false;
|
||||||
|
|
||||||
|
for( int i = 0; i < MaxNHist; i++ ) showHist[i] = true;
|
||||||
|
|
||||||
for( int i = 0; i < 3; i ++) txt[i] = nullptr;
|
for( int i = 0; i < 3; i ++) txt[i] = nullptr;
|
||||||
nData = 1;
|
nData = 1;
|
||||||
Rebin(xbin, xmin, xmax);
|
Rebin(xbin, xmin, xmax);
|
||||||
|
@ -86,12 +88,15 @@ public:
|
||||||
|
|
||||||
QAction * a1 = menu.addAction("UnZoom");
|
QAction * a1 = menu.addAction("UnZoom");
|
||||||
QAction * a5 = menu.addAction("Set/UnSet Log-y");
|
QAction * a5 = menu.addAction("Set/UnSet Log-y");
|
||||||
|
QAction * a6 = nullptr;
|
||||||
|
if( nData > 1 ) a6 = menu.addAction("Toggle lines display");
|
||||||
QAction * a2 = menu.addAction("Clear hist.");
|
QAction * a2 = menu.addAction("Clear hist.");
|
||||||
QAction * a3 = menu.addAction("Toggle Stat.");
|
QAction * a3 = menu.addAction("Toggle Stat.");
|
||||||
QAction * a4 = menu.addAction("Rebin (clear histogram)");
|
QAction * a4 = menu.addAction("Rebin (clear histogram)");
|
||||||
//TODO fitGuass
|
//TODO fitGuass
|
||||||
|
|
||||||
QAction *selectedAction = menu.exec(event->globalPosition().toPoint());
|
QAction *selectedAction = menu.exec(event->globalPosition().toPoint());
|
||||||
|
//*========================================== UnZoom
|
||||||
if( selectedAction == a1 ){
|
if( selectedAction == a1 ){
|
||||||
xAxis->setRangeLower(xMin);
|
xAxis->setRangeLower(xMin);
|
||||||
xAxis->setRangeUpper(xMax);
|
xAxis->setRangeUpper(xMax);
|
||||||
|
@ -101,11 +106,13 @@ public:
|
||||||
usingMenu = false;
|
usingMenu = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//*========================================== Clear Hist
|
||||||
if( selectedAction == a2 ){
|
if( selectedAction == a2 ){
|
||||||
Clear();
|
Clear();
|
||||||
usingMenu = false;
|
usingMenu = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//*========================================== Toggle Stat.
|
||||||
if( selectedAction == a3 ){
|
if( selectedAction == a3 ){
|
||||||
for( int i = 0; i < 3; i++){
|
for( int i = 0; i < 3; i++){
|
||||||
txt[i]->setVisible( !txt[i]->visible());
|
txt[i]->setVisible( !txt[i]->visible());
|
||||||
|
@ -113,6 +120,7 @@ public:
|
||||||
replot();
|
replot();
|
||||||
usingMenu = false;
|
usingMenu = false;
|
||||||
}
|
}
|
||||||
|
//*========================================== Rebin
|
||||||
if( selectedAction == a4 ){
|
if( selectedAction == a4 ){
|
||||||
QDialog dialog(this);
|
QDialog dialog(this);
|
||||||
dialog.setWindowTitle("Rebin histogram");
|
dialog.setWindowTitle("Rebin histogram");
|
||||||
|
@ -174,8 +182,38 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if( selectedAction == a5 ){
|
|
||||||
|
|
||||||
|
//*========================================== Toggle line Display
|
||||||
|
if( selectedAction == a6 ){
|
||||||
|
QDialog dialog(this);
|
||||||
|
dialog.setWindowTitle("Toggle lines Display");
|
||||||
|
|
||||||
|
QFormLayout layout(&dialog);
|
||||||
|
|
||||||
|
QCheckBox ** cbline = new QCheckBox *[nData];
|
||||||
|
for( int i = 0; i < nData; i++ ){
|
||||||
|
cbline[i] = new QCheckBox(graph(i)->name(), &dialog);
|
||||||
|
layout.addRow(cbline[i]);
|
||||||
|
if( showHist[i] ) cbline[i]->setChecked(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &dialog);
|
||||||
|
layout.addRow(&buttonBox);
|
||||||
|
|
||||||
|
QObject::connect(&buttonBox, &QDialogButtonBox::accepted, [&]() {
|
||||||
|
for( int i = 0; i < nData; i++ ){
|
||||||
|
showHist[i] = cbline[i]->isChecked();
|
||||||
|
}
|
||||||
|
dialog.accept();
|
||||||
|
});
|
||||||
|
QObject::connect(&buttonBox, &QDialogButtonBox::rejected, [&]() { dialog.reject();});
|
||||||
|
|
||||||
|
if( dialog.exec() == QDialog::Accepted ){
|
||||||
|
UpdatePlot();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//*========================================== Set Log y
|
||||||
|
if( selectedAction == a5 ){
|
||||||
if( !isLogY ){
|
if( !isLogY ){
|
||||||
this->yAxis->setScaleType(QCPAxis::stLogarithmic);
|
this->yAxis->setScaleType(QCPAxis::stLogarithmic);
|
||||||
isLogY = true;
|
isLogY = true;
|
||||||
|
@ -206,12 +244,16 @@ public:
|
||||||
addGraph();
|
addGraph();
|
||||||
graph(nData - 1)->setName(title);
|
graph(nData - 1)->setName(title);
|
||||||
SetColor(color, nData-1);
|
SetColor(color, nData-1);
|
||||||
yList[nData-1] = yList[0];
|
yList[nData-1].clear();
|
||||||
|
for( int i = 0; i < xList.count(); i++) yList[nData-1].append(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdatePlot(){
|
void UpdatePlot(){
|
||||||
DebugPrint("%s", "Histogram1D");
|
DebugPrint("%s", "Histogram1D");
|
||||||
for( int ID = 0 ; ID < nData; ID ++) graph(ID)->setData(xList, yList[ID]);
|
for( int ID = 0 ; ID < nData; ID ++) {
|
||||||
|
graph(ID)->setVisible(showHist[ID]);
|
||||||
|
graph(ID)->setData(xList, yList[ID]);
|
||||||
|
}
|
||||||
xAxis->setRangeLower(xMin);
|
xAxis->setRangeLower(xMin);
|
||||||
xAxis->setRangeUpper(xMax);
|
xAxis->setRangeUpper(xMax);
|
||||||
yAxis->setRangeLower(0);
|
yAxis->setRangeLower(0);
|
||||||
|
@ -222,7 +264,7 @@ public:
|
||||||
void Clear(){
|
void Clear(){
|
||||||
DebugPrint("%s", "Histogram1D");
|
DebugPrint("%s", "Histogram1D");
|
||||||
for( int ID = 0 ; ID < nData; ID ++) {
|
for( int ID = 0 ; ID < nData; ID ++) {
|
||||||
for( int i = 0; i <= yList[ID].count(); i++) yList[ID][i] = 0;
|
for( int i = 0; i < xList.count(); i++) yList[ID][i] = 0;
|
||||||
}
|
}
|
||||||
yMax = 0;
|
yMax = 0;
|
||||||
txt[0]->setText("Under Flow : 0");
|
txt[0]->setText("Under Flow : 0");
|
||||||
|
@ -234,7 +276,7 @@ public:
|
||||||
UpdatePlot();
|
UpdatePlot();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetXTitle(QString xTitle) { xAxis->setLabel(xTitle); }
|
void SetXTitle(QString xTitle) { xAxis->setLabel(xTitle);}
|
||||||
|
|
||||||
void Rebin(int xbin, double xmin, double xmax){
|
void Rebin(int xbin, double xmin, double xmax){
|
||||||
// DebugPrint("%s", "Histogram1D");
|
// DebugPrint("%s", "Histogram1D");
|
||||||
|
@ -283,16 +325,18 @@ public:
|
||||||
txt[2]->setText("Over Flow : "+ QString::number(overFlow));
|
txt[2]->setText("Over Flow : "+ QString::number(overFlow));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}else{
|
||||||
|
if( value < xMin || value > xMax ) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
double bin = (value - xMin)/dX;
|
int bin = qFloor((value - xMin)/dX);
|
||||||
int index1 = 2*qFloor(bin) + 1;
|
int index1 = 2*bin + 1;
|
||||||
int index2 = index1 + 1;
|
int index2 = index1 + 1;
|
||||||
|
|
||||||
if( 0 <= index1 && index1 <= 2*xBin) yList[ID][index1] += 1;
|
if( 0 <= index1 && index1 <= 2*xBin) yList[ID][index1] += 1;
|
||||||
if( 0 <= index1 && index2 <= 2*xBin) yList[ID][index2] += 1;
|
if( 0 <= index1 && index2 <= 2*xBin) yList[ID][index2] += 1;
|
||||||
|
|
||||||
if( yList[ID][index1] > yMax ) yMax = yList[ID][index1];
|
if( showHist[ID] && yList[ID][index1] > yMax ) yMax = yList[ID][index1];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Print(unsigned int ID = 0){
|
void Print(unsigned int ID = 0){
|
||||||
|
@ -324,6 +368,8 @@ private:
|
||||||
|
|
||||||
bool usingMenu;
|
bool usingMenu;
|
||||||
|
|
||||||
|
bool showHist[MaxNHist];
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
322
Histogram2D.h
322
Histogram2D.h
|
@ -19,8 +19,91 @@ const QList<QPair<QColor, QString>> colorCycle = { {QColor(Qt::red), "Red"},
|
||||||
class Histogram2D : public QCustomPlot{
|
class Histogram2D : public QCustomPlot{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Histogram2D(QString title, QString xLabel, QString yLabel, int xbin, double xmin, double xmax, int ybin, double ymin, double ymax, QWidget * parent = nullptr) : QCustomPlot(parent){
|
Histogram2D(QString title, QString xLabel, QString yLabel,
|
||||||
|
int xbin, double xmin, double xmax,
|
||||||
|
int ybin, double ymin, double ymax,
|
||||||
|
QWidget * parent = nullptr,
|
||||||
|
QString defaultPath = QDir::homePath());
|
||||||
|
|
||||||
|
void SetXTitle(QString xTitle) { xAxis->setLabel(xTitle);}
|
||||||
|
void SetYTitle(QString yTitle) { yAxis->setLabel(yTitle);}
|
||||||
|
void Rebin(int xbin, double xmin, double xmax, int ybin, double ymin, double ymax);
|
||||||
|
void RebinY(int ybin, double ymin, double ymax);
|
||||||
|
|
||||||
|
void SetChannelMap(bool onOff, int tickStep = 1) { isChannelMap = onOff; this->tickStep = tickStep;}
|
||||||
|
|
||||||
|
void UpdatePlot(){ colorMap->rescaleDataRange(); replot(); }
|
||||||
|
void Clear(); // Clear Data and histrogram
|
||||||
|
|
||||||
|
void Fill(double x, double y);
|
||||||
|
|
||||||
|
void DrawCut();
|
||||||
|
void ClearAllCuts();
|
||||||
|
|
||||||
|
QList<QPolygonF> GetCutList() const{return cutList;} // this list may contain empty element
|
||||||
|
QList<int> GetCutEntryList() const{ return cutEntryList;}
|
||||||
|
QList<QString> GetCutNameList() const { return cutNameList;}
|
||||||
|
void PrintCutEntry() const;
|
||||||
|
|
||||||
|
double GetXNBin() const {return xBin;}
|
||||||
|
double GetXMin() const {return xMin;}
|
||||||
|
double GetXMax() const {return xMax;}
|
||||||
|
double GetYNBin() const {return yBin;}
|
||||||
|
double GetYMin() const {return yMin;}
|
||||||
|
double GetYMax() const {return yMax;}
|
||||||
|
|
||||||
|
void SaveCuts(QString cutFileName);
|
||||||
|
void LoadCuts(QString cutFileName);
|
||||||
|
|
||||||
|
private:
|
||||||
|
double xMin, xMax, yMin, yMax;
|
||||||
|
int xBin, yBin;
|
||||||
|
|
||||||
|
bool isChannelMap;
|
||||||
|
int tickStep;
|
||||||
|
bool isLogZ;
|
||||||
|
|
||||||
|
QCPColorMap * colorMap;
|
||||||
|
QCPColorScale *colorScale;
|
||||||
|
|
||||||
|
bool usingMenu;
|
||||||
|
|
||||||
|
int entry[3][3]; // overflow counter, entrt[1][1] is entry in the plot;
|
||||||
|
|
||||||
|
QCPItemRect * box[3][3];
|
||||||
|
QCPItemText * txt[3][3];
|
||||||
|
|
||||||
|
QPolygonF tempCut;
|
||||||
|
int tempCutID; // only incresing;
|
||||||
|
int numCut;
|
||||||
|
QList<QPolygonF> cutList;
|
||||||
|
QList<QString> cutNameList; // name of the cut
|
||||||
|
QList<int> cutEntryList; // number of entry inside the cut.
|
||||||
|
QList<int> cutIDList; // ID of the cut
|
||||||
|
QList<int> cutTextIDList; //
|
||||||
|
QList<int> plottableIDList;
|
||||||
|
bool isDrawCut;
|
||||||
|
int lastPlottableID;
|
||||||
|
|
||||||
|
QCPItemLine * line;
|
||||||
|
double oldMouseX = 0.0, oldMouseY = 0.0;
|
||||||
|
|
||||||
|
bool isBusy;
|
||||||
|
|
||||||
|
void rightMouseClickMenu(QMouseEvent * event);
|
||||||
|
void rightMouseClickRebin();
|
||||||
|
|
||||||
|
QString settingPath;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//^###############################################
|
||||||
|
//^###############################################
|
||||||
|
|
||||||
|
inline Histogram2D::Histogram2D(QString title, QString xLabel, QString yLabel, int xbin, double xmin, double xmax, int ybin, double ymin, double ymax, QWidget * parent, QString defaultPath) : QCustomPlot(parent){
|
||||||
// DebugPrint("%s", "Histogram2D");
|
// DebugPrint("%s", "Histogram2D");
|
||||||
|
|
||||||
|
settingPath = defaultPath;
|
||||||
for( int i = 0; i < 3; i ++ ){
|
for( int i = 0; i < 3; i ++ ){
|
||||||
for( int j = 0; j < 3; j ++ ){
|
for( int j = 0; j < 3; j ++ ){
|
||||||
box[i][j] = nullptr;
|
box[i][j] = nullptr;
|
||||||
|
@ -183,97 +266,9 @@ public:
|
||||||
connect(this, &QCustomPlot::mouseRelease, this, [=](){
|
connect(this, &QCustomPlot::mouseRelease, this, [=](){
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//^===================================
|
|
||||||
|
|
||||||
void SetXTitle(QString xTitle) { xAxis->setLabel(xTitle); }
|
|
||||||
void SetYTitle(QString yTitle) { yAxis->setLabel(yTitle); }
|
|
||||||
void Rebin(int xbin, double xmin, double xmax, int ybin, double ymin, double ymax);
|
|
||||||
void RebinY(int ybin, double ymin, double ymax);
|
|
||||||
|
|
||||||
void SetChannelMap(bool onOff, int tickStep = 1) { isChannelMap = onOff; this->tickStep = tickStep;}
|
|
||||||
|
|
||||||
void UpdatePlot(){
|
|
||||||
// QCPColorGradient color;
|
|
||||||
// color.clearColorStops();
|
|
||||||
// color.setNanColor(QColor("white"));
|
|
||||||
// // color.setColorStopAt( 0.0, QColor("white" ));
|
|
||||||
// // color.setColorStopAt( 1.0/entry[1][1], QColor("purple" ));
|
|
||||||
// color.setColorStopAt( 0.0, QColor("purple" ));
|
|
||||||
// color.setColorStopAt( 0.2, QColor("blue"));
|
|
||||||
// color.setColorStopAt( 0.4, QColor("cyan"));
|
|
||||||
// color.setColorStopAt( 0.6, QColor("green"));
|
|
||||||
// color.setColorStopAt( 0.8, QColor("yellow"));
|
|
||||||
// color.setColorStopAt( 1.0, QColor("red"));
|
|
||||||
// colorMap->setGradient(color);
|
|
||||||
|
|
||||||
colorMap->rescaleDataRange();
|
|
||||||
|
|
||||||
replot();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Clear(); // Clear Data and histrogram
|
|
||||||
|
|
||||||
void Fill(double x, double y);
|
|
||||||
|
|
||||||
void DrawCut();
|
|
||||||
void ClearAllCuts();
|
|
||||||
|
|
||||||
QList<QPolygonF> GetCutList() const{return cutList;} // this list may contain empty element
|
|
||||||
QList<int> GetCutEntryList() const{ return cutEntryList;}
|
|
||||||
QList<QString> GetCutNameList() const { return cutNameList;}
|
|
||||||
void PrintCutEntry() const;
|
|
||||||
|
|
||||||
double GetXNBin() const {return xBin;}
|
|
||||||
double GetXMin() const {return xMin;}
|
|
||||||
double GetXMax() const {return xMax;}
|
|
||||||
double GetYNBin() const {return yBin;}
|
|
||||||
double GetYMin() const {return yMin;}
|
|
||||||
double GetYMax() const {return yMax;}
|
|
||||||
|
|
||||||
private:
|
|
||||||
double xMin, xMax, yMin, yMax;
|
|
||||||
int xBin, yBin;
|
|
||||||
|
|
||||||
bool isChannelMap;
|
|
||||||
int tickStep;
|
|
||||||
bool isLogZ;
|
|
||||||
|
|
||||||
QCPColorMap * colorMap;
|
|
||||||
QCPColorScale *colorScale;
|
|
||||||
|
|
||||||
bool usingMenu;
|
|
||||||
|
|
||||||
int entry[3][3]; // overflow counter, entrt[1][1] is entry in the plot;
|
|
||||||
|
|
||||||
QCPItemRect * box[3][3];
|
|
||||||
QCPItemText * txt[3][3];
|
|
||||||
|
|
||||||
QPolygonF tempCut;
|
|
||||||
int tempCutID; // only incresing;
|
|
||||||
QList<QPolygonF> cutList;
|
|
||||||
QList<int> cutIDList;
|
|
||||||
int numCut;
|
|
||||||
bool isDrawCut;
|
|
||||||
int lastPlottableID;
|
|
||||||
QList<int> cutTextIDList;
|
|
||||||
QList<int> plottableIDList;
|
|
||||||
QList<QString> cutNameList;
|
|
||||||
QList<int> cutEntryList;
|
|
||||||
|
|
||||||
QCPItemLine * line;
|
|
||||||
double oldMouseX = 0.0, oldMouseY = 0.0;
|
|
||||||
|
|
||||||
bool isBusy;
|
|
||||||
|
|
||||||
void rightMouseClickMenu(QMouseEvent * event);
|
|
||||||
void rightMouseClickRebin();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
//^###############################################
|
|
||||||
//^###############################################
|
|
||||||
|
|
||||||
inline void Histogram2D::Fill(double x, double y){
|
inline void Histogram2D::Fill(double x, double y){
|
||||||
// DebugPrint("%s", "Histogram2D");
|
// DebugPrint("%s", "Histogram2D");
|
||||||
|
@ -338,6 +333,9 @@ inline void Histogram2D::Rebin(int xbin, double xmin, double xmax, int ybin, do
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rescaleAxes();
|
||||||
|
UpdatePlot();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Histogram2D::RebinY(int ybin, double ymin, double ymax){
|
inline void Histogram2D::RebinY(int ybin, double ymin, double ymax){
|
||||||
|
@ -388,7 +386,7 @@ inline void Histogram2D::ClearAllCuts(){
|
||||||
inline void Histogram2D::PrintCutEntry() const{
|
inline void Histogram2D::PrintCutEntry() const{
|
||||||
DebugPrint("%s", "Histogram2D");
|
DebugPrint("%s", "Histogram2D");
|
||||||
if( numCut == 0 ) return;
|
if( numCut == 0 ) return;
|
||||||
printf("=============== There are %d cuts.\n", numCut);
|
printf("=============== There are %d cuts. (%lld, %lld)\n", numCut, cutList.count(), cutEntryList.count());
|
||||||
for( int i = 0; i < cutList.count(); i++){
|
for( int i = 0; i < cutList.count(); i++){
|
||||||
if( cutList[i].isEmpty() ) continue;
|
if( cutList[i].isEmpty() ) continue;
|
||||||
printf("%10s | %d \n", cutNameList[i].toStdString().c_str(), cutEntryList[i]);
|
printf("%10s | %d \n", cutNameList[i].toStdString().c_str(), cutEntryList[i]);
|
||||||
|
@ -420,7 +418,7 @@ inline void Histogram2D::DrawCut(){
|
||||||
}
|
}
|
||||||
replot();
|
replot();
|
||||||
|
|
||||||
//qDebug() << "Plottable count : " << plottableCount() << ", cutList.count :" << cutList.count() << ", cutID :" << lastPlottableID;
|
// qDebug() << "Plottable count : " << plottableCount() << ", cutList.count :" << cutList.count() << ", cutID :" << lastPlottableID;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Histogram2D::rightMouseClickMenu(QMouseEvent * event){
|
inline void Histogram2D::rightMouseClickMenu(QMouseEvent * event){
|
||||||
|
@ -436,8 +434,11 @@ inline void Histogram2D::rightMouseClickMenu(QMouseEvent * event){
|
||||||
QAction * a2 = menu->addAction("Clear hist.");
|
QAction * a2 = menu->addAction("Clear hist.");
|
||||||
QAction * a3 = menu->addAction("Toggle Stat.");
|
QAction * a3 = menu->addAction("Toggle Stat.");
|
||||||
QAction * a4 = menu->addAction("Rebin (clear histogram)");
|
QAction * a4 = menu->addAction("Rebin (clear histogram)");
|
||||||
|
QAction * a8 = menu->addAction("Load Cut(s)");
|
||||||
QAction * a5 = menu->addAction("Create a Cut");
|
QAction * a5 = menu->addAction("Create a Cut");
|
||||||
|
QAction * a7 = nullptr;
|
||||||
if( numCut > 0 ) {
|
if( numCut > 0 ) {
|
||||||
|
a7 = menu->addAction("Save Cut(s)");
|
||||||
menu->addSeparator();
|
menu->addSeparator();
|
||||||
menu->addAction("Add/Edit names to Cuts");
|
menu->addAction("Add/Edit names to Cuts");
|
||||||
menu->addAction("Clear all Cuts");
|
menu->addAction("Clear all Cuts");
|
||||||
|
@ -572,6 +573,27 @@ inline void Histogram2D::rightMouseClickMenu(QMouseEvent * event){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( selectedAction == a8 ){ // load Cuts
|
||||||
|
QString filePath = QFileDialog::getOpenFileName(this,
|
||||||
|
"Load Cuts from File",
|
||||||
|
settingPath,
|
||||||
|
"Text file (*.txt)");
|
||||||
|
|
||||||
|
if (!filePath.isEmpty()) LoadCuts(filePath);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if( selectedAction == a7 ){ // Save Cuts
|
||||||
|
|
||||||
|
QString filePath = QFileDialog::getSaveFileName(this,
|
||||||
|
"Save Cuts to File",
|
||||||
|
settingPath,
|
||||||
|
"Text file (*.txt)");
|
||||||
|
|
||||||
|
if (!filePath.isEmpty()) SaveCuts(filePath);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,7 +615,7 @@ inline void Histogram2D::rightMouseClickRebin(){
|
||||||
lineEditX[i] = new QLineEdit(&dialog);
|
lineEditX[i] = new QLineEdit(&dialog);
|
||||||
layout.addRow(nameListX[i] + " : ", lineEditX[i]);
|
layout.addRow(nameListX[i] + " : ", lineEditX[i]);
|
||||||
}
|
}
|
||||||
lineEditX[0]->setText(QString::number(xBin));
|
lineEditX[0]->setText(QString::number(xBin-2));
|
||||||
lineEditX[1]->setText(QString::number(xMin));
|
lineEditX[1]->setText(QString::number(xMin));
|
||||||
lineEditX[2]->setText(QString::number(xMax));
|
lineEditX[2]->setText(QString::number(xMax));
|
||||||
|
|
||||||
|
@ -603,7 +625,7 @@ inline void Histogram2D::rightMouseClickRebin(){
|
||||||
lineEditY[i] = new QLineEdit(&dialog);
|
lineEditY[i] = new QLineEdit(&dialog);
|
||||||
layout.addRow(nameListY[i] + " : ", lineEditY[i]);
|
layout.addRow(nameListY[i] + " : ", lineEditY[i]);
|
||||||
}
|
}
|
||||||
lineEditY[0]->setText(QString::number(yBin));
|
lineEditY[0]->setText(QString::number(yBin-2));
|
||||||
lineEditY[1]->setText(QString::number(yMin));
|
lineEditY[1]->setText(QString::number(yMin));
|
||||||
lineEditY[2]->setText(QString::number(yMax));
|
lineEditY[2]->setText(QString::number(yMax));
|
||||||
|
|
||||||
|
@ -666,12 +688,120 @@ inline void Histogram2D::rightMouseClickRebin(){
|
||||||
if( dialog.exec() == QDialog::Accepted ){
|
if( dialog.exec() == QDialog::Accepted ){
|
||||||
isBusy = true;
|
isBusy = true;
|
||||||
Rebin((int)number[0][0], number[1][0], number[2][0], (int)number[0][1], number[1][1], number[2][1]);
|
Rebin((int)number[0][0], number[1][0], number[2][0], (int)number[0][1], number[1][1], number[2][1]);
|
||||||
rescaleAxes();
|
|
||||||
UpdatePlot();
|
|
||||||
isBusy = false;
|
isBusy = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void Histogram2D::SaveCuts(QString cutFileName){
|
||||||
|
|
||||||
|
QFile file(cutFileName);
|
||||||
|
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||||
|
QTextStream out(&file);
|
||||||
|
|
||||||
|
// Define the text to write
|
||||||
|
QStringList lines;
|
||||||
|
|
||||||
|
for( int i = 0; i < cutList.size(); i++){
|
||||||
|
lines << "====== "+ cutNameList[i];
|
||||||
|
for( int pt = 0 ; pt < cutList[i].size(); pt ++){
|
||||||
|
lines << QString::number(cutList[i][pt].rx(), 'g', 5) + "," + QString::number(cutList[i][pt].ry(), 'g', 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lines << "#===== End of File";
|
||||||
|
|
||||||
|
// Write each line to the file
|
||||||
|
for (const QString &line : lines) out << line << "\n";
|
||||||
|
|
||||||
|
// Close the file
|
||||||
|
file.close();
|
||||||
|
qDebug() << "File written successfully to" << cutFileName;
|
||||||
|
}else{
|
||||||
|
qWarning() << "Unable to open file" << cutFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Histogram2D::LoadCuts(QString cutFileName){
|
||||||
|
|
||||||
|
QFile file(cutFileName);
|
||||||
|
QString cutNameTemp;
|
||||||
|
|
||||||
|
// Open the file in read mode
|
||||||
|
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
|
QTextStream in(&file);
|
||||||
|
|
||||||
|
ClearAllCuts();
|
||||||
|
tempCut.clear();
|
||||||
|
|
||||||
|
// Read each line and append to the QStringList
|
||||||
|
|
||||||
|
while (!in.atEnd()) {
|
||||||
|
QString line = in.readLine();
|
||||||
|
|
||||||
|
if( line.contains("======") ){
|
||||||
|
if( !tempCut.isEmpty() ) {
|
||||||
|
DrawCut();
|
||||||
|
plottableIDList.push_back(plottableCount() -1 );
|
||||||
|
cutNameList.push_back(cutNameTemp);
|
||||||
|
cutEntryList.push_back(0);
|
||||||
|
QCPItemText * text = new QCPItemText(this);
|
||||||
|
text->setText(cutNameList.last());
|
||||||
|
text->position->setCoords(tempCut[0].rx(), tempCut[0].ry());
|
||||||
|
int colorID = tempCutID% colorCycle.count();
|
||||||
|
text->setColor(colorCycle[colorID].first);
|
||||||
|
cutTextIDList.push_back(itemCount() - 1);
|
||||||
|
// cutList.push_back(tempCut);
|
||||||
|
cutIDList.push_back(tempCutID);
|
||||||
|
}
|
||||||
|
tempCut.clear();
|
||||||
|
tempCutID ++;
|
||||||
|
numCut ++;
|
||||||
|
|
||||||
|
int spacePos = line.indexOf(' ');
|
||||||
|
cutNameTemp = line.mid(spacePos + 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( line.contains("#==") ) {
|
||||||
|
DrawCut();
|
||||||
|
plottableIDList.push_back(plottableCount() -1 );
|
||||||
|
cutNameList.push_back(cutNameTemp);
|
||||||
|
cutEntryList.push_back(0);
|
||||||
|
QCPItemText * text = new QCPItemText(this);
|
||||||
|
text->setText(cutNameList.last());
|
||||||
|
text->position->setCoords(tempCut[0].rx(), tempCut[0].ry());
|
||||||
|
int colorID = tempCutID% colorCycle.count();
|
||||||
|
text->setColor(colorCycle[colorID].first);
|
||||||
|
cutTextIDList.push_back(itemCount() - 1);
|
||||||
|
cutList.push_back(tempCut);
|
||||||
|
cutIDList.push_back(tempCutID);
|
||||||
|
break;
|
||||||
|
}else{
|
||||||
|
QStringList haha = line.split(",");
|
||||||
|
// qDebug() << haha;
|
||||||
|
if( haha.size() == 2 ){
|
||||||
|
tempCut.push_back(QPointF(haha[0].toFloat(), haha[1].toFloat()));
|
||||||
|
DrawCut();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close the file
|
||||||
|
file.close();
|
||||||
|
qDebug() << "File read successfully from" << cutFileName;
|
||||||
|
|
||||||
|
// PrintCutEntry();
|
||||||
|
// DrawCut();
|
||||||
|
replot();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
qWarning() << "Unable to open file" << cutFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
100
MultiBuilder.cpp
100
MultiBuilder.cpp
|
@ -7,15 +7,18 @@ MultiBuilder::MultiBuilder(Data ** multiData, std::vector<int> type, std::vector
|
||||||
data = multiData;
|
data = multiData;
|
||||||
typeList = type;
|
typeList = type;
|
||||||
snList = sn;
|
snList = sn;
|
||||||
|
numTotCh = 0;
|
||||||
for( uShort i = 0; i < nData; i++) {
|
for( uShort i = 0; i < nData; i++) {
|
||||||
idList.push_back(i);
|
idList.push_back(i);
|
||||||
dataSize.push_back(data[i]->GetDataSize());
|
dataSize.push_back(data[i]->GetDataSize());
|
||||||
|
numTotCh += data[i]->GetNChannel();
|
||||||
}
|
}
|
||||||
timeWindow = 100;
|
timeWindow = 100;
|
||||||
leftOverTime = 100;
|
leftOverTime = 100;
|
||||||
breakTime = -1;
|
breakTime = -1;
|
||||||
timeJump = 1e8;
|
timeJump = 1e8;
|
||||||
lastEventTime = 0;
|
lastEventTime = 0;
|
||||||
|
forceStop = false;
|
||||||
ClearEvents();
|
ClearEvents();
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,6 +32,7 @@ MultiBuilder::MultiBuilder(Data * singleData, int type, int sn): nData(1){
|
||||||
DebugPrint("%s", "MultiBuilder");
|
DebugPrint("%s", "MultiBuilder");
|
||||||
data = new Data *[1];
|
data = new Data *[1];
|
||||||
data[0] = singleData;
|
data[0] = singleData;
|
||||||
|
numTotCh = data[0]->GetNChannel();
|
||||||
typeList.push_back(type);
|
typeList.push_back(type);
|
||||||
snList.push_back(sn);
|
snList.push_back(sn);
|
||||||
idList.push_back(0);
|
idList.push_back(0);
|
||||||
|
@ -37,7 +41,7 @@ MultiBuilder::MultiBuilder(Data * singleData, int type, int sn): nData(1){
|
||||||
breakTime = -1;
|
breakTime = -1;
|
||||||
timeJump = 1e8;
|
timeJump = 1e8;
|
||||||
lastEventTime = 0;
|
lastEventTime = 0;
|
||||||
|
forceStop = false;
|
||||||
ClearEvents();
|
ClearEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +61,7 @@ void MultiBuilder::ClearEvents(){
|
||||||
loopIndex[i][j] = 0;
|
loopIndex[i][j] = 0;
|
||||||
nextIndex[i][j] = -1;
|
nextIndex[i][j] = -1;
|
||||||
chExhaused[i][j] = false;
|
chExhaused[i][j] = false;
|
||||||
|
lastBackWardIndex[i][j] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
earlistDigi = -1;
|
earlistDigi = -1;
|
||||||
|
@ -77,7 +82,6 @@ void MultiBuilder::PrintStat(){
|
||||||
if( nextIndex[i][ch] >= 0 ) printf("%d %3d %2d | %7d (%d)\n", i, snList[i], ch, nextIndex[i][ch], loopIndex[i][ch]);
|
if( nextIndex[i][ch] >= 0 ) printf("%d %3d %2d | %7d (%d)\n", i, snList[i], ch, nextIndex[i][ch], loopIndex[i][ch]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiBuilder::PrintAllEvent(){
|
void MultiBuilder::PrintAllEvent(){
|
||||||
|
@ -89,7 +93,6 @@ void MultiBuilder::PrintAllEvent(){
|
||||||
events[i][j].Print();
|
events[i][j].Print();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiBuilder::FindEarlistTimeAndCh(bool verbose){
|
void MultiBuilder::FindEarlistTimeAndCh(bool verbose){
|
||||||
|
@ -100,12 +103,15 @@ void MultiBuilder::FindEarlistTimeAndCh(bool verbose){
|
||||||
nExhaushedCh = 0;
|
nExhaushedCh = 0;
|
||||||
for( int i = 0; i < nData; i++){
|
for( int i = 0; i < nData; i++){
|
||||||
|
|
||||||
for( int j = 0; j < data[i]->GetNChannel(); j++ ) chExhaused[i][j] = false;
|
for( int j = 0; j < data[i]->GetNChannel(); j++ ) {
|
||||||
|
chExhaused[i][j] = false;
|
||||||
|
}
|
||||||
|
|
||||||
for(unsigned int ch = 0; ch < data[i]->GetNChannel(); ch ++){
|
for(unsigned int ch = 0; ch < data[i]->GetNChannel(); ch ++){
|
||||||
|
|
||||||
|
{// check is dataIndex is valid
|
||||||
int index = data[i]->GetDataIndex(ch);
|
int index = data[i]->GetDataIndex(ch);
|
||||||
if( ch >= data[i]->GetNChannel() || index < 0 ) {
|
if( index < 0 ) {
|
||||||
nExhaushedCh ++;
|
nExhaushedCh ++;
|
||||||
chExhaused[i][ch] = true;
|
chExhaused[i][ch] = true;
|
||||||
continue;
|
continue;
|
||||||
|
@ -117,6 +123,7 @@ void MultiBuilder::FindEarlistTimeAndCh(bool verbose){
|
||||||
chExhaused[i][ch] = true;
|
chExhaused[i][ch] = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( nextIndex[i][ch] == -1 ) nextIndex[i][ch] = 0;
|
if( nextIndex[i][ch] == -1 ) nextIndex[i][ch] = 0;
|
||||||
|
|
||||||
|
@ -126,6 +133,7 @@ void MultiBuilder::FindEarlistTimeAndCh(bool verbose){
|
||||||
earlistDigi = i;
|
earlistDigi = i;
|
||||||
earlistCh = ch;
|
earlistCh = ch;
|
||||||
}
|
}
|
||||||
|
// printf(" ch : %d | time %llu | %llu\n", ch, time, earlistTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,9 +153,9 @@ void MultiBuilder::FindLatestTimeAndCh(bool verbose){
|
||||||
|
|
||||||
for( int j = 0; j < data[i]->GetNChannel(); j++ ) chExhaused[i][j] = false;
|
for( int j = 0; j < data[i]->GetNChannel(); j++ ) chExhaused[i][j] = false;
|
||||||
|
|
||||||
for(unsigned int ch = 0; ch < MaxNChannels; ch ++){
|
for(unsigned int ch = 0; ch < data[i]->GetNChannel(); ch ++){
|
||||||
|
|
||||||
if( nextIndex[i][ch] < 0 || ch >= data[i]->GetNChannel() || data[i]->GetDataIndex(ch) < 0 ) {
|
if( nextIndex[i][ch] < 0 || data[i]->GetDataIndex(ch) < 0 || nextIndex[i][ch] <= lastBackWardIndex[i][ch] ) {
|
||||||
nExhaushedCh ++;
|
nExhaushedCh ++;
|
||||||
chExhaused[i][ch] = true;
|
chExhaused[i][ch] = true;
|
||||||
// printf(", exhanshed. %d \n", nExhaushedCh);
|
// printf(", exhanshed. %d \n", nExhaushedCh);
|
||||||
|
@ -211,7 +219,8 @@ void MultiBuilder::FindLatestTimeOfData(bool verbose){
|
||||||
|
|
||||||
void MultiBuilder::BuildEvents(bool isFinal, bool skipTrace, bool verbose){
|
void MultiBuilder::BuildEvents(bool isFinal, bool skipTrace, bool verbose){
|
||||||
DebugPrint("%s", "MultiBuilder");
|
DebugPrint("%s", "MultiBuilder");
|
||||||
FindEarlistTimeAmongLastData(verbose); // give lastest Time, Ch, and Digi
|
|
||||||
|
FindEarlistTimeAmongLastData(verbose); // give lastest Time, Ch, and Digi for event building
|
||||||
|
|
||||||
FindEarlistTimeAndCh(verbose); //Give the earliest time, ch, digi
|
FindEarlistTimeAndCh(verbose); //Give the earliest time, ch, digi
|
||||||
if( earlistCh == -1 || nExhaushedCh == nData * MaxNChannels) return; /// no data
|
if( earlistCh == -1 || nExhaushedCh == nData * MaxNChannels) return; /// no data
|
||||||
|
@ -221,13 +230,12 @@ void MultiBuilder::BuildEvents(bool isFinal, bool skipTrace, bool verbose){
|
||||||
Hit em;
|
Hit em;
|
||||||
do{
|
do{
|
||||||
|
|
||||||
|
if( forceStop ) break;
|
||||||
|
|
||||||
eventIndex ++;
|
eventIndex ++;
|
||||||
if( eventIndex >= MaxNEvent ) eventIndex = 0;
|
if( eventIndex >= MaxNEvent ) eventIndex = 0;
|
||||||
events[eventIndex].clear();
|
events[eventIndex].clear();
|
||||||
|
|
||||||
eventBuilt ++;
|
|
||||||
totalEventBuilt ++;
|
|
||||||
|
|
||||||
em.Clear();
|
em.Clear();
|
||||||
|
|
||||||
for( int k = 0; k < nData; k++){
|
for( int k = 0; k < nData; k++){
|
||||||
|
@ -279,6 +287,8 @@ void MultiBuilder::BuildEvents(bool isFinal, bool skipTrace, bool verbose){
|
||||||
if( timeWindow <= 0 ) break;
|
if( timeWindow <= 0 ) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( events[eventIndex].size() == 0 ) continue;
|
||||||
|
|
||||||
if( events[eventIndex].size() > 1) {
|
if( events[eventIndex].size() > 1) {
|
||||||
std::sort(events[eventIndex].begin(), events[eventIndex].end(), [](const Hit& a, const Hit& b) {
|
std::sort(events[eventIndex].begin(), events[eventIndex].end(), [](const Hit& a, const Hit& b) {
|
||||||
return a.timestamp < b.timestamp;
|
return a.timestamp < b.timestamp;
|
||||||
|
@ -293,14 +303,17 @@ void MultiBuilder::BuildEvents(bool isFinal, bool skipTrace, bool verbose){
|
||||||
// //if there is a time jump, say, bigger than TimeJump. break
|
// //if there is a time jump, say, bigger than TimeJump. break
|
||||||
if( earlistTime - lastEventTime > timeJump ) {
|
if( earlistTime - lastEventTime > timeJump ) {
|
||||||
if( verbose ){
|
if( verbose ){
|
||||||
printf("%6lu, %16llu\n", eventIndex, earlistTime);
|
printf("!!!!!!!! Time Jump detected stop event building and get more data.\n");
|
||||||
printf("%5s - %16llu \n", "", lastEventTime);
|
printf("event index : %6lu, earlist time : %16llu\n", eventIndex, earlistTime);
|
||||||
printf("%5s > %16llu \n", "", timeJump);
|
printf(" %6s last event time : %16llu \n", "", lastEventTime);
|
||||||
printf("!!!!!!!! Time Jump detected stop event building. stop event buinding and get more data.\n");
|
printf(" %6s time jump > %16llu \n", "", timeJump);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eventBuilt ++;
|
||||||
|
totalEventBuilt ++;
|
||||||
|
|
||||||
if( verbose ){
|
if( verbose ){
|
||||||
printf(">>>>>>>>>>>>>>>>> Event ID : %ld, total built: %ld, multiplicity : %ld\n", eventIndex, totalEventBuilt, events[eventIndex].size());
|
printf(">>>>>>>>>>>>>>>>> Event ID : %ld, total built: %ld, multiplicity : %ld\n", eventIndex, totalEventBuilt, events[eventIndex].size());
|
||||||
for( int i = 0; i <(int) events[eventIndex].size(); i++){
|
for( int i = 0; i <(int) events[eventIndex].size(); i++){
|
||||||
|
@ -337,13 +350,16 @@ void MultiBuilder::BuildEvents(bool isFinal, bool skipTrace, bool verbose){
|
||||||
}
|
}
|
||||||
}while(nExhaushedCh < nData * MaxNChannels);
|
}while(nExhaushedCh < nData * MaxNChannels);
|
||||||
|
|
||||||
|
forceStop = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiBuilder::BuildEventsBackWard(int maxNumEvent, bool verbose){
|
void MultiBuilder::BuildEventsBackWard(int maxNumEvent, bool verbose){
|
||||||
DebugPrint("%s", "MultiBuilder");
|
DebugPrint("%s", "MultiBuilder");
|
||||||
//skip trace, and only build for maxNumEvent events max
|
//skip trace, and only build for maxNumEvent events max
|
||||||
|
|
||||||
// remember the end of DataIndex, prevent over build
|
// Get the last data index and loop index
|
||||||
|
|
||||||
for( int k = 0; k < nData; k++){
|
for( int k = 0; k < nData; k++){
|
||||||
for( int i = 0; i < data[k]->GetNChannel(); i++){
|
for( int i = 0; i < data[k]->GetNChannel(); i++){
|
||||||
nextIndex[k][i] = data[k]->GetDataIndex(i);
|
nextIndex[k][i] = data[k]->GetDataIndex(i);
|
||||||
|
@ -357,12 +373,11 @@ void MultiBuilder::BuildEventsBackWard(int maxNumEvent, bool verbose){
|
||||||
eventBuilt = 0;
|
eventBuilt = 0;
|
||||||
Hit em;
|
Hit em;
|
||||||
do{
|
do{
|
||||||
|
if( forceStop ) break;
|
||||||
eventIndex ++;
|
eventIndex ++;
|
||||||
if( eventIndex >= MaxNEvent ) eventIndex = 0;
|
if( eventIndex >= MaxNEvent ) eventIndex = 0;
|
||||||
events[eventIndex].clear();
|
events[eventIndex].clear();
|
||||||
|
|
||||||
eventBuilt ++;
|
|
||||||
totalEventBuilt ++;
|
|
||||||
em.Clear();
|
em.Clear();
|
||||||
|
|
||||||
for( int k = 0; k < nData; k++){
|
for( int k = 0; k < nData; k++){
|
||||||
|
@ -373,10 +388,9 @@ void MultiBuilder::BuildEventsBackWard(int maxNumEvent, bool verbose){
|
||||||
for( int i = 0; i < numCh; i++){
|
for( int i = 0; i < numCh; i++){
|
||||||
int ch = (i + latestCh) % numCh;
|
int ch = (i + latestCh) % numCh;
|
||||||
if( chExhaused[bd][ch] ) continue;
|
if( chExhaused[bd][ch] ) continue;
|
||||||
//if( nextIndex[bd][ch] <= lastBackWardIndex[bd][ch] || nextIndex[bd][ch] < 0){
|
if( nextIndex[bd][ch] <= lastBackWardIndex[bd][ch] || nextIndex[bd][ch] <= 0){
|
||||||
if( nextIndex[bd][ch] < 0){
|
|
||||||
chExhaused[bd][ch] = true;
|
|
||||||
nExhaushedCh ++;
|
nExhaushedCh ++;
|
||||||
|
chExhaused[bd][ch] = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,11 +418,26 @@ void MultiBuilder::BuildEventsBackWard(int maxNumEvent, bool verbose){
|
||||||
if( timeWindow == 0 ) break;
|
if( timeWindow == 0 ) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FindLatestTimeAndCh(verbose);
|
||||||
|
|
||||||
|
if( verbose ) printf(" nExhaushedCh %d | numToCh %d \n", nExhaushedCh, numTotCh);
|
||||||
|
if( nExhaushedCh == numTotCh ) {
|
||||||
|
if( verbose ) printf("######################### no more event to be built\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if( verbose ) printf("----- next bd: %d, ch : %d, next latest Time : %llu.\n", latestDigi, latestCh, latestTime);
|
||||||
|
|
||||||
|
if( events[eventIndex].size() > 0 ) {
|
||||||
|
eventBuilt ++;
|
||||||
|
totalEventBuilt ++;
|
||||||
|
|
||||||
std::sort(events[eventIndex].begin(), events[eventIndex].end(), [](const Hit& a, const Hit& b) {
|
std::sort(events[eventIndex].begin(), events[eventIndex].end(), [](const Hit& a, const Hit& b) {
|
||||||
return a.timestamp < b.timestamp;
|
return a.timestamp < b.timestamp;
|
||||||
});
|
});
|
||||||
|
}else{
|
||||||
FindLatestTimeAndCh(verbose);
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if( verbose ){
|
if( verbose ){
|
||||||
printf(">>>>>>>>>>>>>>>>> Event ID : %ld, total built: %ld, multiplicity : %ld\n", eventIndex, totalEventBuilt, events[eventIndex].size());
|
printf(">>>>>>>>>>>>>>>>> Event ID : %ld, total built: %ld, multiplicity : %ld\n", eventIndex, totalEventBuilt, events[eventIndex].size());
|
||||||
|
@ -422,24 +451,19 @@ void MultiBuilder::BuildEventsBackWard(int maxNumEvent, bool verbose){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("%05d, %02d | %5d | %5d %llu \n", sn, chxxx, nextIndex[bd][chxxx], events[eventIndex][i].energy, events[eventIndex][i].timestamp);
|
printf("%5d, %02d | %5d | %5d %llu \n", sn, chxxx, nextIndex[bd][chxxx], events[eventIndex][i].energy, events[eventIndex][i].timestamp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nExhaushedCh == nData * MaxNChannels ) {
|
}while(nExhaushedCh < numTotCh && eventBuilt < maxNumEvent);
|
||||||
printf("######################### no more event to be built\n");
|
|
||||||
break;
|
forceStop = false;
|
||||||
|
|
||||||
|
// remember the end of DataIndex, prevent over build
|
||||||
|
for( int k = 0; k < nData; k++){
|
||||||
|
for( int i = 0; i < data[k]->GetNChannel(); i++){
|
||||||
|
lastBackWardIndex[k][i] = data[k]->GetDataIndex(i);
|
||||||
}
|
}
|
||||||
printf("----- next bd: %d, ch : %d, next latest Time : %llu.\n", latestDigi, latestCh, latestTime);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}while(nExhaushedCh < nData * MaxNChannels && eventBuilt < maxNumEvent);
|
|
||||||
|
|
||||||
// // remember the end of DataIndex, prevent over build
|
|
||||||
// for( int k = 0; k < nData; k++){
|
|
||||||
// for( int i = 0; i < MaxRegChannel; i++){
|
|
||||||
// lastBackWardIndex[k][i] = data[k]->DataIndex[i];
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,16 +14,18 @@ public:
|
||||||
MultiBuilder(Data * singleData, int type, int sn);
|
MultiBuilder(Data * singleData, int type, int sn);
|
||||||
~MultiBuilder();
|
~MultiBuilder();
|
||||||
|
|
||||||
void SetTimeWindow(unsigned short ticks) {timeWindow = ticks; leftOverTime = ticks;}
|
void ForceStop(bool onOff) { forceStop = onOff;}
|
||||||
|
|
||||||
|
void SetTimeWindow(unsigned short nanosec) {timeWindow = nanosec; leftOverTime = nanosec;}
|
||||||
unsigned short GetTimeWindow() const{return timeWindow;}
|
unsigned short GetTimeWindow() const{return timeWindow;}
|
||||||
|
|
||||||
void SetTimeJump(unsigned long long TimeJumpInNanoSec) {timeJump = TimeJumpInNanoSec;}
|
void SetTimeJump(unsigned long long TimeJumpInNanoSec) {timeJump = TimeJumpInNanoSec;}
|
||||||
unsigned long long GetTimeJump() const {return timeJump;}
|
unsigned long long GetTimeJump() const {return timeJump;}
|
||||||
|
|
||||||
void SetLeftOverTime(unsigned long long ticks) {leftOverTime = ticks;}
|
void SetLeftOverTime(unsigned long long nanosec) {leftOverTime = nanosec;}
|
||||||
unsigned long long GetLeftOverTime() const{return leftOverTime;}
|
unsigned long long GetLeftOverTime() const{return leftOverTime;}
|
||||||
|
|
||||||
void SetBreakTime(unsigned long long ticks) {breakTime = ticks;}
|
void SetBreakTime(unsigned long long nanosec) {breakTime = nanosec;}
|
||||||
unsigned long long GetBreakTime() const{return breakTime;}
|
unsigned long long GetBreakTime() const{return breakTime;}
|
||||||
|
|
||||||
unsigned int GetNumOfDigitizer() const {return nData;}
|
unsigned int GetNumOfDigitizer() const {return nData;}
|
||||||
|
@ -48,6 +50,7 @@ private:
|
||||||
std::vector<int> tick2ns;
|
std::vector<int> tick2ns;
|
||||||
const unsigned short nData;
|
const unsigned short nData;
|
||||||
Data ** data; // assume all data has MaxNChannel (16)
|
Data ** data; // assume all data has MaxNChannel (16)
|
||||||
|
int numTotCh; // number of total channel = sum digi[i]->GetNChannel()
|
||||||
|
|
||||||
std::vector<uShort> dataSize;
|
std::vector<uShort> dataSize;
|
||||||
|
|
||||||
|
@ -78,6 +81,8 @@ private:
|
||||||
|
|
||||||
int lastBackWardIndex[MaxNDigitizer][MaxNChannels];
|
int lastBackWardIndex[MaxNDigitizer][MaxNChannels];
|
||||||
|
|
||||||
|
bool forceStop;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
54
README.md
54
README.md
|
@ -6,19 +6,19 @@ https://discord.gg/xVsRhNZF8G
|
||||||
|
|
||||||
This is a DAQ for 1st gen CAEN digitizer for
|
This is a DAQ for 1st gen CAEN digitizer for
|
||||||
|
|
||||||
- V1725, V17255S, V1230 with PHA and PSD firmware.
|
- x725, x725S, x730 with PHA and PSD firmware.
|
||||||
- V1740 with QDC firmware
|
- V1740 with QDC firmware
|
||||||
|
|
||||||
It has scope (updated every half-sec), allow full control of the digitizer (except LVDS), and allow saving waveform.
|
It has scope (updated every half-sec), allow full control of the digitizer (except LVDS), and allow saving waveform.
|
||||||
|
|
||||||
It can be connected to InfluxDB v1.8+ and Elog.
|
It can be connected to InfluxDB v1.8+ and Elog.
|
||||||
|
|
||||||
Each channel has it own 1D histogram. It will not be filled by default, but can enable it in the "Online 1D histgram" panel. The binning of each histogram will be saved under the raw data path as singleSpectaSetting.txt
|
Each channel has it own 1D histogram. It will not be filled by default, but can enable it in the "Online Histgrams" panel. The binning of each histogram will be saved under the raw data path as singleSpectaSetting.txt
|
||||||
|
|
||||||
## Wiki
|
## Wiki
|
||||||
https://fsunuc.physics.fsu.edu/wiki/index.php/CAEN_digitizer
|
https://fsunuc.physics.fsu.edu/wiki/index.php/CAEN_digitizer
|
||||||
|
|
||||||
## Online analyzer
|
# Online analyzer
|
||||||
A Multi-builder (event builder that can build event across multiple digitizer) is made. It has normal event building code and also a backward event building code that build events from the latest data up to certain amont of event.
|
A Multi-builder (event builder that can build event across multiple digitizer) is made. It has normal event building code and also a backward event building code that build events from the latest data up to certain amont of event.
|
||||||
|
|
||||||
A 1-D and 2-D histogram is avalible. In the 2-D histogram, graphical cuts can be created and rename.
|
A 1-D and 2-D histogram is avalible. In the 2-D histogram, graphical cuts can be created and rename.
|
||||||
|
@ -27,6 +27,25 @@ An online analyzer class is created as a template for online analysis. An exampl
|
||||||
|
|
||||||
<span style="color:red;">Notice that, when the FSUDAQ is started, the online analyzer is not created, no event will be built. Once the online anlyzer is created and opened, event will be built, even the window is closed. </span>
|
<span style="color:red;">Notice that, when the FSUDAQ is started, the online analyzer is not created, no event will be built. Once the online anlyzer is created and opened, event will be built, even the window is closed. </span>
|
||||||
|
|
||||||
|
## Create a custom online analyzer
|
||||||
|
|
||||||
|
Under the analyzer folder, there are few examples can be followed. Teh idea is create a derivative class based on the Analyzer.h. To implement the new online analyzer, user need to modify a few things:
|
||||||
|
- add the code file into FSUDAQ_At.pro
|
||||||
|
- add the header to the top of FSUDAQ.cpp
|
||||||
|
- edit the vector onlienAnalyzerList at th etop of FSUDAQ.cpp
|
||||||
|
- edit the FSUDAQ::OpenAnalyzer()
|
||||||
|
|
||||||
|
after that, we need to update the makefile by
|
||||||
|
|
||||||
|
```sh
|
||||||
|
>qmake6 FSUDAQ_Qt6.pro
|
||||||
|
```
|
||||||
|
|
||||||
|
and then recompile by
|
||||||
|
```sh
|
||||||
|
>make
|
||||||
|
```
|
||||||
|
|
||||||
# Operation
|
# Operation
|
||||||
|
|
||||||
When programSettings.txt is presented in the same folder as the FSUDAQ_Qt, the program will load it can config the following
|
When programSettings.txt is presented in the same folder as the FSUDAQ_Qt, the program will load it can config the following
|
||||||
|
@ -65,8 +84,7 @@ User must setup the data path for data take. Without the data path, user still c
|
||||||
|
|
||||||
# ToDo
|
# ToDo
|
||||||
|
|
||||||
- Gaussians fitting for 1D Histogram
|
- Gaussians fitting for 1D Histogra
|
||||||
- Improve the color scheme for 2D histogram
|
|
||||||
- Save Histogram?
|
- Save Histogram?
|
||||||
|
|
||||||
# Required / Development enviroment
|
# Required / Development enviroment
|
||||||
|
@ -77,6 +95,7 @@ Ubuntu 22.04
|
||||||
- CAENCOmm v1.5.3 +
|
- CAENCOmm v1.5.3 +
|
||||||
- CAENDigitizer v2.17.1 +
|
- CAENDigitizer v2.17.1 +
|
||||||
- CAEN A3818 Driver v1.6.8 +
|
- CAEN A3818 Driver v1.6.8 +
|
||||||
|
- CAENUSBdrv v1.5.5 + (for V57XX digitizer with USB connection)
|
||||||
|
|
||||||
- qt6-base-dev
|
- qt6-base-dev
|
||||||
- libqt6charts6-dec
|
- libqt6charts6-dec
|
||||||
|
@ -135,13 +154,28 @@ if you want to use GDB debugger, in the *.pro file add
|
||||||
|
|
||||||
` QMAKE_CXXFLAGS += -g`
|
` QMAKE_CXXFLAGS += -g`
|
||||||
|
|
||||||
|
|
||||||
# Auxillary programs (e.g. Event Builder)
|
# Auxillary programs (e.g. Event Builder)
|
||||||
|
|
||||||
There is a folder Aux, this folder contains many auxillary programs, such as EventBuilder. User can `make` under the folder to compile the programs.
|
There is a folder Aux, this folder contains many auxillary programs, such as EventBuilder. User can `make` under the folder to compile the programs.
|
||||||
|
|
||||||
# Tested Trigger Rate
|
# Enable Core dump
|
||||||
|
|
||||||
|
The program has abort handler to save core dump.
|
||||||
|
|
||||||
|
first, enable the gdb in compilation by edit the FSUDAQ_Qt6.pro by commen out the following lines:
|
||||||
|
```sh
|
||||||
|
QMAKE_CXXFLAGS += -g
|
||||||
|
QMAKE_CXXFLAGS_RELEASE = -O0
|
||||||
|
QMAKE_CFLAGS_RELEASE = -O0
|
||||||
|
```
|
||||||
|
|
||||||
|
second, ensure the core dump file has unlimited size and set the core dump file name
|
||||||
|
```sh
|
||||||
|
>ulimit -c unlimited
|
||||||
|
>echo "core.%e.%p" | sudo tee /proc/sys/kernel/core_pattern
|
||||||
|
```
|
||||||
|
|
||||||
* V1725, 1 MHz to 3 ch (decay = 500 ns), no trace. need to set Agg/Read = 100 and Evt/Agg = 511.
|
|
||||||
|
|
||||||
# Known Issues
|
# Known Issues
|
||||||
|
|
||||||
|
@ -150,10 +184,10 @@ There is a folder Aux, this folder contains many auxillary programs, such as Eve
|
||||||
* When using the scope, the Agg/Read must be smaller than 512.
|
* When using the scope, the Agg/Read must be smaller than 512.
|
||||||
* Although the Events/Agg used the CAEN API to recalculate before ACQ start, for PHA firmware, when the trigger rate changed, the Events per Agg need to be changed.
|
* Although the Events/Agg used the CAEN API to recalculate before ACQ start, for PHA firmware, when the trigger rate changed, the Events per Agg need to be changed.
|
||||||
* The Agg Organization, Event per Agg, Record Length are strongly correlated. Some settings are invalid and will cause the digitizer goes crazy.
|
* The Agg Organization, Event per Agg, Record Length are strongly correlated. Some settings are invalid and will cause the digitizer goes crazy.
|
||||||
* load digitizer setting would not load everything, only load the channel settings and some board settings.
|
* Load digitizer setting would not load everything, only load the channel settings and some board settings.
|
||||||
* Sometimes, the buffer is not in time order, and make the trigger/Accept rate to be nagative. This is nothing to do with the program but the digitizer settings. Recommand reporgram the digitizer.
|
* Sometimes, the buffer is not in time order, and make the trigger/Accept rate to be nagative. This is nothing to do with the program but the digitizer settings. Recommand reporgram the digitizer.
|
||||||
* for 1740 QDC, RecordLenght is board setting, but readout is indivuial group.
|
* For 1740 QDC, RecordLenght is board setting, but readout is indivuial group.
|
||||||
* FOr PHA, the trapezoid scaling and fine-gain register are calculated before ACQ start.
|
* For PHA, the trapezoid scaling and fine-gain register are calculated before ACQ start.
|
||||||
|
|
||||||
# Known Bugs
|
# Known Bugs
|
||||||
|
|
||||||
|
|
79
Scope.cpp
79
Scope.cpp
|
@ -6,6 +6,7 @@
|
||||||
#include <QGroupBox>
|
#include <QGroupBox>
|
||||||
#include <QStandardItemModel>
|
#include <QStandardItemModel>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
#include <QScreen>
|
||||||
|
|
||||||
QVector<QPointF> Scope::TrapezoidFilter(QVector<QPointF> data, int baseLineEndS, int riseTimeS, int flatTopS, float decayTime_ns){
|
QVector<QPointF> Scope::TrapezoidFilter(QVector<QPointF> data, int baseLineEndS, int riseTimeS, int flatTopS, float decayTime_ns){
|
||||||
DebugPrint("%s", "Scope");
|
DebugPrint("%s", "Scope");
|
||||||
|
@ -41,11 +42,11 @@ QVector<QPointF> Scope::TrapezoidFilter(QVector<QPointF> data, int baseLineEndS,
|
||||||
trapezoid.append(QPointF(data[i].x(), sn / decayTime_ns / riseTimeS));
|
trapezoid.append(QPointF(data[i].x(), sn / decayTime_ns / riseTimeS));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return trapezoid;
|
return trapezoid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//^========================================================
|
||||||
|
//^========================================================
|
||||||
Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataThread, QMainWindow * parent) : QMainWindow(parent){
|
Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataThread, QMainWindow * parent) : QMainWindow(parent){
|
||||||
DebugPrint("%s", "Scope");
|
DebugPrint("%s", "Scope");
|
||||||
this->digi = digi;
|
this->digi = digi;
|
||||||
|
@ -53,9 +54,17 @@ Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataTh
|
||||||
this->readDataThread = readDataThread;
|
this->readDataThread = readDataThread;
|
||||||
|
|
||||||
setWindowTitle("Scope");
|
setWindowTitle("Scope");
|
||||||
setGeometry(0, 0, 1000, 800);
|
|
||||||
setWindowFlags( this->windowFlags() & ~Qt::WindowCloseButtonHint );
|
setWindowFlags( this->windowFlags() & ~Qt::WindowCloseButtonHint );
|
||||||
|
|
||||||
|
//====== resize window if screen too small
|
||||||
|
QScreen * screen = QGuiApplication::primaryScreen();
|
||||||
|
QRect screenGeo = screen->geometry();
|
||||||
|
if( screenGeo.width() < 1000 || screenGeo.height() < 800) {
|
||||||
|
setGeometry(0, 0, screenGeo.width() - 100, screenGeo.height() - 100);
|
||||||
|
}else{
|
||||||
|
setGeometry(0, 0, 1000, 800);
|
||||||
|
}
|
||||||
|
|
||||||
enableSignalSlot = false;
|
enableSignalSlot = false;
|
||||||
|
|
||||||
isACQStarted = false;
|
isACQStarted = false;
|
||||||
|
@ -90,16 +99,6 @@ Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataTh
|
||||||
xaxis->setLabelFormat("%.0f");
|
xaxis->setLabelFormat("%.0f");
|
||||||
xaxis->setTitleText("Time [ns]");
|
xaxis->setTitleText("Time [ns]");
|
||||||
|
|
||||||
updateTraceThread = new TimingThread();
|
|
||||||
updateTraceThread->SetWaitTimeinSec(ScopeUpdateMiliSec / 1000.);
|
|
||||||
connect(updateTraceThread, &TimingThread::timeUp, this, &Scope::UpdateScope);
|
|
||||||
|
|
||||||
updateScalarThread = new TimingThread();
|
|
||||||
updateScalarThread->SetWaitTimeinSec(2);
|
|
||||||
connect(updateScalarThread, &TimingThread::timeUp, this, [=](){
|
|
||||||
emit UpdateScaler();
|
|
||||||
});
|
|
||||||
|
|
||||||
NullThePointers();
|
NullThePointers();
|
||||||
|
|
||||||
//*================================== UI
|
//*================================== UI
|
||||||
|
@ -216,7 +215,7 @@ Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataTh
|
||||||
QLabel * lbhints = new QLabel("Type 'r' to restore view, '+/-' Zoom in/out, arrow key to pan.", this);
|
QLabel * lbhints = new QLabel("Type 'r' to restore view, '+/-' Zoom in/out, arrow key to pan.", this);
|
||||||
layout->addWidget(lbhints, rowID, 0, 1, 4);
|
layout->addWidget(lbhints, rowID, 0, 1, 4);
|
||||||
|
|
||||||
QLabel * lbinfo = new QLabel("Trace updates every " + QString::number(updateTraceThread->GetWaitTimeinSec()) + " sec.", this);
|
QLabel * lbinfo = new QLabel("Trace updates every " + QString::number(ScopeUpdateMiliSec / 1000.) + " sec.", this);
|
||||||
lbinfo->setAlignment(Qt::AlignRight);
|
lbinfo->setAlignment(Qt::AlignRight);
|
||||||
layout->addWidget(lbinfo, rowID, 6);
|
layout->addWidget(lbinfo, rowID, 6);
|
||||||
|
|
||||||
|
@ -278,22 +277,32 @@ Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataTh
|
||||||
yaxis->setRange(0, 0xFFF);
|
yaxis->setRange(0, 0xFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
workerThread = new QThread(this);
|
||||||
|
scopeWorker = new ScopeWorker(this);
|
||||||
|
scopeTimer = new QTimer(this);
|
||||||
|
|
||||||
|
scopeWorker->moveToThread(workerThread);
|
||||||
|
|
||||||
|
// Setup the timer to trigger every second
|
||||||
|
connect(scopeTimer, &QTimer::timeout, scopeWorker, [=](){
|
||||||
|
scopeWorker->UpdateScope();
|
||||||
|
});
|
||||||
|
workerThread->start();
|
||||||
|
|
||||||
enableSignalSlot = true;
|
enableSignalSlot = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Scope::~Scope(){
|
Scope::~Scope(){
|
||||||
DebugPrint("%s", "Scope");
|
DebugPrint("%s", "Scope");
|
||||||
updateTraceThread->Stop();
|
|
||||||
updateTraceThread->quit();
|
|
||||||
updateTraceThread->wait();
|
|
||||||
delete updateTraceThread;
|
|
||||||
|
|
||||||
updateScalarThread->Stop();
|
scopeTimer->stop();
|
||||||
updateScalarThread->quit();
|
// scalarTimer->stop();
|
||||||
updateScalarThread->wait();
|
|
||||||
delete updateScalarThread;
|
if( workerThread->isRunning() ){
|
||||||
|
workerThread->quit();
|
||||||
|
workerThread->wait();
|
||||||
|
}
|
||||||
|
|
||||||
for( int i = 0; i < MaxNumberOfTrace; i++) delete dataTrace[i];
|
for( int i = 0; i < MaxNumberOfTrace; i++) delete dataTrace[i];
|
||||||
delete plot;
|
delete plot;
|
||||||
|
@ -422,8 +431,7 @@ void Scope::StartScope(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTraceThread->start();
|
scopeTimer->start(ScopeUpdateMiliSec);
|
||||||
updateScalarThread->start();
|
|
||||||
|
|
||||||
bnScopeStart->setEnabled(false);
|
bnScopeStart->setEnabled(false);
|
||||||
bnScopeStart->setStyleSheet("");
|
bnScopeStart->setStyleSheet("");
|
||||||
|
@ -434,7 +442,7 @@ void Scope::StartScope(){
|
||||||
|
|
||||||
EnableControl(false);
|
EnableControl(false);
|
||||||
|
|
||||||
TellACQOnOff(true);
|
emit TellACQOnOff(true);
|
||||||
|
|
||||||
isACQStarted = true;
|
isACQStarted = true;
|
||||||
|
|
||||||
|
@ -445,13 +453,8 @@ void Scope::StopScope(){
|
||||||
if( !digi ) return;
|
if( !digi ) return;
|
||||||
|
|
||||||
// printf("------ Scope::%s \n", __func__);
|
// printf("------ Scope::%s \n", __func__);
|
||||||
updateTraceThread->Stop();
|
scopeTimer->stop();
|
||||||
updateTraceThread->quit();
|
// scalarTimer->stop();
|
||||||
updateTraceThread->exit();
|
|
||||||
|
|
||||||
updateScalarThread->Stop();
|
|
||||||
updateScalarThread->quit();
|
|
||||||
updateScalarThread->exit();
|
|
||||||
|
|
||||||
if( chkSoleRun->isChecked() ){
|
if( chkSoleRun->isChecked() ){
|
||||||
|
|
||||||
|
@ -467,7 +470,6 @@ void Scope::StopScope(){
|
||||||
|
|
||||||
digiMTX[ID].lock();
|
digiMTX[ID].lock();
|
||||||
digi[ID]->StopACQ();
|
digi[ID]->StopACQ();
|
||||||
digi[ID]->ReadACQStatus();
|
|
||||||
digiMTX[ID].unlock();
|
digiMTX[ID].unlock();
|
||||||
|
|
||||||
//restore setting
|
//restore setting
|
||||||
|
@ -498,9 +500,9 @@ void Scope::StopScope(){
|
||||||
readDataThread[iDigi]->wait();
|
readDataThread[iDigi]->wait();
|
||||||
readDataThread[iDigi]->SetScopeMode(false);
|
readDataThread[iDigi]->SetScopeMode(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
digiMTX[iDigi].lock();
|
digiMTX[iDigi].lock();
|
||||||
digi[iDigi]->StopACQ();
|
digi[iDigi]->StopACQ();
|
||||||
digi[iDigi]->ReadACQStatus();
|
|
||||||
//digi[iDigi]->GetData()->PrintAllData();
|
//digi[iDigi]->GetData()->PrintAllData();
|
||||||
digiMTX[iDigi].unlock();
|
digiMTX[iDigi].unlock();
|
||||||
|
|
||||||
|
@ -511,6 +513,8 @@ void Scope::StopScope(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
runStatus->setStyleSheet(""); // cheated, don;t know why digi[iDigi]->GetACQStatusFromMemory(), sometimes return ACQ one.
|
||||||
|
|
||||||
emit UpdateOtherPanels();
|
emit UpdateOtherPanels();
|
||||||
|
|
||||||
bnScopeStart->setEnabled(true);
|
bnScopeStart->setEnabled(true);
|
||||||
|
@ -523,7 +527,7 @@ void Scope::StopScope(){
|
||||||
|
|
||||||
EnableControl(true);
|
EnableControl(true);
|
||||||
|
|
||||||
TellACQOnOff(false);
|
emit TellACQOnOff(false);
|
||||||
|
|
||||||
isACQStarted = false;
|
isACQStarted = false;
|
||||||
|
|
||||||
|
@ -736,7 +740,7 @@ void Scope::SetUpSpinBox(RSpinBox * &sb, QString str, int row, int col, const Re
|
||||||
value = uint16_t((1.0 - sb->value()/100.) * 0xFFFF);
|
value = uint16_t((1.0 - sb->value()/100.) * 0xFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( para == DPP::PHA::TriggerThreshold ){
|
if( para == DPP::PHA::TriggerThreshold || para == DPP::PSD::TriggerThreshold){
|
||||||
value = sb->value();
|
value = sb->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1254,6 +1258,7 @@ void Scope::UpdatePanel_PSD(){
|
||||||
UpdateSpinBox(sbShortGate, DPP::PSD::ShortGateWidth);
|
UpdateSpinBox(sbShortGate, DPP::PSD::ShortGateWidth);
|
||||||
UpdateSpinBox(sbLongGate, DPP::PSD::LongGateWidth);
|
UpdateSpinBox(sbLongGate, DPP::PSD::LongGateWidth);
|
||||||
UpdateSpinBox(sbGateOffset, DPP::PSD::GateOffset);
|
UpdateSpinBox(sbGateOffset, DPP::PSD::GateOffset);
|
||||||
|
UpdateSpinBox(sbThreshold, DPP::PSD::TriggerThreshold);
|
||||||
|
|
||||||
uint32_t BdCfg = digi[ID]->GetSettingFromMemory(DPP::BoardConfiguration, ch);
|
uint32_t BdCfg = digi[ID]->GetSettingFromMemory(DPP::BoardConfiguration, ch);
|
||||||
|
|
||||||
|
|
27
Scope.h
27
Scope.h
|
@ -12,6 +12,7 @@
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QGridLayout>
|
#include <QGridLayout>
|
||||||
#include <QGroupBox>
|
#include <QGroupBox>
|
||||||
|
#include <QTimer>
|
||||||
#include <QLineSeries>
|
#include <QLineSeries>
|
||||||
#include <QRubberBand>
|
#include <QRubberBand>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
|
@ -22,6 +23,8 @@
|
||||||
#include "CustomThreads.h"
|
#include "CustomThreads.h"
|
||||||
#include "CustomWidgets.h"
|
#include "CustomWidgets.h"
|
||||||
|
|
||||||
|
class ScopeWorker; //Forward declaration
|
||||||
|
|
||||||
//^====================================================
|
//^====================================================
|
||||||
//^====================================================
|
//^====================================================
|
||||||
class Scope : public QMainWindow{
|
class Scope : public QMainWindow{
|
||||||
|
@ -51,7 +54,6 @@ signals:
|
||||||
void CloseWindow();
|
void CloseWindow();
|
||||||
void SendLogMsg(const QString &msg);
|
void SendLogMsg(const QString &msg);
|
||||||
void TellACQOnOff(const bool onOff);
|
void TellACQOnOff(const bool onOff);
|
||||||
void UpdateScaler();
|
|
||||||
void UpdateOtherPanels();
|
void UpdateOtherPanels();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -87,8 +89,6 @@ private:
|
||||||
unsigned short oldCh, oldDigi;
|
unsigned short oldCh, oldDigi;
|
||||||
|
|
||||||
ReadDataThread ** readDataThread;
|
ReadDataThread ** readDataThread;
|
||||||
TimingThread * updateTraceThread;
|
|
||||||
TimingThread * updateScalarThread;
|
|
||||||
|
|
||||||
bool enableSignalSlot;
|
bool enableSignalSlot;
|
||||||
|
|
||||||
|
@ -147,8 +147,29 @@ private:
|
||||||
//sbGateOffset -> GateOffset
|
//sbGateOffset -> GateOffset
|
||||||
//sbTriggerHoldOff ->Trigger Hold Off
|
//sbTriggerHoldOff ->Trigger Hold Off
|
||||||
|
|
||||||
|
QThread * workerThread;
|
||||||
|
ScopeWorker * scopeWorker;
|
||||||
|
QTimer * scopeTimer;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//^#======================================================== ScopeWorker
|
||||||
|
class ScopeWorker : public QObject{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ScopeWorker(Scope * parent): SS(parent){}
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void UpdateScope(){
|
||||||
|
SS->UpdateScope();
|
||||||
|
emit workDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void workDone();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Scope * SS;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -4,12 +4,13 @@
|
||||||
#include <QGroupBox>
|
#include <QGroupBox>
|
||||||
#include <QStandardItemModel>
|
#include <QStandardItemModel>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
// #include <QScreen>
|
||||||
|
|
||||||
SingleSpectra::SingleSpectra(Digitizer ** digi, unsigned int nDigi, QString rawDataPath, QMainWindow * parent) : QMainWindow(parent){
|
SingleSpectra::SingleSpectra(Digitizer ** digi, unsigned int nDigi, QString rawDataPath, QMainWindow * parent) : QMainWindow(parent){
|
||||||
DebugPrint("%s", "SingleSpectra");
|
DebugPrint("%s", "SingleSpectra");
|
||||||
this->digi = digi;
|
this->digi = digi;
|
||||||
this->nDigi = nDigi;
|
this->nDigi = nDigi;
|
||||||
this->rawDataPath = rawDataPath;
|
this->settingPath = rawDataPath + "/HistogramSettings.txt";
|
||||||
|
|
||||||
maxFillTimeinMilliSec = 1000;
|
maxFillTimeinMilliSec = 1000;
|
||||||
maxFillTimePerDigi = maxFillTimeinMilliSec/nDigi;
|
maxFillTimePerDigi = maxFillTimeinMilliSec/nDigi;
|
||||||
|
@ -17,8 +18,15 @@ SingleSpectra::SingleSpectra(Digitizer ** digi, unsigned int nDigi, QString rawD
|
||||||
isSignalSlotActive = true;
|
isSignalSlotActive = true;
|
||||||
|
|
||||||
setWindowTitle("Single Histograms");
|
setWindowTitle("Single Histograms");
|
||||||
|
|
||||||
|
//====== resize window if screen too small
|
||||||
|
QScreen * screen = QGuiApplication::primaryScreen();
|
||||||
|
QRect screenGeo = screen->geometry();
|
||||||
|
if( screenGeo.width() < 1000 || screenGeo.height() < 800) {
|
||||||
|
setGeometry(0, 0, screenGeo.width() - 100, screenGeo.height() - 100);
|
||||||
|
}else{
|
||||||
setGeometry(0, 0, 1000, 800);
|
setGeometry(0, 0, 1000, 800);
|
||||||
//setWindowFlags( this->windowFlags() & ~Qt::WindowCloseButtonHint );
|
}
|
||||||
|
|
||||||
QWidget * layoutWidget = new QWidget(this);
|
QWidget * layoutWidget = new QWidget(this);
|
||||||
setCentralWidget(layoutWidget);
|
setCentralWidget(layoutWidget);
|
||||||
|
@ -73,101 +81,17 @@ SingleSpectra::SingleSpectra(Digitizer ** digi, unsigned int nDigi, QString rawD
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
QPushButton * bnRebinDigi = new QPushButton("Rebin Energy", this);
|
chkIsFillHistogram = new QCheckBox("Fill Histograms", this);
|
||||||
ctrlLayout->addWidget(bnRebinDigi, 0, 6, 1, 2);
|
ctrlLayout->addWidget(chkIsFillHistogram, 0, 6, 1, 2);
|
||||||
connect(bnRebinDigi, &QPushButton::clicked, this, [=](){
|
|
||||||
int ID = cbDigi->currentIndex();
|
|
||||||
int ch = cbCh->currentIndex();
|
|
||||||
|
|
||||||
int a_Bin;
|
|
||||||
float a_Min, a_Max;
|
|
||||||
|
|
||||||
if( ch >= 0 ){
|
|
||||||
a_Bin = hist[ID][ch]->GetNBin();
|
|
||||||
a_Min = hist[ID][ch]->GetXMin();
|
|
||||||
a_Max = hist[ID][ch]->GetXMax();
|
|
||||||
}else{
|
|
||||||
a_Bin = hist2D[ID]->GetYNBin();
|
|
||||||
a_Min = hist2D[ID]->GetYMin();
|
|
||||||
a_Max = hist2D[ID]->GetYMax();
|
|
||||||
}
|
|
||||||
|
|
||||||
//pop up a dialog for nBin and ranhe
|
|
||||||
|
|
||||||
QDialog dialog(this);
|
|
||||||
dialog.setWindowTitle("Rebin histograms");
|
|
||||||
|
|
||||||
QFormLayout layout(&dialog);
|
|
||||||
|
|
||||||
QLabel * info = new QLabel(&dialog);
|
|
||||||
info->setStyleSheet("color:red;");
|
|
||||||
info->setText("This will also clear histogram!!");
|
|
||||||
layout.addRow(info);
|
|
||||||
|
|
||||||
QStringList nameList = {"Num. Bin", "x-Min", "x-Max"};
|
|
||||||
QLineEdit* lineEdit[3];
|
|
||||||
|
|
||||||
for (int i = 0; i < 3; ++i) {
|
|
||||||
lineEdit[i] = new QLineEdit(&dialog);
|
|
||||||
layout.addRow(nameList[i] + " : ", lineEdit[i]);
|
|
||||||
}
|
|
||||||
lineEdit[0]->setText(QString::number(a_Bin));
|
|
||||||
lineEdit[1]->setText(QString::number(a_Min));
|
|
||||||
lineEdit[2]->setText(QString::number(a_Max));
|
|
||||||
|
|
||||||
QLabel * msg = new QLabel(&dialog);
|
|
||||||
msg->setStyleSheet("color:red;");
|
|
||||||
layout.addRow(msg);
|
|
||||||
|
|
||||||
QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &dialog);
|
|
||||||
layout.addRow(&buttonBox);
|
|
||||||
|
|
||||||
double number[3];
|
|
||||||
|
|
||||||
QObject::connect(&buttonBox, &QDialogButtonBox::accepted, [&]() {
|
|
||||||
int OKcount = 0;
|
|
||||||
bool conversionOk = true;
|
|
||||||
for( int i = 0; i < 3; i++ ){
|
|
||||||
number[i] = lineEdit[i]->text().toDouble(&conversionOk);
|
|
||||||
if( conversionOk ){
|
|
||||||
OKcount++;
|
|
||||||
}else{
|
|
||||||
msg->setText(nameList[i] + " is invalid.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( OKcount == 3 ) {
|
|
||||||
if( number[2] > number[1] ) {
|
|
||||||
dialog.accept();
|
|
||||||
}else{
|
|
||||||
msg->setText(nameList[2] + " is smaller than " + nameList[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
QObject::connect(&buttonBox, &QDialogButtonBox::rejected, [&]() { dialog.reject();});
|
|
||||||
|
|
||||||
if( dialog.exec() == QDialog::Accepted ){
|
|
||||||
if( hist2D[ID] ) {
|
|
||||||
hist2D[ID]->RebinY((int)number[0], number[1], number[2]);
|
|
||||||
hist2D[ID]->rescaleAxes();
|
|
||||||
hist2D[ID]->UpdatePlot();
|
|
||||||
}
|
|
||||||
for( int j = 0; j < digi[ID]->GetNumInputCh(); j++){
|
|
||||||
if( hist[ID][j] ) {
|
|
||||||
hist[ID][j]->Rebin((int)number[0], number[1], number[2]);
|
|
||||||
hist[ID][j]->UpdatePlot();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
QCheckBox * chkIsFillHistogram = new QCheckBox("Fill Histograms", this);
|
|
||||||
ctrlLayout->addWidget(chkIsFillHistogram, 0, 8);
|
|
||||||
connect(chkIsFillHistogram, &QCheckBox::stateChanged, this, [=](int state){ fillHistograms = state;});
|
|
||||||
chkIsFillHistogram->setChecked(false);
|
chkIsFillHistogram->setChecked(false);
|
||||||
fillHistograms = false;
|
isFillingHistograms = false;
|
||||||
|
|
||||||
|
QLabel * lbSettingPath = new QLabel( settingPath , this);
|
||||||
|
ctrlLayout->addWidget(lbSettingPath, 1, 0, 1, 6);
|
||||||
|
|
||||||
|
QPushButton * bnSaveButton = new QPushButton("Save Hist. Settings", this);
|
||||||
|
ctrlLayout->addWidget(bnSaveButton, 1, 6, 1, 2);
|
||||||
|
connect(bnSaveButton, &QPushButton::clicked, this, &SingleSpectra::SaveSetting);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,6 +117,9 @@ SingleSpectra::SingleSpectra(Digitizer ** digi, unsigned int nDigi, QString rawD
|
||||||
for( int j = 0; j < digi[i]->GetNumInputCh(); j++){
|
for( int j = 0; j < digi[i]->GetNumInputCh(); j++){
|
||||||
if( i < nDigi ) {
|
if( i < nDigi ) {
|
||||||
hist[i][j] = new Histogram1D("Digi-" + QString::number(digi[i]->GetSerialNumber()) +", Ch-" + QString::number(j), "Raw Energy [ch]", nBin, eMin, eMax);
|
hist[i][j] = new Histogram1D("Digi-" + QString::number(digi[i]->GetSerialNumber()) +", Ch-" + QString::number(j), "Raw Energy [ch]", nBin, eMin, eMax);
|
||||||
|
if( digi[i]->GetDPPType() == DPPTypeCode::DPP_PSD_CODE ){
|
||||||
|
hist[i][j]->AddDataList("Short Energy", Qt::green);
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
hist[i][j] = nullptr;
|
hist[i][j] = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -216,10 +143,28 @@ SingleSpectra::SingleSpectra(Digitizer ** digi, unsigned int nDigi, QString rawD
|
||||||
ClearInternalDataCount();
|
ClearInternalDataCount();
|
||||||
|
|
||||||
|
|
||||||
|
workerThread = new QThread(this);
|
||||||
|
histWorker = new HistWorker(this);
|
||||||
|
timer = new QTimer(this);
|
||||||
|
|
||||||
|
histWorker->moveToThread(workerThread);
|
||||||
|
|
||||||
|
// Setup the timer to trigger every second
|
||||||
|
connect(timer, &QTimer::timeout, histWorker, &HistWorker::FillHistograms);
|
||||||
|
workerThread->start();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SingleSpectra::~SingleSpectra(){
|
SingleSpectra::~SingleSpectra(){
|
||||||
DebugPrint("%s", "SingleSpectra");
|
DebugPrint("%s", "SingleSpectra");
|
||||||
|
|
||||||
|
timer->stop();
|
||||||
|
|
||||||
|
if( workerThread->isRunning() ){
|
||||||
|
workerThread->quit();
|
||||||
|
workerThread->wait();
|
||||||
|
}
|
||||||
|
|
||||||
SaveSetting();
|
SaveSetting();
|
||||||
|
|
||||||
for( unsigned int i = 0; i < nDigi; i++ ){
|
for( unsigned int i = 0; i < nDigi; i++ ){
|
||||||
|
@ -289,9 +234,13 @@ void SingleSpectra::ChangeHistView(){
|
||||||
}
|
}
|
||||||
|
|
||||||
void SingleSpectra::FillHistograms(){
|
void SingleSpectra::FillHistograms(){
|
||||||
// DebugPrint("%s", "SingleSpectra");
|
|
||||||
if( !fillHistograms ) return;
|
|
||||||
|
|
||||||
|
// printf("%s | %d %d \n", __func__, chkIsFillHistogram->checkState(), isFillingHistograms);
|
||||||
|
if( this->isVisible() == false ) return;
|
||||||
|
if( chkIsFillHistogram->checkState() == Qt::Unchecked ) return;
|
||||||
|
if( isFillingHistograms) return;
|
||||||
|
|
||||||
|
isFillingHistograms = true;
|
||||||
timespec t0, t1;
|
timespec t0, t1;
|
||||||
|
|
||||||
QVector<int> randomDigiList = generateNonRepeatedCombination(nDigi);
|
QVector<int> randomDigiList = generateNonRepeatedCombination(nDigi);
|
||||||
|
@ -304,17 +253,15 @@ void SingleSpectra::FillHistograms(){
|
||||||
QVector<int> randomChList = generateNonRepeatedCombination(digi[ID]->GetNumInputCh());
|
QVector<int> randomChList = generateNonRepeatedCombination(digi[ID]->GetNumInputCh());
|
||||||
|
|
||||||
// qDebug() << randomChList;
|
// qDebug() << randomChList;
|
||||||
|
// digiMTX[ID].lock();
|
||||||
digiMTX[ID].lock();
|
|
||||||
|
|
||||||
// digi[ID]->GetData()->PrintAllData();
|
// digi[ID]->GetData()->PrintAllData();
|
||||||
|
|
||||||
clock_gettime(CLOCK_REALTIME, &t0);
|
clock_gettime(CLOCK_REALTIME, &t0);
|
||||||
for( int k = 0; k < digi[ID]->GetNumInputCh(); k ++ ){
|
for( int k = 0; k < digi[ID]->GetNumInputCh(); k ++ ){
|
||||||
int ch = randomChList[k];
|
int ch = randomChList[k];
|
||||||
int lastIndex = digi[ID]->GetData()->GetDataIndex(ch);
|
int lastIndex = digi[ID]->GetData()->GetDataIndex(ch);
|
||||||
// printf("--- ch %2d | last index %d \n", ch, lastIndex);
|
|
||||||
if( lastIndex < 0 ) continue;
|
if( lastIndex < 0 ) continue;
|
||||||
|
// printf("--- ch %2d | last index %d \n", ch, lastIndex);
|
||||||
|
|
||||||
int loopIndex = digi[ID]->GetData()->GetLoopIndex(ch);
|
int loopIndex = digi[ID]->GetData()->GetLoopIndex(ch);
|
||||||
|
|
||||||
|
@ -345,6 +292,11 @@ void SingleSpectra::FillHistograms(){
|
||||||
// printf(" ch: %d, last fill idx : %d | %d \n", ch, lastFilledIndex[ID][ch], data);
|
// printf(" ch: %d, last fill idx : %d | %d \n", ch, lastFilledIndex[ID][ch], data);
|
||||||
|
|
||||||
hist[ID][ch]->Fill( data );
|
hist[ID][ch]->Fill( data );
|
||||||
|
if( digi[i]->GetDPPType() == DPPTypeCode::DPP_PSD_CODE ){
|
||||||
|
uShort e2 = digi[ID]->GetData()->GetEnergy2(ch, lastFilledIndex[ID][ch]);
|
||||||
|
// printf("%u \n", e2);
|
||||||
|
hist[ID][ch]->Fill( e2, 1);
|
||||||
|
}
|
||||||
hist2D[ID]->Fill(ch, data);
|
hist2D[ID]->Fill(ch, data);
|
||||||
}
|
}
|
||||||
if( histVisibility[ID][ch] ) hist[ID][ch]->UpdatePlot();
|
if( histVisibility[ID][ch] ) hist[ID][ch]->UpdatePlot();
|
||||||
|
@ -354,16 +306,30 @@ void SingleSpectra::FillHistograms(){
|
||||||
}
|
}
|
||||||
|
|
||||||
if( hist2DVisibility[ID] ) hist2D[ID]->UpdatePlot();
|
if( hist2DVisibility[ID] ) hist2D[ID]->UpdatePlot();
|
||||||
digiMTX[ID].unlock();
|
// digiMTX[ID].unlock();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isFillingHistograms = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SingleSpectra::SaveSetting(){
|
void SingleSpectra::SaveSetting(){
|
||||||
DebugPrint("%s", "SingleSpectra");
|
DebugPrint("%s", "SingleSpectra");
|
||||||
QFile file(rawDataPath + "/singleSpectraSetting.txt");
|
|
||||||
|
|
||||||
file.open(QIODevice::Text | QIODevice::WriteOnly);
|
QFile file(settingPath );
|
||||||
|
|
||||||
|
if (!file.exists()) {
|
||||||
|
// If the file does not exist, create it
|
||||||
|
if (!file.open(QIODevice::WriteOnly)) {
|
||||||
|
qWarning() << "Could not create file" << settingPath;
|
||||||
|
} else {
|
||||||
|
qDebug() << "File" << settingPath << "created successfully";
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( file.open(QIODevice::Text | QIODevice::WriteOnly) ){
|
||||||
|
|
||||||
for( unsigned int i = 0; i < nDigi; i++){
|
for( unsigned int i = 0; i < nDigi; i++){
|
||||||
file.write(("======= " + QString::number(digi[i]->GetSerialNumber()) + "\n").toStdString().c_str());
|
file.write(("======= " + QString::number(digi[i]->GetSerialNumber()) + "\n").toStdString().c_str());
|
||||||
|
@ -376,22 +342,29 @@ void SingleSpectra::SaveSetting(){
|
||||||
}
|
}
|
||||||
|
|
||||||
QString a = QString::number(digi[i]->GetNumInputCh()).rightJustified(2, ' ');
|
QString a = QString::number(digi[i]->GetNumInputCh()).rightJustified(2, ' ');
|
||||||
QString b = QString::number(hist2D[i]->GetXNBin()).rightJustified(6, ' ');
|
QString b = QString::number(hist2D[i]->GetXNBin()-2).rightJustified(6, ' ');
|
||||||
QString c = QString::number(hist2D[i]->GetXMin()).rightJustified(6, ' ');
|
QString c = QString::number(hist2D[i]->GetXMin()).rightJustified(6, ' ');
|
||||||
QString d = QString::number(hist2D[i]->GetXMax()).rightJustified(6, ' ');
|
QString d = QString::number(hist2D[i]->GetXMax()).rightJustified(6, ' ');
|
||||||
QString e = QString::number(hist2D[i]->GetYNBin()).rightJustified(6, ' ');
|
QString e = QString::number(hist2D[i]->GetYNBin()-2).rightJustified(6, ' ');
|
||||||
QString f = QString::number(hist2D[i]->GetYMin()).rightJustified(6, ' ');
|
QString f = QString::number(hist2D[i]->GetYMin()).rightJustified(6, ' ');
|
||||||
QString g = QString::number(hist2D[i]->GetYMax()).rightJustified(6, ' ');
|
QString g = QString::number(hist2D[i]->GetYMax()).rightJustified(6, ' ');
|
||||||
file.write( QString("%1 %2 %3 %4 %5 %6 %7\n").arg(a).arg(b).arg(c).arg(d).arg(e).arg(f).arg(g).toStdString().c_str() );
|
file.write( QString("%1 %2 %3 %4 %5 %6 %7\n").arg(a).arg(b).arg(c).arg(d).arg(e).arg(f).arg(g).toStdString().c_str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
file.write("//========== End of file\n");
|
file.write("##========== End of file\n");
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
|
printf("Saved Histogram Settings to %s\n", settingPath.toStdString().c_str());
|
||||||
|
}else{
|
||||||
|
printf("%s|cannot open HistogramSettings.txt\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SingleSpectra::LoadSetting(){
|
void SingleSpectra::LoadSetting(){
|
||||||
DebugPrint("%s", "SingleSpectra");
|
DebugPrint("%s", "SingleSpectra");
|
||||||
QFile file(rawDataPath + "/singleSpectraSetting.txt");
|
|
||||||
|
QFile file(settingPath);
|
||||||
|
|
||||||
if( file.open(QIODevice::Text | QIODevice::ReadOnly) ){
|
if( file.open(QIODevice::Text | QIODevice::ReadOnly) ){
|
||||||
|
|
||||||
|
@ -402,7 +375,7 @@ void SingleSpectra::LoadSetting(){
|
||||||
int digiID = -1;
|
int digiID = -1;
|
||||||
|
|
||||||
while ( !line.isNull() ){
|
while ( !line.isNull() ){
|
||||||
if( line.contains("//========== ") ) break;
|
if( line.contains("##========== ") ) break;
|
||||||
if( line.contains("//") ) continue;
|
if( line.contains("//") ) continue;
|
||||||
if( line.contains("======= ") ){
|
if( line.contains("======= ") ){
|
||||||
digiSN = line.mid(7).toInt();
|
digiSN = line.mid(7).toInt();
|
||||||
|
@ -422,21 +395,21 @@ void SingleSpectra::LoadSetting(){
|
||||||
|
|
||||||
QStringList list = line.split(QRegularExpression("\\s+"));
|
QStringList list = line.split(QRegularExpression("\\s+"));
|
||||||
list.removeAll("");
|
list.removeAll("");
|
||||||
if( list.count() != 4 ) {
|
// if( list.count() != 4 ) {
|
||||||
line = in.readLine();
|
// line = in.readLine();
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
QVector<int> data;
|
QVector<float> data;
|
||||||
for( int i = 0; i < list.count(); i++){
|
for( int i = 0; i < list.count(); i++){
|
||||||
data.push_back(list[i].toInt());
|
data.push_back(list[i].toFloat());
|
||||||
}
|
}
|
||||||
|
|
||||||
if( 0 <= data[0] && data[0] < digi[digiID]->GetNumInputCh() ){
|
if( 0 <= data[0] && data[0] < digi[digiID]->GetNumInputCh() ){
|
||||||
hist[digiID][data[0]]->Rebin(data[1], data[2], data[3]);
|
hist[digiID][int(data[0])]->Rebin(data[1], data[2], data[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( data[0] == digi[digiID]->GetNumInputCh() && data.size() == 7 ){
|
if( int(data[0]) == digi[digiID]->GetNumInputCh() && data.size() == 7 ){
|
||||||
hist2D[digiID]->Rebin(data[1], data[2], data[3], data[4], data[5], data[6]);
|
hist2D[digiID]->Rebin(int(data[1]), data[2], data[3], int(data[4]), data[5], data[6]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -446,6 +419,8 @@ void SingleSpectra::LoadSetting(){
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
|
|
||||||
|
printf("%s|cannot open HistogramSettings.txt\n", __func__);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "Histogram1D.h"
|
#include "Histogram1D.h"
|
||||||
#include "Histogram2D.h"
|
#include "Histogram2D.h"
|
||||||
|
|
||||||
|
class HistWorker; //Forward decalration
|
||||||
|
|
||||||
//^====================================================
|
//^====================================================
|
||||||
//^====================================================
|
//^====================================================
|
||||||
|
@ -31,8 +32,8 @@ public:
|
||||||
~SingleSpectra();
|
~SingleSpectra();
|
||||||
|
|
||||||
void ClearInternalDataCount();
|
void ClearInternalDataCount();
|
||||||
void SetFillHistograms(bool onOff) { fillHistograms = onOff;}
|
// void SetFillHistograms(bool onOff) { fillHistograms = onOff;}
|
||||||
bool IsFillHistograms() const {return fillHistograms;}
|
// bool IsFillHistograms() const {return fillHistograms;}
|
||||||
|
|
||||||
void LoadSetting();
|
void LoadSetting();
|
||||||
void SaveSetting();
|
void SaveSetting();
|
||||||
|
@ -45,17 +46,33 @@ public:
|
||||||
public slots:
|
public slots:
|
||||||
void FillHistograms();
|
void FillHistograms();
|
||||||
void ChangeHistView();
|
void ChangeHistView();
|
||||||
|
void startTimer(){
|
||||||
|
// printf("timer start\n");
|
||||||
|
timer->start(maxFillTimeinMilliSec);
|
||||||
|
}
|
||||||
|
void stopTimer(){
|
||||||
|
// printf("timer stop\n");
|
||||||
|
timer->stop();
|
||||||
|
ClearInternalDataCount();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Digitizer ** digi;
|
Digitizer ** digi;
|
||||||
unsigned short nDigi;
|
unsigned short nDigi;
|
||||||
|
|
||||||
|
int lastFilledIndex[MaxNDigitizer][MaxNChannels];
|
||||||
|
int loopFilledIndex[MaxNDigitizer][MaxNChannels];
|
||||||
|
bool histVisibility[MaxNDigitizer][MaxNChannels];
|
||||||
|
bool hist2DVisibility[MaxNDigitizer];
|
||||||
|
unsigned short maxFillTimePerDigi;
|
||||||
|
|
||||||
|
bool isFillingHistograms;
|
||||||
Histogram1D * hist[MaxNDigitizer][MaxNChannels];
|
Histogram1D * hist[MaxNDigitizer][MaxNChannels];
|
||||||
Histogram2D * hist2D[MaxNDigitizer];
|
Histogram2D * hist2D[MaxNDigitizer];
|
||||||
|
|
||||||
bool histVisibility[MaxNDigitizer][MaxNChannels];
|
|
||||||
bool hist2DVisibility[MaxNDigitizer];
|
QCheckBox * chkIsFillHistogram;
|
||||||
|
|
||||||
RComboBox * cbDivision;
|
RComboBox * cbDivision;
|
||||||
|
|
||||||
|
@ -66,17 +83,35 @@ private:
|
||||||
QGridLayout * histLayout;
|
QGridLayout * histLayout;
|
||||||
int oldBd, oldCh;
|
int oldBd, oldCh;
|
||||||
|
|
||||||
int lastFilledIndex[MaxNDigitizer][MaxNChannels];
|
QString settingPath;
|
||||||
int loopFilledIndex[MaxNDigitizer][MaxNChannels];
|
|
||||||
|
|
||||||
bool fillHistograms;
|
|
||||||
|
|
||||||
QString rawDataPath;
|
|
||||||
|
|
||||||
unsigned short maxFillTimeinMilliSec;
|
unsigned short maxFillTimeinMilliSec;
|
||||||
unsigned short maxFillTimePerDigi;
|
|
||||||
|
|
||||||
bool isSignalSlotActive;
|
bool isSignalSlotActive;
|
||||||
|
|
||||||
|
QThread * workerThread;
|
||||||
|
HistWorker * histWorker;
|
||||||
|
QTimer * timer;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//^#======================================================== HistWorker
|
||||||
|
class HistWorker : public QObject{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
HistWorker(SingleSpectra * parent): SS(parent){}
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void FillHistograms(){
|
||||||
|
SS->FillHistograms();
|
||||||
|
emit workDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void workDone();
|
||||||
|
|
||||||
|
private:
|
||||||
|
SingleSpectra * SS;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -13,7 +13,9 @@ Analyzer::Analyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent )
|
||||||
setGeometry(0, 0, 1000, 800);
|
setGeometry(0, 0, 1000, 800);
|
||||||
|
|
||||||
influx = nullptr;
|
influx = nullptr;
|
||||||
|
dataBaseIP = "";
|
||||||
dataBaseName = "";
|
dataBaseName = "";
|
||||||
|
dataBaseToken = "";
|
||||||
|
|
||||||
dataList = new Data*[nDigi];
|
dataList = new Data*[nDigi];
|
||||||
typeList.clear();
|
typeList.clear();
|
||||||
|
@ -28,9 +30,9 @@ Analyzer::Analyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent )
|
||||||
isBuildBackward = false;
|
isBuildBackward = false;
|
||||||
mb = new MultiBuilder(dataList, typeList, snList);
|
mb = new MultiBuilder(dataList, typeList, snList);
|
||||||
|
|
||||||
buildTimerThread = new TimingThread(this);
|
// buildTimerThread = new TimingThread(this);
|
||||||
buildTimerThread->SetWaitTimeinSec(1.0); //^Set event build interval
|
// buildTimerThread->SetWaitTimeinSec(1.0); //^Set event build interval
|
||||||
connect( buildTimerThread, &TimingThread::timeUp, this, &Analyzer::UpdateHistograms);
|
// connect( buildTimerThread, &TimingThread::timeUp, this, &Analyzer::UpdateHistograms);
|
||||||
|
|
||||||
QWidget * layoutWidget = new QWidget(this);
|
QWidget * layoutWidget = new QWidget(this);
|
||||||
setCentralWidget(layoutWidget);
|
setCentralWidget(layoutWidget);
|
||||||
|
@ -40,9 +42,41 @@ Analyzer::Analyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent )
|
||||||
// QPushButton * bnSetting = new QPushButton("Settings", this);
|
// QPushButton * bnSetting = new QPushButton("Settings", this);
|
||||||
// layout->addWidget(bnSetting);
|
// layout->addWidget(bnSetting);
|
||||||
|
|
||||||
|
anaThread = new QThread(this);
|
||||||
|
anaWorker = new AnalyzerWorker(this);
|
||||||
|
anaTimer = new QTimer();
|
||||||
|
isWorking = false;
|
||||||
|
|
||||||
|
anaWorker->moveToThread(anaThread);
|
||||||
|
|
||||||
|
connect(anaTimer, &QTimer::timeout, anaWorker, [=](){
|
||||||
|
if( isWorking ) return;
|
||||||
|
isWorking = true;
|
||||||
|
anaWorker->UpdateHistograms();
|
||||||
|
isWorking = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// connect(anaWorker, &AnalyzerWorker::workDone, this, [=](){
|
||||||
|
// printf(" --------- work Done\n");
|
||||||
|
// });
|
||||||
|
|
||||||
|
anaThread->start();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Analyzer::~Analyzer(){
|
Analyzer::~Analyzer(){
|
||||||
|
|
||||||
|
printf("Analyzer::%s\n", __func__);
|
||||||
|
anaTimer->stop();
|
||||||
|
|
||||||
|
printf(" is anaThread is running %d \n", anaThread->isRunning());
|
||||||
|
if( anaThread->isRunning() ){
|
||||||
|
anaThread->quit();
|
||||||
|
anaThread->wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("------ end of anaThread \n");
|
||||||
|
|
||||||
delete influx;
|
delete influx;
|
||||||
delete mb;
|
delete mb;
|
||||||
delete [] dataList;
|
delete [] dataList;
|
||||||
|
@ -60,6 +94,62 @@ double Analyzer::RandomGauss(double mean, double sigma){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Analyzer::SetDatabase(QString IP, QString Name, QString Token){
|
||||||
|
dataBaseIP = IP;
|
||||||
|
dataBaseName = Name;
|
||||||
|
dataBaseToken = Token;
|
||||||
|
|
||||||
|
if( influx ) {
|
||||||
|
delete influx;
|
||||||
|
influx = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
influx = new InfluxDB(dataBaseIP.toStdString());
|
||||||
|
|
||||||
|
if( influx->TestingConnection() ){
|
||||||
|
printf("InfluxDB URL (%s) is Valid. Version : %s\n", dataBaseIP.toStdString().c_str(), influx->GetVersionString().c_str());
|
||||||
|
|
||||||
|
if( influx->GetVersionNo() > 1 && dataBaseToken.isEmpty() ) {
|
||||||
|
printf("A Token is required for accessing the database.\n");
|
||||||
|
delete influx;
|
||||||
|
influx = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
influx->SetToken(dataBaseToken.toStdString());
|
||||||
|
|
||||||
|
//==== chck database exist
|
||||||
|
influx->CheckDatabases();
|
||||||
|
std::vector<std::string> databaseList = influx->GetDatabaseList();
|
||||||
|
bool foundDatabase = false;
|
||||||
|
for( int i = 0; i < (int) databaseList.size(); i++){
|
||||||
|
if( databaseList[i] == dataBaseName.toStdString() ) foundDatabase = true;
|
||||||
|
// printf("%d | %s\n", i, databaseList[i].c_str());
|
||||||
|
}
|
||||||
|
if( foundDatabase ){
|
||||||
|
influx->AddDataPoint("test value=1");
|
||||||
|
influx->WriteData(dataBaseName.toStdString());
|
||||||
|
influx->ClearDataPointsBuffer();
|
||||||
|
if( influx->IsWriteOK() ){
|
||||||
|
printf("test write database OK.\n");
|
||||||
|
}else{
|
||||||
|
printf("################# test write database FAIL.\n");
|
||||||
|
delete influx;
|
||||||
|
influx = nullptr;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
printf("Database name : %s NOT found.\n", dataBaseName.toStdString().c_str());
|
||||||
|
delete influx;
|
||||||
|
influx = nullptr;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
printf("InfluxDB URL (%s) is NOT Valid. \n", dataBaseIP.toStdString().c_str());
|
||||||
|
delete influx;
|
||||||
|
influx = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void Analyzer::RedefineEventBuilder(std::vector<int> idList){
|
void Analyzer::RedefineEventBuilder(std::vector<int> idList){
|
||||||
delete mb;
|
delete mb;
|
||||||
delete [] dataList;
|
delete [] dataList;
|
||||||
|
@ -76,31 +166,70 @@ void Analyzer::RedefineEventBuilder(std::vector<int> idList){
|
||||||
mb = new MultiBuilder(dataList, typeList, snList);
|
mb = new MultiBuilder(dataList, typeList, snList);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Analyzer::StartThread(){
|
|
||||||
mb->ClearEvents();
|
|
||||||
buildTimerThread->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Analyzer::StopThread(){
|
|
||||||
// printf("%s\n", __func__);
|
|
||||||
buildTimerThread->Stop();
|
|
||||||
buildTimerThread->quit();
|
|
||||||
buildTimerThread->wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Analyzer::BuildEvents(bool verbose){
|
void Analyzer::BuildEvents(bool verbose){
|
||||||
|
|
||||||
unsigned int nData = mb->GetNumOfDigitizer();
|
// unsigned int nData = mb->GetNumOfDigitizer();
|
||||||
std::vector<int> idList = mb->GetDigiIDList();
|
// std::vector<int> idList = mb->GetDigiIDList();
|
||||||
for( unsigned int i = 0; i < nData; i++ ) digiMTX[idList[i]].lock();
|
// for( unsigned int i = 0; i < nData; i++ ) digiMTX[idList[i]].lock();
|
||||||
if( isBuildBackward ){
|
if( isBuildBackward ){
|
||||||
mb->BuildEventsBackWard(maxNumEventBuilt, verbose);
|
mb->BuildEventsBackWard(maxNumEventBuilt, verbose);
|
||||||
}else{
|
}else{
|
||||||
mb->BuildEvents(0, 0, verbose);
|
mb->BuildEvents(0, true, verbose);
|
||||||
|
}
|
||||||
|
// mb->PrintStat();
|
||||||
|
// for( unsigned int i = 0; i < nData; i++ ) digiMTX[idList[i]].unlock();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Analyzer::SetDatabaseButton(){
|
||||||
|
|
||||||
|
QDialog dialog;
|
||||||
|
dialog.setWindowTitle("Influx Database");
|
||||||
|
|
||||||
|
QGridLayout layout(&dialog);
|
||||||
|
|
||||||
|
//------------------------------
|
||||||
|
QLabel ipLabel("Database IP : ");
|
||||||
|
layout.addWidget(&ipLabel, 0, 0);
|
||||||
|
|
||||||
|
QLineEdit ipLineEdit;
|
||||||
|
ipLineEdit.setFixedSize(1000, 20);
|
||||||
|
ipLineEdit.setText(dataBaseIP);
|
||||||
|
layout.addWidget(&ipLineEdit, 0, 1);
|
||||||
|
|
||||||
|
//------------------------------
|
||||||
|
QLabel nameLabel("Database Name : ");
|
||||||
|
layout.addWidget(&nameLabel, 1, 0);
|
||||||
|
|
||||||
|
QLineEdit nameLineEdit;
|
||||||
|
nameLineEdit.setFixedSize(1000, 20);
|
||||||
|
nameLineEdit.setText(dataBaseName);
|
||||||
|
layout.addWidget(&nameLineEdit, 1, 1);
|
||||||
|
|
||||||
|
//------------------------------
|
||||||
|
QLabel tokenLabel("Database Token : ");
|
||||||
|
layout.addWidget(&tokenLabel, 2, 0);
|
||||||
|
|
||||||
|
QLineEdit tokenLineEdit;
|
||||||
|
tokenLineEdit.setFixedSize(1000, 20);
|
||||||
|
tokenLineEdit.setText(dataBaseToken);
|
||||||
|
layout.addWidget(&tokenLineEdit, 2, 1);
|
||||||
|
|
||||||
|
layout.addWidget(new QLabel("Only for version 2+, version 1+ can be skipped."), 3, 0, 1, 2);
|
||||||
|
|
||||||
|
// Buttons for OK and Cancel
|
||||||
|
QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||||
|
layout.addWidget(&buttonBox);
|
||||||
|
|
||||||
|
QObject::connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
|
||||||
|
QObject::connect(&buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
|
||||||
|
|
||||||
|
dialog.resize(400, dialog.sizeHint().height()); // Set the width to 400 pixels
|
||||||
|
|
||||||
|
// Show the dialog and get the result
|
||||||
|
if (dialog.exec() == QDialog::Accepted) {
|
||||||
|
SetDatabase(ipLineEdit.text().trimmed(), nameLineEdit.text().trimmed(),tokenLineEdit.text().trimmed());
|
||||||
}
|
}
|
||||||
for( unsigned int i = 0; i < nData; i++ ) digiMTX[idList[i]].unlock();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,10 +29,17 @@ This is the mother of all other derivative analysis class.
|
||||||
|
|
||||||
derivative class should define the SetUpCanvas() and UpdateHistogram();
|
derivative class should define the SetUpCanvas() and UpdateHistogram();
|
||||||
|
|
||||||
|
After creating a new class based on the Analyzer class,
|
||||||
|
users need to add the class files to the FSUDAQ_Qt6.pro project file,
|
||||||
|
include the header file in FSUDAQ.cpp,
|
||||||
|
modify the MainWindow::OpenAnalyzer() method,
|
||||||
|
and recompile FSUDAQ to incorporate the changes and activate the custom analyzer.
|
||||||
|
|
||||||
***************************************/
|
***************************************/
|
||||||
#include "Histogram1D.h"
|
#include "Histogram1D.h"
|
||||||
#include "Histogram2D.h"
|
#include "Histogram2D.h"
|
||||||
|
|
||||||
|
class AnalyzerWorker; //Forward decalration
|
||||||
|
|
||||||
//^==============================================
|
//^==============================================
|
||||||
//^==============================================
|
//^==============================================
|
||||||
|
@ -43,32 +50,47 @@ public:
|
||||||
Analyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent = nullptr);
|
Analyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent = nullptr);
|
||||||
virtual ~Analyzer();
|
virtual ~Analyzer();
|
||||||
|
|
||||||
virtual void SetUpCanvas();
|
|
||||||
|
|
||||||
MultiBuilder * GetEventBuilder() { return mb;}
|
MultiBuilder * GetEventBuilder() { return mb;}
|
||||||
|
|
||||||
void RedefineEventBuilder(std::vector<int> idList);
|
void RedefineEventBuilder(std::vector<int> idList);
|
||||||
void SetBackwardBuild(bool TF, int maxNumEvent = 100) { isBuildBackward = TF; maxNumEventBuilt = maxNumEvent;}
|
void SetBackwardBuild(bool TF, int maxNumEvent = 100) { isBuildBackward = TF; maxNumEventBuilt = maxNumEvent;}
|
||||||
|
void SetDatabase(QString IP, QString Name, QString Token);
|
||||||
|
|
||||||
double RandomGauss(double mean, double sigma);
|
double RandomGauss(double mean, double sigma);
|
||||||
|
void SetDatabaseButton();
|
||||||
|
|
||||||
public slots:
|
double GetUpdateTimeInSec() const {return waitTimeinSec;}
|
||||||
void StartThread();
|
|
||||||
void StopThread();
|
virtual void SetUpCanvas();
|
||||||
virtual void UpdateHistograms(); // where event-building, analysis, and ploting
|
virtual void UpdateHistograms(); // where event-building, analysis, and ploting
|
||||||
|
|
||||||
private slots:
|
public slots:
|
||||||
|
void startTimer(){
|
||||||
|
// printf("start timer\n");
|
||||||
|
mb->ForceStop(false);
|
||||||
|
mb->ClearEvents();
|
||||||
|
anaTimer->start(waitTimeinSec*1000);
|
||||||
|
}
|
||||||
|
void stopTimer(){
|
||||||
|
// printf("stop worker\n");
|
||||||
|
anaTimer->stop();
|
||||||
|
mb->ForceStop(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QGridLayout * layout;
|
QGridLayout * layout;
|
||||||
void BuildEvents(bool verbose = false);
|
void BuildEvents(bool verbose = false);
|
||||||
void SetUpdateTimeInSec(double sec = 1.0) {waitTimeinSec = sec; buildTimerThread->SetWaitTimeinSec(waitTimeinSec);}
|
void SetUpdateTimeInSec(double sec = 1.0) { waitTimeinSec = sec; }
|
||||||
|
|
||||||
InfluxDB * influx;
|
InfluxDB * influx;
|
||||||
std::string dataBaseName;
|
QString dataBaseIP;
|
||||||
|
QString dataBaseName;
|
||||||
|
QString dataBaseToken;
|
||||||
|
|
||||||
|
bool isWorking; // a flag to indicate the worker is working
|
||||||
|
|
||||||
private:
|
|
||||||
Digitizer ** digi;
|
Digitizer ** digi;
|
||||||
unsigned short nDigi;
|
unsigned short nDigi;
|
||||||
|
|
||||||
|
@ -81,8 +103,32 @@ private:
|
||||||
MultiBuilder * mb;
|
MultiBuilder * mb;
|
||||||
bool isBuildBackward;
|
bool isBuildBackward;
|
||||||
int maxNumEventBuilt;
|
int maxNumEventBuilt;
|
||||||
TimingThread * buildTimerThread;
|
// TimingThread * buildTimerThread;
|
||||||
|
|
||||||
|
QThread * anaThread;
|
||||||
|
AnalyzerWorker * anaWorker;
|
||||||
|
QTimer * anaTimer;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//^================================================ AnalyzerWorker
|
||||||
|
|
||||||
|
class AnalyzerWorker : public QObject{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
AnalyzerWorker(Analyzer * parent): SS(parent){}
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void UpdateHistograms(){
|
||||||
|
SS->UpdateHistograms();
|
||||||
|
emit workDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void workDone();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Analyzer * SS;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,7 +33,7 @@ public:
|
||||||
evtbder->SetTimeWindow(500);
|
evtbder->SetTimeWindow(500);
|
||||||
|
|
||||||
//========== use the influx from the Analyzer
|
//========== use the influx from the Analyzer
|
||||||
influx = new InfluxDB("https://fsunuc.physics.fsu.edu/influx/");
|
influx = new InfluxDB("https://localhost:8086");
|
||||||
dataBaseName = "testing";
|
dataBaseName = "testing";
|
||||||
|
|
||||||
SetUpCanvas(); // see below
|
SetUpCanvas(); // see below
|
||||||
|
@ -85,7 +85,7 @@ inline void BeamTune::SetUpCanvas(){
|
||||||
layout->addWidget(hFrame, 0, 0, 1, 2);
|
layout->addWidget(hFrame, 0, 0, 1, 2);
|
||||||
|
|
||||||
hFrame1 = new Histogram2D("X Map", "X-axis", "Y-axis", 100, -10, 110, 100, -0.8, 0.8, this);
|
hFrame1 = new Histogram2D("X Map", "X-axis", "Y-axis", 100, -10, 110, 100, -0.8, 0.8, this);
|
||||||
layout->addWidget(hFrame1, 1, 1, 1, 2);
|
layout->addWidget(hFrame1, 1, 0, 1, 2);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -166,9 +166,9 @@ inline void BeamTune::UpdateHistograms(){
|
||||||
//event[k].Print();
|
//event[k].Print();
|
||||||
|
|
||||||
if( event[k].ch == 2 ) {s0 = event[k].energy; s_t0 = event[k].timestamp;} //
|
if( event[k].ch == 2 ) {s0 = event[k].energy; s_t0 = event[k].timestamp;} //
|
||||||
if( event[k].ch == 3 ) {s1= event[k].energy; s_t1 = event[k].timestamp;} // The 4 output signals from the
|
if( event[k].ch == 3 ) {s1 = event[k].energy; s_t1 = event[k].timestamp;} // The 4 output signals from the
|
||||||
if( event[k].ch == 4 ) {s2 = event[k].energy; s_t2 = event[k].timestamp;} // MCP detector
|
if( event[k].ch == 4 ) {s2 = event[k].energy; s_t2 = event[k].timestamp;} // MCP detector
|
||||||
if( event[k].ch == 5 ) {s3= event[k].energy; s_t3 = event[k].timestamp;} //
|
if( event[k].ch == 5 ) {s3 = event[k].energy; s_t3 = event[k].timestamp;} //
|
||||||
|
|
||||||
if( event[k].ch == 10 ) {e0 = event[k].energy; t0 = event[k].timestamp;} //
|
if( event[k].ch == 10 ) {e0 = event[k].energy; t0 = event[k].timestamp;} //
|
||||||
if( event[k].ch == 11 ) {e1= event[k].energy; t1 = event[k].timestamp;} // The 4 output signals from the
|
if( event[k].ch == 11 ) {e1= event[k].energy; t1 = event[k].timestamp;} // The 4 output signals from the
|
||||||
|
|
|
@ -2,37 +2,29 @@
|
||||||
#define COINCIDENTANLAYZER_H
|
#define COINCIDENTANLAYZER_H
|
||||||
|
|
||||||
#include "Analyser.h"
|
#include "Analyser.h"
|
||||||
|
#include "FSUDAQ.h"
|
||||||
|
|
||||||
//^===========================================
|
//^===========================================
|
||||||
class CoincidentAnalyzer : public Analyzer{
|
class CoincidentAnalyzer : public Analyzer{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
CoincidentAnalyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent = nullptr): Analyzer(digi, nDigi, parent){
|
CoincidentAnalyzer(Digitizer ** digi, unsigned int nDigi, QString rawDataPath, QMainWindow * parent = nullptr): Analyzer(digi, nDigi, parent){
|
||||||
|
|
||||||
this->digi = digi;
|
this->rawDataPath = rawDataPath;
|
||||||
this->nDigi = nDigi;
|
|
||||||
|
|
||||||
SetUpdateTimeInSec(1.0);
|
SetUpdateTimeInSec(1.0);
|
||||||
|
|
||||||
//RedefineEventBuilder({0}); // only build for the 0-th digitizer, otherwise, it will build event accross all digitizers
|
//RedefineEventBuilder({0}); // only build for the 0-th digitizer, otherwise, it will build event accross all digitizers
|
||||||
SetBackwardBuild(false, 100); // using normal building (acceding in time) or backward building, int the case of backward building, default events to be build is 100.
|
SetBackwardBuild(false, 100); // using normal building (acceding in time) or backward building, int the case of backward building, default events to be build is 100.
|
||||||
|
|
||||||
evtbder = GetEventBuilder();
|
mb->SetTimeWindow(500);
|
||||||
evtbder->SetTimeWindow(500);
|
|
||||||
|
|
||||||
//========== use the influx from the Analyzer
|
|
||||||
influx = new InfluxDB("https://fsunuc.physics.fsu.edu/influx/");
|
|
||||||
dataBaseName = "testing";
|
|
||||||
|
|
||||||
allowSignalSlot = false;
|
allowSignalSlot = false;
|
||||||
SetUpCanvas();
|
SetUpCanvas();
|
||||||
|
|
||||||
LoadHistRange();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~CoincidentAnalyzer(){
|
~CoincidentAnalyzer(){
|
||||||
SaveHistRange();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetUpCanvas();
|
void SetUpCanvas();
|
||||||
|
@ -42,13 +34,11 @@ public slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Digitizer ** digi;
|
|
||||||
unsigned int nDigi;
|
|
||||||
|
|
||||||
MultiBuilder *evtbder;
|
|
||||||
|
|
||||||
bool allowSignalSlot;
|
bool allowSignalSlot;
|
||||||
|
|
||||||
|
QLineEdit * leInfluxIP;
|
||||||
|
QLineEdit * leDBName;
|
||||||
|
|
||||||
// declaie histograms
|
// declaie histograms
|
||||||
Histogram2D * h2D;
|
Histogram2D * h2D;
|
||||||
Histogram1D * h1;
|
Histogram1D * h1;
|
||||||
|
@ -73,35 +63,48 @@ private:
|
||||||
RComboBox * aDigi;
|
RComboBox * aDigi;
|
||||||
RComboBox * aCh;
|
RComboBox * aCh;
|
||||||
|
|
||||||
void SaveHistRange();
|
QString rawDataPath;
|
||||||
void LoadHistRange();
|
void SaveSettings();
|
||||||
|
void LoadSettings();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
inline void CoincidentAnalyzer::SetUpCanvas(){
|
inline void CoincidentAnalyzer::SetUpCanvas(){
|
||||||
|
|
||||||
|
setWindowTitle("Online Coincident Analyzer");
|
||||||
setGeometry(0, 0, 1600, 1000);
|
setGeometry(0, 0, 1600, 1000);
|
||||||
|
|
||||||
{//^====== magnet and reaction setting
|
{//^====== channel settings
|
||||||
QGroupBox * box = new QGroupBox("Configuration", this);
|
QGroupBox * box = new QGroupBox("Configuration", this);
|
||||||
layout->addWidget(box, 0, 0);
|
layout->addWidget(box, 0, 0);
|
||||||
QGridLayout * boxLayout = new QGridLayout(box);
|
QGridLayout * boxLayout = new QGridLayout(box);
|
||||||
boxLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
boxLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||||
box->setLayout(boxLayout);
|
box->setLayout(boxLayout);
|
||||||
|
|
||||||
|
int rowID = 0;
|
||||||
|
|
||||||
{
|
{
|
||||||
chkRunAnalyzer = new QCheckBox("Run Analyzer", this);
|
chkRunAnalyzer = new QCheckBox("Run Analyzer", this);
|
||||||
boxLayout->addWidget(chkRunAnalyzer, 0, 0);
|
boxLayout->addWidget(chkRunAnalyzer, rowID, 0);
|
||||||
|
|
||||||
|
connect(chkRunAnalyzer, &QCheckBox::stateChanged, this, [=](int state){
|
||||||
|
|
||||||
|
sbBuildWindow->setEnabled(state != Qt::Checked);
|
||||||
|
sbUpdateTime->setEnabled(state != Qt::Checked);
|
||||||
|
chkBackWardBuilding->setEnabled(state != Qt::Checked);
|
||||||
|
sbBackwardCount->setEnabled(state != Qt::Checked);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
QLabel * lbUpdateTime = new QLabel("Update Period [s]", this);
|
QLabel * lbUpdateTime = new QLabel("Update Period [s]", this);
|
||||||
lbUpdateTime->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
lbUpdateTime->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
||||||
boxLayout->addWidget(lbUpdateTime, 0, 1);
|
boxLayout->addWidget(lbUpdateTime, rowID, 1);
|
||||||
sbUpdateTime = new RSpinBox(this, 1);
|
sbUpdateTime = new RSpinBox(this, 1);
|
||||||
sbUpdateTime->setMinimum(0.1);
|
sbUpdateTime->setMinimum(0.1);
|
||||||
sbUpdateTime->setMaximum(5);
|
sbUpdateTime->setMaximum(5);
|
||||||
sbUpdateTime->setValue(1);
|
sbUpdateTime->setValue(1);
|
||||||
boxLayout->addWidget(sbUpdateTime, 0, 2);
|
boxLayout->addWidget(sbUpdateTime, rowID, 2);
|
||||||
|
|
||||||
connect(sbUpdateTime, &RSpinBox::valueChanged, this, [=](){ sbUpdateTime->setStyleSheet("color : blue"); });
|
connect(sbUpdateTime, &RSpinBox::valueChanged, this, [=](){ sbUpdateTime->setStyleSheet("color : blue"); });
|
||||||
|
|
||||||
|
@ -110,17 +113,36 @@ inline void CoincidentAnalyzer::SetUpCanvas(){
|
||||||
SetUpdateTimeInSec(sbUpdateTime->value());
|
SetUpdateTimeInSec(sbUpdateTime->value());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QLabel * lbBuildWindow = new QLabel("Event Window [ns]", this);
|
||||||
|
lbBuildWindow->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
||||||
|
boxLayout->addWidget(lbBuildWindow, rowID, 3);
|
||||||
|
sbBuildWindow = new RSpinBox(this, 0);
|
||||||
|
sbBuildWindow->setMinimum(1);
|
||||||
|
sbBuildWindow->setMaximum(9999999999);
|
||||||
|
sbBuildWindow->setValue(1000);
|
||||||
|
boxLayout->addWidget(sbBuildWindow, rowID, 4);
|
||||||
|
|
||||||
|
connect(sbBuildWindow, &RSpinBox::valueChanged, this, [=](){
|
||||||
|
sbBuildWindow->setStyleSheet("color : blue;");
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(sbBuildWindow, &RSpinBox::returnPressed, this, [=](){
|
||||||
|
sbBuildWindow->setStyleSheet("");
|
||||||
|
mb->SetTimeWindow((int)sbBuildWindow->value());
|
||||||
|
});
|
||||||
|
|
||||||
|
rowID ++;
|
||||||
chkBackWardBuilding = new QCheckBox("Use Backward builder", this);
|
chkBackWardBuilding = new QCheckBox("Use Backward builder", this);
|
||||||
boxLayout->addWidget(chkBackWardBuilding, 1, 0);
|
boxLayout->addWidget(chkBackWardBuilding, rowID, 0);
|
||||||
|
|
||||||
QLabel * lbBKWindow = new QLabel("Max No. Backward Event", this);
|
QLabel * lbBKWindow = new QLabel("Max No. Backward Event", this);
|
||||||
lbBKWindow->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
lbBKWindow->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
||||||
boxLayout->addWidget(lbBKWindow, 1, 1);
|
boxLayout->addWidget(lbBKWindow, rowID, 1);
|
||||||
sbBackwardCount = new RSpinBox(this, 0);
|
sbBackwardCount = new RSpinBox(this, 0);
|
||||||
sbBackwardCount->setMinimum(1);
|
sbBackwardCount->setMinimum(1);
|
||||||
sbBackwardCount->setMaximum(9999);
|
sbBackwardCount->setMaximum(9999);
|
||||||
sbBackwardCount->setValue(100);
|
sbBackwardCount->setValue(100);
|
||||||
boxLayout->addWidget(sbBackwardCount, 1, 2);
|
boxLayout->addWidget(sbBackwardCount, rowID, 2);
|
||||||
|
|
||||||
chkBackWardBuilding->setChecked(false);
|
chkBackWardBuilding->setChecked(false);
|
||||||
sbBackwardCount->setEnabled(false);
|
sbBackwardCount->setEnabled(false);
|
||||||
|
@ -140,61 +162,48 @@ inline void CoincidentAnalyzer::SetUpCanvas(){
|
||||||
SetBackwardBuild(true, sbBackwardCount->value());
|
SetBackwardBuild(true, sbBackwardCount->value());
|
||||||
});
|
});
|
||||||
|
|
||||||
QLabel * lbBuildWindow = new QLabel("Event Window [tick]", this);
|
|
||||||
lbBuildWindow->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
|
||||||
boxLayout->addWidget(lbBuildWindow, 2, 1);
|
|
||||||
sbBuildWindow = new RSpinBox(this, 0);
|
|
||||||
sbBuildWindow->setMinimum(1);
|
|
||||||
sbBuildWindow->setMaximum(9999999999);
|
|
||||||
boxLayout->addWidget(sbBuildWindow, 2, 2);
|
|
||||||
|
|
||||||
connect(sbBuildWindow, &RSpinBox::valueChanged, this, [=](){
|
|
||||||
sbBuildWindow->setStyleSheet("color : blue;");
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(sbBuildWindow, &RSpinBox::returnPressed, this, [=](){
|
|
||||||
sbBuildWindow->setStyleSheet("");
|
|
||||||
evtbder->SetTimeWindow((int)sbBuildWindow->value());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
QFrame *separator = new QFrame(box);
|
rowID ++;
|
||||||
separator->setFrameShape(QFrame::HLine);
|
QFrame *separator0 = new QFrame(box);
|
||||||
separator->setFrameShadow(QFrame::Sunken);
|
separator0->setFrameShape(QFrame::HLine);
|
||||||
boxLayout->addWidget(separator, 3, 0, 1, 4);
|
separator0->setFrameShadow(QFrame::Sunken);
|
||||||
|
boxLayout->addWidget(separator0, rowID, 0, 1, 4);
|
||||||
|
|
||||||
|
rowID ++;
|
||||||
QLabel * lbXDigi = new QLabel("X-Digi", this);
|
QLabel * lbXDigi = new QLabel("X-Digi", this);
|
||||||
lbXDigi->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
lbXDigi->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
||||||
boxLayout->addWidget(lbXDigi, 4, 0);
|
boxLayout->addWidget(lbXDigi, rowID, 0);
|
||||||
xDigi = new RComboBox(this);
|
xDigi = new RComboBox(this);
|
||||||
for(unsigned int i = 0; i < nDigi; i ++ ){
|
for(unsigned int i = 0; i < nDigi; i ++ ){
|
||||||
xDigi->addItem("Digi-" + QString::number(digi[i]->GetSerialNumber()), i);
|
xDigi->addItem("Digi-" + QString::number(digi[i]->GetSerialNumber()), i);
|
||||||
}
|
}
|
||||||
boxLayout->addWidget(xDigi, 4, 1);
|
boxLayout->addWidget(xDigi, rowID, 1);
|
||||||
|
|
||||||
QLabel * lbXCh = new QLabel("X-Ch", this);
|
QLabel * lbXCh = new QLabel("X-Ch", this);
|
||||||
lbXCh->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
lbXCh->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
||||||
boxLayout->addWidget(lbXCh, 4, 2);
|
boxLayout->addWidget(lbXCh, rowID, 2);
|
||||||
xCh = new RComboBox(this);
|
xCh = new RComboBox(this);
|
||||||
for( int i = 0; i < digi[0]->GetNumInputCh(); i++) xCh->addItem("Ch-" + QString::number(i), i);
|
for( int i = 0; i < digi[0]->GetNumInputCh(); i++) xCh->addItem("Ch-" + QString::number(i), i);
|
||||||
boxLayout->addWidget(xCh, 4, 3);
|
boxLayout->addWidget(xCh, rowID, 3);
|
||||||
|
|
||||||
|
rowID ++;
|
||||||
QLabel * lbYDigi = new QLabel("Y-Digi", this);
|
QLabel * lbYDigi = new QLabel("Y-Digi", this);
|
||||||
lbYDigi->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
lbYDigi->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
||||||
boxLayout->addWidget(lbYDigi, 5, 0);
|
boxLayout->addWidget(lbYDigi, rowID, 0);
|
||||||
yDigi = new RComboBox(this);
|
yDigi = new RComboBox(this);
|
||||||
for(unsigned int i = 0; i < nDigi; i ++ ){
|
for(unsigned int i = 0; i < nDigi; i ++ ){
|
||||||
yDigi->addItem("Digi-" + QString::number(digi[i]->GetSerialNumber()), i);
|
yDigi->addItem("Digi-" + QString::number(digi[i]->GetSerialNumber()), i);
|
||||||
}
|
}
|
||||||
boxLayout->addWidget(yDigi, 5, 1);
|
boxLayout->addWidget(yDigi, rowID, 1);
|
||||||
|
|
||||||
QLabel * lbYCh = new QLabel("Y-Ch", this);
|
QLabel * lbYCh = new QLabel("Y-Ch", this);
|
||||||
lbYCh->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
lbYCh->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
||||||
boxLayout->addWidget(lbYCh, 5, 2);
|
boxLayout->addWidget(lbYCh, rowID, 2);
|
||||||
yCh = new RComboBox(this);
|
yCh = new RComboBox(this);
|
||||||
for( int i = 0; i < digi[0]->GetNumInputCh(); i++) yCh->addItem("Ch-" + QString::number(i), i);
|
for( int i = 0; i < digi[0]->GetNumInputCh(); i++) yCh->addItem("Ch-" + QString::number(i), i);
|
||||||
boxLayout->addWidget(yCh, 5, 3);
|
boxLayout->addWidget(yCh, rowID, 3);
|
||||||
|
|
||||||
connect(xDigi, &RComboBox::currentIndexChanged, this, [=](){
|
connect(xDigi, &RComboBox::currentIndexChanged, this, [=](){
|
||||||
allowSignalSlot = false;
|
allowSignalSlot = false;
|
||||||
|
@ -241,26 +250,28 @@ inline void CoincidentAnalyzer::SetUpCanvas(){
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
rowID ++;
|
||||||
QFrame *separator1 = new QFrame(box);
|
QFrame *separator1 = new QFrame(box);
|
||||||
separator1->setFrameShape(QFrame::HLine);
|
separator1->setFrameShape(QFrame::HLine);
|
||||||
separator1->setFrameShadow(QFrame::Sunken);
|
separator1->setFrameShadow(QFrame::Sunken);
|
||||||
boxLayout->addWidget(separator1, 6, 0, 1, 4);
|
boxLayout->addWidget(separator1, rowID, 0, 1, 4);
|
||||||
|
|
||||||
|
rowID ++;
|
||||||
QLabel * lbaDigi = new QLabel("ID-Digi", this);
|
QLabel * lbaDigi = new QLabel("ID-Digi", this);
|
||||||
lbaDigi->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
lbaDigi->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
||||||
boxLayout->addWidget(lbaDigi, 7, 0);
|
boxLayout->addWidget(lbaDigi, rowID, 0);
|
||||||
aDigi = new RComboBox(this);
|
aDigi = new RComboBox(this);
|
||||||
for(unsigned int i = 0; i < nDigi; i ++ ){
|
for(unsigned int i = 0; i < nDigi; i ++ ){
|
||||||
aDigi->addItem("Digi-" + QString::number(digi[i]->GetSerialNumber()), digi[i]->GetSerialNumber());
|
aDigi->addItem("Digi-" + QString::number(digi[i]->GetSerialNumber()), i);
|
||||||
}
|
}
|
||||||
boxLayout->addWidget(aDigi, 7, 1);
|
boxLayout->addWidget(aDigi, rowID, 1);
|
||||||
|
|
||||||
QLabel * lbaCh = new QLabel("1D-Ch", this);
|
QLabel * lbaCh = new QLabel("1D-Ch", this);
|
||||||
lbaCh->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
lbaCh->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
||||||
boxLayout->addWidget(lbaCh, 7, 2);
|
boxLayout->addWidget(lbaCh, rowID, 2);
|
||||||
aCh = new RComboBox(this);
|
aCh = new RComboBox(this);
|
||||||
for( int i = 0; i < digi[0]->GetNumInputCh(); i++) aCh->addItem("Ch-" + QString::number(i), i);
|
for( int i = 0; i < digi[0]->GetNumInputCh(); i++) aCh->addItem("Ch-" + QString::number(i), i);
|
||||||
boxLayout->addWidget(aCh, 7, 3);
|
boxLayout->addWidget(aCh, rowID, 3);
|
||||||
|
|
||||||
connect(aDigi, &RComboBox::currentIndexChanged, this, [=](){
|
connect(aDigi, &RComboBox::currentIndexChanged, this, [=](){
|
||||||
allowSignalSlot = false;
|
allowSignalSlot = false;
|
||||||
|
@ -290,13 +301,47 @@ inline void CoincidentAnalyzer::SetUpCanvas(){
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
QFrame *separator1 = new QFrame(box);
|
rowID ++;
|
||||||
separator1->setFrameShape(QFrame::HLine);
|
QFrame *separator2 = new QFrame(box);
|
||||||
separator1->setFrameShadow(QFrame::Sunken);
|
separator2->setFrameShape(QFrame::HLine);
|
||||||
boxLayout->addWidget(separator1, 8, 0, 1, 4);
|
separator2->setFrameShadow(QFrame::Sunken);
|
||||||
|
boxLayout->addWidget(separator2, rowID, 0, 1, 4);
|
||||||
|
|
||||||
QPushButton * bnClearHist = new QPushButton("Clear All Hist.");
|
rowID ++;
|
||||||
boxLayout->addWidget(bnClearHist, 9, 1);
|
QLabel * lbIP = new QLabel("Database IP :", box);
|
||||||
|
lbIP->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
||||||
|
boxLayout->addWidget(lbIP, rowID, 0);
|
||||||
|
leInfluxIP = new QLineEdit(box);
|
||||||
|
leInfluxIP->setReadOnly(true);
|
||||||
|
boxLayout->addWidget(leInfluxIP, rowID, 1, 1, 3);
|
||||||
|
|
||||||
|
QPushButton * bnInflux = new QPushButton("Set Influx", box);
|
||||||
|
boxLayout->addWidget(bnInflux, rowID, 4);
|
||||||
|
|
||||||
|
rowID ++;
|
||||||
|
QLabel * lbDBName = new QLabel("Database name :", box);
|
||||||
|
lbDBName->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
||||||
|
boxLayout->addWidget(lbDBName, rowID, 0);
|
||||||
|
leDBName = new QLineEdit(box);
|
||||||
|
leDBName->setReadOnly(true);
|
||||||
|
boxLayout->addWidget(leDBName, rowID, 1);
|
||||||
|
|
||||||
|
connect(bnInflux, &QPushButton::clicked, this, [=](){
|
||||||
|
SetDatabaseButton();
|
||||||
|
if( influx ) {
|
||||||
|
leDBName->setText(dataBaseName);
|
||||||
|
leInfluxIP->setText(dataBaseIP);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// rowID ++;
|
||||||
|
// QFrame *separator3 = new QFrame(box);
|
||||||
|
// separator3->setFrameShape(QFrame::HLine);
|
||||||
|
// separator3->setFrameShadow(QFrame::Sunken);
|
||||||
|
// boxLayout->addWidget(separator3, rowID, 0, 1, 4);
|
||||||
|
|
||||||
|
QPushButton * bnClearHist = new QPushButton("Clear All Hist.", this);
|
||||||
|
boxLayout->addWidget(bnClearHist, rowID, 2);
|
||||||
|
|
||||||
connect(bnClearHist, &QPushButton::clicked, this, [=](){
|
connect(bnClearHist, &QPushButton::clicked, this, [=](){
|
||||||
h2D->Clear();
|
h2D->Clear();
|
||||||
|
@ -305,17 +350,26 @@ inline void CoincidentAnalyzer::SetUpCanvas(){
|
||||||
hMulti->Clear();
|
hMulti->Clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
QPushButton * bnSaveSettings = new QPushButton("Save Settings", this);
|
||||||
|
boxLayout->addWidget(bnSaveSettings, rowID, 3);
|
||||||
|
|
||||||
|
connect(bnSaveSettings, &QPushButton::clicked, this, &CoincidentAnalyzer::SaveSettings);
|
||||||
|
|
||||||
|
QPushButton * bnLoadSettings = new QPushButton("Load Settings", this);
|
||||||
|
boxLayout->addWidget(bnLoadSettings, rowID, 4);
|
||||||
|
|
||||||
|
connect(bnLoadSettings, &QPushButton::clicked, this, &CoincidentAnalyzer::LoadSettings);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//============ histograms
|
//============ histograms
|
||||||
hMulti = new Histogram1D("Multiplicity", "", 10, 0, 10, this);
|
hMulti = new Histogram1D("Multiplicity", "", 16, 0, 16, this);
|
||||||
layout->addWidget(hMulti, 0, 1);
|
layout->addWidget(hMulti, 0, 1);
|
||||||
|
|
||||||
// the "this" make the histogram a child of the SplitPole class. When SplitPole destory, all childs destory as well.
|
// the "this" make the histogram a child of the SplitPole class. When SplitPole destory, all childs destory as well.
|
||||||
h2D = new Histogram2D("Coincident Plot", "XXX", "YYY", 100, 0, 5000, 100, 0, 5000, this);
|
h2D = new Histogram2D("Coincident Plot", "XXX", "YYY", 200, 0, 30000, 200, 0, 30000, this, rawDataPath);
|
||||||
//layout is inheriatge from Analyzer
|
//layout is inheriatge from Analyzer
|
||||||
layout->addWidget(h2D, 1, 0, 2, 1);
|
layout->addWidget(h2D, 1, 0, 2, 1);
|
||||||
|
|
||||||
|
@ -327,17 +381,16 @@ inline void CoincidentAnalyzer::SetUpCanvas(){
|
||||||
h2D->SetYTitle("Digi-" + QString::number(digi[bd]->GetSerialNumber()) + ", Ch-" + QString::number(ch));
|
h2D->SetYTitle("Digi-" + QString::number(digi[bd]->GetSerialNumber()) + ", Ch-" + QString::number(ch));
|
||||||
h2D->UpdatePlot();
|
h2D->UpdatePlot();
|
||||||
|
|
||||||
|
h1 = new Histogram1D("1D Plot", "XXX", 300, 0, 30000, this);
|
||||||
h1 = new Histogram1D("1D Plot", "XXX", 300, 0, 5000, this);
|
|
||||||
h1->SetColor(Qt::darkGreen);
|
h1->SetColor(Qt::darkGreen);
|
||||||
h1->AddDataList("Test", Qt::red); // add another histogram in h1, Max Data List is 10
|
// h1->AddDataList("Test", Qt::red); // add another histogram in h1, Max Data List is 10
|
||||||
bd = aDigi->currentData().toInt();
|
bd = aDigi->currentData().toInt();
|
||||||
ch = aCh->currentData().toInt();
|
ch = aCh->currentData().toInt();
|
||||||
h1->SetXTitle("Digi-" + QString::number(digi[bd]->GetSerialNumber()) + ", Ch-" + QString::number(ch));
|
h1->SetXTitle("Digi-" + QString::number(digi[bd]->GetSerialNumber()) + ", Ch-" + QString::number(ch));
|
||||||
h1->UpdatePlot();
|
h1->UpdatePlot();
|
||||||
layout->addWidget(h1, 1, 1);
|
layout->addWidget(h1, 1, 1);
|
||||||
|
|
||||||
h1g = new Histogram1D("1D Plot (PID gated)", "XXX", 300, 0, 5000, this);
|
h1g = new Histogram1D("1D Plot (PID gated)", "XXX", 300, 0, 30000, this);
|
||||||
h1g->SetXTitle("Digi-" + QString::number(digi[bd]->GetSerialNumber()) + ", Ch-" + QString::number(ch));
|
h1g->SetXTitle("Digi-" + QString::number(digi[bd]->GetSerialNumber()) + ", Ch-" + QString::number(ch));
|
||||||
h1g->UpdatePlot();
|
h1g->UpdatePlot();
|
||||||
layout->addWidget(h1g, 2, 1);
|
layout->addWidget(h1g, 2, 1);
|
||||||
|
@ -345,17 +398,25 @@ inline void CoincidentAnalyzer::SetUpCanvas(){
|
||||||
layout->setColumnStretch(0, 1);
|
layout->setColumnStretch(0, 1);
|
||||||
layout->setColumnStretch(1, 1);
|
layout->setColumnStretch(1, 1);
|
||||||
|
|
||||||
|
allowSignalSlot = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void CoincidentAnalyzer::UpdateHistograms(){
|
inline void CoincidentAnalyzer::UpdateHistograms(){
|
||||||
|
|
||||||
|
// printf(">>>>>>>>>>>>> CoincidentAnalyzer::%s | %d %d %d \n", __func__, this->isVisible(), chkRunAnalyzer->isChecked(), isWorking);
|
||||||
|
|
||||||
if( this->isVisible() == false ) return;
|
if( this->isVisible() == false ) return;
|
||||||
if( chkRunAnalyzer->isChecked() == false ) return;
|
if( chkRunAnalyzer->isChecked() == false ) return;
|
||||||
|
|
||||||
BuildEvents(); // call the event builder to build events
|
unsigned long long t0 = getTime_ns();
|
||||||
|
BuildEvents(false); // call the event builder to build events
|
||||||
|
// unsigned long long t1 = getTime_ns();
|
||||||
|
// printf("Event Build time : %llu ns = %.f msec\n", t1 - t0, (t1-t0)/1e6);
|
||||||
|
|
||||||
//============ Get events, and do analysis
|
//============ Get events, and do analysis
|
||||||
long eventBuilt = evtbder->eventBuilt;
|
long eventBuilt = mb->eventBuilt;
|
||||||
|
|
||||||
if( eventBuilt == 0 ) return;
|
if( eventBuilt == 0 ) return;
|
||||||
|
|
||||||
//============ Get the cut list, if any
|
//============ Get the cut list, if any
|
||||||
|
@ -374,13 +435,17 @@ inline void CoincidentAnalyzer::UpdateHistograms(){
|
||||||
int y_bd = yDigi->currentData().toInt();
|
int y_bd = yDigi->currentData().toInt();
|
||||||
int y_ch = yCh->currentData().toInt();
|
int y_ch = yCh->currentData().toInt();
|
||||||
|
|
||||||
|
int a_sn = digi[a_bd]->GetSerialNumber();
|
||||||
|
int x_sn = digi[x_bd]->GetSerialNumber();
|
||||||
|
int y_sn = digi[y_bd]->GetSerialNumber();
|
||||||
|
|
||||||
//============ Processing data and fill histograms
|
//============ Processing data and fill histograms
|
||||||
long eventIndex = evtbder->eventIndex;
|
long eventIndex = mb->eventIndex;
|
||||||
long eventStart = eventIndex - eventBuilt + 1;
|
long eventStart = eventIndex - eventBuilt + 1;
|
||||||
if(eventStart < 0 ) eventStart += MaxNEvent;
|
if(eventStart < 0 ) eventStart += MaxNEvent;
|
||||||
|
|
||||||
for( long i = eventStart ; i <= eventIndex; i ++ ){
|
for( long i = eventStart ; i <= eventIndex; i ++ ){
|
||||||
std::vector<Hit> event = evtbder->events[i];
|
std::vector<Hit> event = mb->events[i];
|
||||||
|
|
||||||
hMulti->Fill((int) event.size());
|
hMulti->Fill((int) event.size());
|
||||||
if( event.size() == 0 ) return;
|
if( event.size() == 0 ) return;
|
||||||
|
@ -389,17 +454,17 @@ inline void CoincidentAnalyzer::UpdateHistograms(){
|
||||||
int xE = -1, yE = -1;
|
int xE = -1, yE = -1;
|
||||||
unsigned long long xT = 0;
|
unsigned long long xT = 0;
|
||||||
for( int k = 0; k < (int) event.size(); k++ ){
|
for( int k = 0; k < (int) event.size(); k++ ){
|
||||||
//event[k].Print();
|
// event[k].Print();
|
||||||
if( event[k].sn == a_bd && event[k].ch == a_ch) {
|
if( event[k].sn == a_sn && event[k].ch == a_ch) {
|
||||||
h1->Fill(event[k].energy);
|
h1->Fill(event[k].energy);
|
||||||
aE = event[k].energy;
|
aE = event[k].energy;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( event[k].sn == x_bd && event[k].ch == x_ch) {
|
if( event[k].sn == x_sn && event[k].ch == x_ch) {
|
||||||
xE = event[k].energy;
|
xE = event[k].energy;
|
||||||
xT = event[k].timestamp;
|
xT = event[k].timestamp;
|
||||||
}
|
}
|
||||||
if( event[k].sn == y_bd && event[k].ch == y_ch) yE = event[k].energy;
|
if( event[k].sn == y_sn && event[k].ch == y_ch) yE = event[k].energy;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( xE >= 0 && yE >= 0 ) h2D->Fill(xE, yE);
|
if( xE >= 0 && yE >= 0 ) h2D->Fill(xE, yE);
|
||||||
|
@ -415,6 +480,10 @@ inline void CoincidentAnalyzer::UpdateHistograms(){
|
||||||
if( p == 0 && aE >= 0 ) h1g->Fill(aE); // only for the 1st gate
|
if( p == 0 && aE >= 0 ) h1g->Fill(aE); // only for the 1st gate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned long long ta = getTime_ns();
|
||||||
|
if( ta - t0 > sbUpdateTime->value() * 0.9 * GetUpdateTimeInSec() * 1e9 ) break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h2D->UpdatePlot();
|
h2D->UpdatePlot();
|
||||||
|
@ -422,25 +491,177 @@ inline void CoincidentAnalyzer::UpdateHistograms(){
|
||||||
hMulti->UpdatePlot();
|
hMulti->UpdatePlot();
|
||||||
h1g->UpdatePlot();
|
h1g->UpdatePlot();
|
||||||
|
|
||||||
// QList<QString> cutNameList = h2D->GetCutNameList();
|
if( influx ){
|
||||||
// for( int p = 0; p < cutList.count(); p ++){
|
QList<QString> cutNameList = h2D->GetCutNameList();
|
||||||
// if( cutList[p].isEmpty() ) continue;
|
for( int p = 0; p < cutList.count(); p ++){
|
||||||
// double dT = (tMax[p]-tMin[p]) * tick2ns / 1e9; // tick to sec
|
if( cutList[p].isEmpty() ) continue;
|
||||||
// double rate = count[p]*1.0/(dT);
|
double dT = (tMax[p]-tMin[p]) / 1e9;
|
||||||
//printf("%llu %llu, %f %d\n", tMin[p], tMax[p], dT, count[p]);
|
double rate = count[p]*1.0/(dT);
|
||||||
//printf("%10s | %d | %f Hz \n", cutNameList[p].toStdString().c_str(), count[p], rate);
|
// printf("%llu %llu, %f %d\n", tMin[p], tMax[p], dT, count[p]);
|
||||||
|
printf("%10s | %d | %f Hz \n", cutNameList[p].toStdString().c_str(), count[p], rate);
|
||||||
|
|
||||||
// influx->AddDataPoint("Cut,name=" + cutNameList[p].toStdString()+ " value=" + std::to_string(rate));
|
influx->AddDataPoint("Cut,name=" + cutNameList[p].toStdString()+ " value=" + std::to_string(rate));
|
||||||
// influx->WriteData(dataBaseName);
|
}
|
||||||
// influx->ClearDataPointsBuffer();
|
|
||||||
// }
|
influx->WriteData(dataBaseName.toStdString());
|
||||||
|
influx->ClearDataPointsBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void CoincidentAnalyzer::SaveHistRange(){
|
inline void CoincidentAnalyzer::SaveSettings(){
|
||||||
|
QString filePath = QFileDialog::getSaveFileName(this,
|
||||||
|
"Save Settings to File",
|
||||||
|
QDir::toNativeSeparators(rawDataPath + "/CoinAnaSettings.txt" ),
|
||||||
|
"Text file (*.txt)");
|
||||||
|
|
||||||
|
if (!filePath.isEmpty()){
|
||||||
|
|
||||||
|
QFile file(filePath);
|
||||||
|
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||||
|
QTextStream out(&file);
|
||||||
|
|
||||||
|
// Define the text to write
|
||||||
|
QStringList lines;
|
||||||
|
|
||||||
|
lines << QString::number(digi[aDigi->currentData().toInt()]->GetSerialNumber());
|
||||||
|
lines << QString::number(aCh->currentData().toInt());
|
||||||
|
lines << QString::number(h1->GetNBin());
|
||||||
|
lines << QString::number(h1->GetXMin());
|
||||||
|
lines << QString::number(h1->GetXMax());
|
||||||
|
|
||||||
|
lines << QString::number(digi[xDigi->currentData().toInt()]->GetSerialNumber());
|
||||||
|
lines << QString::number(xCh->currentData().toInt());
|
||||||
|
lines << QString::number(h2D->GetXNBin());
|
||||||
|
lines << QString::number(h2D->GetXMin());
|
||||||
|
lines << QString::number(h2D->GetXMax());
|
||||||
|
|
||||||
|
lines << QString::number(digi[yDigi->currentData().toInt()]->GetSerialNumber());
|
||||||
|
lines << QString::number(yCh->currentData().toInt());
|
||||||
|
lines << QString::number(h2D->GetYNBin());
|
||||||
|
lines << QString::number(h2D->GetYMin());
|
||||||
|
lines << QString::number(h2D->GetYMax());
|
||||||
|
|
||||||
|
lines << QString::number(sbUpdateTime->value());
|
||||||
|
lines << QString::number(chkBackWardBuilding->isChecked());
|
||||||
|
lines << QString::number(sbBackwardCount->value());
|
||||||
|
|
||||||
|
lines<< dataBaseIP;
|
||||||
|
lines<< dataBaseName;
|
||||||
|
lines<< dataBaseToken;
|
||||||
|
|
||||||
|
lines << "#===== End of File";
|
||||||
|
|
||||||
|
// Write each line to the file
|
||||||
|
for (const QString &line : lines) out << line << "\n";
|
||||||
|
|
||||||
|
// Close the file
|
||||||
|
file.close();
|
||||||
|
qDebug() << "File written successfully to" << filePath;
|
||||||
|
}else{
|
||||||
|
qWarning() << "Unable to open file" << filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
inline void CoincidentAnalyzer::LoadHistRange(){
|
inline void CoincidentAnalyzer::LoadSettings(){
|
||||||
|
|
||||||
|
QString filePath = QFileDialog::getOpenFileName(this,
|
||||||
|
"Load Settings to File",
|
||||||
|
rawDataPath,
|
||||||
|
"Text file (*.txt)");
|
||||||
|
|
||||||
|
int a_sn, a_ch, a_bin;
|
||||||
|
float a_min, a_max;
|
||||||
|
int x_sn, x_ch, x_bin;
|
||||||
|
float x_min, x_max;
|
||||||
|
int y_sn, y_ch, y_bin;
|
||||||
|
float y_min, y_max;
|
||||||
|
|
||||||
|
float updateTime = 1.0;
|
||||||
|
int bkCount = 100;
|
||||||
|
bool isBkEvtBuild = false;
|
||||||
|
|
||||||
|
if (!filePath.isEmpty()) {
|
||||||
|
|
||||||
|
QFile file(filePath);
|
||||||
|
|
||||||
|
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
|
QTextStream in(&file);
|
||||||
|
|
||||||
|
short count = 0;
|
||||||
|
while (!in.atEnd()) {
|
||||||
|
QString line = in.readLine();
|
||||||
|
|
||||||
|
if( count == 0 ) a_sn = line.toInt();
|
||||||
|
if( count == 1 ) a_ch = line.toInt();
|
||||||
|
if( count == 2 ) a_bin = line.toInt();
|
||||||
|
if( count == 3 ) a_min = line.toFloat();
|
||||||
|
if( count == 4 ) a_max = line.toFloat();
|
||||||
|
|
||||||
|
if( count == 5 ) x_sn = line.toFloat();
|
||||||
|
if( count == 6 ) x_ch = line.toFloat();
|
||||||
|
if( count == 7 ) x_bin = line.toFloat();
|
||||||
|
if( count == 8 ) x_min = line.toFloat();
|
||||||
|
if( count == 9 ) x_max = line.toFloat();
|
||||||
|
|
||||||
|
if( count == 10 ) y_sn = line.toFloat();
|
||||||
|
if( count == 11 ) y_ch = line.toFloat();
|
||||||
|
if( count == 12 ) y_bin = line.toFloat();
|
||||||
|
if( count == 13 ) y_min = line.toFloat();
|
||||||
|
if( count == 14 ) y_max = line.toFloat();
|
||||||
|
|
||||||
|
if( count == 15 ) updateTime = line.toFloat();
|
||||||
|
if( count == 16 ) isBkEvtBuild = line.toInt();
|
||||||
|
if( count == 17 ) bkCount = line.toInt();
|
||||||
|
|
||||||
|
if( count == 18 ) dataBaseIP = line;
|
||||||
|
if( count == 19 ) dataBaseName = line;
|
||||||
|
if( count == 20 ) dataBaseToken = line;
|
||||||
|
|
||||||
|
count ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
qDebug() << "File read successfully from" << filePath;
|
||||||
|
|
||||||
|
if( count >= 21 ){
|
||||||
|
|
||||||
|
sbUpdateTime->setValue(updateTime);
|
||||||
|
chkBackWardBuilding->setChecked(isBkEvtBuild);
|
||||||
|
sbBackwardCount->setValue(bkCount);
|
||||||
|
|
||||||
|
int x_index = xDigi->findText("Digi-" + QString::number(x_sn));
|
||||||
|
int y_index = yDigi->findText("Digi-" + QString::number(y_sn));
|
||||||
|
int a_index = aDigi->findText("Digi-" + QString::number(a_sn));
|
||||||
|
if( x_index == -1 ) qWarning() << " Cannot find digitizer " << x_sn;
|
||||||
|
if( y_index == -1 ) qWarning() << " Cannot find digitizer " << y_sn;
|
||||||
|
if( a_index == -1 ) qWarning() << " Cannot find digitizer " << a_sn;
|
||||||
|
|
||||||
|
xDigi->setCurrentIndex(x_index);
|
||||||
|
yDigi->setCurrentIndex(y_index);
|
||||||
|
aDigi->setCurrentIndex(a_index);
|
||||||
|
|
||||||
|
xCh->setCurrentIndex(x_ch);
|
||||||
|
yCh->setCurrentIndex(y_ch);
|
||||||
|
aCh->setCurrentIndex(a_ch);
|
||||||
|
|
||||||
|
h1->Rebin(a_bin, a_min, a_max);
|
||||||
|
h1g->Rebin(a_bin, a_min, a_max);
|
||||||
|
h2D->Rebin(x_bin, x_min, x_max, y_bin, y_min, y_max);
|
||||||
|
|
||||||
|
SetDatabase(dataBaseIP, dataBaseName, dataBaseToken);
|
||||||
|
if( influx ){
|
||||||
|
leDBName->setText(dataBaseName);
|
||||||
|
leInfluxIP->setText(dataBaseIP);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}else {
|
||||||
|
qWarning() << "Unable to open file" << filePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include "Isotope.h"
|
#include "Isotope.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <QApplication>
|
||||||
|
// #include <QScreen>
|
||||||
|
|
||||||
namespace EncoreChMap{
|
namespace EncoreChMap{
|
||||||
|
|
||||||
|
@ -82,8 +84,15 @@ private:
|
||||||
|
|
||||||
inline void Encore::SetUpCanvas(){
|
inline void Encore::SetUpCanvas(){
|
||||||
|
|
||||||
setGeometry(0, 0, 1600, 1600);
|
//====== resize window if screen too small
|
||||||
|
QScreen * screen = QGuiApplication::primaryScreen();
|
||||||
|
QRect screenGeo = screen->geometry();
|
||||||
|
if( screenGeo.width() < 1000 || screenGeo.height() < 1000) {
|
||||||
|
setGeometry(0, 0, screenGeo.width() - 100, screenGeo.height() -100);
|
||||||
|
}else{
|
||||||
|
setGeometry(0, 0, 1000, 1000);
|
||||||
|
}
|
||||||
|
// setGeometry(0, 0, 1600, 1600);
|
||||||
chkRunAnalyzer = new QCheckBox("Run Analyzer", this);
|
chkRunAnalyzer = new QCheckBox("Run Analyzer", this);
|
||||||
layout->addWidget(chkRunAnalyzer, 0, 0);
|
layout->addWidget(chkRunAnalyzer, 0, 0);
|
||||||
|
|
||||||
|
|
|
@ -31,9 +31,7 @@ public:
|
||||||
evtbder = GetEventBuilder();
|
evtbder = GetEventBuilder();
|
||||||
evtbder->SetTimeWindow(500); //ns
|
evtbder->SetTimeWindow(500); //ns
|
||||||
|
|
||||||
//========== use the influx from the Analyzer
|
SetDatabase("https://localhost:8086", "testing", "zKhzKk4Yhf1l9QU-yE2GsIZ1RazqUgoW3NlF8LJqq_xDMwatOJwg1sKrjgq36uLEsQf8Fmn4sJALP7Kkilk14A==");
|
||||||
influx = new InfluxDB("https://fsunuc.physics.fsu.edu/influx/");
|
|
||||||
dataBaseName = "testing";
|
|
||||||
|
|
||||||
SetUpCanvas(); // see below
|
SetUpCanvas(); // see below
|
||||||
|
|
||||||
|
@ -251,7 +249,7 @@ inline void MCP::UpdateHistograms(){
|
||||||
//printf("%10s | %d | %f Hz \n", cutNameList[p].toStdString().c_str(), count[p], rate);
|
//printf("%10s | %d | %f Hz \n", cutNameList[p].toStdString().c_str(), count[p], rate);
|
||||||
|
|
||||||
influx->AddDataPoint("Cut,name=" + cutNameList[p].toStdString()+ " value=" + std::to_string(rate));
|
influx->AddDataPoint("Cut,name=" + cutNameList[p].toStdString()+ " value=" + std::to_string(rate));
|
||||||
influx->WriteData(dataBaseName);
|
influx->WriteData(dataBaseName.toStdString());
|
||||||
influx->ClearDataPointsBuffer();
|
influx->ClearDataPointsBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,9 +28,7 @@ public:
|
||||||
evtbder = GetEventBuilder();
|
evtbder = GetEventBuilder();
|
||||||
evtbder->SetTimeWindow(500);
|
evtbder->SetTimeWindow(500);
|
||||||
|
|
||||||
//========== use the influx from the Analyzer
|
SetDatabase("https://localhost:8086", "testing", "zKhzKk4Yhf1l9QU-yE2GsIZ1RazqUgoW3NlF8LJqq_xDMwatOJwg1sKrjgq36uLEsQf8Fmn4sJALP7Kkilk14A==");
|
||||||
influx = new InfluxDB("https://fsunuc.physics.fsu.edu/influx/");
|
|
||||||
dataBaseName = "testing";
|
|
||||||
|
|
||||||
SetUpCanvas(); // see below
|
SetUpCanvas(); // see below
|
||||||
|
|
||||||
|
|
178
analyzers/MUSICAnalyzer.h
Normal file
178
analyzers/MUSICAnalyzer.h
Normal file
|
@ -0,0 +1,178 @@
|
||||||
|
#ifndef MUSICANLAYZER_H
|
||||||
|
#define MUSICANLAYZER_H
|
||||||
|
|
||||||
|
#include "Analyser.h"
|
||||||
|
#include "Isotope.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <QApplication>
|
||||||
|
// #include <QScreen>
|
||||||
|
|
||||||
|
namespace MUSICChMap{
|
||||||
|
|
||||||
|
const std::map<unsigned short, int> SN2Bd = {
|
||||||
|
{16828, 0},
|
||||||
|
{16829, 1},
|
||||||
|
{16827, 2},
|
||||||
|
{23986, 3}
|
||||||
|
};
|
||||||
|
|
||||||
|
//Left 0->15
|
||||||
|
//Right 16->31
|
||||||
|
//Individual{32=Grid, 33=S0, 34=cathode, 35=S17, 36=Si_dE, 100>pulser},
|
||||||
|
//-1=empty
|
||||||
|
const int mapping[4][16] = {
|
||||||
|
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
|
||||||
|
{34, -1, 1, -1, 33, 101, 5, -1, 0, -1, 9, -1, 17, 13, -1, 32},
|
||||||
|
{ 2, -1, 16, -1, 21, 102, 20, -1, 8, -1, 24, -1, 27, 28, -1, 14},
|
||||||
|
{19, -1, 3, -1, 6, 103, 7, -1, 25, -1, 11, -1, 12, 15, -1, 10},
|
||||||
|
{ 4, -1, 18, 36, 23, 104, 22, -1, 29, -1, 26, -1, 31, 30, -1, 35}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Gain matching [ch][bd]
|
||||||
|
const double corr[16][4] = {
|
||||||
|
{ 1.00000, 1.00000, 1.00000, 1.0000},
|
||||||
|
{ 1.00000, 1.00000, 1.03158, 1.0000},
|
||||||
|
{ 1.00000, 1.00000, 0.99240, 1.0000},
|
||||||
|
{ 1.00000, 1.03704, 0.94004, 1.0000},
|
||||||
|
{ 1.01031, 1.02084, 1.10114, 1.0000},
|
||||||
|
{ 1.00000, 0.94685, 1.00513, 1.0000},
|
||||||
|
{ 1.00000, 1.03431, 1.00513, 1.0000},
|
||||||
|
{ 1.00000, 0.92670, 0.96078, 1.0000},
|
||||||
|
{ 1.03431, 0.94685, 0.96314, 1.0000},
|
||||||
|
{ 1.00000, 1.03158, 0.95145, 1.0000},
|
||||||
|
{ 0.95145, 1.00256, 0.97270, 1.0000},
|
||||||
|
{ 1.00000, 1.00256, 0.90950, 1.0000},
|
||||||
|
{ 1.03704, 0.99492, 0.98740, 1.0000},
|
||||||
|
{ 1.00000, 1.00000, 0.99746, 1.0000},
|
||||||
|
{ 0.96078, 1.03980, 1.00513, 1.0000},
|
||||||
|
{ 1.00000, 1.05095, 1.00000, 1.0000},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class MUSIC : public Analyzer{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
|
||||||
|
MUSIC(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent = nullptr): Analyzer(digi, nDigi, parent){
|
||||||
|
|
||||||
|
SetUpdateTimeInSec(1.0);
|
||||||
|
|
||||||
|
SetBackwardBuild(true, 100); // using normal building (acceding in time) or backward building, int the case of backward building, default events to be build is 100.
|
||||||
|
evtbder = GetEventBuilder();
|
||||||
|
evtbder->SetTimeWindow(10000);
|
||||||
|
|
||||||
|
SetUpCanvas();
|
||||||
|
}
|
||||||
|
|
||||||
|
// MUSIC(){};
|
||||||
|
|
||||||
|
void SetUpCanvas();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void UpdateHistograms();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
MultiBuilder *evtbder;
|
||||||
|
|
||||||
|
Histogram2D * hLeft;
|
||||||
|
Histogram2D * hRight;
|
||||||
|
Histogram2D * hLR;
|
||||||
|
|
||||||
|
Histogram1D * hMulti;
|
||||||
|
|
||||||
|
QCheckBox * chkRunAnalyzer;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline void MUSIC::SetUpCanvas(){
|
||||||
|
|
||||||
|
//====== resize window if screen too small
|
||||||
|
QScreen * screen = QGuiApplication::primaryScreen();
|
||||||
|
QRect screenGeo = screen->geometry();
|
||||||
|
if( screenGeo.width() < 1000 || screenGeo.height() < 1000) {
|
||||||
|
setGeometry(0, 0, screenGeo.width() - 100, screenGeo.height() -100);
|
||||||
|
}else{
|
||||||
|
setGeometry(0, 0, 1000, 1000);
|
||||||
|
}
|
||||||
|
// setGeometry(0, 0, 1600, 1600);
|
||||||
|
chkRunAnalyzer = new QCheckBox("Run Analyzer", this);
|
||||||
|
layout->addWidget(chkRunAnalyzer, 0, 0);
|
||||||
|
|
||||||
|
hLeft = new Histogram2D("Left", "Ch", "Energy", 16, 0, 16, 200, 0, 200, this);
|
||||||
|
layout->addWidget(hLeft, 1, 0);
|
||||||
|
hRight = new Histogram2D("Right", "Ch", "Energy", 16, 0, 16, 200, 0, 200, this);
|
||||||
|
layout->addWidget(hRight, 1, 1);
|
||||||
|
hLR = new Histogram2D("Left + Right", "Ch", "Energy", 17, 0, 16, 200, 0, 200, this);
|
||||||
|
layout->addWidget(hLR, 2, 0);
|
||||||
|
hMulti = new Histogram1D("Multi", "multiplicity", 40, 0, 40);
|
||||||
|
layout->addWidget(hMulti, 2, 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void MUSIC::UpdateHistograms(){
|
||||||
|
|
||||||
|
if( this->isVisible() == false ) return;
|
||||||
|
if( chkRunAnalyzer->isChecked() == false ) return;
|
||||||
|
|
||||||
|
BuildEvents(false); // call the event builder to build events
|
||||||
|
|
||||||
|
//============ Get events, and do analysis
|
||||||
|
long eventBuilt = evtbder->eventBuilt;
|
||||||
|
if( eventBuilt == 0 ) return;
|
||||||
|
|
||||||
|
//============ Processing data and fill histograms
|
||||||
|
long eventIndex = evtbder->eventIndex;
|
||||||
|
long eventStart = eventIndex - eventBuilt + 1;
|
||||||
|
if(eventStart < 0 ) eventStart += MaxNEvent;
|
||||||
|
|
||||||
|
// printf("MUSIC::%s----------- 2 : %ld %ld \n", __func__, eventStart, eventIndex);
|
||||||
|
for( long i = eventStart ; i <= eventIndex; i ++ ){
|
||||||
|
std::vector<Hit> event = evtbder->events[i];
|
||||||
|
// printf("MUSIC::%s----------- %ld, %zu\n", __func__, i, event.size());
|
||||||
|
|
||||||
|
hMulti->Fill((int) event.size());
|
||||||
|
if( event.size() == 0 ) return;
|
||||||
|
|
||||||
|
double sum[17] = {0};
|
||||||
|
for( int k = 0; k < (int) event.size(); k++ ){
|
||||||
|
|
||||||
|
// printf("--- %d\n", k);
|
||||||
|
int bd = MUSICChMap::SN2Bd.at(event[k].sn);
|
||||||
|
int ch = event[k].ch;
|
||||||
|
|
||||||
|
int ID = MUSICChMap::mapping[bd][ch];
|
||||||
|
|
||||||
|
if( ID < 0 ) continue;
|
||||||
|
|
||||||
|
double eC = event[k].energy;
|
||||||
|
if( 0 <= ID && ID < 16 ) {
|
||||||
|
eC *= MUSICChMap::corr[ch][bd];
|
||||||
|
hLeft->Fill(ID, eC);
|
||||||
|
sum[ID] += eC;
|
||||||
|
}
|
||||||
|
if( 16 <= ID && ID < 32 ) {
|
||||||
|
eC *= MUSICChMap::corr[ch][bd];
|
||||||
|
hRight->Fill(ID-16, eC );
|
||||||
|
sum[ID-16] += eC ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for( int ch = 0; ch < 17; ch++){
|
||||||
|
if( sum[ch] > 0 ) hLR->Fill(ch, sum[ch]);
|
||||||
|
//printf("%d | sum %d\n", ch, sum[ch]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hLeft->UpdatePlot();
|
||||||
|
hRight->UpdatePlot();
|
||||||
|
hMulti->UpdatePlot();
|
||||||
|
hLR->UpdatePlot();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
239
analyzers/NeutronGamma.h
Normal file
239
analyzers/NeutronGamma.h
Normal file
|
@ -0,0 +1,239 @@
|
||||||
|
#ifndef NEUTRONGAMMA_H
|
||||||
|
#define NEUTRONGAMMA_H
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************\
|
||||||
|
*
|
||||||
|
* This Analyzer does not use event builder,
|
||||||
|
* this simply use the energy_short and energy_long for each data.
|
||||||
|
*
|
||||||
|
*************************************/
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QChart>
|
||||||
|
#include <QChartView>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QGroupBox>
|
||||||
|
#include <QVector>
|
||||||
|
#include <QRandomGenerator>
|
||||||
|
|
||||||
|
#include "Analyser.h"
|
||||||
|
|
||||||
|
//^====================================================
|
||||||
|
//^====================================================
|
||||||
|
class NeutronGamma : public Analyzer{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
NeutronGamma(Digitizer ** digi, unsigned int nDigi, QString rawDataPath, QMainWindow * parent = nullptr): Analyzer(digi, nDigi, parent){
|
||||||
|
this->digi = digi;
|
||||||
|
this->nDigi = nDigi;
|
||||||
|
this->settingPath = rawDataPath + "/NG_HistogramSettings.txt";
|
||||||
|
|
||||||
|
SetUpdateTimeInSec(1.0);
|
||||||
|
|
||||||
|
isSignalSlotActive = false;
|
||||||
|
SetUpCanvas();
|
||||||
|
|
||||||
|
ClearInternalDataCount();
|
||||||
|
};
|
||||||
|
|
||||||
|
~NeutronGamma(){
|
||||||
|
// for( unsigned int i = 0; i < nDigi; i++ ){
|
||||||
|
// for( int ch = 0; ch < digi[i]->GetNumInputCh(); ch++){
|
||||||
|
// delete hist2D[i][ch];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
delete hist2D;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearInternalDataCount();
|
||||||
|
|
||||||
|
// void LoadSetting();
|
||||||
|
// void SaveSetting();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void UpdateHistograms();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVector<int> generateNonRepeatedCombination(int size);
|
||||||
|
void SetUpCanvas();
|
||||||
|
|
||||||
|
Digitizer ** digi;
|
||||||
|
unsigned short nDigi;
|
||||||
|
|
||||||
|
Histogram2D * hist2D;
|
||||||
|
|
||||||
|
RComboBox * cbDigi;
|
||||||
|
RComboBox * cbCh;
|
||||||
|
|
||||||
|
QGroupBox * histBox;
|
||||||
|
QGridLayout * histLayout;
|
||||||
|
|
||||||
|
int lastFilledIndex[MaxNDigitizer][MaxNChannels];
|
||||||
|
int loopFilledIndex[MaxNDigitizer][MaxNChannels];
|
||||||
|
|
||||||
|
bool fillHistograms;
|
||||||
|
|
||||||
|
QString settingPath;
|
||||||
|
|
||||||
|
unsigned short maxFillTimeinMilliSec;
|
||||||
|
unsigned short maxFillTimePerDigi;
|
||||||
|
|
||||||
|
bool isSignalSlotActive;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void NeutronGamma::SetUpCanvas(){
|
||||||
|
|
||||||
|
setWindowTitle("Neutron-Gamma Separation");
|
||||||
|
|
||||||
|
QScreen * screen = QGuiApplication::primaryScreen();
|
||||||
|
QRect screenGeo = screen->geometry();
|
||||||
|
if( screenGeo.width() < 1000 || screenGeo.height() < 800) {
|
||||||
|
setGeometry(0, 0, screenGeo.width() - 100, screenGeo.height() - 100);
|
||||||
|
}else{
|
||||||
|
setGeometry(0, 0, 1000, 800);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget * layoutWidget = new QWidget(this);
|
||||||
|
setCentralWidget(layoutWidget);
|
||||||
|
QVBoxLayout * layout = new QVBoxLayout(layoutWidget);
|
||||||
|
layoutWidget->setLayout(layout);
|
||||||
|
|
||||||
|
{//^==================================
|
||||||
|
QGroupBox * controlBox = new QGroupBox("Control", this);
|
||||||
|
layout->addWidget(controlBox);
|
||||||
|
QGridLayout * ctrlLayout = new QGridLayout(controlBox);
|
||||||
|
controlBox->setLayout(ctrlLayout);
|
||||||
|
|
||||||
|
|
||||||
|
cbDigi = new RComboBox(this);
|
||||||
|
for( unsigned int i = 0; i < nDigi; i++) cbDigi->addItem("Digi-" + QString::number( digi[i]->GetSerialNumber() ), i);
|
||||||
|
ctrlLayout->addWidget(cbDigi, 0, 0, 1, 2);
|
||||||
|
connect( cbDigi, &RComboBox::currentIndexChanged, this, [=](int index){
|
||||||
|
isSignalSlotActive = false;
|
||||||
|
cbCh->clear();
|
||||||
|
for( int i = 0; i < digi[index]->GetNumInputCh(); i++) cbCh->addItem("ch-" + QString::number( i ), i);
|
||||||
|
|
||||||
|
hist2D->Clear();
|
||||||
|
isSignalSlotActive = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
cbCh = new RComboBox(this);
|
||||||
|
for( int i = 0; i < digi[0]->GetNumInputCh(); i++) cbCh->addItem("ch-" + QString::number( i ), i);
|
||||||
|
ctrlLayout->addWidget(cbCh, 0, 2, 1, 2);
|
||||||
|
// connect( cbCh, &RComboBox::currentIndexChanged, this, &SingleSpectra::ChangeHistView);
|
||||||
|
connect( cbCh, &RComboBox::currentIndexChanged, this, [=](){
|
||||||
|
hist2D->Clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
QCheckBox * chkIsFillHistogram = new QCheckBox("Fill Histograms", this);
|
||||||
|
ctrlLayout->addWidget(chkIsFillHistogram, 0, 8);
|
||||||
|
connect(chkIsFillHistogram, &QCheckBox::stateChanged, this, [=](int state){ fillHistograms = state;});
|
||||||
|
chkIsFillHistogram->setChecked(false);
|
||||||
|
fillHistograms = false;
|
||||||
|
|
||||||
|
QLabel * lbSettingPath = new QLabel( settingPath , this);
|
||||||
|
ctrlLayout->addWidget(lbSettingPath, 1, 0, 1, 8);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
{//^====================================
|
||||||
|
|
||||||
|
histBox = new QGroupBox("Histgrams", this);
|
||||||
|
layout->addWidget(histBox, 10);
|
||||||
|
histLayout = new QGridLayout(histBox);
|
||||||
|
histBox->setLayout(histLayout);
|
||||||
|
|
||||||
|
double eMax = 50000;
|
||||||
|
double eMin = 0;
|
||||||
|
double nBin = 1000;
|
||||||
|
|
||||||
|
// for( unsigned int i = 0; i < MaxNDigitizer; i++){
|
||||||
|
// if( i >= nDigi ) continue;
|
||||||
|
// for( int j = 0; j < digi[i]->GetNumInputCh(); j++){
|
||||||
|
// if( i < nDigi ) {
|
||||||
|
// hist2D[i][j] = new Histogram2D("Digi-" + QString::number(digi[i]->GetSerialNumber()), "Long Energy [ch]", "Short Energy [ch]", nBin, eMin, eMax, nBin, eMin, eMax);
|
||||||
|
// }else{
|
||||||
|
// hist2D[i][j] = nullptr;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// histLayout->addWidget(hist2D[0][0], 0, 0);
|
||||||
|
|
||||||
|
hist2D = new Histogram2D("Neutron-Gamma", "Long Energy [ch]", "PSD = (l-s)/l", nBin, eMin, eMax, nBin, 0, 1);
|
||||||
|
|
||||||
|
histLayout->addWidget(hist2D, 0, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void NeutronGamma::ClearInternalDataCount(){
|
||||||
|
for( unsigned int i = 0; i < nDigi; i++){
|
||||||
|
for( int ch = 0; ch < MaxRegChannel ; ch++) {
|
||||||
|
lastFilledIndex[i][ch] = -1;
|
||||||
|
loopFilledIndex[i][ch] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void NeutronGamma::UpdateHistograms(){
|
||||||
|
if( !fillHistograms ) return;
|
||||||
|
if( this->isVisible() == false ) return;
|
||||||
|
|
||||||
|
int ID = cbDigi->currentData().toInt();
|
||||||
|
int ch = cbCh->currentData().toInt();
|
||||||
|
|
||||||
|
int lastIndex = digi[ID]->GetData()->GetDataIndex(ch);
|
||||||
|
if( lastIndex < 0 ) return;
|
||||||
|
|
||||||
|
int loopIndex = digi[ID]->GetData()->GetLoopIndex(ch);
|
||||||
|
|
||||||
|
int temp1 = lastIndex + loopIndex * digi[ID]->GetData()->GetDataSize();
|
||||||
|
int temp2 = lastFilledIndex[ID][ch] + loopFilledIndex[ID][ch] * digi[ID]->GetData()->GetDataSize() + 1;
|
||||||
|
|
||||||
|
if( temp1 - temp2 > digi[ID]->GetData()->GetDataSize() ) { //DefaultDataSize = 10k
|
||||||
|
temp2 = temp1 - digi[ID]->GetData()->GetDataSize();
|
||||||
|
lastFilledIndex[ID][ch] = lastIndex;
|
||||||
|
lastFilledIndex[ID][ch] = loopIndex - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( int j = 0 ; j <= temp1 - temp2; j ++){
|
||||||
|
lastFilledIndex[ID][ch] ++;
|
||||||
|
if( lastFilledIndex[ID][ch] > digi[ID]->GetData()->GetDataSize() ) {
|
||||||
|
lastFilledIndex[ID][ch] = 0;
|
||||||
|
loopFilledIndex[ID][ch] ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uShort data_long = digi[ID]->GetData()->GetEnergy(ch, lastFilledIndex[ID][ch]);
|
||||||
|
uShort data_short = digi[ID]->GetData()->GetEnergy2(ch, lastFilledIndex[ID][ch]);
|
||||||
|
|
||||||
|
// printf(" ch: %d, last fill idx : %d | %d \n", ch, lastFilledIndex[ID][ch], data);
|
||||||
|
|
||||||
|
double psd = (data_long - data_short) *1.0 / data_long;
|
||||||
|
|
||||||
|
hist2D->Fill(data_long, psd);
|
||||||
|
}
|
||||||
|
|
||||||
|
hist2D->UpdatePlot();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QVector<int> NeutronGamma::generateNonRepeatedCombination(int size) {
|
||||||
|
QVector<int> combination;
|
||||||
|
for (int i = 0; i < size; ++i) combination.append(i);
|
||||||
|
|
||||||
|
for (int i = 0; i < size - 1; ++i) {
|
||||||
|
int j = QRandomGenerator::global()->bounded(i, size);
|
||||||
|
combination.swapItemsAt(i, j);
|
||||||
|
}
|
||||||
|
return combination;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -27,9 +27,7 @@ public:
|
||||||
evtbder = GetEventBuilder();
|
evtbder = GetEventBuilder();
|
||||||
evtbder->SetTimeWindow(500);
|
evtbder->SetTimeWindow(500);
|
||||||
|
|
||||||
//========== use the influx from the Analyzer
|
SetDatabase("https://localhost:8086", "testing", "zKhzKk4Yhf1l9QU-yE2GsIZ1RazqUgoW3NlF8LJqq_xDMwatOJwg1sKrjgq36uLEsQf8Fmn4sJALP7Kkilk14A==");
|
||||||
influx = new InfluxDB("https://fsunuc.physics.fsu.edu/influx/");
|
|
||||||
dataBaseName = "testing";
|
|
||||||
|
|
||||||
SetUpCanvas(); // see below
|
SetUpCanvas(); // see below
|
||||||
|
|
||||||
|
|
134
analyzers/RAISOR.h
Normal file
134
analyzers/RAISOR.h
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
#ifndef RASIOR_h
|
||||||
|
#define RASIOR_h
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* This is online analyzer for RASIOR, ANL
|
||||||
|
*
|
||||||
|
* Created by Ryan @ 2023-10-16
|
||||||
|
*
|
||||||
|
* ******************************************/
|
||||||
|
#include "Analyser.h"
|
||||||
|
|
||||||
|
|
||||||
|
class RAISOR : public Analyzer{
|
||||||
|
|
||||||
|
public:
|
||||||
|
RAISOR(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent = nullptr): Analyzer(digi, nDigi, parent){
|
||||||
|
|
||||||
|
|
||||||
|
SetUpdateTimeInSec(1.0);
|
||||||
|
|
||||||
|
RedefineEventBuilder({0}); // only builder for the 0-th digitizer.
|
||||||
|
tick2ns = digi[0]->GetTick2ns();
|
||||||
|
|
||||||
|
SetBackwardBuild(false, 100); // using normal building (acceding in time) or backward building, int the case of backward building, default events to be build is 100.
|
||||||
|
evtbder = GetEventBuilder();
|
||||||
|
evtbder->SetTimeWindow(500);
|
||||||
|
|
||||||
|
//========== use the influx from the Analyzer
|
||||||
|
influx = new InfluxDB("https://fsunuc.physics.fsu.edu/influx/");
|
||||||
|
dataBaseName = "testing";
|
||||||
|
|
||||||
|
SetUpCanvas(); // see below
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
void SetUpCanvas();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void UpdateHistograms();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
MultiBuilder *evtbder;
|
||||||
|
|
||||||
|
Histogram2D * hPID;
|
||||||
|
|
||||||
|
int tick2ns;
|
||||||
|
|
||||||
|
float dE, E;
|
||||||
|
unsigned long long dE_t, E_t;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline void RAISOR::SetUpCanvas(){
|
||||||
|
|
||||||
|
setGeometry(0, 0, 500, 500);
|
||||||
|
|
||||||
|
//============ histograms
|
||||||
|
hPID = new Histogram2D("RAISOR", "E", "dE", 100, 0, 5000, 100, 0, 20000, this);
|
||||||
|
layout->addWidget(hPID, 0, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void RAISOR::UpdateHistograms(){
|
||||||
|
|
||||||
|
if( this->isVisible() == false ) return;
|
||||||
|
|
||||||
|
BuildEvents(false); // call the event builder to build events
|
||||||
|
|
||||||
|
//============ Get events, and do analysis
|
||||||
|
long eventBuilt = evtbder->eventBuilt;
|
||||||
|
if( eventBuilt == 0 ) return;
|
||||||
|
|
||||||
|
//============ Get the cut list, if any
|
||||||
|
QList<QPolygonF> cutList = hPID->GetCutList();
|
||||||
|
const int nCut = cutList.count();
|
||||||
|
unsigned long long tMin[nCut] = {0xFFFFFFFFFFFFFFFF}, tMax[nCut] = {0};
|
||||||
|
unsigned int count[nCut]={0};
|
||||||
|
|
||||||
|
//============ Processing data and fill histograms
|
||||||
|
long eventIndex = evtbder->eventIndex;
|
||||||
|
long eventStart = eventIndex - eventBuilt + 1;
|
||||||
|
if(eventStart < 0 ) eventStart += MaxNEvent;
|
||||||
|
|
||||||
|
for( long i = eventStart ; i <= eventIndex; i ++ ){
|
||||||
|
std::vector<Hit> event = evtbder->events[i];
|
||||||
|
//printf("-------------- %ld\n", i);
|
||||||
|
|
||||||
|
if( event.size() == 0 ) return;
|
||||||
|
|
||||||
|
for( int k = 0; k < (int) event.size(); k++ ){
|
||||||
|
//event[k].Print();
|
||||||
|
if( event[k].ch == 0 ) {dE = event[k].energy; dE_t = event[k].timestamp;}
|
||||||
|
if( event[k].ch == 1 ) {E = event[k].energy; E_t = event[k].timestamp;}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// printf("(E, dE) = (%f, %f)\n", E, dE);
|
||||||
|
hPID->Fill(E + RandomGauss(0, 100), dE+ RandomGauss(0, 100)); // x, y
|
||||||
|
|
||||||
|
//check events inside any Graphical cut and extract the rate
|
||||||
|
for(int p = 0; p < cutList.count(); p++ ){
|
||||||
|
if( cutList[p].isEmpty() ) continue;
|
||||||
|
if( cutList[p].containsPoint(QPointF(E, dE), Qt::OddEvenFill) ){
|
||||||
|
if( dE_t < tMin[p] ) tMin[p] = dE_t;
|
||||||
|
if( dE_t > tMax[p] ) tMax[p] = dE_t;
|
||||||
|
count[p] ++;
|
||||||
|
//printf(".... %d \n", count[p]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hPID->UpdatePlot();
|
||||||
|
|
||||||
|
//========== output to Influx
|
||||||
|
QList<QString> cutNameList = hPID->GetCutNameList();
|
||||||
|
for( int p = 0; p < cutList.count(); p ++){
|
||||||
|
if( cutList[p].isEmpty() ) continue;
|
||||||
|
double dT = (tMax[p]-tMin[p]) * tick2ns / 1e9; // tick to sec
|
||||||
|
double rate = count[p]*1.0/(dT);
|
||||||
|
//printf("%llu %llu, %f %d\n", tMin[p], tMax[p], dT, count[p]);
|
||||||
|
//printf("%10s | %d | %f Hz \n", cutNameList[p].toStdString().c_str(), count[p], rate);
|
||||||
|
|
||||||
|
influx->AddDataPoint("Cut,name=" + cutNameList[p].toStdString()+ " value=" + std::to_string(rate));
|
||||||
|
influx->WriteData(dataBaseName.toStdString());
|
||||||
|
influx->ClearDataPointsBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -25,9 +25,7 @@ public:
|
||||||
evtbder = GetEventBuilder();
|
evtbder = GetEventBuilder();
|
||||||
evtbder->SetTimeWindow(500);
|
evtbder->SetTimeWindow(500);
|
||||||
|
|
||||||
//========== use the influx from the Analyzer
|
SetDatabase("https://localhost:8086", "testing", "zKhzKk4Yhf1l9QU-yE2GsIZ1RazqUgoW3NlF8LJqq_xDMwatOJwg1sKrjgq36uLEsQf8Fmn4sJALP7Kkilk14A==");
|
||||||
influx = new InfluxDB("https://fsunuc.physics.fsu.edu/influx/");
|
|
||||||
dataBaseName = "testing";
|
|
||||||
|
|
||||||
SetUpCanvas(); // see below
|
SetUpCanvas(); // see below
|
||||||
|
|
||||||
|
@ -261,7 +259,7 @@ inline void RAISOR1::UpdateHistograms(){
|
||||||
//printf("%10s | %d | %f Hz \n", cutNameList[p].toStdString().c_str(), count[p], rate);
|
//printf("%10s | %d | %f Hz \n", cutNameList[p].toStdString().c_str(), count[p], rate);
|
||||||
|
|
||||||
influx->AddDataPoint("Cut,name=" + cutNameList[p].toStdString()+ " value=" + std::to_string(rate));
|
influx->AddDataPoint("Cut,name=" + cutNameList[p].toStdString()+ " value=" + std::to_string(rate));
|
||||||
influx->WriteData(dataBaseName);
|
influx->WriteData(dataBaseName.toStdString());
|
||||||
influx->ClearDataPointsBuffer();
|
influx->ClearDataPointsBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,8 +26,7 @@ public:
|
||||||
evtbder->SetTimeWindow(500);
|
evtbder->SetTimeWindow(500);
|
||||||
|
|
||||||
//========== use the influx from the Analyzer
|
//========== use the influx from the Analyzer
|
||||||
influx = new InfluxDB("https://fsunuc.physics.fsu.edu/influx/");
|
SetDatabase("https://localhost:8086", "testing", "zKhzKk4Yhf1l9QU-yE2GsIZ1RazqUgoW3NlF8LJqq_xDMwatOJwg1sKrjgq36uLEsQf8Fmn4sJALP7Kkilk14A==");
|
||||||
dataBaseName = "testing";
|
|
||||||
|
|
||||||
SetUpCanvas(); // see below
|
SetUpCanvas(); // see below
|
||||||
|
|
||||||
|
@ -289,7 +288,7 @@ inline void RAISOR2::UpdateHistograms(){
|
||||||
//printf("%10s | %d | %f Hz \n", cutNameList[p].toStdString().c_str(), count[p], rate);
|
//printf("%10s | %d | %f Hz \n", cutNameList[p].toStdString().c_str(), count[p], rate);
|
||||||
|
|
||||||
influx->AddDataPoint("Cut,name=" + cutNameList[p].toStdString()+ " value=" + std::to_string(rate));
|
influx->AddDataPoint("Cut,name=" + cutNameList[p].toStdString()+ " value=" + std::to_string(rate));
|
||||||
influx->WriteData(dataBaseName);
|
influx->WriteData(dataBaseName.toStdString());
|
||||||
influx->ClearDataPointsBuffer();
|
influx->ClearDataPointsBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
93
analyzers/README.md
Normal file
93
analyzers/README.md
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
# Introduction
|
||||||
|
|
||||||
|
This folder stored all online analyzers. The Analyser.cpp/h is the base class for all analyzer.
|
||||||
|
|
||||||
|
The Analyzer.cpp/h has the MultiBuilder (to handle event building) and InfluxDB (to handle pushing data to influxDB database) classes. In Addision, it has a QThread, a AnalyzerWorker, and a QTimer, these three object handle the threading of UpdateHistograms().
|
||||||
|
|
||||||
|
The AnalyzerWorker moves to the QThread. QTimer::timeout will trigger AnalyzerWorker::UpdateHistograms().
|
||||||
|
|
||||||
|
There is an important bool 'isWorking'. This boolean variable is true when AnalyzerWorker::UpdateHistograms() is running, and it is false when finsihed. This prevent UpdateHistograms() runs twice at the same time.
|
||||||
|
|
||||||
|
There are two virual methods
|
||||||
|
- SetupCanvas()
|
||||||
|
- UpdateHistograms()
|
||||||
|
|
||||||
|
Users must implement these two methods in theie custom analyzer.
|
||||||
|
|
||||||
|
|
||||||
|
# Intruction to make new Analyzer
|
||||||
|
|
||||||
|
The CoindientAnalyzer.h is a good example.
|
||||||
|
|
||||||
|
1. inheirate the Analyzer class
|
||||||
|
```cpp
|
||||||
|
class CustomAnalyzer : public Analyzer{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
CustomAnalyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent = nullptr): Analyzer(digi, nDigi, parent){
|
||||||
|
SetUpdateTimeInSec(1.0); // set histogram update period in sec
|
||||||
|
mb->SetTimeWindow(500); // set the event time windows
|
||||||
|
// ... other custom stuffs
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetUpCanvas();
|
||||||
|
public slots:
|
||||||
|
void UpdateHistograms();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Histogram2D * h2D;
|
||||||
|
Histogram1D * h1D;
|
||||||
|
// some priavte variables
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2. implement the SetUpCanvas() method
|
||||||
|
```cpp
|
||||||
|
inline void CustomAnalyzer::SetUpCanvas(){
|
||||||
|
setWindowTitle("Title");
|
||||||
|
setGeometry(0, 0, 1600, 1000);
|
||||||
|
|
||||||
|
h2D = new Histogram2D("Coincident Plot", "XXX", "YYY", 200, 0, 30000, 200, 0, 30000, this, rawDataPath);
|
||||||
|
|
||||||
|
//layout is inheriatge from Analyzer
|
||||||
|
layout->addWidget(h2D, 0, 0); // row-0, col-0
|
||||||
|
|
||||||
|
h1 = new Histogram1D("1D Plot", "XXX", 300, 0, 30000, this);
|
||||||
|
h1->SetColor(Qt::darkGreen);
|
||||||
|
layout->addWidget(h1, 0, 1); // row-0, col-1
|
||||||
|
|
||||||
|
//other GUI elements
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
3. implement the UpdateHistograms() method
|
||||||
|
```cpp
|
||||||
|
inline void CustomAnalyzer::UpdateHistograms(){
|
||||||
|
// don't update histogram when the windows not visible
|
||||||
|
if( this->isVisible() == false ) return;
|
||||||
|
|
||||||
|
BuildEvents(false); // call the event builder to build events, no verbose
|
||||||
|
|
||||||
|
//check number of event built
|
||||||
|
long eventBuilt = mb->eventBuilt;
|
||||||
|
if( eventBuilt == 0 ) return;
|
||||||
|
|
||||||
|
//============ Processing data and fill histograms
|
||||||
|
long eventIndex = mb->eventIndex;
|
||||||
|
long eventStart = eventIndex - eventBuilt + 1;
|
||||||
|
if(eventStart < 0 ) eventStart += MaxNEvent;
|
||||||
|
|
||||||
|
for( long i = eventStart ; i <= eventIndex; i ++ ){
|
||||||
|
std::vector<Hit> event = mb->events[i];
|
||||||
|
|
||||||
|
//analysis and fill historgam
|
||||||
|
}
|
||||||
|
|
||||||
|
//Render histograms
|
||||||
|
h2D->UpdatePlot();
|
||||||
|
h1D->UpdatePlot();
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
|
@ -30,8 +30,7 @@ public:
|
||||||
RedefineEventBuilder({0}); // only build for the 0-th digitizer, otherwise, it will build event accross all digitizers
|
RedefineEventBuilder({0}); // only build for the 0-th digitizer, otherwise, it will build event accross all digitizers
|
||||||
tick2ns = digi[0]->GetTick2ns();
|
tick2ns = digi[0]->GetTick2ns();
|
||||||
SetBackwardBuild(false, 100); // using normal building (acceding in time) or backward building, int the case of backward building, default events to be build is 100.
|
SetBackwardBuild(false, 100); // using normal building (acceding in time) or backward building, int the case of backward building, default events to be build is 100.
|
||||||
evtbder = GetEventBuilder();
|
mb->SetTimeWindow(3000);
|
||||||
evtbder->SetTimeWindow(500);
|
|
||||||
|
|
||||||
//========== use the influx from the Analyzer
|
//========== use the influx from the Analyzer
|
||||||
influx = new InfluxDB("https://fsunuc.physics.fsu.edu/influx/");
|
influx = new InfluxDB("https://fsunuc.physics.fsu.edu/influx/");
|
||||||
|
@ -41,7 +40,7 @@ public:
|
||||||
leTarget->setText("12C");
|
leTarget->setText("12C");
|
||||||
leBeam->setText("d");
|
leBeam->setText("d");
|
||||||
leRecoil->setText("p");
|
leRecoil->setText("p");
|
||||||
sbBfield->setValue(0.76);
|
sbBfield->setValue(0.75);
|
||||||
sbAngle->setValue(20);
|
sbAngle->setValue(20);
|
||||||
sbEnergy->setValue(16);
|
sbEnergy->setValue(16);
|
||||||
|
|
||||||
|
@ -67,8 +66,6 @@ public slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
MultiBuilder *evtbder;
|
|
||||||
|
|
||||||
// declaie histograms
|
// declaie histograms
|
||||||
Histogram2D * hPID;
|
Histogram2D * hPID;
|
||||||
|
|
||||||
|
@ -87,6 +84,7 @@ private:
|
||||||
RSpinBox * sbEnergy;
|
RSpinBox * sbEnergy;
|
||||||
RSpinBox * sbAngle;
|
RSpinBox * sbAngle;
|
||||||
|
|
||||||
|
RSpinBox * sbEventWin;
|
||||||
QCheckBox * chkRunAnalyzer;
|
QCheckBox * chkRunAnalyzer;
|
||||||
|
|
||||||
QLineEdit * leMassTablePath;
|
QLineEdit * leMassTablePath;
|
||||||
|
@ -212,9 +210,33 @@ inline void SplitPole::SetUpCanvas(){
|
||||||
FillConstants();
|
FillConstants();
|
||||||
});
|
});
|
||||||
|
|
||||||
chkRunAnalyzer = new QCheckBox("Run Analyzer", this);
|
|
||||||
boxLayout->addWidget(chkRunAnalyzer, 4, 1);
|
|
||||||
|
|
||||||
|
QLabel * lbEventWindow = new QLabel("Event Window [ns] ", box);
|
||||||
|
lbEventWindow->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
||||||
|
boxLayout->addWidget(lbEventWindow, 4, 0);
|
||||||
|
sbEventWin = new RSpinBox(this);
|
||||||
|
sbEventWin->setDecimals(0);
|
||||||
|
sbEventWin->setSingleStep(100);
|
||||||
|
sbEventWin->setMaximum(1000000);
|
||||||
|
boxLayout->addWidget(sbEventWin, 4, 1);
|
||||||
|
sbEventWin->setValue(3000);
|
||||||
|
connect(sbEventWin, &RSpinBox::returnPressed, this, [=](){
|
||||||
|
mb->SetTimeWindow(sbEventWin->value());
|
||||||
|
});
|
||||||
|
|
||||||
|
chkRunAnalyzer = new QCheckBox("Run Analyzer", this);
|
||||||
|
boxLayout->addWidget(chkRunAnalyzer, 4, 3);
|
||||||
|
connect(chkRunAnalyzer, &QCheckBox::stateChanged, this, [=](int state){
|
||||||
|
|
||||||
|
sbBfield->setEnabled(state != Qt::Checked);
|
||||||
|
leTarget->setEnabled(state != Qt::Checked);
|
||||||
|
leBeam->setEnabled(state != Qt::Checked);
|
||||||
|
leRecoil->setEnabled(state != Qt::Checked);
|
||||||
|
sbEnergy->setEnabled(state != Qt::Checked);
|
||||||
|
sbAngle->setEnabled(state != Qt::Checked);
|
||||||
|
sbEventWin->setEnabled(state != Qt::Checked);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
QFrame *separator = new QFrame(box);
|
QFrame *separator = new QFrame(box);
|
||||||
separator->setFrameShape(QFrame::HLine);
|
separator->setFrameShape(QFrame::HLine);
|
||||||
|
@ -298,20 +320,20 @@ inline void SplitPole::SetUpCanvas(){
|
||||||
}
|
}
|
||||||
|
|
||||||
//============ histograms
|
//============ histograms
|
||||||
hMulti = new Histogram1D("Multiplicity", "", 10, 0, 10, this);
|
hMulti = new Histogram1D("Multiplicity", "", 16, 0, 16, this);
|
||||||
layout->addWidget(hMulti, 0, 1);
|
layout->addWidget(hMulti, 0, 1);
|
||||||
|
|
||||||
// the "this" make the histogram a child of the SplitPole class. When SplitPole destory, all childs destory as well.
|
// the "this" make the histogram a child of the SplitPole class. When SplitPole destory, all childs destory as well.
|
||||||
hPID = new Histogram2D("Split Pole PID", "Scin-L", "Anode-Font", 100, 0, 5000, 100, 0, 5000, this);
|
hPID = new Histogram2D("Split Pole PID", "Scin-L", "Anode-Back", 100, 0, 20000, 100, 0, 40000, this);
|
||||||
//layout is inheriatge from Analyzer
|
//layout is inheriatge from Analyzer
|
||||||
layout->addWidget(hPID, 1, 0, 2, 1);
|
layout->addWidget(hPID, 1, 0, 2, 1);
|
||||||
|
|
||||||
h1 = new Histogram1D("Spectrum", "x", 300, 30, 70, this);
|
h1 = new Histogram1D("Spectrum", "x1", 300, -200, 200, this);
|
||||||
h1->SetColor(Qt::darkGreen);
|
h1->SetColor(Qt::darkGreen);
|
||||||
//h1->AddDataList("Test", Qt::red); // add another histogram in h1, Max Data List is 10
|
//h1->AddDataList("Test", Qt::red); // add another histogram in h1, Max Data List is 10
|
||||||
layout->addWidget(h1, 1, 1);
|
layout->addWidget(h1, 1, 1);
|
||||||
|
|
||||||
h1g = new Histogram1D("Spectrum (PID gated)", "Ex", 300, -2, 10, this);
|
h1g = new Histogram1D("Spectrum (PID gated)", "x1", 300, -200, 200, this);
|
||||||
layout->addWidget(h1g, 2, 1);
|
layout->addWidget(h1g, 2, 1);
|
||||||
|
|
||||||
layout->setColumnStretch(0, 1);
|
layout->setColumnStretch(0, 1);
|
||||||
|
@ -327,7 +349,7 @@ inline void SplitPole::UpdateHistograms(){
|
||||||
BuildEvents(); // call the event builder to build events
|
BuildEvents(); // call the event builder to build events
|
||||||
|
|
||||||
//============ Get events, and do analysis
|
//============ Get events, and do analysis
|
||||||
long eventBuilt = evtbder->eventBuilt;
|
long eventBuilt = mb->eventBuilt;
|
||||||
if( eventBuilt == 0 ) return;
|
if( eventBuilt == 0 ) return;
|
||||||
|
|
||||||
//============ Get the cut list, if any
|
//============ Get the cut list, if any
|
||||||
|
@ -337,12 +359,12 @@ inline void SplitPole::UpdateHistograms(){
|
||||||
unsigned int count[nCut]={0};
|
unsigned int count[nCut]={0};
|
||||||
|
|
||||||
//============ Processing data and fill histograms
|
//============ Processing data and fill histograms
|
||||||
long eventIndex = evtbder->eventIndex;
|
long eventIndex = mb->eventIndex;
|
||||||
long eventStart = eventIndex - eventBuilt + 1;
|
long eventStart = eventIndex - eventBuilt + 1;
|
||||||
if(eventStart < 0 ) eventStart += MaxNEvent;
|
if(eventStart < 0 ) eventStart += MaxNEvent;
|
||||||
|
|
||||||
for( long i = eventStart ; i <= eventIndex; i ++ ){
|
for( long i = eventStart ; i <= eventIndex; i ++ ){
|
||||||
std::vector<Hit> event = evtbder->events[i];
|
std::vector<Hit> event = mb->events[i];
|
||||||
//printf("-------------- %ld\n", i);
|
//printf("-------------- %ld\n", i);
|
||||||
|
|
||||||
hMulti->Fill((int) event.size());
|
hMulti->Fill((int) event.size());
|
||||||
|
@ -353,28 +375,32 @@ inline void SplitPole::UpdateHistograms(){
|
||||||
|
|
||||||
for( int k = 0; k < (int) event.size(); k++ ){
|
for( int k = 0; k < (int) event.size(); k++ ){
|
||||||
//event[k].Print();
|
//event[k].Print();
|
||||||
if( event[k].ch == SPS::ChMap::ScinR ) {hit.eSR = event[k].energy; hit.tSR = event[k].timestamp;}
|
if( event[k].ch == SPS::ChMap::ScinR ) {hit.eSR = event[k].energy; hit.tSR = event[k].timestamp + event[k].fineTime/1000.;}
|
||||||
if( event[k].ch == SPS::ChMap::ScinL ) {hit.eSL = event[k].energy; hit.tSL = event[k].timestamp;}
|
if( event[k].ch == SPS::ChMap::ScinL ) {hit.eSL = event[k].energy; hit.tSL = event[k].timestamp + event[k].fineTime/1000.;}
|
||||||
if( event[k].ch == SPS::ChMap::dFR ) {hit.eFR = event[k].energy; hit.tFR = event[k].timestamp;}
|
if( event[k].ch == SPS::ChMap::dFR ) {hit.eFR = event[k].energy; hit.tFR = event[k].timestamp + event[k].fineTime/1000.;}
|
||||||
if( event[k].ch == SPS::ChMap::dFL ) {hit.eFL = event[k].energy; hit.tFL = event[k].timestamp;}
|
if( event[k].ch == SPS::ChMap::dFL ) {hit.eFL = event[k].energy; hit.tFL = event[k].timestamp + event[k].fineTime/1000.;}
|
||||||
if( event[k].ch == SPS::ChMap::dBR ) {hit.eBL = event[k].energy; hit.tBL = event[k].timestamp;}
|
if( event[k].ch == SPS::ChMap::dBR ) {hit.eBL = event[k].energy; hit.tBL = event[k].timestamp + event[k].fineTime/1000.;}
|
||||||
if( event[k].ch == SPS::ChMap::dBL ) {hit.eBL = event[k].energy; hit.tBL = event[k].timestamp;}
|
if( event[k].ch == SPS::ChMap::dBL ) {hit.eBL = event[k].energy; hit.tBL = event[k].timestamp + event[k].fineTime/1000.;}
|
||||||
if( event[k].ch == SPS::ChMap::Cathode ) {hit.eCath = event[k].energy; hit.tCath = event[k].timestamp;}
|
if( event[k].ch == SPS::ChMap::Cathode ) {hit.eCath = event[k].energy; hit.tCath = event[k].timestamp + event[k].fineTime/1000.;}
|
||||||
if( event[k].ch == SPS::ChMap::AnodeF ) {hit.eAF = event[k].energy; hit.tAF = event[k].timestamp;}
|
if( event[k].ch == SPS::ChMap::AnodeF ) {hit.eAF = event[k].energy; hit.tAF = event[k].timestamp + event[k].fineTime/1000.;}
|
||||||
if( event[k].ch == SPS::ChMap::AnodeB ) {hit.eAB = event[k].energy; hit.tAB = event[k].timestamp;}
|
if( event[k].ch == SPS::ChMap::AnodeB ) {hit.eAB = event[k].energy; hit.tAB = event[k].timestamp + event[k].fineTime/1000.;}
|
||||||
}
|
}
|
||||||
|
|
||||||
hit.CalData();
|
hit.CalData();
|
||||||
|
|
||||||
double pidX = hit.eSL;
|
double pidX = hit.eSL;
|
||||||
unsigned long long tPidX = hit.tSL;
|
unsigned long long tPidX = hit.tSL;
|
||||||
double pidY = hit.eAF;
|
double pidY = hit.eAB;
|
||||||
|
|
||||||
|
if( pidX > 0 && pidY > 0 ){
|
||||||
hPID->Fill(pidX, pidY); // x, y
|
hPID->Fill(pidX, pidY); // x, y
|
||||||
|
}
|
||||||
h1->Fill(hit.xAvg);
|
if( !std::isnan(hit.x1) ) {
|
||||||
|
h1->Fill(hit.x1);
|
||||||
|
}
|
||||||
//h1->Fill(hit.eSR, 1);
|
//h1->Fill(hit.eSR, 1);
|
||||||
|
|
||||||
|
|
||||||
//check events inside any Graphical cut and extract the rate, using tSR only
|
//check events inside any Graphical cut and extract the rate, using tSR only
|
||||||
for(int p = 0; p < cutList.count(); p++ ){
|
for(int p = 0; p < cutList.count(); p++ ){
|
||||||
if( cutList[p].isEmpty() ) continue;
|
if( cutList[p].isEmpty() ) continue;
|
||||||
|
@ -383,10 +409,13 @@ inline void SplitPole::UpdateHistograms(){
|
||||||
if( tPidX > tMax[p] ) tMax[p] = tPidX;
|
if( tPidX > tMax[p] ) tMax[p] = tPidX;
|
||||||
count[p] ++;
|
count[p] ++;
|
||||||
//printf(".... %d \n", count[p]);
|
//printf(".... %d \n", count[p]);
|
||||||
if( p == 0 ) {
|
// if( p == 0 ) {
|
||||||
double xAvg = hit.xAvg * 10;
|
// double xAvg = hit.xAvg * 10;
|
||||||
double xAvgC = xAvg * sbRhoScale->value() + sbRhoOffset->value();
|
// double xAvgC = xAvg * sbRhoScale->value() + sbRhoOffset->value();
|
||||||
h1g->Fill(hit.Rho2Ex(xAvgC/1000.));
|
// h1g->Fill(hit.Rho2Ex(xAvgC/1000.));
|
||||||
|
// }
|
||||||
|
if( p == 0 ){
|
||||||
|
h1g->Fill(hit.x1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -406,7 +435,7 @@ inline void SplitPole::UpdateHistograms(){
|
||||||
//printf("%10s | %d | %f Hz \n", cutNameList[p].toStdString().c_str(), count[p], rate);
|
//printf("%10s | %d | %f Hz \n", cutNameList[p].toStdString().c_str(), count[p], rate);
|
||||||
|
|
||||||
influx->AddDataPoint("Cut,name=" + cutNameList[p].toStdString()+ " value=" + std::to_string(rate));
|
influx->AddDataPoint("Cut,name=" + cutNameList[p].toStdString()+ " value=" + std::to_string(rate));
|
||||||
influx->WriteData(dataBaseName);
|
influx->WriteData(dataBaseName.toStdString());
|
||||||
influx->ClearDataPointsBuffer();
|
influx->ClearDataPointsBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,8 +39,8 @@ namespace SPS{
|
||||||
const short ScinL = 1;
|
const short ScinL = 1;
|
||||||
const short dFR = 9;
|
const short dFR = 9;
|
||||||
const short dFL = 8;
|
const short dFL = 8;
|
||||||
const short dBR = 10;
|
const short dBR = 11;
|
||||||
const short dBL = 11;
|
const short dBL = 10;
|
||||||
const short Cathode = 7;
|
const short Cathode = 7;
|
||||||
const short AnodeF = 13;
|
const short AnodeF = 13;
|
||||||
const short AnodeB = 15;
|
const short AnodeB = 15;
|
||||||
|
@ -76,7 +76,7 @@ public:
|
||||||
|
|
||||||
float eSAvg;
|
float eSAvg;
|
||||||
float x1, x2, theta;
|
float x1, x2, theta;
|
||||||
float xAvg;
|
double xAvg;
|
||||||
|
|
||||||
double GetQ0() const {return Q0;}
|
double GetQ0() const {return Q0;}
|
||||||
double GetRho0() const {return rho0;}
|
double GetRho0() const {return rho0;}
|
||||||
|
@ -194,14 +194,22 @@ public:
|
||||||
isConstantCal = false;
|
isConstantCal = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CalData(){
|
void CalData(float scale = 2.){
|
||||||
|
|
||||||
if( eSR > 0 && eSL > 0 ) eSAvg = (eSR + eSL)/2;
|
if( eSR > 0 && eSL > 0 ) eSAvg = (eSR + eSL)/2;
|
||||||
if( eSR > 0 && eSL == 0 ) eSAvg = eSR;
|
if( eSR > 0 && eSL == 0 ) eSAvg = eSR;
|
||||||
if( eSR == 0 && eSL > 0 ) eSAvg = eSL;
|
if( eSR == 0 && eSL > 0 ) eSAvg = eSL;
|
||||||
|
|
||||||
if( tFR > 0 && tFL > 0 ) x1 = (tFL - tFR)/2./2.1;
|
if( tFR > 0 && tFL > 0 ) {
|
||||||
if( tBR > 0 && tBL > 0 ) x2 = (tBL - tBR)/2./1.98;
|
if( tFL > tFR) x1 = (tFL - tFR)/scale/2.1;
|
||||||
|
if( tFL < tFR) x1 = (tFR - tFL)/scale/-2.1;
|
||||||
|
}
|
||||||
|
if( tBR > 0 && tBL > 0 ) {
|
||||||
|
if( tBL > tBR) x2 = (tBL - tBR)/scale/1.98;
|
||||||
|
if( tBR > tBL) x2 = (tBR - tBL)/scale/-1.98;
|
||||||
|
}
|
||||||
|
|
||||||
|
// printf("x1: %f, x2 : %f \n", x1, x2);
|
||||||
|
|
||||||
if( !std::isnan(x1) && !std::isnan(x2)) {
|
if( !std::isnan(x1) && !std::isnan(x2)) {
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,7 @@ public:
|
||||||
evtbder = GetEventBuilder();
|
evtbder = GetEventBuilder();
|
||||||
evtbder->SetTimeWindow(500);
|
evtbder->SetTimeWindow(500);
|
||||||
|
|
||||||
//========== use the influx from the Analyzer
|
SetDatabase("https://localhost:8086", "testing", "zKhzKk4Yhf1l9QU-yE2GsIZ1RazqUgoW3NlF8LJqq_xDMwatOJwg1sKrjgq36uLEsQf8Fmn4sJALP7Kkilk14A==");
|
||||||
influx = new InfluxDB("https://fsunuc.physics.fsu.edu/influx/");
|
|
||||||
dataBaseName = "testing";
|
|
||||||
|
|
||||||
SetUpCanvas(); // see below
|
SetUpCanvas(); // see below
|
||||||
|
|
||||||
|
@ -264,7 +262,7 @@ inline void TEST::UpdateHistograms(){
|
||||||
//printf("%10s | %d | %f Hz \n", cutNameList[p].toStdString().c_str(), count[p], rate);
|
//printf("%10s | %d | %f Hz \n", cutNameList[p].toStdString().c_str(), count[p], rate);
|
||||||
|
|
||||||
influx->AddDataPoint("Cut,name=" + cutNameList[p].toStdString()+ " value=" + std::to_string(rate));
|
influx->AddDataPoint("Cut,name=" + cutNameList[p].toStdString()+ " value=" + std::to_string(rate));
|
||||||
influx->WriteData(dataBaseName);
|
influx->WriteData(dataBaseName.toStdString());
|
||||||
influx->ClearDataPointsBuffer();
|
influx->ClearDataPointsBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,9 +27,7 @@ public:
|
||||||
evtbder = GetEventBuilder();
|
evtbder = GetEventBuilder();
|
||||||
evtbder->SetTimeWindow(500);
|
evtbder->SetTimeWindow(500);
|
||||||
|
|
||||||
//========== use the influx from the Analyzer
|
SetDatabase("https://localhost:8086", "testing", "zKhzKk4Yhf1l9QU-yE2GsIZ1RazqUgoW3NlF8LJqq_xDMwatOJwg1sKrjgq36uLEsQf8Fmn4sJALP7Kkilk14A==");
|
||||||
influx = new InfluxDB("https://fsunuc.physics.fsu.edu/influx/");
|
|
||||||
dataBaseName = "testing";
|
|
||||||
|
|
||||||
SetUpCanvas(); // see below
|
SetUpCanvas(); // see below
|
||||||
|
|
||||||
|
|
2
macro.h
2
macro.h
|
@ -11,6 +11,8 @@
|
||||||
#define MaxRecordLength 0x3fff * 8
|
#define MaxRecordLength 0x3fff * 8
|
||||||
#define MaxSaveFileSize 1024 * 1024 * 1024 * 2
|
#define MaxSaveFileSize 1024 * 1024 * 1024 * 2
|
||||||
|
|
||||||
|
#define ScalarUpdateinMiliSec 1000 // msec
|
||||||
|
|
||||||
#define MaxDisplayTraceTimeLength 20000 //ns
|
#define MaxDisplayTraceTimeLength 20000 //ns
|
||||||
#define ScopeUpdateMiliSec 200 // msec
|
#define ScopeUpdateMiliSec 200 // msec
|
||||||
#define MaxNumberOfTrace 5 // in an event
|
#define MaxNumberOfTrace 5 // in an event
|
||||||
|
|
27
main.cpp
27
main.cpp
|
@ -3,6 +3,7 @@
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QLocale>
|
||||||
|
|
||||||
#include "FSUDAQ.h"
|
#include "FSUDAQ.h"
|
||||||
|
|
||||||
|
@ -11,24 +12,28 @@
|
||||||
|
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
|
|
||||||
// class CustomApplication : public QApplication{
|
#include <csignal>
|
||||||
// public:
|
#include <cstdlib>
|
||||||
// CustomApplication(int &argc, char **argv) : QApplication(argc, argv) {}
|
#include <iostream>
|
||||||
|
|
||||||
// protected:
|
void abortHandler(int signal) {
|
||||||
// bool notify(QObject *receiver, QEvent *event) override{
|
std::cerr << "Signal received: " << signal << ", aborting..." << std::endl;
|
||||||
// qDebug() << event->type() << "Receiver:" << receiver;
|
std::abort(); // Calls abort to generate core dump
|
||||||
// return QApplication::notify(receiver, event);
|
}
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]){
|
int main(int argc, char *argv[]){
|
||||||
|
|
||||||
|
std::signal(SIGSEGV, abortHandler);
|
||||||
|
|
||||||
|
setpriority(PRIO_PROCESS, 0, -20);
|
||||||
|
|
||||||
// CustomApplication a(argc, argv);
|
// CustomApplication a(argc, argv);
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
|
|
||||||
setpriority(PRIO_PROCESS, 0, -20);
|
// Set Locale
|
||||||
|
QLocale::setDefault(QLocale::system());
|
||||||
|
|
||||||
|
// Set Lock file
|
||||||
bool isLock = false;
|
bool isLock = false;
|
||||||
int pid = 0;
|
int pid = 0;
|
||||||
QFile lockFile(DAQLockFile);
|
QFile lockFile(DAQLockFile);
|
||||||
|
@ -70,7 +75,7 @@ int main(int argc, char *argv[]){
|
||||||
pidFile.write( QString::number(QCoreApplication::applicationPid() ).toStdString().c_str() );
|
pidFile.write( QString::number(QCoreApplication::applicationPid() ).toStdString().c_str() );
|
||||||
pidFile.close();
|
pidFile.close();
|
||||||
|
|
||||||
MainWindow w;
|
FSUDAQ w;
|
||||||
w.show();
|
w.show();
|
||||||
return a.exec();
|
return a.exec();
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user