Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-17 08:28:57

0001 #pragma once
0002 #ifndef COMMONHELPERFUNCTIONS_H
0003 #define COMMONHELPERFUNCTIONS_H
0004 
0005   #include <iostream>
0006   #include <fstream>
0007   #include "TString.h"
0008   #include "TObjString.h"
0009   #include <vector>
0010   #include <map>
0011   #include <utility>
0012 
0013   #include <cstdint>
0014   #include <string>
0015   
0016   struct Layer{
0017     Layer(): nCells(0), energy(0.), avX(0.), avY(0.) {}
0018     double nCells;
0019     double energy;
0020     double avX;
0021     double avY;
0022   } ;
0023 
0024   inline int GetMaxLayer(std::map<int,Layer> layers){
0025     int maxLayer      = -1;
0026     double maxELayer  = 0;
0027     std::map<int, Layer>::iterator ithLayer;
0028     for(ithLayer=layers.begin(); ithLayer!=layers.end(); ++ithLayer){
0029       if (maxELayer < ithLayer->second.energy ){
0030         maxELayer = ithLayer->second.energy;
0031         maxLayer  = ithLayer->first;
0032       }
0033     }
0034     return maxLayer;
0035   }
0036   inline double GetAverageLayer(std::map<int,Layer> layers){
0037     double avLayer    = 0;
0038     double totE  = 0;
0039     std::map<int, Layer>::iterator ithLayer;
0040     for(ithLayer=layers.begin(); ithLayer!=layers.end(); ++ithLayer){
0041       avLayer +=   ithLayer->first*ithLayer->second.energy;
0042       totE    += ithLayer->second.energy;
0043     }
0044     avLayer = avLayer/totE;
0045     return avLayer;
0046   }
0047   
0048   inline double GetXAverage(std::map<int,Layer> layers, int layerMax = -100){
0049     double avLayer    = 0;
0050     double totE  = 0;
0051     std::map<int, Layer>::iterator ithLayer;
0052     for(ithLayer=layers.begin(); ithLayer!=layers.end(); ++ithLayer){
0053       if ((layerMax != -100) && (ithLayer->first > layerMax) )
0054         continue;
0055       avLayer += ithLayer->second.avX*ithLayer->second.energy;
0056       totE    += ithLayer->second.energy;
0057     }
0058     avLayer = avLayer/totE;
0059     return avLayer;
0060   }
0061 
0062   inline double GetYAverage(std::map<int,Layer> layers, int layerMax = -100){
0063     double avLayer    = 0;
0064     double totE  = 0;
0065     std::map<int, Layer>::iterator ithLayer;
0066     for(ithLayer=layers.begin(); ithLayer!=layers.end(); ++ithLayer){
0067       if ( (layerMax !=-100) && (ithLayer->first > layerMax) )
0068         continue;
0069       avLayer += ithLayer->second.avY*ithLayer->second.energy;
0070       totE    += ithLayer->second.energy;
0071     }
0072     avLayer = avLayer/totE;
0073     return avLayer;
0074   }
0075   
0076   struct RunInfo{
0077     RunInfo(): runNr(0), species(""), pdg(0), energy(0), vop(0), vbr(0), lgSet(0), hgSet(0), posX(0), posY(0), shapetime(0), assemblyNr(0), year(-1), month(-1), detector(""), readout(""), facility(""), beamline(""), samples(0), trigDelay(0), trigDead(0), phase(0), nFPGA(0), nASIC(0), rf(12), cf(10), cc(12), cfcomp(10), temp(20.), injMode(0), injDAC(0) {}
0078     int runNr;
0079     TString species;
0080     int pdg;
0081     float energy;
0082     float vop;
0083     float vbr;
0084     int lgSet;
0085     int hgSet;
0086     float posX;
0087     float posY;
0088     float shapetime;
0089     int assemblyNr;
0090     int year;
0091     int month;
0092     TString detector;
0093     TString readout;
0094     TString facility;
0095     TString beamline;
0096     int samples;
0097     int trigDelay;
0098     int trigDead;
0099     int phase;
0100     int nFPGA;
0101     int nASIC;
0102     int rf;
0103     int cf;
0104     int cc; 
0105     int cfcomp;
0106     float temp;
0107     int injMode;  // 0: low, 1: high, 2:2.5V
0108     double injDAC;
0109   } ;
0110 
0111   TString GetStringFromRunInfo(RunInfo, Int_t);
0112 
0113   //__________________________________________________________________________________________________________
0114   //__________________ Read run infos from text file _________________________________________________________
0115   //__________________________________________________________________________________________________________    
0116   // specialData: 0 - std. TB, 1 - SPE data ORNL
0117   inline std::map<int,RunInfo> readRunInfosFromFile(TString runListFileName, int debug, int specialData = 0 ){
0118     std::map<int,RunInfo> runs;
0119     //std::cout << "INFO: You have given the following run list file: " << runListFileName.Data() << std::endl;
0120     std::ifstream runListFile;
0121     runListFile.open(runListFileName,std::ios_base::in);
0122     if (!runListFile) {
0123       std::cout << "ERROR:  runlist file " << runListFileName.Data() << " not found!" << std::endl;
0124       return runs;
0125     }
0126 
0127     TString facility="";
0128     TString beamline="";
0129     TString readout="";
0130     TString detector="LFHCal";
0131     int year = -1;
0132     int month = -1;
0133     for( TString tempLine; tempLine.ReadLine(runListFile, kTRUE); ) {
0134       // check if line should be considered
0135       if (tempLine.BeginsWith("%") || tempLine.BeginsWith("#")){
0136         continue;
0137       }
0138       if (debug > 1) std::cout << tempLine.Data() << std::endl;
0139       
0140       TObjArray *tempArr2  = tempLine.Tokenize(" ");
0141       if(tempArr2->GetEntries()>0){
0142         if (tempLine.BeginsWith("year")){
0143           year=((TString)((TObjString*)tempArr2->At(1))->GetString()).Atoi();
0144           continue;
0145         } else if (tempLine.BeginsWith("month")){
0146           month=((TString)((TObjString*)tempArr2->At(1))->GetString()).Atoi();
0147           continue;
0148         } else if (tempLine.BeginsWith("readout")){
0149           readout=((TString)((TObjString*)tempArr2->At(1))->GetString());
0150           continue;
0151         } else if (tempLine.BeginsWith("facility")){
0152           facility=((TString)((TObjString*)tempArr2->At(1))->GetString());
0153           continue;
0154         } else if (tempLine.BeginsWith("beam-line")){ 
0155           beamline=((TString)((TObjString*)tempArr2->At(1))->GetString());
0156           continue;
0157         } else if (tempLine.BeginsWith("detector")){ 
0158           detector=((TString)((TObjString*)tempArr2->At(1))->GetString());
0159           continue;
0160         }
0161       }
0162       
0163       // Separate the string according to tabulators
0164       TObjArray *tempArr  = tempLine.Tokenize(",");
0165       if(tempArr->GetEntries()<1){
0166         if (debug > 1) std::cout << "nothing to be done" << std::endl;
0167         delete tempArr;
0168         continue;
0169       } 
0170 
0171       // Put them to the correct variables    
0172       RunInfo tempRun;
0173       tempRun.detector= detector;
0174       tempRun.facility= facility;
0175       tempRun.beamline= beamline;
0176       tempRun.readout = readout;
0177       tempRun.year    = year; 
0178       tempRun.month    = month; 
0179       
0180       // normal run 
0181       if (beamline.CompareTo("injection") != 0){
0182         tempRun.runNr    = ((TString)((TObjString*)tempArr->At(0))->GetString()).Atoi();
0183         tempRun.species  =  (TString)((TObjString*)tempArr->At(1))->GetString();
0184         tempRun.pdg      = ((TString)((TObjString*)tempArr->At(2))->GetString()).Atoi();
0185         tempRun.energy   = ((TString)((TObjString*)tempArr->At(3))->GetString()).Atof();
0186         tempRun.vop      = ((TString)((TObjString*)tempArr->At(4))->GetString()).Atof();
0187         tempRun.vbr      = ((TString)((TObjString*)tempArr->At(5))->GetString()).Atof();
0188         tempRun.temp      = -1.; // set default (might be overwritten)
0189         
0190         if (readout.CompareTo("CAEN") == 0){
0191           tempRun.hgSet    = ((TString)((TObjString*)tempArr->At(6))->GetString()).Atoi();
0192           tempRun.lgSet    = ((TString)((TObjString*)tempArr->At(7))->GetString()).Atoi();
0193           if (tempArr->GetEntries() > 10 & tempRun.year < 2024){
0194             tempRun.shapetime = ((TString)((TObjString*)tempArr->At(10))->GetString()).Atof();
0195           } else {
0196             tempRun.temp      = ((TString)((TObjString*)tempArr->At(10))->GetString()).Atof();
0197             tempRun.shapetime = ((TString)((TObjString*)tempArr->At(11))->GetString()).Atof();
0198           }
0199         } else {
0200           tempRun.trigDelay = ((TString)((TObjString*)tempArr->At(6))->GetString()).Atoi();
0201           tempRun.samples   = ((TString)((TObjString*)tempArr->At(7))->GetString()).Atoi();
0202           tempRun.trigDead  = ((TString)((TObjString*)tempArr->At(10))->GetString()).Atoi();
0203           tempRun.phase     = ((TString)((TObjString*)tempArr->At(11))->GetString()).Atoi();
0204           tempRun.nFPGA     = ((TString)((TObjString*)tempArr->At(12))->GetString()).Atoi();
0205           tempRun.nASIC     = ((TString)((TObjString*)tempArr->At(13))->GetString()).Atoi();
0206         }
0207         tempRun.posX    = ((TString)((TObjString*)tempArr->At(8))->GetString()).Atoi();
0208         tempRun.posY    = ((TString)((TObjString*)tempArr->At(9))->GetString()).Atoi();
0209         if (specialData == 1) tempRun.assemblyNr = ((TString)((TObjString*)tempArr->At(10))->GetString()).Atoi();
0210         
0211         if (tempRun.year > 2025){
0212           tempRun.temp      = ((TString)((TObjString*)tempArr->At(14))->GetString()).Atof();
0213           tempRun.rf        = ((TString)((TObjString*)tempArr->At(15))->GetString()).Atoi();
0214           tempRun.cf        = ((TString)((TObjString*)tempArr->At(16))->GetString()).Atoi();
0215           tempRun.cc        = ((TString)((TObjString*)tempArr->At(17))->GetString()).Atoi();
0216           tempRun.cfcomp    = ((TString)((TObjString*)tempArr->At(18))->GetString()).Atoi();
0217         } else {
0218           tempRun.rf        = 12;
0219           tempRun.cf        = 10;
0220           tempRun.cc        = 12;
0221           tempRun.cfcomp    = 10;
0222         }
0223         
0224         tempRun.injMode   = -1;
0225         tempRun.injDAC    = -1;
0226        
0227         if (debug > 1) std::cout << "Run " << tempRun.runNr << "\t species: " << tempRun.species << "\t energy: "  << tempRun.energy << "\t Vop: " << tempRun.vop << "\t Vov: " << tempRun.vop-tempRun.vbr << "\t Xbeam: " << tempRun.posX<< "\t Ybeam: " << tempRun.posY << "\t shaping time: " << tempRun.shapetime << std::endl;
0228   
0229       // injection tests
0230       } else {
0231         tempRun.runNr    = ((TString)((TObjString*)tempArr->At(0))->GetString()).Atoi();
0232         tempRun.species  =  (TString)((TObjString*)tempArr->At(1))->GetString();
0233         tempRun.pdg      = 0;
0234         tempRun.energy   = 0.;
0235         tempRun.vop      = ((TString)((TObjString*)tempArr->At(2))->GetString()).Atof();
0236         tempRun.vbr      = ((TString)((TObjString*)tempArr->At(3))->GetString()).Atof();
0237         tempRun.posX     = 0.;
0238         tempRun.posY     = 0.;
0239         tempRun.samples   = ((TString)((TObjString*)tempArr->At(4))->GetString()).Atoi();
0240         tempRun.trigDelay = 0;
0241         tempRun.trigDead  = ((TString)((TObjString*)tempArr->At(5))->GetString()).Atoi();
0242         tempRun.phase     = ((TString)((TObjString*)tempArr->At(6))->GetString()).Atoi();
0243         tempRun.nFPGA     = ((TString)((TObjString*)tempArr->At(7))->GetString()).Atoi();
0244         tempRun.nASIC     = ((TString)((TObjString*)tempArr->At(8))->GetString()).Atoi();
0245         tempRun.rf        = ((TString)((TObjString*)tempArr->At(9))->GetString()).Atoi();
0246         tempRun.cf        = ((TString)((TObjString*)tempArr->At(10))->GetString()).Atoi();
0247         tempRun.cc        = ((TString)((TObjString*)tempArr->At(11))->GetString()).Atoi();
0248         tempRun.cfcomp    = ((TString)((TObjString*)tempArr->At(12))->GetString()).Atoi();
0249         tempRun.temp      = 20.;
0250         tempRun.injMode   = ((TString)((TObjString*)tempArr->At(13))->GetString()).Atoi();
0251         tempRun.injDAC    = ((TString)((TObjString*)tempArr->At(14))->GetString()).Atoi();
0252         if (debug > 1) std::cout << "Run " << tempRun.runNr << "\t type: " << tempRun.species << "\t Vop: " << tempRun.vop << "\t Vov: " << tempRun.vop-tempRun.vbr << "\t RF: " << tempRun.rf <<"\t CF: " << tempRun.cf<< "\t CC: " << tempRun.cc<< "\t CFcomp: "<< tempRun.cfcomp<< "\t inj mode: " << tempRun.injMode<< "\t inj value: "<< tempRun.injDAC<< std::endl;
0253       }
0254       runs[tempRun.runNr]=tempRun;
0255     }
0256     std::cout << year << "-" << month << "\t:\t" << facility.Data() << "-" << beamline.Data() << "\t Readout: " << readout.Data() << std::endl;
0257     std::cout << "registered " << runs.size() << " runs from  "<< runListFileName.Data() << std::endl;
0258     
0259     return runs;
0260   };
0261 
0262   inline int GetSpeciesIntFromRunInfo(RunInfo currRunInfo){
0263       if (currRunInfo.species.Contains("cosmics")){
0264           return  0; // cosmics
0265       } else if (currRunInfo.species.CompareTo("g") == 0){
0266           return  1; // gamma
0267       } else if (currRunInfo.species.Contains("muon") || currRunInfo.species.Contains("Muon") || currRunInfo.species.CompareTo("mu-") == 0){
0268           return  2; // muon
0269       } else if (currRunInfo.species.Contains("Electron") || currRunInfo.species.Contains("electron") || currRunInfo.species.CompareTo("e-") == 0 ){
0270           return  3; // electron
0271       } else if (currRunInfo.species.Contains("Positron") || currRunInfo.species.Contains("positron") || currRunInfo.species.CompareTo("e+") == 0 ){
0272           return  6; // positron
0273       } else if (currRunInfo.species.Contains("Pion") || currRunInfo.species.Contains("pion") || currRunInfo.species.CompareTo("pi-") == 0 || currRunInfo.species.CompareTo("pi+") == 0 ){
0274           return  4; // pion
0275       } else if (currRunInfo.species.Contains("Hadron") || currRunInfo.species.Contains("hadron") || currRunInfo.species.CompareTo("h+") == 0 || currRunInfo.species.CompareTo("h-") == 0 ){
0276           return  5; // hadron/proton
0277       }
0278       
0279       return -1;
0280   }
0281 
0282   inline TString GetSpeciesStringFromPDG(int pdg){
0283     switch (pdg){
0284       case 0:
0285         return "ped";
0286       case 11:
0287         return "e^{-}";
0288       case -11:
0289         return "e^{+}";
0290       case 13:
0291         return "#mu^{-}";
0292       case -13:
0293         return "#mu^{+}";
0294       case 211:
0295         return "#pi^{+}";
0296       case -211:
0297         return "#pi^{-}";
0298       case 2212:
0299         return "p";
0300       case -2212:
0301         return "#bar{p}";
0302       default: 
0303         return "";
0304     }
0305   }
0306     
0307   inline Double_t ReturnMipPlotRangeDepVov(double Vov, bool isHG, ReadOut::Type type){
0308     if (type == ReadOut::Type::Caen){
0309       if (isHG){
0310         if (Vov < 2)
0311           return 550.;
0312         else if (Vov < 3)
0313           return 750.;
0314         else if (Vov < 4)
0315           return 950.;
0316         else if (Vov < 5)
0317           return 1150.;
0318         else
0319           return 1350.;
0320       } else {
0321         if (Vov < 2)
0322           return 85.;
0323         else if (Vov < 3)
0324           return 105.;
0325         else if (Vov < 4)
0326           return 125.;
0327         else if (Vov < 5)
0328           return 145.;
0329         else
0330           return 165.;      
0331       }
0332     } else {
0333       if (Vov < 4.5)
0334         return 150.;
0335       else
0336         return 250.;
0337       
0338     }
0339   }
0340 
0341   //****************************************************************************
0342   // Setting minimum for mip plot range, depending of Vov
0343   //****************************************************************************
0344   inline Double_t ReturnMipMinPlotRangeDepVov(double Vov, bool isHG, ReadOut::Type type){
0345     if (type == ReadOut::Type::Caen){
0346       if (isHG){
0347         return -100;
0348       } else {
0349         return -100;
0350       }
0351     } else {
0352       return -25.;
0353     }
0354   }
0355   
0356   //****************************************************************************
0357   // decoding of RF setting for HGCROC
0358   //****************************************************************************
0359   inline Double_t ReturnRFValue(int rf, int debug = 0){
0360     if (debug) std::cout << "RF:  " << rf ;
0361     Double_t rfOhm = 0;
0362     Double_t ohmBit[4]  = {80., 40., 20., 10.}; // documentation version SiPM H2GCROC3b
0363     // Double_t ohmBit[4]  = {100., 66.66, 50., 25.}; // documentation version 1_4
0364     if ((rf - 8) >= 0){
0365       rfOhm = rfOhm+1/ohmBit[3];
0366       rf = rf-8;
0367     }  
0368     if ((rf - 4) >= 0){
0369       rfOhm = rfOhm+1/ohmBit[2];
0370       rf = rf-4;
0371     }  
0372     if ((rf - 2) >= 0){
0373       rfOhm = rfOhm+1/ohmBit[1];
0374       rf = rf-2;
0375     }  
0376     if ((rf - 1) == 0){
0377       rfOhm = rfOhm+1/ohmBit[0];
0378       rf = rf-1;
0379     }
0380     if (debug) std::cout << "\t" << 1./rfOhm << " kOhm" << std::endl;
0381     return 1./rfOhm;
0382   }
0383   
0384   //****************************************************************************
0385   // decoding of CF setting for HGCROC
0386   //****************************************************************************
0387   inline Double_t ReturnCFValue(int cf, int debug = 0){
0388     if (debug) std::cout << "CF:  " << cf ;
0389     Double_t cffF = 0;
0390     if ((cf - 8) >= 0){
0391       cffF = cffF+400;
0392       cf = cf-8;
0393     }  
0394     if ((cf - 4) >= 0){
0395       cffF = cffF+200;
0396       cf = cf-4;
0397     }  
0398     if ((cf - 2) >= 0){
0399       cffF = cffF+100;
0400       cf = cf-2;
0401     }  
0402     if ((cf - 1) == 0){
0403       cffF = cffF+50;
0404       cf = cf-1;
0405     }
0406     if (debug) std::cout << "\t" << cffF << " fF" << std::endl;
0407     return cffF;
0408   }
0409   
0410   //****************************************************************************
0411   // decoding of CFcomp setting for HGCROC
0412   //****************************************************************************
0413   inline Double_t ReturnCFCompValue(int cf, int debug = 0){
0414     if (debug) std::cout << "CFComp:  " << cf ;
0415     Double_t cffF = 0;
0416     if ((cf - 8) >= 0){
0417       cffF = cffF+400;
0418       cf = cf-8;
0419     }  
0420     if ((cf - 4) >= 0){
0421       cffF = cffF+200;
0422       cf = cf-4;
0423     }  
0424     if ((cf - 2) >= 0){
0425       cffF = cffF+100;
0426       cf = cf-2;
0427     }  
0428     if ((cf - 1) == 0){
0429       cffF = cffF+50;
0430       cf = cf-1;
0431     }
0432     if (debug) std::cout << "\t" << cffF << " fF" << std::endl;
0433     return cffF;
0434   }
0435   
0436   //****************************************************************************
0437   // decoding of CC setting for HGCROC
0438   //****************************************************************************
0439   inline Double_t ReturnCCValue(int cc, int debug = 0){
0440     if (debug) std::cout << "CC:  " << cc ;
0441     Double_t ccVal = 0;
0442     if ((cc - 8) >= 0){
0443       ccVal = ccVal+0.2;
0444       cc = cc-8;
0445     }  
0446     if ((cc - 4) >= 0){
0447       ccVal = ccVal+0.1;
0448       cc = cc-4;
0449     }  
0450     if ((cc - 2) >= 0){
0451       ccVal = ccVal+0.05;
0452       cc = cc-2;
0453     }  
0454     if ((cc - 1) == 0){
0455       ccVal = ccVal+0.025;
0456       cc = cc-1;
0457     }
0458     if (debug) std::cout << "\t" << ccVal  << std::endl;
0459     return ccVal;
0460   }
0461   
0462   //****************************************************************************
0463   // decoding of injection equivalent calculation for HGCROC
0464   //****************************************************************************
0465   inline double GetInjectionfCEquivalent(double dac, int range){
0466     if (range == 0){
0467       return dac*500./4095;  //maximum injected charge 500fC, max dac = 4095
0468     } else if (range == 1){
0469       return dac*8000./4095;  //maximum injected charge 8000fC, max dac = 4095
0470     }
0471     return -1;
0472   }
0473   
0474   //****************************************************************************
0475   //****************************************************************************
0476   inline TString GetLabelHGCROCSettings(RunInfo currRunInfo){
0477     TString label = "";
0478     if (currRunInfo.rf > -10000.)
0479       label = Form("%sRF=%.1fk#Omega ",label.Data() , ReturnRFValue(currRunInfo.rf));
0480     if (currRunInfo.cf > -10000.)
0481       label = Form("%sCF=%.1ffF ",label.Data() , ReturnCFValue(currRunInfo.cf));
0482     if (currRunInfo.cfcomp > -10000.)
0483       label = Form("%sCF_{comp}=%.1ffF ",label.Data() , ReturnCFCompValue(currRunInfo.cfcomp));
0484     if (currRunInfo.cc > -10000.)
0485       label = Form("%sCC=%.3f",label.Data() , ReturnCCValue(currRunInfo.cc));
0486     return label;
0487   }
0488 
0489   //****************************************************************************
0490   //****************************************************************************
0491   inline TString GetLabelHGCROCSettingsCF(RunInfo currRunInfo){
0492     TString label = "";
0493     if (currRunInfo.cf > -10000.)
0494       label = Form("%sCF=%.1ffF",label.Data() , ReturnCFValue(currRunInfo.cf));
0495     if (currRunInfo.cfcomp > -10000.){
0496       if (label.CompareTo("") != 0)
0497         label = Form("%s, CF_{comp}=%.1ffF",label.Data() , ReturnCFCompValue(currRunInfo.cfcomp));
0498       else 
0499         label = Form("%sCF_{comp}=%.1ffF",label.Data() , ReturnCFCompValue(currRunInfo.cfcomp));
0500     }
0501     return label;
0502   }
0503   
0504   //****************************************************************************
0505   //****************************************************************************
0506   inline TString GetLabelHGCROCSettingsRFCC(RunInfo currRunInfo){
0507     TString label = "";
0508     if (currRunInfo.rf > -10000.)
0509       label = Form("%sRF=%.1fk#Omega",label.Data() , ReturnRFValue(currRunInfo.rf));
0510     if (currRunInfo.cc > -10000.){
0511       if (label.CompareTo("") != 0)
0512         label = Form("%s, CC=%.3f",label.Data() , ReturnCCValue(currRunInfo.cc));
0513       else 
0514         label = Form("%sCC=%.3f",label.Data() , ReturnCCValue(currRunInfo.cc));
0515     }
0516     return label;
0517   }
0518   
0519   //****************************************************************************
0520   //****************************************************************************
0521   inline TString GetLabelVoltageTemp(RunInfo currRunInfo){
0522     TString label = "";
0523     if (currRunInfo.vop > -10000.)
0524       label = Form("%sV_{op}=%.1f V",label.Data() , currRunInfo.vop);
0525     if (currRunInfo.temp > -10000.){
0526       if (label.CompareTo("") != 0)
0527         label = Form("%s, T=%.1f C",label.Data() , currRunInfo.temp);
0528       else 
0529         label = Form("%sT=%.1f C",label.Data() , currRunInfo.temp);
0530     }
0531     if (currRunInfo.energy > -10000. && currRunInfo.species.Contains("laser")){
0532       if (label.CompareTo("") != 0)
0533         label = Form("%s, I_{laser}=%.0f",label.Data() , currRunInfo.energy);
0534       else 
0535         label = Form("%sI_{laser}=%.0f",label.Data() , currRunInfo.energy);
0536     } else if (currRunInfo.energy > -10000.){
0537       if (label.CompareTo("") != 0)
0538         label = Form("%s, E=%.1f GeV",label.Data() , currRunInfo.energy);
0539       else 
0540         label = Form("%sE=%.1f GeV",label.Data() , currRunInfo.energy);
0541     }
0542     return label;
0543   }
0544   
0545   //****************************************************************************
0546   //****************************************************************************
0547   inline void PrintSettingsRunInfo(RunInfo currRunInfo){
0548     TString label = "";
0549     if (currRunInfo.injDAC > -1)
0550       label = Form("%sinj=%.1ffC ", label.Data(), GetInjectionfCEquivalent(currRunInfo.injDAC,currRunInfo.injMode));
0551     if (currRunInfo.rf > -1)
0552       label = Form("%sRF=%.1fk#Omega ",label.Data() , ReturnRFValue(currRunInfo.rf));
0553     if (currRunInfo.cc > -1)
0554       label = Form("%sCC=%.3f ",label.Data() , ReturnCCValue(currRunInfo.cc));
0555     if (currRunInfo.cfcomp > -1)
0556       label = Form("%sCF_{comp}=%.1ffF ",label.Data() , ReturnCFCompValue(currRunInfo.cfcomp));
0557     if (currRunInfo.cf > -1)
0558       label = Form("%sCF=%.1ffF ",label.Data() , ReturnCFValue(currRunInfo.cf));
0559     std::cout<< label.Data() << std::endl;
0560     return;
0561   }
0562 
0563   //****************************************************************************
0564   //****************************************************************************  
0565   inline RunInfo GetCommonRunInfoFromList( std::vector<RunInfo> runList, Int_t option = -1){
0566     
0567     bool isSameVoltage    = true;
0568     double commonVoltage  = runList.at(0).vop;
0569     bool isSameRF         = true;
0570     bool isSameCF         = true;
0571     bool isSameCFcomp     = true;
0572     bool isSameCC         = true;
0573     bool isSameInj        = true;
0574     bool isSameTemp       = true;
0575     bool isSameE          = true;
0576     bool isSameRun        = true;
0577     bool isSamePDG        = true;
0578     double commonRF       = runList.at(0).rf;
0579     double commonCF       = runList.at(0).cf;
0580     double commonCFcomp   = runList.at(0).cfcomp;
0581     double commonCC       = runList.at(0).cc;
0582     double commonInj      = (double)GetInjectionfCEquivalent(runList.at(0).injDAC, runList.at(0).injMode); 
0583     double commonTemp     = runList.at(0).temp;
0584     double commonE        = runList.at(0).energy;
0585     int commonRun         = runList.at(0).runNr;
0586     int commonPDG         = runList.at(0).pdg;
0587     
0588     std::cout << runList.at(0).runNr << "\t"<<  commonVoltage << "\t" << commonE << "\t"<< commonTemp << "\t Sett: "<< commonRF << "\t" << commonCF << "\t"<< commonCC << "\t" << commonCFcomp << "\tinj:"<< commonInj << std::endl;
0589     
0590     for (Int_t r = 1; r< (int)runList.size(); r++){
0591       if (commonVoltage != runList.at(r).vop)   isSameVoltage = false;
0592       if (commonRF != runList.at(r).rf)         isSameRF      = false;
0593       if (commonCF != runList.at(r).cf)         isSameCF      = false;
0594       if (commonCFcomp != runList.at(r).cfcomp)    isSameCFcomp  = false;
0595       if (commonCC != runList.at(r).cc)         isSameCC      = false;
0596       double currentInj = (double)GetInjectionfCEquivalent(runList.at(r).injDAC, runList.at(r).injMode);
0597       if (commonInj != currentInj)              isSameInj     = false;
0598       if (commonE   != runList.at(r).energy)    isSameE       = false;
0599       if (commonTemp != runList.at(r).temp)   isSameTemp    = false;
0600       if (commonRun != runList.at(r).runNr)   isSameRun    = false;
0601       if (commonPDG != runList.at(r).pdg)   isSamePDG    = false;
0602       std::cout << runList.at(r).runNr << "\t" <<  runList.at(r).vop << "\t" << runList.at(r).energy << "\t"<< runList.at(r).temp << "\t Sett: "<< runList.at(r).rf << "\t" << runList.at(r).cf << "\t"<<  runList.at(r).cc << "\t" << runList.at(r).cfcomp << "\tinj:"<< currentInj << std::endl;
0603     }
0604     
0605     std::cout << "Show all common settings" << std::endl;
0606     std::cout << "Common Voltage: "<< isSameVoltage << "\t"  << commonVoltage
0607               << "\t RF: " << isSameRF << "\t"  << commonRF
0608               << "\t CF: " << isSameCF << "\t"  << commonCF 
0609               << "\t CFcomp: " << isSameCFcomp << "\t"  << commonCFcomp 
0610               << "\t CC: " << isSameCC << "\t"  << commonCC 
0611               << "\t E: " << isSameE << "\t"  << commonE 
0612               << "\t T: " << isSameTemp << "\t"  << commonTemp 
0613               << "\t Inj: " << isSameInj << "\t"  << commonInj 
0614               << std::endl;
0615     
0616     RunInfo commonRunInfo;
0617     commonRunInfo.nFPGA       = runList.at(0).nFPGA;
0618     commonRunInfo.nASIC       = runList.at(0).nASIC;
0619     commonRunInfo.detector    = runList.at(0).detector;
0620     commonRunInfo.beamline    = runList.at(0).beamline;
0621     commonRunInfo.facility    = runList.at(0).facility;
0622     commonRunInfo.readout     = runList.at(0).readout;
0623     commonRunInfo.month       = runList.at(0).month;
0624     commonRunInfo.year        = runList.at(0).year;
0625     commonRunInfo.samples     = runList.at(0).samples;
0626     commonRunInfo.vbr         = runList.at(0).vbr;
0627     commonRunInfo.species     = runList.at(0).species;
0628   
0629     if (isSameRF)
0630       commonRunInfo.rf        = commonRF;
0631     else 
0632       commonRunInfo.rf        = -10000.;
0633     if (isSameCF)
0634       commonRunInfo.cf        = commonCF;
0635     else 
0636       commonRunInfo.cf        = -10000.;
0637     if (isSameCFcomp)
0638       commonRunInfo.cfcomp    = commonCFcomp;
0639     else 
0640       commonRunInfo.cfcomp    = -10000.;
0641     if (isSameCC)
0642       commonRunInfo.cc        = commonCC;
0643     else 
0644       commonRunInfo.cc        = -10000.;
0645     if (isSameVoltage)
0646       commonRunInfo.vop       = commonVoltage;
0647     else 
0648       commonRunInfo.vop       = -10000.;
0649     
0650     if (isSameInj)
0651       commonRunInfo.injDAC    = commonInj;
0652     else 
0653       commonRunInfo.injDAC    = -10000.;
0654     
0655     if (isSameE)
0656       commonRunInfo.energy    = commonE;
0657     else 
0658       commonRunInfo.energy    = -10000.;
0659 
0660     if (isSameTemp)
0661       commonRunInfo.temp    = commonTemp;
0662     else 
0663       commonRunInfo.temp    = -10000.;
0664     
0665     if (isSameRun)
0666       commonRunInfo.runNr    = commonRun;
0667     else 
0668       commonRunInfo.runNr    = -10000;
0669    
0670     if (isSamePDG){
0671       commonRunInfo.pdg      = commonPDG;
0672     } else { 
0673       commonRunInfo.pdg      = -10000.;
0674     }
0675     return commonRunInfo;
0676     
0677   }
0678 
0679   //****************************************************************************
0680   //****************************************************************************  
0681   inline Int_t GetNSameSettings(RunInfo currRunInfo, int option = 0){
0682     Int_t nSameSettings = 0;
0683     if (currRunInfo.species.Contains("injection")){
0684       if (currRunInfo.rf > -10000.) nSameSettings++;
0685       if (currRunInfo.cf > -10000.) nSameSettings++;
0686       if (currRunInfo.cfcomp > -10000.) nSameSettings++;
0687       if (currRunInfo.cc > -10000.) nSameSettings++;
0688       if (currRunInfo.vop > -10000.) nSameSettings++;
0689       if (currRunInfo.injDAC > -10000.) nSameSettings++;
0690       if (currRunInfo.energy > -10000.) nSameSettings++;
0691     } else if (currRunInfo.species.Contains("laser")){
0692       if (currRunInfo.energy > -10000.) nSameSettings++;
0693       if (currRunInfo.temp > -10000.) nSameSettings++;
0694       if (currRunInfo.vop > -10000.) nSameSettings++;
0695     } else if ( option == 1 ){ // waveform data from beam 
0696       if (currRunInfo.rf > -10000.) nSameSettings++;
0697       if (currRunInfo.cf > -10000.) nSameSettings++;
0698       if (currRunInfo.cfcomp > -10000.) nSameSettings++;
0699       if (currRunInfo.cc > -10000.) nSameSettings++;
0700       if (currRunInfo.vop > -10000.) nSameSettings++;
0701       if (currRunInfo.energy > -10000.) nSameSettings++;    
0702     }
0703     return nSameSettings;
0704   }
0705 
0706   //****************************************************************************
0707   // Setting header for legend of comparison plots
0708   //****************************************************************************  
0709   inline TString GetHeaderLegendCommonRunObject (RunInfo currRunInfo, 
0710                                                  int nSameSettings, 
0711                                                  double &width, int &columns, 
0712                                                  double labelScale  ){
0713     TString header = "";
0714     if (currRunInfo.species.Contains("injection")){
0715       if (nSameSettings == 6){
0716         // width = 0.9;
0717         // std::cout <<  currRunInfo.rf << "\t" << currRunInfo.cf << "\t" << currRunInfo.cfcomp << "\t" << currRunInfo.cc << "\t" << currRunInfo.vop << "\t" << currRunInfo.energy << std::endl;
0718         if (currRunInfo.rf < -9999) header = "RF (k#Omega)";
0719         if (currRunInfo.cf < -9999) header = "CF (fF)";
0720         if (currRunInfo.cfcomp < -9999) header = "CF_{comp} (fF)";
0721         if (currRunInfo.cc < -9999)  header = "CC";
0722         if (currRunInfo.vop < -9999)  header = "V_{op} (V)";
0723         if (currRunInfo.injDAC < -9999)  header = "inj (fC)";
0724         if (currRunInfo.energy < -9999)  header = "E ";
0725       } else if (nSameSettings == 5){
0726           // width = 0.9;
0727         columns = 2;
0728         labelScale = 0.6;
0729         // std::cout <<  currRunInfo.rf << "\t" << currRunInfo.cf << "\t" << currRunInfo.cfcomp << "\t" << currRunInfo.cc << "\t" << currRunInfo.vop << "\t" << currRunInfo.energy << std::endl;
0730         if (currRunInfo.rf < -9999)       header = "RF (k#Omega) ";
0731         if (currRunInfo.cf < -9999)       header = header+"CF (fF) ";
0732         if (currRunInfo.cfcomp < -9999)   header = header+"CF_{comp} (fF) ";
0733         if (currRunInfo.cc < -9999)       header = header+"CC ";
0734         if (currRunInfo.vop < -9999)      header = header+"V_{op} (V) ";
0735         if (currRunInfo.injDAC < -9999)   header = header+"inj (fC) ";      
0736         if (currRunInfo.energy < -9999)   header = header+"E  ";      
0737       }
0738     } else if (currRunInfo.species.Contains("laser")){
0739       if (currRunInfo.energy < -9999)       header = header+"Laser Intensity  ";
0740       if (currRunInfo.temp < -9999)         header = header+"Temperature (#circ C) ";
0741     } else if (nSameSettings == 5){
0742       if (currRunInfo.rf < -9999) header = "RF (k#Omega)";
0743       if (currRunInfo.cf < -9999) header = "CF (fF)";
0744       if (currRunInfo.cfcomp < -9999) header = "CF_{comp} (fF)";
0745       if (currRunInfo.cc < -9999)  header = "CC";
0746       if (currRunInfo.vop < -9999)  header = "V_{op} (V)";
0747       if (currRunInfo.energy < -9999)  header = "E ";
0748     } else if (nSameSettings == 4){
0749       columns = 2;
0750       labelScale = 0.6;
0751       // std::cout <<  currRunInfo.rf << "\t" << currRunInfo.cf << "\t" << currRunInfo.cfcomp << "\t" << currRunInfo.cc << "\t" << currRunInfo.vop << "\t" << currRunInfo.energy << std::endl;
0752       if (currRunInfo.rf < -9999)       header = "RF (k#Omega) ";
0753       if (currRunInfo.cf < -9999)       header = header+"CF (fF) ";
0754       if (currRunInfo.cfcomp < -9999)   header = header+"CF_{comp} (fF) ";
0755       if (currRunInfo.cc < -9999)       header = header+"CC ";
0756       if (currRunInfo.vop < -9999)      header = header+"V_{op} (V) ";
0757       if (currRunInfo.energy < -9999)   header = header+"E  ";            
0758     }
0759     return header;
0760   }
0761   
0762   
0763   // // Function to generate the CRC-32 lookup table at runtime (or compile time with C++11 constexpr)
0764   // void generate_crc32_table(uint32_t(&table)[256]) {
0765   //     uint32_t polynomial = 0x104C11DB7; // Common CRC-32 polynomial
0766   //     for (uint32_t i = 0; i < 256; i++) {
0767   //         uint32_t c = i;
0768   //         for (size_t j = 0; j < 8; j++) {
0769   //             if (c & 1) {
0770   //                 c = polynomial ^ (c >> 1);
0771   //             } else {
0772   //                 c >>= 1;
0773   //             }
0774   //         }
0775   //         table[i] = c;
0776   //     }
0777   // }
0778   // 
0779   // // Function to calculate the CRC-32 checksum for a buffer
0780   // uint32_t calculate_crc32(const uint8_t* data, size_t length) {
0781   //     uint32_t crc = 0x0;           // Initial value (standard for HGCROC)
0782   //     // uint32_t crc = 0xFFFFFFFF; // Initial value (standard for CRC-32)
0783   //     uint32_t table[256];
0784   //     generate_crc32_table(table);
0785   // 
0786   //     for (size_t i = 0; i < length; ++i) {
0787   //         crc = table[(crc ^ data[i]) & 0xFF] ^ (crc >> 8);
0788   //     }
0789   // 
0790   //     return crc ^ 0xFFFFFFFF; // Final XOR (standard for CRC-32)
0791   // }  
0792 
0793   // Usage CRC
0794   // std::string message = "123456789"; // Standard test string for CRC-32 check value
0795   // The expected CRC-32 result for this string is 0xCBF43926
0796   //  uint32_t checksum = calculate_crc32(reinterpret_cast<const uint8_t*>(message.c_str()), message.length());
0797   //  std::cout << "CRC-32 Checksum: 0x" << std::hex << std::uppercase << checksum << std::endl;
0798 
0799   struct runRecData{
0800     int runNr;
0801     int pid;            
0802     int nFPGA           = 0;
0803     int triggers        = -1;
0804     int recEvents       = -1;
0805     double recEffi      = -1.;
0806     double sizeConv     = -1.;
0807     double sizeRaw      = -1.;
0808     double comp         = -1.;
0809     int resetsOffset    = -1;
0810     long packets        = -1;
0811     long brokenPackets  = -1;
0812     double fracBroken   = -1;;
0813     std::map<int,int> triggersPerFPGA;
0814     std::map<int,int> recEventsPerFPGA;
0815     std::map<int,double> effiPerFPGA;
0816     std::map<int,int> abortedEventsPerFPGA;
0817     std::map<int,int> inProgEventsPerFPGA;
0818   };
0819 
0820   inline TString PrintRunRecData( runRecData info, bool simple = false){
0821     TString toPrint = "";
0822     toPrint += Form("%d\t%d\t%d\t%d\t%0.3f\n", info.runNr, info.pid, info.triggers, 
0823       info.recEvents, info.recEffi);
0824     if (!simple){
0825       for (int f= 0; f < info.nFPGA; f++){
0826         toPrint +=Form("\t\t%d\t%d\t%d\t%d\t%d\t\t%0.3f\n", f, info.triggersPerFPGA[f], info.recEventsPerFPGA[f], info.abortedEventsPerFPGA[f], info.inProgEventsPerFPGA[f], info.effiPerFPGA[f] );
0827       }
0828     }
0829     return toPrint;
0830   }
0831 
0832 
0833 #endif