Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-05 08:29:02

0001 #include "Analyses.h"
0002 #include <vector>
0003 #include "TROOT.h"
0004 #include <bitset>
0005 #ifdef __APPLE__
0006 #include <unistd.h>
0007 #endif
0008 #include "TF1.h"
0009 #include "TFitResult.h"
0010 #include "TFitResultPtr.h"
0011 #include "TH1D.h"
0012 #include "TH2D.h"
0013 #include "TProfile.h"
0014 #include "TChain.h"
0015 #include "CommonHelperFunctions.h"
0016 #include "TileSpectra.h"
0017 #include "CalibSummary.h"
0018 #include "PlotHelper.h"
0019 #include "MultiCanvas.h"
0020 #include "TRandom3.h"
0021 #include "TMath.h"
0022 #include "Math/Minimizer.h"
0023 #include "Math/MinimizerOptions.h"
0024 
0025 #include "HGCROC_Convert.h"
0026 
0027 #include "waveform_fitting/waveform_fit_base.h"
0028 #include "waveform_fitting/crystal_ball_fit.h"
0029 #include "waveform_fitting/max_sample_fit.h"
0030 
0031 // ****************************************************************************
0032 // Checking and opening input and output files
0033 // ****************************************************************************
0034 bool Analyses::CheckAndOpenIO(void){
0035   int matchingbranch;
0036   if(!ASCIIinputName.IsNull()){
0037     std::cout << "Input to be converted into correct format :" <<  ASCIIinputName.Data() << std::endl;
0038     ASCIIinput.open(ASCIIinputName.Data(),std::ios::in);
0039     if(!ASCIIinput.is_open()){
0040       std::cout<<"Could not open input file: "<<std::endl;
0041       return false;
0042     }
0043   }
0044 
0045   //Need to check first input to get the setup...I do not think it is necessary
0046   std::cout <<"=============================================================" << std::endl;
0047   std::cout<<"Input name set to: "<<RootInputName.Data() <<std::endl;
0048   std::cout<<"Output name set to: "<<RootOutputName.Data() <<std::endl;
0049   if (!Convert) std::cout<<"Calib name set to: "<<RootCalibInputName.Data() <<std::endl;
0050   std::cout <<"=============================================================" << std::endl;
0051   if(!RootInputName.IsNull()){
0052     //File exist?
0053     RootInput=new TFile(RootInputName.Data(),"READ");
0054     if(RootInput->IsZombie()){
0055       std::cout<<"Error opening '"<<RootInputName<<"', does the file exist?"<<std::endl;
0056       return false;
0057     }
0058 
0059     //Retrieve info, start with setup, only if its not to be overwritten
0060     if (!OverWriteSetup){
0061       TsetupIn = (TTree*) RootInput->Get("Setup");
0062       if(!TsetupIn){
0063         std::cout<<"Could not retrieve the Setup tree, leaving"<<std::endl;
0064         return false;
0065       }
0066       setup=Setup::GetInstance();
0067       std::cout<<"Setup add "<<setup<<std::endl;
0068       //matchingbranch=TsetupIn->SetBranchAddress("setup",&setup);
0069       matchingbranch=TsetupIn->SetBranchAddress("setup",&rswptr);
0070       if(matchingbranch<0){
0071         std::cout<<"Error retrieving Setup info from the tree"<<std::endl;
0072         return false;
0073       }
0074       std::cout<<"Entries "<<TsetupIn->GetEntries()<<std::endl;
0075       TsetupIn->GetEntry(0);
0076       setup->Initialize(*rswptr);
0077       std::cout<<"Reading "<<RootInput->GetName()<<std::endl;
0078       std::cout<<"Setup Info "<<setup->IsInit()<<"  and  "<<setup->GetCellID(0,0)<<std::endl;
0079     }
0080 
0081     //Retrieve info, existing data?
0082     TdataIn = (TTree*) RootInput->Get("Data");
0083     if(!TdataIn){
0084       std::cout<<"Could not retrieve the Data tree, leaving"<<std::endl;
0085       return false;
0086     }
0087     matchingbranch=TdataIn->SetBranchAddress("event",&eventptr);
0088     if(matchingbranch<0){
0089       std::cout<<"Error retrieving Event info from the tree"<<std::endl;
0090       return false;
0091     }
0092     
0093     // Read calib object directly from input data file default!
0094     TcalibIn = (TTree*) RootInput->Get("Calib");
0095     if(!TcalibIn){
0096       std::cout<<"Could not retrieve Calib tree, leaving"<<std::endl;
0097       //return false;
0098     }
0099     else {
0100       matchingbranch=TcalibIn->SetBranchAddress("calib",&calibptr);
0101       if(matchingbranch<0){
0102         std::cout<<"Error retrieving calibration info from the tree"<<std::endl;
0103         TcalibIn=nullptr;
0104       }
0105       std::cout << "Retrieved calib object from input root file" << std::endl;
0106     }
0107     
0108     //All good
0109   }
0110   else if(!Convert){
0111     std::cout<<"Explicit Input option mandatory except for convertion ASCII -> ROOT"<<std::endl;
0112     return false;
0113   }  
0114   
0115   //Setup Output files
0116   if(!RootOutputName.IsNull()){    
0117     if (!Convert){
0118       TString temp = RootOutputName;
0119       temp         = temp.ReplaceAll(".root","_Hists.root");
0120       SetRootOutputHists(temp);
0121       // std::cout << "creating additional histo file: " << RootOutputNameHist.Data() << " tree in : "<< RootOutputName.Data() << std::endl;
0122     }
0123     
0124     if (!ExtractToAPhase && !IsVisualizeWaveform) {
0125       bool sCOF = CreateOutputRootFile();
0126       if (!sCOF) return false;
0127       TsetupOut = new TTree("Setup","Setup");
0128       setup=Setup::GetInstance();
0129       //TsetupOut->Branch("setup",&setup);
0130       TsetupOut->Branch("setup",&rsw);
0131       TdataOut = new TTree("Data","Data");
0132       TdataOut->Branch("event",&event);
0133       TcalibOut = new TTree("Calib","Calib");
0134       TcalibOut->Branch("calib",&calib);
0135     } else {
0136       std::cout << "No tree output needed, not creating file" << std::endl;
0137     }
0138   }
0139   else if (!SaveCalibOnly){
0140     std::cout<<"Output option mandatory except when converting"<<std::endl;
0141     return false;
0142   }
0143   
0144   if(!RootCalibInputName.IsNull()){
0145     RootCalibInput=new TFile(RootCalibInputName.Data(),"READ");
0146     if(RootCalibInput->IsZombie()){
0147       std::cout<<"Error opening '"<<RootCalibInputName<<"', does the file exist?"<<std::endl;
0148       return false;
0149     }
0150     TcalibIn = nullptr;
0151     TcalibIn = (TTree*) RootCalibInput->Get("Calib");
0152     if(!TcalibIn){
0153       std::cout<<"Could not retrieve Calib tree, leaving"<<std::endl;
0154       return false;
0155     } else {
0156       std::cout<<"Retrieved calib object from external input! " << RootCalibInputName <<std::endl;
0157     }
0158     matchingbranch=TcalibIn->SetBranchAddress("calib",&calibptr);
0159     if(matchingbranch<0){
0160       std::cout<<"Error retrieving calibration info from the tree"<<std::endl;
0161       return false;
0162     }else {
0163       std::cout<<"Correctly set branch for external calib input."<<std::endl;
0164     }
0165     
0166   }
0167 
0168   if(!RootCalibOutputName.IsNull() && SaveCalibOnly){
0169     std::cout << "entered here" << std::endl;
0170     RootCalibOutput=new TFile(RootCalibOutputName.Data(),"RECREATE");
0171     if(RootCalibOutput->IsZombie()){
0172       std::cout<<"Error opening '"<<RootCalibOutputName<<"', does the file exist?"<<std::endl;
0173       return false;
0174     }
0175     
0176     if (RootOutputName.IsNull()){
0177       TsetupOut = new TTree("Setup","Setup");
0178       setup=Setup::GetInstance();
0179       //TsetupOut->Branch("setup",&setup);
0180       TsetupOut->Branch("setup",&rsw);
0181       TcalibOut = new TTree("Calib","Calib");
0182       TcalibOut->Branch("calib",&calib);
0183     }
0184   }
0185 
0186   if(!RootPedestalInputName.IsNull()){
0187     RootPedestalInput = new TFile(RootPedestalInputName.Data(),"READ");
0188     if(RootPedestalInput->IsZombie()){
0189       std::cout<<"Error opening '"<<RootPedestalInputName<<"', does the file exist?"<<std::endl;
0190       return false;
0191     }
0192     TcalibIn = (TTree*) RootPedestalInput->Get("Calib");
0193     if(!TcalibIn){
0194       std::cout<<"Could not retrieve Calib tree, leaving"<<std::endl;
0195       return false;
0196     } else {
0197       std::cout<<"Retrieved calib object from external input for pedestals!"<<std::endl;
0198     }
0199     matchingbranch=TcalibIn->SetBranchAddress("calib",&calibptr);
0200     if(matchingbranch<0){
0201       std::cout<<"Error retrieving calibration info from the tree"<<std::endl;
0202       return false;
0203     }else {
0204       std::cout<<"Correctly set branch for external calib for pedestal input."<<std::endl;
0205     }
0206     //std::cout<<"Did the address changed? "<<&calib<<std::endl;
0207   }
0208   
0209   if(!MapInputName.IsNull()){
0210     MapInput.open(MapInputName.Data(),std::ios::in);
0211     if(!MapInput.is_open()){
0212       std::cout<<"Could not open mapping file: "<<MapInputName<<std::endl;
0213       return false;
0214     }
0215   }
0216   std::cout <<"=============================================================" << std::endl;
0217   std::cout <<" Basic setup complete" << std::endl;
0218   std::cout <<"=============================================================" << std::endl;
0219   return true;    
0220 }
0221 
0222 // ****************************************************************************
0223 // Primary process function to start all calibrations
0224 // ****************************************************************************
0225 bool Analyses::Process(void){
0226   bool status = true;
0227   ROOT::EnableImplicitMT();
0228   
0229   if(Convert){
0230     std::cout << "Converting !" << std::endl;
0231     if (HGCROC) {
0232       // Set waveform builder
0233       waveform_fit_base *waveform_builder = nullptr;
0234       // waveform_builder = new crystal_ball_fit();
0235 
0236       // // Set the parameters based off what I found in the stand alone analysis
0237       // // Alpha
0238       // waveform_builder->set_parameter(0, 1.1);  // Initial value
0239       // waveform_builder->set_parameter(10, 1);   // Lower bound
0240       // waveform_builder->set_parameter(20, 1.2); // Uppser bound
0241 
0242       // // n
0243       // waveform_builder->set_parameter(1, 0.3);
0244       // waveform_builder->set_parameter(11, 0.2);
0245       // waveform_builder->set_parameter(21, 0.6);
0246 
0247       // // x_bar
0248       // waveform_builder->set_parameter(2, 0.7);
0249       // waveform_builder->set_parameter(12, 0.5);
0250       // waveform_builder->set_parameter(22, 4.5);
0251 
0252       // // sigma
0253       // waveform_builder->set_parameter(3, 0.3);
0254       // waveform_builder->set_parameter(13, 0.25);
0255       // waveform_builder->set_parameter(23, 0.65);
0256 
0257       // // N
0258       // waveform_builder->set_parameter(4, 0);
0259       // waveform_builder->set_parameter(14, 0);
0260       // waveform_builder->set_parameter(24, 2000);
0261 
0262       // // Offset
0263       // waveform_builder->set_parameter(5, 100);  // This needs to become pedestals eventually... 
0264       // waveform_builder->set_parameter(15, 0);
0265       // waveform_builder->set_parameter(25, 160);
0266 
0267       waveform_builder = new max_sample_fit();
0268 
0269       std::cout << "Running HGCROC conversion" << std::endl;
0270       status=run_hgcroc_conversion(this, waveform_builder);
0271     } else {
0272       if (!(GetASCIIinputName().EndsWith(".root"))){
0273         status=ConvertASCII2Root();
0274       } else {
0275         std::cout << "WARNING: This option should only be used for the 2023 SPS test beam for which the CAEN raw data was lost!" << std::endl;
0276         status=ConvertOldRootFile2Root();
0277       }
0278     }
0279   } // end if Convert
0280   
0281   if (OverWriteSetup){
0282     status=OverWriteSetupTree();
0283     return status;
0284   }
0285   
0286   // extract pedestal from pure pedestal runs (internal triggers)
0287   if(ExtractPedestal){
0288     status=GetPedestal();
0289   }
0290   
0291   // extract pedestal from pure pedestal runs (internal triggers)
0292   if(ExtractToAPhase){
0293     status=EvaluateHGCROCToAPhases();
0294   }
0295   
0296   // copy existing calibration to other file
0297   if(ApplyTransferCalib){
0298     status=TransferCalib();
0299   }
0300 
0301   // copy existing calibration to other file
0302   if(ReextractLGHGCorr){
0303     status=ReevaluateLGHGCorr();
0304   }
0305   
0306   
0307   if (IsVisualizeWaveform){
0308     status=VisualizeWaveform();
0309   }
0310   // extract mip calibration 
0311   if(ExtractScaling){
0312     status=GetScaling();
0313   }
0314   
0315   // extract noise sample from trigger flagged files
0316   if(ReextractNoise){
0317     status=GetNoiseSampleAndRefitPedestal();
0318   }
0319   
0320   // rerun mip calibration based on triggers
0321   if (ExtractScalingImproved){
0322     status=GetImprovedScaling();
0323   }
0324   
0325   // copy full calibration to different file and calculate energy
0326   if(ApplyCalibration){
0327     status=Calibrate();
0328   }
0329   
0330   // reduce file to only noise triggers
0331   if(SaveNoiseOnly){
0332     status=SaveNoiseTriggersOnly();
0333   }
0334   
0335   // reduce file to only mip triggers
0336   if(SaveMipsOnly){
0337     status=SaveMuonTriggersOnly();
0338   }
0339   
0340   // skim HGCROC data to discard pure noise events
0341   if(SkimHGCROC){
0342     status=SkimHGCROCData();
0343   }
0344   
0345   // reduce file to only mip triggers
0346   if(EvalLocalTriggers){
0347     status=RunEvalLocalTriggers();
0348   }
0349   
0350   // save calib to output only
0351   if (SaveCalibOnly){
0352     status = SaveCalibToOutputOnly();
0353   }
0354   return status;
0355 } // end Analyses::Process()
0356 
0357 // ****************************************************************************
0358 // convert original ASCII file from CAEN output to root format
0359 // ****************************************************************************
0360 bool Analyses::ConvertASCII2Root(void){
0361   //============================================
0362   //Init first
0363   //============================================
0364   // initialize setup
0365   if (MapInputName.CompareTo("")== 0) {
0366       std::cerr << "ERROR: No mapping file has been provided, please make sure you do so! Aborting!" << std::endl;
0367       return false;
0368   }
0369   std::cout << "creating mapping " << std::endl;
0370   setup->Initialize(MapInputName.Data(),debug);
0371   // initialize run number file
0372   if (RunListInputName.CompareTo("")== 0) {
0373       std::cerr << "ERROR: No run list file has been provided, please make sure you do so! Aborting!" << std::endl;
0374       return false;
0375   }
0376   std::map<int,RunInfo> ri=readRunInfosFromFile(RunListInputName.Data(),debug,0);
0377   
0378   // Clean up file headers
0379   TObjArray* tok=ASCIIinputName.Tokenize("/");
0380   // get file name
0381   TString file=((TObjString*)tok->At(tok->GetEntries()-1))->String();
0382   delete tok;
0383   tok=file.Tokenize("_");
0384   TString header=((TObjString*)tok->At(0))->String();
0385   delete tok;
0386   
0387   // Get run number from file & find necessary run infos
0388   TString RunString=header(3,header.Sizeof());
0389   std::map<int,RunInfo>::iterator it=ri.find(RunString.Atoi());
0390   //std::cout<<RunString.Atoi()<<"\t"<<it->second.species<<std::endl;
0391   event.SetRunNumber(RunString.Atoi());
0392   event.SetROtype(ReadOut::Type::Caen);
0393   event.SetBeamName(it->second.species);
0394   event.SetBeamID(it->second.pdg);
0395   event.SetBeamEnergy(it->second.energy);
0396   event.SetVop(it->second.vop);
0397   event.SetVov(it->second.vop-it->second.vbr);
0398   event.SetBeamPosX(it->second.posX);
0399   event.SetBeamPosY(it->second.posY);
0400   calib.SetRunNumber(RunString.Atoi());
0401   calib.SetVop(it->second.vop);
0402   calib.SetVov(it->second.vop-it->second.vbr);  
0403   calib.SetBCCalib(false);
0404   //============================================
0405   // Start decoding file
0406   //============================================
0407   TString aline         = "";
0408   TString versionCAEN   = "";
0409   TObjArray* tokens;
0410   std::map<int,std::vector<Caen> > tmpEvent;
0411   std::map<int,double> tmpTime;
0412   std::map<int,std::vector<Caen> >::iterator itevent;
0413   long tempEvtCounter   = 0;
0414   long writeEvtCounter  = 0;
0415   
0416   if (maxEvents != -1){
0417       std::cout << "**********************************************************************" << std::endl;
0418       std::cout << "*************************ATTENTION!************************************" << std::endl;
0419       std::cout << "Reconstruction of events will be aborted after " << maxEvents << "!" << std::endl;
0420       std::cout << "This was set manually! Make sure its what you desired!" << std::endl;
0421       std::cout << "**********************************************************************" << std::endl;
0422   }
0423   
0424   while(!ASCIIinput.eof()){                                                     // run till end of file is reached and read line by line
0425     aline.ReadLine(ASCIIinput);
0426     if(!ASCIIinput.good()) break;
0427     if(aline[0]=='/'){
0428       if (aline.Contains("File Format Version")){
0429         tokens      = aline.Tokenize(" ");
0430         versionCAEN = ((TObjString*)tokens->At(4))->String();
0431         std::cout << "File version: " << ((TObjString*)tokens->At(4))->String() << std::endl;
0432         
0433         if (!(versionCAEN.CompareTo("3.3") == 0 || versionCAEN.CompareTo("3.1") == 0)){
0434           std::cerr << "This version cannot be converted with the current code, please add the corresponding file format to the converter" << std::endl;
0435           tokens->Clear();
0436           delete tokens;
0437           return false;
0438         }  
0439         
0440         tokens->Clear();
0441         delete tokens;
0442       }
0443       else if(aline.Contains("Run start time")){
0444         tokens    = aline.Tokenize(" ");
0445         int year=((TObjString*)tokens->At(8))->String().Atoi();
0446         int month;
0447         TString Stringmonth=((TObjString*)tokens->At(5))->String();
0448         if(Stringmonth=="Jan") month=1;
0449         else if(Stringmonth=="Feb") month=2;
0450         else if(Stringmonth=="Mar") month=3;
0451         else if(Stringmonth=="Apr") month=4;
0452         else if(Stringmonth=="May") month=5;
0453         else if(Stringmonth=="Jun") month=6;
0454         else if(Stringmonth=="Jul") month=7;
0455         else if(Stringmonth=="Aug") month=8;
0456         else if(Stringmonth=="Sep") month=9;
0457         else if(Stringmonth=="Oct") month=10;
0458         else if(Stringmonth=="Nov") month=11;
0459         else if(Stringmonth=="Dec") month=12;
0460         int day=((TObjString*)tokens->At(6))->String().Atoi();
0461         int hour=((TString)((TObjString*)tokens->At(7))->String()(0,2)).Atoi();
0462         int min=((TString)((TObjString*)tokens->At(7))->String()(3,5)).Atoi();
0463         int sec=((TString)((TObjString*)tokens->At(7))->String()(6,8)).Atoi();
0464         TTimeStamp t=TTimeStamp(year,month,day,hour,min,sec);
0465         event.SetBeginRunTime(t);
0466         calib.SetBeginRunTime(t);
0467         tokens->Clear();
0468         delete tokens;
0469       }
0470       continue;
0471     }
0472     tokens=aline.Tokenize(" \t");
0473     tokens->SetOwner(true);
0474     
0475     if (versionCAEN.CompareTo("3.3") == 0){
0476       int Nfields=tokens->GetEntries();
0477       // std::cout << Nfields << std::endl;
0478       if(((TObjString*)tokens->At(0))->String()=="Brd") {
0479         tokens->Clear();
0480         delete tokens;
0481         continue;
0482       }
0483       //================================================================================
0484       // data format example
0485       // Brd  Ch       LG       HG        Tstamp_us        TrgID        NHits
0486       // 7  00       51       68     10203578.136            0      64
0487       // 7  01       55       75 
0488       //================================================================================
0489       if(Nfields!=7){
0490         std::cout<<"Unexpected number of fields"<<std::endl;
0491         std::cout<<"Expected 7, got: "<<Nfields<<", exit"<<std::endl;
0492         for(int j=0; j<Nfields;j++) std::cout<<j<<"  "<<((TObjString*)tokens->At(j))->String()<<std::endl;
0493         tokens->Clear();
0494         delete tokens;
0495         return -1;
0496       }
0497       int TriggerID=((TObjString*)tokens->At(5))->String().Atoi();
0498       int NHits=((TObjString*)tokens->At(6))->String().Atoi();
0499       double Time = ((TObjString*)tokens->At(4))->String().Atof();
0500       Caen aTile;
0501       int aBoard=((TObjString*)tokens->At(0))->String().Atoi();
0502       int achannel=((TObjString*)tokens->At(1))->String().Atoi();
0503       aTile.SetE(((TObjString*)tokens->At(3))->String().Atoi());//To Test
0504       aTile.SetADCHigh(((TObjString*)tokens->At(3))->String().Atoi());
0505       aTile.SetADCLow (((TObjString*)tokens->At(2))->String().Atoi());
0506       tokens->Clear();
0507       delete tokens;
0508       aTile.SetCellID(setup->GetCellID(aBoard,achannel));
0509       itevent=tmpEvent.find(TriggerID);
0510 
0511       if(itevent!=tmpEvent.end()){
0512         tmpTime[TriggerID]+=Time;
0513         if (aTile.GetCellID() != -1){
0514           itevent->second.push_back(aTile);
0515         } else {
0516           if(debug ==10) std::cout << "cell " << aBoard << "\t" << achannel << " wasn't active according to mapping file!" << std::endl;
0517         }
0518         for(int ich=1; ich<NHits; ich++){
0519           aline.ReadLine(ASCIIinput);
0520           tokens=aline.Tokenize(" ");
0521           tokens->SetOwner(true);
0522           Nfields=tokens->GetEntries();
0523           if(Nfields!=4){
0524             std::cout<<"Expecting 4 fields but read "<<Nfields << " at event " << tempEvtCounter <<std::endl;
0525             return -1;
0526           }
0527           achannel=((TObjString*)tokens->At(1))->String().Atoi();
0528           aTile.SetE(((TObjString*)tokens->At(3))->String().Atoi());//To Test
0529           aTile.SetADCHigh(((TObjString*)tokens->At(3))->String().Atoi());
0530           aTile.SetADCLow (((TObjString*)tokens->At(2))->String().Atoi());
0531           aTile.SetCellID(setup->GetCellID(aBoard,achannel));
0532 
0533           if (aTile.GetCellID() != -1){
0534             itevent->second.push_back(aTile);
0535           } else {
0536             if(debug ==10) std::cout << "cell " << aBoard << "\t" << achannel << " wasn't active according to mapping file!" << std::endl;
0537           }
0538           tokens->Clear();
0539           delete tokens;
0540         }
0541         // std::cout << itevent->second.size() << "\t" << setup->GetTotalNbChannels() << std::endl;
0542 
0543         if((int)itevent->second.size()==setup->GetTotalNbChannels()/*8*64*/){
0544           //Fill the tree the event is complete and erase from the map
0545           event.SetTimeStamp(tmpTime[TriggerID]/setup->GetNMaxROUnit());
0546           if(debug==1000){
0547             std::cerr<<event.GetTimeStamp()<<std::endl;
0548           }
0549           event.SetEventID(itevent->first);
0550           for(std::vector<Caen>::iterator itv=itevent->second.begin(); itv!=itevent->second.end(); ++itv){
0551             event.AddTile(new Caen(*itv));
0552           }
0553           TdataOut->Fill();
0554           writeEvtCounter++;
0555           tmpEvent.erase(itevent);
0556           tmpTime.erase(TriggerID);
0557         } 
0558       } else {
0559         //This is a new event;
0560         tempEvtCounter++;                                                                   // in crease event counts for monitoring of progress
0561         if ( maxEvents != -1 && tempEvtCounter > maxEvents){                                // abort reading of file at fixed number of events
0562           std::cout << "Manually aborted reading of file at:  " <<  maxEvents << " events" << std::endl;
0563           
0564           RootOutput->cd();
0565           // setup 
0566           RootSetupWrapper rswtmp=RootSetupWrapper(setup);
0567           rsw=rswtmp;
0568           TsetupOut->Fill();
0569           // calib
0570           TcalibOut->Fill();
0571           TcalibOut->Write();
0572           // event data
0573           TdataOut->Fill();
0574           TsetupOut->Write();
0575           TdataOut->Write();
0576           
0577           double effi = 0;
0578           if (tempEvtCounter > 0) 
0579             effi = (double)writeEvtCounter/tempEvtCounter;
0580           std::cout << "Run nr: " << event.GetRunNumber() << "\t"<< "Events written to file: " << writeEvtCounter << "\t effi: "<< effi<< std::endl;
0581           if (writeEvtCounter < 2){
0582             std::cout << "ERROR: Only " << writeEvtCounter << " events were written, something didn't go right, please check your mapping file!" << std::endl; 
0583           }
0584           TH1D* hEvents = new TH1D( "hNEvents","event category; events",  2,-0.5,1.5);
0585           hEvents->SetBinContent(1, tempEvtCounter);
0586           hEvents->SetBinContent(2, writeEvtCounter);
0587           hEvents->Write();
0588                     
0589           break;                         
0590         }
0591 
0592         if (tempEvtCounter%5000 == 0 && debug > 0) std::cout << "Converted " <<  tempEvtCounter << " events" << std::endl;
0593         // if (tempEvtCounter > 1000) continue;
0594         std::vector<Caen> vCaen;
0595         if (aTile.GetCellID() != -1){
0596           vCaen.push_back(aTile);
0597         } else {
0598           if(debug ==10) std::cout << "cell " << aBoard << "\t" << achannel << " wasn't active according to mapping file!" << std::endl;
0599         }
0600         for(int ich=1; ich<NHits; ich++){
0601           aline.ReadLine(ASCIIinput);
0602           tokens=aline.Tokenize(" ");
0603           tokens->SetOwner(true);
0604           Nfields=tokens->GetEntries();
0605           if(Nfields!=4){
0606             std::cout<<"Expecting 4 fields but read "<<Nfields<< " at event " << tempEvtCounter <<std::endl;
0607             return -1;
0608           }
0609           achannel=((TObjString*)tokens->At(1))->String().Atoi();
0610           aTile.SetE(((TObjString*)tokens->At(3))->String().Atoi());//To Test
0611           aTile.SetADCHigh(((TObjString*)tokens->At(3))->String().Atoi());
0612           aTile.SetADCLow (((TObjString*)tokens->At(2))->String().Atoi());
0613           aTile.SetCellID(setup->GetCellID(aBoard,achannel));
0614           if (aTile.GetCellID() != -1){
0615             vCaen.push_back(aTile);
0616           } else {
0617             if(debug ==10) std::cout << "cell " << aBoard << "\t" << achannel << " wasn't active according to mapping file!" << std::endl;
0618           }
0619           tokens->Clear();
0620           delete tokens;
0621         }       
0622         tmpTime[TriggerID]=Time;
0623         tmpEvent[TriggerID]=vCaen;
0624         
0625         // std::cout << vCaen.size() << "\t" << setup->GetTotalNbChannels() << std::endl;
0626         if((int)vCaen.size()==setup->GetTotalNbChannels()/*8*64*/){
0627           itevent=tmpEvent.find(TriggerID);
0628           //Fill the tree the event is complete and erase from the map
0629           event.SetTimeStamp(tmpTime[TriggerID]/setup->GetNMaxROUnit());
0630           if(debug==1000){
0631             std::cerr<<event.GetTimeStamp()<<std::endl;
0632           }
0633           event.SetEventID(itevent->first);
0634           for(std::vector<Caen>::iterator itv=vCaen.begin(); itv!=vCaen.end(); ++itv){
0635             event.AddTile(new Caen(*itv));
0636           }
0637           TdataOut->Fill();
0638           writeEvtCounter++;
0639           tmpEvent.erase(itevent);
0640           tmpTime.erase(TriggerID);
0641         } 
0642       }
0643     } else if (versionCAEN.CompareTo("3.1") == 0){
0644       int Nfields=tokens->GetEntries();
0645       if(((TObjString*)tokens->At(0))->String()=="Tstamp_us") {
0646         tokens->Clear();
0647         delete tokens;
0648         continue;
0649       }
0650       
0651       //================================================================================
0652       // data format example
0653       //   Tstamp_us        TrgID   Brd  Ch       LG       HG
0654       // 4970514.360            0    01  00       49       46 
0655       //                             01  01       49       35 
0656       //================================================================================
0657       
0658       if(Nfields!=6){
0659         std::cout<<"Unexpected number of fields"<<std::endl;
0660         std::cout<<"Expected 6, got: "<<Nfields<<", exit"<<std::endl;
0661         for(int j=0; j<Nfields;j++) std::cout<<j<<"  "<<((TObjString*)tokens->At(j))->String()<<std::endl;
0662         tokens->Clear();
0663         delete tokens;
0664         return -1;
0665       }
0666       
0667       // std::cout << aline.Data() << std::endl;
0668       int TriggerID = ((TObjString*)tokens->At(1))->String().Atoi();
0669       int NHits     = 64;                                           // temporary fix
0670       double Time   = ((TObjString*)tokens->At(0))->String().Atof();
0671       Caen aTile;
0672       int aBoard    =((TObjString*)tokens->At(2))->String().Atoi();
0673       int achannel  =((TObjString*)tokens->At(3))->String().Atoi();
0674       aTile.SetE(((TObjString*)tokens->At(5))->String().Atoi());//To Test
0675       aTile.SetADCHigh(((TObjString*)tokens->At(5))->String().Atoi());
0676       aTile.SetADCLow (((TObjString*)tokens->At(4))->String().Atoi());
0677       tokens->Clear();
0678       delete tokens;
0679       aTile.SetCellID(setup->GetCellID(aBoard,achannel));
0680       itevent=tmpEvent.find(TriggerID);
0681       
0682       if(itevent!=tmpEvent.end()){
0683         tmpTime[TriggerID]+=Time;
0684         if (aTile.GetCellID() != -1){
0685           itevent->second.push_back(aTile);
0686         } else {
0687           if(debug ==10) std::cout << "cell " << aBoard << "\t" << achannel << " wasn't active according to mapping file!" << std::endl;
0688         }
0689         for(int ich=1; ich<NHits; ich++){
0690             aline.ReadLine(ASCIIinput);
0691             // std::cout << aline.Data() << std::endl;
0692             tokens=aline.Tokenize(" ");
0693             tokens->SetOwner(true);
0694             Nfields=tokens->GetEntries();
0695             
0696             if(Nfields!=4){
0697               std::cout<< "Current line :" << aline.Data() << std::endl;
0698               std::cout<<"Expecting 4 fields but read "<<Nfields << " at event " << tempEvtCounter <<std::endl;
0699               return -1;
0700             }
0701             achannel=((TObjString*)tokens->At(1))->String().Atoi();
0702             aTile.SetE(((TObjString*)tokens->At(3))->String().Atoi());//To Test
0703             aTile.SetADCHigh(((TObjString*)tokens->At(3))->String().Atoi());
0704             aTile.SetADCLow (((TObjString*)tokens->At(2))->String().Atoi());
0705             aTile.SetCellID(setup->GetCellID(aBoard,achannel));
0706             
0707             if (aTile.GetCellID() != -1){
0708               itevent->second.push_back(aTile);
0709             } else {
0710               if(debug ==10) std::cout << "cell " << aBoard << "\t" << achannel << " wasn't active according to mapping file!" << std::endl;
0711             }
0712             tokens->Clear();
0713             delete tokens;
0714         }
0715         if((int)itevent->second.size()==setup->GetTotalNbChannels()){
0716           //Fill the tree the event is complete and erase from the map
0717           event.SetTimeStamp(tmpTime[TriggerID]/setup->GetNMaxROUnit());
0718           event.SetEventID(itevent->first);
0719           if(debug==1000){
0720             std::cerr<<event.GetTimeStamp()<<std::endl;
0721           }
0722           for(std::vector<Caen>::iterator itv=itevent->second.begin(); itv!=itevent->second.end(); ++itv){
0723             event.AddTile(new Caen(*itv));
0724           }
0725           TdataOut->Fill();
0726           writeEvtCounter++;
0727           tmpEvent.erase(itevent);
0728           tmpTime.erase(TriggerID);
0729         } else {
0730           std::cout << "didn't fill" << (int)itevent->second.size()  <<  setup->GetTotalNbChannels()<< std::endl; 
0731         }
0732       } else {
0733         //This is a new event;
0734         tempEvtCounter++;                                                                   // in crease event counts for monitoring of progress
0735         if ( maxEvents != -1 && tempEvtCounter > maxEvents){                                // abort reading of file at fixed number of events
0736           std::cout << "Manually aborted reading of file at:  " <<  maxEvents << " events" << std::endl;
0737           
0738           RootOutput->cd();
0739           // setup 
0740           RootSetupWrapper rswtmp=RootSetupWrapper(setup);
0741           rsw=rswtmp;
0742           TsetupOut->Fill();
0743           // calib
0744           TcalibOut->Fill();
0745           TcalibOut->Write();
0746           // event data
0747           TdataOut->Fill();
0748           TsetupOut->Write();
0749           TdataOut->Write();
0750           
0751           double effi = 0;
0752           if (tempEvtCounter > 0) 
0753             effi = (double)writeEvtCounter/tempEvtCounter;
0754           std::cout << "Run nr: " << event.GetRunNumber() << "\t"<< "Events written to file: " << writeEvtCounter << "\t effi: "<< effi<< std::endl;
0755           if (writeEvtCounter < 2){
0756             std::cout << "ERROR: Only " << writeEvtCounter << " events were written, something didn't go right, please check your mapping file!" << std::endl; 
0757           }
0758           TH1D* hEvents = new TH1D( "hNEvents","event category; events",  2,-0.5,1.5);
0759           hEvents->SetBinContent(1, tempEvtCounter);
0760           hEvents->SetBinContent(2, writeEvtCounter);
0761           hEvents->Write();
0762           break;                         
0763         }
0764         if (tempEvtCounter%5000 == 0 && debug > 0) std::cout << "Converted " <<  tempEvtCounter << " events" << std::endl;
0765         std::vector<Caen> vCaen;
0766         
0767         if (aTile.GetCellID() != -1){
0768           vCaen.push_back(aTile);
0769         } else {
0770           if(debug ==10) std::cout << "cell " << aBoard << "\t" << achannel << " wasn't active according to mapping file!" << std::endl;
0771         }
0772         for(int ich=1; ich<NHits; ich++){
0773           aline.ReadLine(ASCIIinput);
0774           // std::cout << aline.Data() << std::endl;
0775           tokens=aline.Tokenize(" ");
0776           tokens->SetOwner(true);
0777           Nfields=tokens->GetEntries();
0778           if(Nfields!=4){
0779             std::cout<< "Current line :" << aline.Data() << std::endl;
0780             std::cout<<"Expecting 4 fields but read "<<Nfields << " at event " << tempEvtCounter <<std::endl;
0781             return -1;
0782           }
0783           achannel=((TObjString*)tokens->At(1))->String().Atoi();
0784           aTile.SetE(((TObjString*)tokens->At(3))->String().Atoi());//To Test
0785           aTile.SetADCHigh(((TObjString*)tokens->At(3))->String().Atoi());
0786           aTile.SetADCLow (((TObjString*)tokens->At(2))->String().Atoi());
0787           aTile.SetCellID(setup->GetCellID(aBoard,achannel));
0788           if (aTile.GetCellID() != -1){
0789             vCaen.push_back(aTile);
0790           } else {
0791             if(debug ==10) std::cout << "cell " << aBoard << "\t" << achannel << " wasn't active according to mapping file!" << std::endl;
0792           }
0793           tokens->Clear();
0794           delete tokens;
0795         }
0796         tmpTime[TriggerID]=Time;
0797         tmpEvent[TriggerID]=vCaen;
0798         
0799         if((int)vCaen.size()==setup->GetTotalNbChannels()/*8*64*/){
0800           itevent=tmpEvent.find(TriggerID);
0801           //Fill the tree the event is complete and erase from the map
0802           event.SetTimeStamp(tmpTime[TriggerID]/setup->GetNMaxROUnit());
0803           if(debug==1000){
0804             std::cerr<<event.GetTimeStamp()<<std::endl;
0805           }
0806           event.SetEventID(itevent->first);
0807           for(std::vector<Caen>::iterator itv=vCaen.begin(); itv!=vCaen.end(); ++itv){
0808             event.AddTile(new Caen(*itv));
0809           }
0810           TdataOut->Fill();
0811           writeEvtCounter++;
0812           tmpEvent.erase(itevent);
0813           tmpTime.erase(TriggerID);
0814         }
0815         
0816       }      
0817     }
0818   } // finished reading in file
0819   // 
0820   
0821   
0822   if (debug > 0) std::cout << "Converted a total of " <<  tempEvtCounter << " events" << std::endl;
0823   
0824   //============================================
0825   // Fill & write all trees to output file 
0826   //============================================
0827   RootOutput->cd();
0828   // setup 
0829   RootSetupWrapper rswtmp=RootSetupWrapper(setup);
0830   rsw=rswtmp;
0831   TsetupOut->Fill();
0832   // calib
0833   TcalibOut->Fill();
0834   TcalibOut->Write();
0835   // event data
0836   TdataOut->Fill();
0837   TsetupOut->Write();
0838   TdataOut->Write();
0839 
0840   double effi = 0;
0841   if (tempEvtCounter > 0) 
0842     effi = (double)writeEvtCounter/tempEvtCounter;
0843   std::cout << "Run nr: " << event.GetRunNumber() << "\t"<< "Events written to file: " << writeEvtCounter << "\t effi: "<< effi<< std::endl;
0844   if (writeEvtCounter < 2){
0845     std::cout << "ERROR: Only " << writeEvtCounter << " events were written, something didn't go right, please check your mapping file!" << std::endl; 
0846   }
0847   TH1D* hEvents = new TH1D( "hNEvents","event category; events",  2,-0.5,1.5);
0848   hEvents->SetBinContent(1, tempEvtCounter);
0849   hEvents->SetBinContent(2, writeEvtCounter);
0850   hEvents->Write();
0851   
0852   
0853   RootOutput->Close();
0854   return true;
0855 } // end Analyses::ConvertASCII2Root()
0856 
0857 // ****************************************************************************
0858 // convert already processed root file from CAEN output to new root format
0859 // ****************************************************************************
0860 bool Analyses::ConvertOldRootFile2Root(void){
0861   //============================================
0862   //Init first
0863   //============================================
0864   // initialize setup
0865   if (MapInputName.CompareTo("")== 0) {
0866       std::cerr << "ERROR: No mapping file has been provided, please make sure you do so! Aborting!" << std::endl;
0867       return false;
0868   }
0869   setup->Initialize(MapInputName.Data(),debug);
0870   // initialize run number file
0871   if (RunListInputName.CompareTo("")== 0) {
0872       std::cerr << "ERROR: No run list file has been provided, please make sure you do so! Aborting!" << std::endl;
0873       return false;
0874   }
0875   std::map<int,RunInfo> ri=readRunInfosFromFile(RunListInputName.Data(),debug,0);
0876   
0877   // Clean up file headers
0878   TObjArray* tok=ASCIIinputName.Tokenize("/");
0879   // get file name
0880   TString file=((TObjString*)tok->At(tok->GetEntries()-1))->String();
0881   delete tok;
0882   tok=file.Tokenize("_");
0883   TString header=((TObjString*)tok->At(0))->String();
0884   delete tok;
0885   
0886   // Get run number from file & find necessary run infos
0887   TString RunString=header(3,header.Sizeof());
0888   std::map<int,RunInfo>::iterator it=ri.find(RunString.Atoi());
0889   //std::cout<<RunString.Atoi()<<"\t"<<it->second.species<<std::endl;
0890   event.SetRunNumber(RunString.Atoi());
0891   event.SetROtype(ReadOut::Type::Caen);
0892   event.SetBeamName(it->second.species);
0893   event.SetBeamID(it->second.pdg);
0894   event.SetBeamEnergy(it->second.energy);
0895   event.SetVop(it->second.vop);
0896   event.SetVov(it->second.vop-it->second.vbr);
0897   event.SetBeamPosX(it->second.posX);
0898   event.SetBeamPosY(it->second.posY);
0899   calib.SetRunNumber(RunString.Atoi());
0900   calib.SetVop(it->second.vop);
0901   calib.SetVov(it->second.vop-it->second.vbr);  
0902   calib.SetBCCalib(false);
0903     // load tree
0904   TChain *const tt_event = new TChain("tree");
0905   if (ASCIIinputName.EndsWith(".root")) {                     // are we loading a single root tree?
0906       std::cout << "loading a single root file" << std::endl;
0907       tt_event->AddFile(ASCIIinputName);
0908       TFile testFile(ASCIIinputName.Data());
0909       if (testFile.IsZombie()){
0910         std::cout << Form("The file %s is not a root file or doesn't exit, please fix the file path", ASCIIinputName.Data()) << std::endl;
0911         return false;
0912       }
0913 
0914   } else {
0915       std::cout << "please try again this isn't a root file" << std::endl;
0916   } 
0917   if(!tt_event){ std::cout << "tree not found... returning!"<< std::endl; return false;}
0918 
0919   // Define tree variables
0920   Long64_t gTrID;
0921   Double_t gTRtimeStamp;
0922   const int gMaxChannels = 64;
0923   Long64_t* gBoard          = new Long64_t[gMaxChannels];
0924   Long64_t* gChannel        = new Long64_t[gMaxChannels];
0925   Long64_t* gLG             = new Long64_t[gMaxChannels];
0926   Long64_t* gHG             = new Long64_t[gMaxChannels];
0927 
0928   if (tt_event->GetBranchStatus("t_stamp") ){
0929     tt_event->SetBranchAddress("trgid",            &gTrID);
0930     tt_event->SetBranchAddress("t_stamp",          &gTRtimeStamp);
0931     tt_event->SetBranchAddress("board",            gBoard);
0932     tt_event->SetBranchAddress("channel",          gChannel);
0933     tt_event->SetBranchAddress("LG",               gLG);
0934     tt_event->SetBranchAddress("HG",               gHG);
0935   }
0936   
0937   Long64_t nEntriesTree                 = tt_event->GetEntries();
0938   std::cout << "Number of events in tree: " << nEntriesTree << std::endl;
0939 
0940   std::map<int,std::vector<Caen> > tmpEvent;
0941   std::map<int,double> tmpTime;
0942   for (Long64_t i=0; i<nEntriesTree;i++) {
0943     // load current event
0944     tt_event->GetEntry(i);  
0945     if (i%5000 == 0 && debug > 0) std::cout << "Converted " <<  i << " events" << std::endl;    
0946     int TriggerID = gTrID;
0947     double Time   = gTRtimeStamp;
0948     std::vector<Caen> vCaen;
0949     
0950     for(Int_t ch=0; ch<gMaxChannels; ch++){   
0951       Caen aTile;
0952       int aBoard      = gBoard[ch];
0953       int achannel    = gChannel[ch];
0954       aTile.SetE(gHG[ch]);//To Test
0955       aTile.SetADCHigh(gHG[ch]);
0956       aTile.SetADCLow (gLG[ch]);
0957       aTile.SetCellID(setup->GetCellID(aBoard,achannel));
0958       if (aTile.GetCellID() != -1){
0959         vCaen.push_back(aTile);
0960       } else {
0961         if(debug ==10) std::cout << "cell " << aBoard << "\t" << achannel << " wasn't active according to mapping file!" << std::endl;
0962       }
0963     }
0964     
0965      if((int)vCaen.size()==setup->GetTotalNbChannels()){
0966       //Fill the tree the event is complete and erase from the map
0967       event.SetTimeStamp(Time);
0968       if(debug==1000){
0969             std::cerr<<event.GetTimeStamp()<<std::endl;
0970       }
0971       event.SetEventID(TriggerID);
0972       for(std::vector<Caen>::iterator itv=vCaen.begin(); itv!=vCaen.end(); ++itv){
0973         event.AddTile(new Caen(*itv));
0974       }
0975       TdataOut->Fill();
0976       vCaen.clear();
0977     }
0978   } // finished reading the file
0979 
0980   // 
0981   if (debug > 0) std::cout << "Converted a total of " <<  nEntriesTree << " events" << std::endl;
0982   
0983   //============================================
0984   // Fill & write all trees to output file 
0985   //============================================
0986   RootOutput->cd();
0987   // setup 
0988   RootSetupWrapper rswtmp=RootSetupWrapper(setup);
0989   rsw=rswtmp;
0990   TsetupOut->Fill();
0991   // calib
0992   TcalibOut->Fill();
0993   TcalibOut->Write();
0994   // event data
0995   TdataOut->Fill();
0996   TsetupOut->Write();
0997   TdataOut->Write();
0998 
0999   RootOutput->Close();
1000   return true;
1001 } // end Analyses::ConvertOldRootFile2Root()
1002 
1003 // ****************************************************************************
1004 // extract pedestral from dedicated data run, no other data in run 
1005 // ****************************************************************************
1006 bool Analyses::GetPedestal(void){
1007   std::cout<<"GetPedestal for maximium "<< setup->GetMaxCellID() << " cells" <<std::endl;
1008     
1009   // Event loop to fill histograms & output tree
1010   std::cout << "N max layers: " << setup->GetNMaxLayer() << "\t columns: " <<  setup->GetNMaxColumn() << "\t row: " << setup->GetNMaxRow() << "\t module: " <<  setup->GetNMaxModule() << std::endl;
1011   if(TcalibIn) TcalibIn->GetEntry(0);
1012   // check whether calib should be overwritten based on external text file
1013   if (OverWriteCalib){
1014     calib.ReadCalibFromTextFile(ExternalCalibFile,debug);
1015   }
1016   
1017   int evts=TdataIn->GetEntries();
1018   TdataIn->GetEntry(0);
1019   int runNr             = event.GetRunNumber();
1020   ReadOut::Type typeRO  = event.GetROtype();
1021   if (maxEvents == -1){
1022     maxEvents = evts;
1023   } else {
1024     std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
1025     std::cout << "ATTENTION: YOU ARE RESETTING THE MAXIMUM NUMBER OF EVENTS TO BE PROCESSED TO: " << maxEvents << ". THIS SHOULD ONLY BE USED FOR TESTING!" << std::endl;
1026     std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
1027   }
1028   std::cout<< "original run numbers calib: "<<calib.GetRunNumber() << "\t" << calib.GetRunNumberPed() << "\t" << calib.GetRunNumberMip() << std::endl;
1029   calib.SetRunNumberPed(runNr);
1030   calib.SetBeginRunTimePed(event.GetBeginRunTimeAlt());
1031   std::cout<< "reset run numbers calib: "<< calib.GetRunNumber() << "\t" << calib.GetRunNumberPed() << "\t" << calib.GetRunNumberMip() << std::endl;
1032 
1033   // Get run info object
1034   std::map<int,RunInfo> ri=readRunInfosFromFile(RunListInputName.Data(),debug,0);
1035   std::map<int,RunInfo>::iterator it=ri.find(runNr);
1036   // Find detector config 
1037   DetConf::Type detConf = setup->GetDetectorConfig();
1038   if (it->second.detector == "FoCal-H")
1039     detConf = DetConf::Type::FocalH; 
1040 
1041   
1042   int maxChannelPerLayer          = (setup->GetNMaxColumn()+1)*(setup->GetNMaxRow()+1)*(setup->GetNMaxModule()+1);
1043   int maxChannelPerLayerSingleMod = (setup->GetNMaxColumn()+1)*(setup->GetNMaxRow()+1);
1044   ROOT::Math::MinimizerOptions::SetDefaultMinimizer("Minuit2", "Migrad");  
1045   
1046   // create HG and LG histo's per channel
1047   TH2D* hspectraHGvsCellID      = new TH2D( "hspectraHG_vsCellID","ADC spectrum High Gain vs CellID; cell ID; ADC_{HG} (arb. units) ",
1048                                             setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 4000,0,4000);
1049   hspectraHGvsCellID->SetDirectory(0);
1050   TH2D* hspectraLGvsCellID      = new TH2D( "hspectraLG_vsCellID","ADC spectrum Low Gain vs CellID; cell ID; ADC_{LG} (arb. units)  ",
1051                                             setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 4000,0,4000);
1052   hspectraLGvsCellID->SetDirectory(0);
1053   TH1D* hMeanPedHGvsCellID      = new TH1D( "hMeanPedHG_vsCellID","mean Ped High Gain vs CellID ; cell ID; #mu_{noise, HG} (arb. units) ",
1054                                             setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5);
1055   hMeanPedHGvsCellID->SetDirectory(0);
1056   TH2D* hspectraHGMeanVsLayer   = new TH2D( "hspectraHGMeanVsLayer","Mean Ped High Gain vs CellID; layer; brd channel; #mu_{Ped HG} (arb. units) ",
1057                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
1058   hspectraHGMeanVsLayer->SetDirectory(0);
1059   TH2D* hspectraHGSigmaVsLayer  = new TH2D( "hspectraHGSigmaVsLayer","Mean Ped High Gain vs CellID; layer; brd channel; #sigma_{Ped HG} (arb. units) ",
1060                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
1061   hspectraHGSigmaVsLayer->SetDirectory(0);
1062   TH1D* hMeanPedLGvsCellID      = new TH1D( "hMeanPedLG_vsCellID","mean Ped Low Gain vs CellID ; cell ID; #mu_{noise, LG} (arb. units) ",
1063                                             setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5);
1064   hMeanPedLGvsCellID->SetDirectory(0);
1065   TH2D* hspectraLGMeanVsLayer   = new TH2D( "hspectraLGMeanVsLayer","Mean Ped Low Gain vs CellID; layer; brd channel; #mu_{PED LG} (arb. units) ",
1066                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
1067   hspectraLGMeanVsLayer->SetDirectory(0);
1068   TH2D* hspectraLGSigmaVsLayer  = new TH2D( "hspectraLGSigmaVsLayer","Mean Ped Low Gain vs CellID; layer; brd channel; #sigma_{Ped LG} (arb. units)",
1069                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
1070   hspectraLGSigmaVsLayer->SetDirectory(0);
1071 
1072   TH2D* hPedMeanHGvsLG          = new TH2D( "hPedMeanHGvsLG","Mean Ped High Gain vs Low Gain; #mu_{noise, HG} (arb. units); #mu_{noise, LG} (arb. units)", 500, 0, 250, 500, 0, 250);
1073   hPedMeanHGvsLG->SetDirectory(0);
1074   
1075   if (typeRO == ReadOut::Type::Caen) 
1076     std::cout << "Read-out type CAEN" << std::endl;
1077   else{
1078     std::cout << "Read-out type HGCROC" << std::endl;
1079     hPedMeanHGvsLG->GetYaxis()->SetTitle("#mu_{noise, wave} (arb. units)");
1080     hPedMeanHGvsLG->GetXaxis()->SetTitle("#mu_{noise, 0th sample} (arb. units)");
1081     hPedMeanHGvsLG->SetTitle("Pedestal Eval 0th sample vs wave");
1082     hspectraLGvsCellID->SetYTitle("ADC (arb. units) all samples");
1083   }
1084 
1085   
1086   std::map<int,TileSpectra> hSpectra;
1087   std::map<int, TileSpectra>::iterator ithSpectra;  
1088 
1089   // create output file for histos
1090   CreateOutputRootHistFile();
1091   // entering histoOutput file
1092   RootOutputHist->mkdir("IndividualCells");
1093   RootOutputHist->cd("IndividualCells");
1094 
1095   RootOutput->cd();
1096   
1097   
1098   for(int i=0; i<evts && i < maxEvents; i++){
1099     TdataIn->GetEntry(i);
1100     if (i%5000 == 0&& i > 0 && debug > 0) std::cout << "Reading " <<  i << "/" << evts << " events"<< std::endl;
1101     for(int j=0; j<event.GetNTiles(); j++){
1102       if (typeRO == ReadOut::Type::Caen) {
1103         Caen* aTile=(Caen*)event.GetTile(j);
1104         if (i == 0 && debug > 2){
1105           std::cout << ((TString)setup->DecodeCellID(aTile->GetCellID())).Data() << std::endl;
1106         }
1107         ithSpectra=hSpectra.find(aTile->GetCellID());
1108         if(ithSpectra!=hSpectra.end()){
1109           ithSpectra->second.FillCAEN(aTile->GetADCLow(),aTile->GetADCHigh());
1110         } else {
1111           RootOutputHist->cd("IndividualCells");
1112           hSpectra[aTile->GetCellID()]=TileSpectra("1stExtraction",aTile->GetCellID(),calib.GetTileCalib(aTile->GetCellID()), event.GetROtype(), debug);
1113           hSpectra[aTile->GetCellID()].FillCAEN(aTile->GetADCLow(),aTile->GetADCHigh());
1114           RootOutput->cd();
1115         }
1116         hspectraHGvsCellID->Fill(aTile->GetCellID(), aTile->GetADCHigh());
1117         hspectraLGvsCellID->Fill(aTile->GetCellID(), aTile->GetADCLow());
1118       }
1119       else if (typeRO == ReadOut::Type::Hgcroc){ // Process HGCROC Data
1120         Hgcroc* aTile=(Hgcroc*)event.GetTile(j);
1121         if (i == 0 && debug == 3 ){
1122           std::cout << ((TString)setup->DecodeCellID(aTile->GetCellID())).Data() << std::endl;
1123         }
1124         // if (debug > 3 && aTile->GetCellID() == 2 ){
1125           // std::bitset<10> pedBit(aTile->GetPedestal());
1126           // std::bitset<5> pedBit5bit(aTile->GetPedestal());
1127           // std::cout << aTile->GetPedestal() << "\t" << pedBit << "\t" << pedBit5bit << std::endl;
1128         // }
1129         
1130         // single tile debug info print
1131         if (debug > 10 ){
1132           aTile->PrintWaveFormDebugInfo(aTile->GetPedestal(), aTile->GetPedestal(), 1);
1133         }
1134         
1135         ithSpectra=hSpectra.find(aTile->GetCellID());
1136         if(ithSpectra!=hSpectra.end()){
1137           // Get the tile spectra if it already exists
1138           ithSpectra->second.FillExtHGCROCPed(aTile->GetADCWaveform(),aTile->GetPedestal());
1139         } else {
1140           // Make a new tile spectra if it isn't found
1141           RootOutputHist->cd("IndividualCells");
1142           hSpectra[aTile->GetCellID()]= TileSpectra("1stExtraction", 4, aTile->GetCellID(), calib.GetTileCalib(aTile->GetCellID()), event.GetROtype(), debug);
1143           hSpectra[aTile->GetCellID()].FillExtHGCROCPed(aTile->GetADCWaveform(),aTile->GetPedestal());
1144           RootOutput->cd();
1145         }
1146         // std::cout << "Cell ID: " << aTile->GetCellID() << ", Tile E: " << aTile->GetPedestal() << std::endl;
1147         hspectraHGvsCellID->Fill(aTile->GetCellID(), aTile->GetPedestal());
1148         for (int k = 0; k < (int)(aTile->GetADCWaveform()).size(); k++ ){
1149           hspectraLGvsCellID->Fill(aTile->GetCellID(),aTile->GetADCWaveform().at(k));
1150         }
1151       }
1152     }
1153     RootOutput->cd();
1154     TdataOut->Fill();
1155   }
1156   
1157   //==================================================================================
1158   // fit pedestal
1159   //==================================================================================
1160   double* parameters=new double[8];
1161   bool isGood  = true;
1162   bool isGood2 = true;
1163 
1164   for(ithSpectra=hSpectra.begin(); ithSpectra!=hSpectra.end(); ++ithSpectra){
1165     if ( debug > 2) std::cout << ((TString)setup->DecodeCellID(ithSpectra->second.GetCellID())).Data() << std::endl;
1166     // std::cerr << "Fitting noise for cell ID: " << ithSpectra->second.GetCellID() << std::endl;
1167     isGood=ithSpectra->second.FitNoise(parameters, yearData, false);
1168     if (!isGood && !(typeRO == ReadOut::Type::Hgcroc)) {
1169       std::cerr << "Noise fit failed for cell ID: " << ithSpectra->second.GetCellID() << std::endl;
1170       continue;
1171     }
1172 
1173     if (typeRO == ReadOut::Type::Hgcroc){
1174       isGood2=ithSpectra->second.FitPedConstWave(debug);
1175 
1176       if (!isGood && !isGood2) {
1177         std::cerr << "both noise fits failed " << ithSpectra->second.GetCellID() << std::endl;
1178         continue;
1179       } else {
1180         if (!isGood2) std::cerr << "Noise-wave form fit failed for cell ID: " << ithSpectra->second.GetCellID() << std::endl;
1181         if (!isGood){
1182           std::cerr << "1D Noise fit failed for cell ID: " << ithSpectra->second.GetCellID() << std::endl;
1183           parameters[4] = -1;
1184           parameters[5] = -1;
1185           parameters[6] = -1;
1186           parameters[7] = -1;
1187         }
1188       }
1189     }
1190     int cellID    = ithSpectra->second.GetCellID();
1191     int layer     = setup->GetLayer(cellID);
1192     int chInLayer = setup->GetChannelInLayerFull(cellID, detConf);
1193     
1194     
1195     
1196     hMeanPedHGvsCellID->SetBinContent(hMeanPedHGvsCellID->FindBin(cellID), parameters[4]);
1197     hMeanPedHGvsCellID->SetBinError  (hMeanPedHGvsCellID->FindBin(cellID), parameters[6]);
1198     hspectraHGMeanVsLayer->SetBinContent(hspectraHGMeanVsLayer->FindBin(layer,chInLayer), parameters[4]);
1199     hspectraHGMeanVsLayer->SetBinError(hspectraHGMeanVsLayer->FindBin(layer,chInLayer), parameters[5]);
1200     hspectraHGSigmaVsLayer->SetBinContent(hspectraHGSigmaVsLayer->FindBin(layer,chInLayer), parameters[6]);
1201     hspectraHGSigmaVsLayer->SetBinError(hspectraHGSigmaVsLayer->FindBin(layer,chInLayer), parameters[7]);
1202     if (typeRO == ReadOut::Type::Caen){
1203       hMeanPedLGvsCellID->SetBinContent(hMeanPedLGvsCellID->FindBin(cellID), parameters[0]);
1204       hMeanPedLGvsCellID->SetBinError  (hMeanPedLGvsCellID->FindBin(cellID), parameters[2]);
1205       hspectraLGMeanVsLayer->SetBinContent(hspectraLGMeanVsLayer->FindBin(layer,chInLayer), parameters[0]);
1206       hspectraLGMeanVsLayer->SetBinError(hspectraLGMeanVsLayer->FindBin(layer,chInLayer), parameters[1]);
1207       hspectraLGSigmaVsLayer->SetBinContent(hspectraLGSigmaVsLayer->FindBin(layer,chInLayer), parameters[2]);
1208       hspectraLGSigmaVsLayer->SetBinError(hspectraLGSigmaVsLayer->FindBin(layer,chInLayer), parameters[3]);
1209       
1210       hPedMeanHGvsLG->Fill(parameters[4],parameters[0]);
1211     } else if (isGood2 && typeRO == ReadOut::Type::Hgcroc){
1212       hMeanPedLGvsCellID->SetBinContent(hMeanPedLGvsCellID->FindBin(cellID), calib.GetPedestalMeanL(cellID));
1213       hMeanPedLGvsCellID->SetBinError  (hMeanPedLGvsCellID->FindBin(cellID), calib.GetPedestalSigL(cellID));
1214       hspectraLGMeanVsLayer->SetBinContent(hspectraLGMeanVsLayer->FindBin(layer,chInLayer), calib.GetPedestalMeanL(cellID));
1215       hspectraLGMeanVsLayer->SetBinError(hspectraLGMeanVsLayer->FindBin(layer,chInLayer), calib.GetPedestalSigL(cellID));
1216       
1217       hPedMeanHGvsLG->Fill(parameters[4],calib.GetPedestalMeanL(cellID));
1218     }
1219   }
1220 
1221   //==================================================================================
1222   // Write Root Files with pure data tree & histo output
1223   //==================================================================================
1224   //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1225   // Write tree output
1226   //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1227   RootOutput->cd();
1228   // write output tree (copy of raw data)
1229   TdataOut->Write();
1230   // write setup tree (copy of raw data)
1231   TsetupIn->CloneTree()->Write();
1232   if (IsCalibSaveToFile()){
1233     TString fileCalibPrint = RootOutputName;
1234     fileCalibPrint         = fileCalibPrint.ReplaceAll(".root","_calib.txt");
1235     calib.PrintCalibToFile(fileCalibPrint);
1236   }
1237   // fill calib tree & write it  
1238   TcalibOut->Fill();
1239   TcalibOut->Write();
1240   // close open root output file
1241   RootOutput->Write();
1242   RootOutput->Close();
1243   
1244   //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1245   // Write histoOutput file
1246   //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1247   RootOutputHist->cd("IndividualCells");
1248   for(ithSpectra=hSpectra.begin(); ithSpectra!=hSpectra.end(); ++ithSpectra){
1249     ithSpectra->second.Write(true);
1250   }
1251   RootOutputHist->cd();
1252   hspectraHGvsCellID->Write();
1253   hMeanPedHGvsCellID->Write();
1254   hspectraHGMeanVsLayer->Write();
1255   hspectraHGSigmaVsLayer->Write();
1256   hPedMeanHGvsLG->Write();
1257   if (typeRO == ReadOut::Type::Caen){
1258     hspectraLGvsCellID->Write();
1259     hMeanPedLGvsCellID->Write();
1260     hspectraLGMeanVsLayer->Write();
1261     hspectraLGSigmaVsLayer->Write();
1262   } else {
1263     hspectraLGvsCellID->Write("hAllADC_vsCellID");
1264     hMeanPedLGvsCellID->GetYaxis()->SetTitle("#mu_{Ped ADC, wave} (arb. units)");
1265     hMeanPedLGvsCellID->Write("hMeanPedWave_vsCellID");
1266     hspectraLGMeanVsLayer->GetZaxis()->SetTitle("#mu_{Ped ADC, wave} (arb. units)");
1267     hspectraLGMeanVsLayer->Write("hspectraPedWaveMeanVsLayer");
1268   }
1269   // close open root hist output file
1270   RootOutputHist->Write();
1271   RootOutputHist->Close();
1272   // close open input root file
1273   RootInput->Close();
1274 
1275   
1276   //==================================================================================
1277   // Plotting 
1278   //==================================================================================  
1279   // create directory for plot output
1280   TString outputDirPlots = GetPlotOutputDir();
1281   gSystem->Exec("mkdir -p "+outputDirPlots);
1282   // general variable setup 
1283   double averagePedMeanHG = calib.GetAveragePedestalMeanHigh();
1284   double averagePedSigHG  = calib.GetAveragePedestalSigHigh();
1285   double averagePedMeanLG = calib.GetAveragePedestalMeanLow();
1286   double averagePedSigLG  = calib.GetAveragePedestalSigLow();
1287 
1288   //**********************************************************************
1289   // Create canvases for channel overview plotting
1290   //**********************************************************************
1291   Double_t textSizeRel = 0.035;
1292   StyleSettingsBasics("pdf");
1293   SetPlotStyle();
1294   
1295   TCanvas* canvas2DCorr = new TCanvas("canvasCorrPlots","",0,0,1450,1200);  // gives the page size
1296   DefaultCanvasSettings( canvas2DCorr, 0.08, 0.13, 0.045, 0.07);
1297   canvas2DCorr->SetLogz();
1298   
1299   // overview all spectra CAEN HG / HGCROC 0th sample ADC 
1300   if (typeRO == ReadOut::Type::Hgcroc) hspectraHGvsCellID->GetYaxis()->SetTitle("Pedestal ADC (arb units)");
1301   PlotSimple2D( canvas2DCorr, hspectraHGvsCellID, 300, setup->GetMaxCellID()+1, textSizeRel, Form("%s/HG_Noise.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 5, kFALSE, "colz", true);
1302   
1303   // overview all spectra CAEN LG / HGCROC all sample ADC 
1304   if (typeRO == ReadOut::Type::Caen){
1305     PlotSimple2D( canvas2DCorr, hspectraLGvsCellID, 300, setup->GetMaxCellID()+1, textSizeRel, Form("%s/LG_Noise.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 5, kFALSE, "colz", true);
1306   } else {
1307     PlotSimple2D( canvas2DCorr, hspectraLGvsCellID, 300, setup->GetMaxCellID()+1, textSizeRel, Form("%s/AllSampleADC.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 5, kFALSE, "colz", true);
1308   }
1309   
1310   canvas2DCorr->SetLogz(0);
1311   // overview all pedestal means CAEN HG / HGCROC 0th sample ADC 
1312   PlotSimple2D( canvas2DCorr, hspectraHGMeanVsLayer, -10000, -10000, textSizeRel, Form("%s/HG_NoiseMean.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 5, kFALSE, "colz", true, Form("#LT#mu_{HG}#GT = %2.2f", averagePedMeanHG));
1313   // overview all pedestal width CAEN HG / HGCROC 0th sample ADC 
1314   PlotSimple2D( canvas2DCorr, hspectraHGSigmaVsLayer,-10000, -10000, textSizeRel, Form("%s/HG_NoiseSigma.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 5,  kFALSE, "colz", true, Form("#LT#sigma_{HG}#GT = %2.2f", averagePedSigHG));
1315   // overview all correlation different pedestal means
1316   PlotSimple2D( canvas2DCorr, hPedMeanHGvsLG, -10000, -10000, textSizeRel, Form("%s/PedMean_HG_LG.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 5, kFALSE, "colz", true, "");
1317 
1318   if (typeRO == ReadOut::Type::Caen){
1319     // overview all pedestal means CAEN LG 
1320     PlotSimple2D( canvas2DCorr, hspectraLGMeanVsLayer, -10000, -10000, textSizeRel, Form("%s/LG_NoiseMean.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 5, kFALSE, "colz", true, Form("#LT#mu_{LG}#GT = %2.2f", averagePedMeanLG));
1321     // overview all pedestal width CAEN LG 
1322     PlotSimple2D( canvas2DCorr, hspectraLGSigmaVsLayer, -10000, -10000, textSizeRel, Form("%s/LG_NoiseSigma.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 5, kFALSE, "colz", true, Form("#LT#sigma_{LG}#GT = %2.2f", averagePedSigLG));
1323   } else {
1324     // overview all pedestal means HGCROC waveform fit
1325     PlotSimple2D( canvas2DCorr, hspectraLGMeanVsLayer, -10000, -10000, textSizeRel, Form("%s/PedWave_NoiseMean.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 5, kFALSE, "colz", true, Form("#LT#mu_{wave}#GT = %2.2f", averagePedMeanLG));
1326   }
1327   
1328   // *********************************************************************************************************
1329   // Set up ranges for multipanel plotting
1330   // *********************************************************************************************************
1331   Int_t textSizePixel = 30;
1332   double minADCRange = 0; 
1333   double maxADCRange = 275;
1334   if( typeRO == ReadOut::Type::Hgcroc ){
1335     minADCRange = 50; 
1336     maxADCRange = 150;
1337   }
1338   //***********************************************************************************************************
1339   // do single layer plotting
1340   //***********************************************************************************************************
1341   MultiCanvas panelPlot(detConf, "Pedestal");
1342   bool init1D = panelPlot.Initialize(1);
1343   MultiCanvas panelPlot2D(detConf, "Pedestal2D");
1344   bool init2D = panelPlot2D.Initialize(2);
1345   
1346   panelPlot.PlotNoiseWithFits(hSpectra, 0, minADCRange, maxADCRange, 1.2, 
1347                               Form("%s/Noise_HG",outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer );
1348   if (typeRO == ReadOut::Type::Caen){
1349     panelPlot.PlotNoiseWithFits(hSpectra, 1, minADCRange, maxADCRange, 1.2, 
1350                               Form("%s/Noise_LG",outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);    
1351   } else if (typeRO == ReadOut::Type::Hgcroc){
1352     panelPlot.PlotNoiseWithFits(hSpectra, 1, minADCRange, maxADCRange, 1.2, 
1353                               Form("%s/AllSampleADC",outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer );
1354     panelPlot2D.PlotCorr2DLayer(hSpectra, 1, 0, it->second.samples+1, 0, 300, 
1355                                 Form("%s/Waveform",outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, 0, -1, skipPlotLayer );
1356   }
1357   
1358   return true;
1359 } // end Analyses::GetPedestal()
1360 
1361 // ****************************************************************************
1362 // extract toA offset from data runs
1363 // ideally a run with lots of amplitude should be used (i.e. hadrons)
1364 // ****************************************************************************
1365 bool Analyses::EvaluateHGCROCToAPhases(void){
1366   
1367   std::cout<<"Evaluate HGCROC ToA Phases"<<std::endl;
1368   int evts=TdataIn->GetEntries();
1369 
1370   // initialize calib
1371   TcalibIn->GetEntry(0);        // use first calib object in list (there might be more)
1372   
1373   // initialize lookup-table run list
1374   std::map<int,RunInfo> ri=readRunInfosFromFile(RunListInputName.Data(),debug,0);
1375   
1376   // intialize run infos & reset calib object to correct run number
1377   TdataIn->GetEntry(0);     // use first event to get infos
1378   Int_t runNr = event.GetRunNumber();
1379   ReadOut::Type typeRO  = event.GetROtype();
1380   std::cout<< "original run numbers calib: "<<calib.GetRunNumber() << "\t" << calib.GetRunNumberPed() << "\t" << calib.GetRunNumberMip() << std::endl;
1381   calib.SetRunNumber(runNr);
1382   calib.SetBeginRunTime(event.GetBeginRunTimeAlt());
1383   std::cout<< "reset run numbers calib: "<< calib.GetRunNumber() << "\t" << calib.GetRunNumberPed() << "\t" << calib.GetRunNumberMip() << std::endl;
1384   
1385   // Get run info object
1386   std::map<int,RunInfo>::iterator it=ri.find(runNr);
1387   
1388   // No need to event attempt to run on CAEN data
1389   if (typeRO == ReadOut::Type::Caen){
1390     std::cout <<"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
1391     std::cout << "ATTENTION this function isn't meant to run on data collected with the CAEN DT5202!\n ABORTING!" << std::endl;
1392     std::cout <<"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
1393     return false; 
1394   }
1395   
1396   // check whether calib should be overwritten based on external text file
1397   if (OverWriteCalib){
1398     calib.ReadCalibFromTextFile(ExternalCalibFile,debug);
1399   }  
1400   
1401   Int_t minNSampleToA = 2;
1402   //==================================================================================
1403   // create additional output hist
1404   //==================================================================================
1405   CreateOutputRootHistFile();
1406   RootOutputHist->cd();
1407 
1408   TH2D* hSampleTOAVsCellID       = new TH2D( "hSampleTOAvsCellID","#sample ToA; cell ID; #sample TOA",
1409                                             setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, it->second.samples,0,it->second.samples);
1410   hSampleTOAVsCellID->SetDirectory(0);
1411 
1412   TH2D* hTOANsVsCellID       = new TH2D( "hTOANsVsCellID","ToA (ns); cell ID; ToA (ns)",
1413                                             setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 500,-250,0);
1414   hTOANsVsCellID->SetDirectory(0);
1415   TH2D* hSampleMaxADCVsCellID       = new TH2D( "hSampleMaxADCvsCellID","#sample ToA; cell ID; #sample Max ADC",
1416                                             setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, it->second.samples,0,it->second.samples);
1417   hSampleMaxADCVsCellID->SetDirectory(0);
1418 
1419   TH1D* hSampleTOA               = new TH1D( "hSampleTOA","#sample ToA; #sample TOA",
1420                                               it->second.samples,0,it->second.samples);
1421   hSampleTOA->SetDirectory(0);
1422   TH1D* hSampleMaxADC            = new TH1D( "hSampleMaxADC","#sample ToA; #sample maxADC",
1423                                               it->second.samples,0,it->second.samples);
1424   hSampleMaxADC->SetDirectory(0);
1425   TH1D* hSampleAboveTh           = new TH1D( "hSampleAboveTh","#sample ToA; #sample above th",
1426                                               it->second.samples,0,it->second.samples);
1427   hSampleAboveTh->SetDirectory(0);
1428   TH1D* hSampleDiff              = new TH1D( "hSampleDiff","#sample ToA-#sample Max ADC; #sample maxADC-#sampleMax ADC",
1429                                               8,-0.5,7.5);
1430   hSampleDiff->SetDirectory(0);
1431   TH1D* hSampleDiffMin           = new TH1D( "hSampleDiffMin","#sample ToA-#sample above th; #sample maxADC-#sample  above th",
1432                                               8,-0.5,7.5);
1433   hSampleDiffMin->SetDirectory(0);
1434   
1435   TH2D* h2DToAvsADC[setup->GetNMaxROUnit()+1][2][5];
1436   TProfile* hToAvsADC[setup->GetNMaxROUnit()+1][2][5];
1437   TH2D* h2DWaveFormHalfAsic[setup->GetNMaxROUnit()+1][2][5];
1438   TProfile* hWaveFormHalfAsic[setup->GetNMaxROUnit()+1][2][5];
1439   TH2D* h2DToAvsnSample[setup->GetNMaxROUnit()+1][2];
1440 
1441   TH2D* h2DWaveFormHalfAsicAll[setup->GetNMaxROUnit()+1][2];
1442   TProfile* hWaveFormHalfAsicAll[setup->GetNMaxROUnit()+1][2];
1443   
1444   for (Int_t ro = 0; ro < setup->GetNMaxROUnit()+1; ro++){
1445     for (int h = 0; h< 2; h++){
1446       h2DToAvsnSample[ro][h]    = new TH2D(Form("h2DTOASample_Asic_%d_Half_%d",ro,h),
1447                                             Form("Sample vs TOA %d %d; TOA (arb. units); #sample",ro,h), 1024/8,0,1024,it->second.samples,0,it->second.samples);
1448       hWaveFormHalfAsicAll[ro][h]    = new TProfile(Form("WaveForm_Asic_%d_Half_%d",ro,h),
1449                                         Form("ADC-TOA correlation %d %d;  t (ns) ; ADC (arb. units)",ro,h),550,-50,500);
1450       h2DWaveFormHalfAsicAll[ro][h]  = new TH2D(Form("h2DWaveForm_Asic_%d_Half_%d",ro,h),
1451                                         Form("2D ADC vs TOA %d %d;  t (ns) ; ADC (arb. units)",ro,h), 
1452                                         550,-50,500, 1044/4, -20, 1024);
1453       h2DToAvsnSample[ro][h]->SetDirectory(0);
1454       hWaveFormHalfAsicAll[ro][h]->SetDirectory(0);
1455       h2DWaveFormHalfAsicAll[ro][h]->SetDirectory(0);
1456       
1457       for (int p = 0; p< 5; p++){
1458         hToAvsADC[ro][h][p]    = new TProfile(Form("ADCTOA_Asic_%d_Half_%d_NToASample_%d",ro,h,minNSampleToA+p),
1459                                           Form("ADC-TOA correlation %d %d %d; TOA (arb. units); ADC (arb. units)",ro,h,minNSampleToA+p),1024/4,0,1024, "");
1460         h2DToAvsADC[ro][h][p]  = new TH2D(Form("h2DADCTOA_Asic_%d_Half_%d_NToASample_%d",ro,h,minNSampleToA+p),
1461                                       Form("2D ADC vs TOA %d %d %d; TOA (arb. units); ADC (arb. units)",ro,h, minNSampleToA+p), 1024/4,0,1024,1124/4,-100,1024);
1462         
1463         hWaveFormHalfAsic[ro][h][p]    = new TProfile(Form("WaveForm_Asic_%d_Half_%d_NToASample_%d",ro,h,minNSampleToA+p),
1464                                           Form("ADC-TOA correlation %d %d %d;  t (ns) ; ADC (arb. units)",ro,h,minNSampleToA+p),550,-50,500);
1465         h2DWaveFormHalfAsic[ro][h][p]  = new TH2D(Form("h2DWaveForm_Asic_%d_Half_%d_NToASample_%d",ro,h,minNSampleToA+p),
1466                                           Form("2D ADC vs TOA %d %d %d;  t (ns) ; ADC (arb. units)",ro,h,minNSampleToA+p), 
1467                                           550,-50,500, 1044/4, -20, 1024);
1468         hToAvsADC[ro][h][p]->SetDirectory(0);
1469         h2DToAvsADC[ro][h][p]->SetDirectory(0);
1470         hWaveFormHalfAsic[ro][h][p]->SetDirectory(0);
1471         h2DWaveFormHalfAsic[ro][h][p]->SetDirectory(0);
1472       }
1473     }
1474   }
1475   
1476   ROOT::Math::MinimizerOptions::SetDefaultMinimizer("Minuit2", "Migrad");  
1477   if (maxEvents == -1){
1478     maxEvents = evts;
1479   } else {
1480     std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
1481     std::cout << "ATTENTION: YOU ARE RESETTING THE MAXIMUM NUMBER OF EVENTS TO BE PROCESSED TO: " << maxEvents << ". THIS SHOULD ONLY BE USED FOR TESTING!" << std::endl;
1482     std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
1483   }
1484   
1485   //==================================================================================
1486   // setup waveform builder for HGCROC data
1487   //==================================================================================
1488   waveform_fit_base *waveform_builder = nullptr;
1489   waveform_builder = new max_sample_fit();
1490   //==================================================================================
1491   // process events from tree
1492   //==================================================================================
1493   for(int i=0; i<evts && i < maxEvents ; i++){
1494     if (i%5000 == 0&& i > 0 && debug > 0) std::cout << "Reading " <<  i << "/" << evts << " events"<< std::endl;
1495     TdataIn->GetEntry(i); 
1496     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1497     // process tiles in event
1498     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++    
1499     for(int j=0; j<event.GetNTiles(); j++){
1500       //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
1501       // histo filling for HGCROC specific things & resetting of ped
1502       //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++        
1503       Hgcroc* aTile=(Hgcroc*)event.GetTile(j);
1504       int cellID = aTile->GetCellID();
1505       
1506       // get pedestal values from calib object
1507       double ped    = calib.GetPedestalMeanL(cellID);
1508       double pedErr = calib.GetPedestalSigL(cellID);
1509       if (ped == -1000){
1510         ped     = calib.GetPedestalMeanH(cellID);
1511         pedErr  = calib.GetPedestalSigH(cellID);
1512         if (ped == -1000){
1513           ped     = aTile->GetPedestal();
1514           pedErr  = 5;
1515         }
1516       }
1517       // reevaluate waveform
1518       waveform_builder->set_waveform(aTile->GetADCWaveform());
1519       waveform_builder->fit_with_average_ped(ped);
1520       aTile->SetIntegratedADC(waveform_builder->get_E());
1521       aTile->SetPedestal(waveform_builder->get_pedestal());
1522       
1523       // obtain integrated tile quantities for histo filling
1524       double adc      = aTile->GetIntegratedADC();
1525       double toa      = aTile->GetRawTOA();
1526       bool hasTOA     = false;
1527       // check if we have a toa
1528       if (toa > 0)
1529         hasTOA        = true;
1530 
1531       Int_t nSampTOA  = aTile->GetFirstTOASample();        
1532       double toaNs      = (double)aTile->GetLinearizedRawTOA()*aTile->GetTOATimeResolution();
1533       
1534       Int_t nMaxADC   = aTile->GetMaxSampleADC();
1535       Int_t nADCFirst = aTile->GetFirstSampleAboveTh();
1536       Int_t nDiffFirstT= nSampTOA-nADCFirst;
1537       Int_t nDiffFirstM= nMaxADC-nADCFirst;
1538       Int_t nDiffMaxT  = nMaxADC-nSampTOA;
1539       Int_t nOffEmpty  = 2;
1540       
1541       if (hasTOA){
1542         hSampleTOA->Fill(nSampTOA);
1543         hSampleTOAVsCellID->Fill(cellID,nSampTOA);
1544       }
1545       if (adc > ped+2*pedErr){
1546         hSampleMaxADC->Fill(nMaxADC);
1547         hSampleMaxADCVsCellID->Fill(cellID,nMaxADC);
1548         hSampleAboveTh->Fill(nADCFirst);
1549       }
1550       
1551       if (hasTOA && adc > ped+2*pedErr){
1552         hSampleDiff->Fill(nSampTOA-nMaxADC);
1553         hSampleDiffMin->Fill(nSampTOA-nADCFirst);
1554       }
1555       
1556       Int_t asic      = setup->GetROunit(cellID);
1557       Int_t roCh      = setup->GetROchannel(cellID);
1558 
1559       if (hasTOA){
1560         hTOANsVsCellID->Fill(cellID,toaNs);
1561         
1562         // fill overview hists for half asics
1563         h2DToAvsnSample[asic][int(roCh/36)]->Fill(toa, nSampTOA);
1564         for (int k = 0; k < (int)(aTile->GetADCWaveform()).size(); k++ ){
1565           double timetemp = ((k+nOffEmpty)*1024 + (double)aTile->GetLinearizedRawTOA())*aTile->GetTOATimeResolution() ;
1566           hWaveFormHalfAsicAll[asic][int(roCh/36)]->Fill(timetemp,(aTile->GetADCWaveform()).at(k)-ped);
1567           h2DWaveFormHalfAsicAll[asic][int(roCh/36)]->Fill(timetemp,(aTile->GetADCWaveform()).at(k)-ped);
1568         }          
1569         
1570         int binSample = nSampTOA-minNSampleToA;
1571         if (!(nSampTOA > minNSampleToA-1 && nSampTOA < minNSampleToA+5)) continue;
1572         hToAvsADC[asic][int(roCh/36)][binSample]->Fill(toa, adc);
1573         h2DToAvsADC[asic][int(roCh/36)][binSample]->Fill(toa, adc);
1574         for (int k = 0; k < (int)(aTile->GetADCWaveform()).size(); k++ ){
1575           double timetemp = ((k+nOffEmpty)*1024 + (double)aTile->GetLinearizedRawTOA())*aTile->GetTOATimeResolution() ;
1576           hWaveFormHalfAsic[asic][int(roCh/36)][binSample]->Fill(timetemp,(aTile->GetADCWaveform()).at(k)-ped);
1577           h2DWaveFormHalfAsic[asic][int(roCh/36)][binSample]->Fill(timetemp,(aTile->GetADCWaveform()).at(k)-ped);
1578         }          
1579       }        
1580     }
1581   }
1582   RootInput->Close();
1583   //==================================================================================
1584   // Setup general plotting infos
1585   //==================================================================================    
1586   TString outputDirPlots = GetPlotOutputDir();
1587   Double_t textSizeRel = 0.035;
1588 
1589   gSystem->Exec("mkdir -p "+outputDirPlots);
1590   StyleSettingsBasics("pdf");
1591   SetPlotStyle();  
1592   
1593   //==================================================================================
1594   // Create Summary plots
1595   //==================================================================================    
1596   TCanvas* canvas2DSigQA = new TCanvas("canvas2DSigQA","",0,0,1450,1300);  // gives the page size
1597   DefaultCanvasSettings( canvas2DSigQA, 0.08, 0.13, 0.045, 0.07);
1598 
1599   PlotSimple2D( canvas2DSigQA, hSampleTOAVsCellID, (double)it->second.samples,setup->GetMaxCellID()+1, textSizeRel, Form("%s/SampleTOAvsCellID.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
1600   PlotSimple2D( canvas2DSigQA, hSampleMaxADCVsCellID, (double)it->second.samples, setup->GetMaxCellID()+1, textSizeRel, Form("%s/SampleMaxADCvsCellID.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
1601 
1602   PlotSimple2D( canvas2DSigQA, hTOANsVsCellID, -10000, setup->GetMaxCellID()+1, textSizeRel, Form("%s/TOANsvsCellID.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
1603   
1604   canvas2DSigQA->SetLogz(1);
1605   
1606   Int_t diffBins = 4;
1607     
1608   for (int p = 0; p< 5; p++){
1609     std::cout << "************************************************" << std::endl;
1610     std::cout << "TOA offset estimate: " << std::endl; 
1611     std::cout << "nSample ToA: " << p+minNSampleToA << std::endl; 
1612     std::cout << "nCells in sample: " << hSampleTOA->GetBinContent(hSampleTOA->FindBin(p+minNSampleToA+0.001)) << std::endl;
1613     std::cout << "************************************************" << std::endl;
1614     std::cout << "# ASIC\tHalf\tOffset" << std::endl;
1615     TString outputDirNameToa=Form("%s/nToA_%d",outputDirPlots.Data(), p+minNSampleToA);
1616     gSystem->Exec("mkdir -p "+outputDirNameToa);
1617     for (Int_t ro = 0; ro < setup->GetNMaxROUnit()+1; ro++){
1618       for (int h = 0; h< 2; h++){ 
1619         
1620         Double_t largestDiff = 0.;
1621         Int_t bin         = 1;
1622         for (Int_t b = 1; b < hToAvsADC[ro][h][p]->GetNbinsX(); b++){
1623           Int_t maxBin  = (b+diffBins);
1624           if (maxBin > hToAvsADC[ro][h][p]->GetNbinsX()){
1625             maxBin      = maxBin-hToAvsADC[ro][h][p]->GetNbinsX();
1626           }
1627           Double_t diff = hToAvsADC[ro][h][p]->GetBinContent(maxBin) - hToAvsADC[ro][h][p]->GetBinContent(b);
1628           if (largestDiff < diff){
1629             largestDiff = diff;
1630             bin         = b;
1631           }
1632         }
1633         Int_t centerbin = bin+Int_t(diffBins/2);
1634         if (centerbin > (hToAvsADC[ro][h][p]->GetNbinsX()-diffBins/2))
1635           centerbin     = centerbin-(hToAvsADC[ro][h][p]->GetNbinsX()-diffBins/2);
1636         
1637         Int_t offset = (Int_t)(hToAvsADC[ro][h][p]->GetBinCenter(centerbin));
1638         std::cout << ro <<"\t" <<h << "\t" << offset << std::endl;
1639         
1640         Plot2DWithProfile( canvas2DSigQA, h2DToAvsADC[ro][h][p], hToAvsADC[ro][h][p], -10000, -10000, textSizeRel,
1641                           Form("%s/ToAvsADC_Asic_%d_Half_%d_NToASample_%d.%s", outputDirNameToa.Data(), ro, h,p+minNSampleToA, plotSuffix.Data()), 
1642                           it->second, 1, kFALSE, "colz",true, Form("Asic %d, Half %d,  nSample ToA: %d",ro,h, p+minNSampleToA), offset);
1643         
1644         h2DWaveFormHalfAsic[ro][h][p]->GetXaxis()->SetRangeUser(-25, (it->second.samples)*25);
1645         Plot2DWithProfile( canvas2DSigQA, h2DWaveFormHalfAsic[ro][h][p], hWaveFormHalfAsic[ro][h][p], -10000, -10000, textSizeRel,
1646                           Form("%s/Waveform_Asic_%d_Half_%d_NToASample_%d.%s", outputDirNameToa.Data(), ro, h, p+minNSampleToA, plotSuffix.Data()), 
1647                           it->second, 1, kFALSE, "colz",true, Form("Asic %d, Half %d, nSample ToA: %d",ro,h, p+minNSampleToA), -1);
1648       }
1649     }
1650   }
1651   
1652   for (Int_t ro = 0; ro < setup->GetNMaxROUnit()+1; ro++){
1653     for (int h = 0; h< 2; h++){      
1654         PlotSimple2D( canvas2DSigQA, h2DToAvsnSample[ro][h],(double)it->second.samples, -10000, textSizeRel,
1655                           Form("%s/ToaVsNSample_Asic_%d_Half_%d.%s", outputDirPlots.Data(), ro, h, plotSuffix.Data()), 
1656                           it->second, 1, kFALSE, "colz",true, Form("Asic %d, Half %d",ro,h));
1657         h2DWaveFormHalfAsicAll[ro][h]->GetXaxis()->SetRangeUser(-25, (it->second.samples)*25);
1658         Plot2DWithProfile( canvas2DSigQA, h2DWaveFormHalfAsicAll[ro][h], hWaveFormHalfAsicAll[ro][h], -10000, -10000, textSizeRel,
1659                           Form("%s/Waveform_Asic_%d_Half_%d.%s", outputDirPlots.Data(), ro, h, plotSuffix.Data()), 
1660                           it->second, 1, kFALSE, "colz",true, Form("Asic %d, Half %d",ro,h), -1);
1661     }
1662   }
1663 
1664   TCanvas* canvas1DSimple = new TCanvas("canvas1DSimple","",0,0,1450,1300);  // gives the page size
1665   DefaultCanvasSettings( canvas1DSimple, 0.08, 0.03, 0.03, 0.07);
1666 
1667   PlotSimple1D(canvas1DSimple, hSampleTOA, -10000, (double)it->second.samples, textSizeRel, Form("%s/NSampleToA.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1);
1668   PlotSimple1D(canvas1DSimple, hSampleMaxADC, -10000, (double)it->second.samples, textSizeRel, Form("%s/NSampleMaxADC.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1);
1669   PlotSimple1D(canvas1DSimple, hSampleAboveTh, -10000, (double)it->second.samples, textSizeRel, Form("%s/NSampleAboveTh.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1);
1670   PlotSimple1D(canvas1DSimple, hSampleDiff, -10000, (double)it->second.samples, textSizeRel, Form("%s/NSampleDiff.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1);
1671   PlotSimple1D(canvas1DSimple, hSampleDiffMin, -10000, (double)it->second.samples, textSizeRel, Form("%s/NSampleDiffMin.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1);
1672   
1673   //=====================================================================
1674   // Write output histograms
1675   //=====================================================================
1676   RootOutputHist->cd();
1677     hSampleTOA->Write();
1678     hSampleMaxADC->Write();
1679     hSampleAboveTh->Write();
1680     hSampleDiff->Write();
1681     hSampleDiffMin->Write();
1682     hSampleTOAVsCellID->Write();
1683     hTOANsVsCellID->Write();
1684     hSampleMaxADCVsCellID->Write();
1685 
1686     for (Int_t ro = 0; ro < setup->GetNMaxROUnit()+1; ro++){
1687       for (int h = 0; h< 2; h++){
1688         h2DToAvsnSample[ro][h]->Write();
1689         h2DWaveFormHalfAsicAll[ro][h]->Write();
1690         hWaveFormHalfAsicAll[ro][h]->Write();
1691         for (int p = 0; p< 5; p++){
1692           hToAvsADC[ro][h][p]->Write();
1693           h2DToAvsADC[ro][h][p]->Write();
1694           h2DWaveFormHalfAsic[ro][h][p]->Write();
1695           hWaveFormHalfAsic[ro][h][p]->Write();
1696         }
1697       }
1698     }
1699   RootOutputHist->Close();
1700   
1701   return true;
1702 } // end Analyses::EvaluateHGCROCToAPhases()
1703 
1704 
1705 // ****************************************************************************
1706 // extract pedestral from dedicated data run, no other data in run 
1707 // ****************************************************************************
1708 bool Analyses::TransferCalib(void){
1709   std::cout<<"Transfer calib"<<std::endl;
1710   int evts=TdataIn->GetEntries();
1711 
1712   // initialize lookup-table run list
1713   std::map<int,RunInfo> ri=readRunInfosFromFile(RunListInputName.Data(),debug,0);
1714   std::map<int,TileSpectra> hSpectra;
1715   std::map<int, TileSpectra>::iterator ithSpectra;
1716   std::map<int,TileSpectra> hSpectraTrigg;
1717   std::map<int, TileSpectra>::iterator ithSpectraTrigg;
1718 
1719   
1720   // initialize calib
1721   TcalibIn->GetEntry(0);
1722   // check whether calib should be overwritten based on external text file
1723   if (OverWriteCalib){
1724     calib.ReadCalibFromTextFile(ExternalCalibFile,debug);
1725   }
1726   // add ToA offsets for half asics to calib objects if available
1727   if (ExternalToACalibOffSetFile.CompareTo("") != 0 ){
1728     calib.ReadExternalToAOffsets(ExternalToACalibOffSetFile,debug);
1729   }
1730   std::map<int,short> bcmap;
1731   std::map<int,short>::iterator bcmapIte;
1732   if (CalcBadChannel == 1)
1733     bcmap = ReadExternalBadChannelMap();
1734   
1735   // intialize run infos & reset calib object to correct run number
1736   TdataIn->GetEntry(0);     // use first event to get infos
1737   int runNr             = event.GetRunNumber();
1738   ReadOut::Type typeRO  = event.GetROtype();
1739   std::cout<< "original run numbers calib: "<<calib.GetRunNumber() << "\t" << calib.GetRunNumberPed() << "\t" << calib.GetRunNumberMip() << std::endl;
1740   calib.SetRunNumber(runNr);
1741   calib.SetBeginRunTime(event.GetBeginRunTimeAlt());
1742   std::cout<< "reset run numbers calib: "<< calib.GetRunNumber() << "\t" << calib.GetRunNumberPed() << "\t" << calib.GetRunNumberMip() << std::endl;
1743   std::map<int,RunInfo>::iterator it=ri.find(runNr);
1744 
1745   // Find detector config
1746   DetConf::Type detConf = setup->GetDetectorConfig();
1747   if (it->second.detector == "FoCal-H")
1748     detConf = DetConf::Type::FocalH; 
1749 
1750     
1751   //==================================================================================
1752   // create additional output hist 
1753   //==================================================================================
1754   CreateOutputRootHistFile();
1755 
1756   int maxChanneTransferCaliblPerLayer       = (setup->GetNMaxColumn()+1)*(setup->GetNMaxRow()+1)*(setup->GetNMaxModule()+1);
1757   int maxChannelPerLayerSingleMod           = (setup->GetNMaxColumn()+1)*(setup->GetNMaxRow()+1);
1758 
1759   // HGCROC specific histo creation
1760   TH2D* hspectraADCvsCellID         = nullptr;
1761   TH2D* hspectraADCPedvsCellID      = nullptr;
1762   TH2D* hHighestADCAbovePedVsLayer  = nullptr;
1763   TH2D* hspectraTOTvsCellID   =nullptr;
1764   TH2D* hspectraTOAvsCellID   =nullptr;   
1765   TH2D* hSampleTOAVsCellID    =nullptr;
1766   TH1D* hSampleTOA            =nullptr;   
1767   TH2D* hTOANsVsCellID        =nullptr;   
1768   TH2D* hTOACorrNsVsCellID    =nullptr;   
1769   TH2D* hNCellsWTOAVsTotADC   =nullptr;
1770   TH2D* hNCellsWmADCVsTotADC  =nullptr;        
1771   // plot setup per half asic for ToA 
1772   TH2D* h2DToAvsnSample[setup->GetNMaxROUnit()+1][2];
1773   TH2D* h2DWaveFormHalfAsicAll[setup->GetNMaxROUnit()+1][2];
1774   TProfile* hWaveFormHalfAsicAll[setup->GetNMaxROUnit()+1][2];
1775   
1776   // only create these if we have an HGCROC data type as input
1777   if (typeRO == ReadOut::Type::Hgcroc){
1778     hspectraADCvsCellID      = new TH2D( "hspectraADCvsCellID","ADC spectrums CellID; cell ID; ADC (arb. units) ",
1779                                               setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 1024,0,1024);
1780     hspectraADCvsCellID->SetDirectory(0);
1781     
1782     hspectraADCPedvsCellID      = new TH2D( "hspectraADCPedvsCellID","Pedestal ADC spectrums CellID; cell ID; ADC (arb. units) ",
1783                                               setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 1024,0,1024);
1784     hspectraADCPedvsCellID->SetDirectory(0);
1785     
1786     hHighestADCAbovePedVsLayer   = new TH2D( "hHighestEAbovePedVsLayer","Highest ADC above PED; layer; brd channel; #Sigma(ADC) (arb. units) ",
1787                                               setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChanneTransferCaliblPerLayer, -0.5, maxChanneTransferCaliblPerLayer-0.5);
1788     hHighestADCAbovePedVsLayer->SetDirectory(0);
1789     hHighestADCAbovePedVsLayer->Sumw2();
1790     hspectraTOTvsCellID      = new TH2D( "hspectraTOTvsCellID","TOT spectrums CellID; cell ID; TOT (arb. units) ",
1791                                             setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 4096,0,4096);
1792     hspectraTOTvsCellID->SetDirectory(0);
1793     hspectraTOAvsCellID      = new TH2D( "hspectraTOAvsCellID","TOA spectrums CellID; cell ID; TOA (arb. units) ",
1794                                             setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 1024,0,1024);
1795     hspectraTOAvsCellID->SetDirectory(0);
1796     hSampleTOAVsCellID       = new TH2D( "hSampleTOAvsCellID","#sample ToA; cell ID; #sample TOA",
1797                                             setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, it->second.samples,0,it->second.samples);
1798     hSampleTOAVsCellID->SetDirectory(0);
1799     hSampleTOA                = new TH1D( "hSampleTOA","#sample ToA; #sample TOA",
1800                                               it->second.samples,0,it->second.samples);
1801     hSampleTOA->SetDirectory(0);
1802     hTOANsVsCellID            = new TH2D( "hTOANsVsCellID","ToA (ns); cell ID; ToA (ns)",
1803                                       setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 500,-250,0);
1804     hTOANsVsCellID->SetDirectory(0);
1805     hTOACorrNsVsCellID        = new TH2D( "hTOACorrNsVsCellID","ToA (ns); cell ID; ToA (ns)",
1806                                       setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 500,-250,0);
1807     hTOACorrNsVsCellID->SetDirectory(0);
1808     
1809     hNCellsWTOAVsTotADC          = new TH2D( "hNCellsWTOAVsTotADC","NCells above TOA vs tot ADC; NCells above TOA; #Sigma(ADC) (arb. units) ",
1810                                             setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 5000,0,10000);
1811     hNCellsWTOAVsTotADC->SetDirectory(0);
1812     hNCellsWmADCVsTotADC          = new TH2D( "hNCellsWmADCVsTotADC","NCells w. ADC > 10 vs tot ADC; NCells above min ADC; #Sigma(ADC) (arb. units) ",
1813                                             setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 5000,0,10000);
1814     hNCellsWmADCVsTotADC->SetDirectory(0);
1815 
1816     for (Int_t ro = 0; ro < setup->GetNMaxROUnit()+1; ro++){
1817       for (int h = 0; h< 2; h++){
1818         h2DToAvsnSample[ro][h]    = new TH2D(Form("h2DTOASample_Asic_%d_Half_%d",ro,h),
1819                                               Form("Sample vs TOA %d %d; TOA (arb. units); #sample",ro,h), 1024/8,0,1024,it->second.samples,0,it->second.samples);
1820         h2DToAvsnSample[ro][h]->SetDirectory(0);
1821         hWaveFormHalfAsicAll[ro][h]    = new TProfile(Form("WaveForm_Asic_%d_Half_%d",ro,h),
1822                                           Form("ADC-TOA correlation %d %d;  t (ns) ; ADC (arb. units)",ro,h),550,-50,500);
1823         hWaveFormHalfAsicAll[ro][h]->SetDirectory(0);
1824         h2DWaveFormHalfAsicAll[ro][h]  = new TH2D(Form("h2DWaveForm_Asic_%d_Half_%d",ro,h),
1825                                           Form("2D ADC vs TOA %d %d;  t (ns) ; ADC (arb. units)",ro,h), 
1826                                             550,-50,500, 1044/4, -20, 1024);      
1827         h2DWaveFormHalfAsicAll[ro][h]->SetDirectory(0);
1828       }
1829     }
1830   } 
1831   
1832   RootOutputHist->mkdir("IndividualCells");
1833   if(typeRO == ReadOut::Type::Hgcroc) RootOutputHist->mkdir("IndividualCellsTrigg");
1834   if(typeRO == ReadOut::Type::Caen) RootOutputHist->mkdir("IndividualCellsRejected");
1835   RootOutputHist->cd("IndividualCells");
1836   
1837   ROOT::Math::MinimizerOptions::SetDefaultMinimizer("Minuit2", "Migrad");  
1838   if (maxEvents == -1){
1839     maxEvents = evts;
1840   } else {
1841     std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
1842     std::cout << "ATTENTION: YOU ARE RESETTING THE MAXIMUM NUMBER OF EVENTS TO BE PROCESSED TO: " << maxEvents << ". THIS SHOULD ONLY BE USED FOR TESTING!" << std::endl;
1843     std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
1844   }
1845   
1846   if (EventCleanup == 1){
1847     std::cout << "==============================================================================" << std::endl;
1848     std::cout << "==============================================================================" << std::endl;
1849     if (calib.GetAverageScaleHigh() != -10000 ){
1850       std::cout << "resetting rejection thresholds with average HG Scale" << std::endl;
1851       cleanupLGTh   =  ((calib.GetAverageScaleHigh()-calib.GetAverageLGHGCorrOff())/calib.GetAverageLGHGCorr() )* 2.5;
1852       cleanupHGTh   =  calib.GetAverageScaleHigh()*1.5;
1853     }
1854     std::cout << "Thresholds for rejections: \t LG: " << cleanupLGTh << "\t HG: " << cleanupHGTh << std::endl;
1855     std::cout << "==============================================================================" << std::endl;
1856     std::cout << "==============================================================================" << std::endl;
1857   }
1858   
1859   //==================================================================================
1860   // setup waveform builder for HGCROC data
1861   //==================================================================================
1862   waveform_fit_base *waveform_builder = nullptr;
1863   waveform_builder = new max_sample_fit();
1864   double minNSigma = 5;
1865   int nCellsAboveTOA  = 0;
1866   int nCellsAboveMADC = 0;
1867   double totADCs      = 0.;
1868   int rejectedEvents  = 0;
1869   //==================================================================================
1870   // process events from tree:
1871   // - fill spectra plots for cross checking
1872   // - HGCROC data: 
1873   //     * set pedestal values from externally processed data
1874   //     * reevaluate waveform fits
1875   //     * plot waveforms
1876   //==================================================================================
1877   for(int i=0; i<evts && i < maxEvents ; i++){
1878     if (i%5000 == 0&& i > 0 && debug > 0) std::cout << "Reading " <<  i << "/" << evts << " events"<< std::endl;
1879     if (debug > 2 && typeRO == ReadOut::Type::Hgcroc){
1880       std::cout << "************************************* NEW EVENT " << i << "  *********************************" << std::endl;
1881     }
1882     TdataIn->GetEntry(i);
1883    
1884     bool bREvent = false;
1885     if (EventCleanup == 1){
1886       if (!event.CheckEventIntegrity(calib, cleanupLGTh, cleanupHGTh)){
1887         rejectedEvents++;
1888         bREvent = true;
1889         // continue;
1890       }
1891     }
1892     
1893     // initialize counters per event
1894     nCellsAboveTOA  = 0;
1895     nCellsAboveMADC = 0;
1896     totADCs         = 0.;
1897     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1898     // process tiles in event
1899     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1900     for(int j=0; j<event.GetNTiles(); j++){
1901       //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1902       // histo filling for CAEN specific things
1903       //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1904       if (typeRO == ReadOut::Type::Caen) {
1905         Caen* aTile=(Caen*)event.GetTile(j);
1906         ithSpectra      = hSpectra.find(aTile->GetCellID());
1907         ithSpectraTrigg = hSpectraTrigg.find(aTile->GetCellID());
1908         double hgCorr = aTile->GetADCHigh()-calib.GetPedestalMeanH(aTile->GetCellID());
1909         double lgCorr = aTile->GetADCLow()-calib.GetPedestalMeanL(aTile->GetCellID());
1910         // fill spectra histos
1911         if (!bREvent){
1912           if(ithSpectra!=hSpectra.end()){
1913             ithSpectra->second.FillExtCAEN(lgCorr,hgCorr, 0., 0.);
1914           } else {
1915             RootOutputHist->cd("IndividualCells");
1916             hSpectra[aTile->GetCellID()]=TileSpectra("All",2,aTile->GetCellID(),calib.GetTileCalib(aTile->GetCellID()),event.GetROtype(),debug);
1917             hSpectra[aTile->GetCellID()].FillExtCAEN(lgCorr,hgCorr, 0., 0.);
1918             RootOutput->cd();
1919           }
1920         } else {
1921           if(ithSpectraTrigg!=hSpectraTrigg.end()){
1922             ithSpectraTrigg->second.FillExtCAEN(lgCorr,hgCorr, 0., 0.);
1923           } else {
1924             RootOutputHist->cd("IndividualCellsRejected");
1925             hSpectraTrigg[aTile->GetCellID()]=TileSpectra("Rejected",2,aTile->GetCellID(),calib.GetTileCalib(aTile->GetCellID()),event.GetROtype(),debug);
1926             hSpectraTrigg[aTile->GetCellID()].FillExtCAEN(lgCorr,hgCorr, 0., 0.);
1927             RootOutput->cd();
1928           }
1929         }
1930       //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
1931       // histo filling for HGCROC specific things & resetting of ped
1932       //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1933       } else if (typeRO == ReadOut::Type::Hgcroc) {
1934         Hgcroc* aTile=(Hgcroc*)event.GetTile(j);
1935         int cellID    = aTile->GetCellID();
1936         ithSpectra=hSpectra.find(cellID);
1937         ithSpectraTrigg=hSpectraTrigg.find(cellID);
1938         
1939         // get pedestal values from calib object
1940         double ped = calib.GetPedestalMeanL(cellID); // ped based on waveform fit
1941         if (ped == -1000){
1942           ped = calib.GetPedestalMeanH(cellID);      // ped based on first sample fit
1943           if (ped == -1000){
1944             ped = aTile->GetPedestal();              // event-by-event first sample
1945           }
1946         }
1947         // reevaluate waveform
1948         waveform_builder->set_waveform(aTile->GetADCWaveform());
1949         waveform_builder->fit_with_average_ped(ped);
1950         aTile->SetIntegratedADC(waveform_builder->get_E());
1951         aTile->SetPedestal(waveform_builder->get_pedestal());
1952         
1953         // obtain integrated tile quantities for histo filling
1954         int layer     = setup->GetLayer(cellID);
1955         int chInLayer = setup->GetChannelInLayerFull(cellID, detConf);
1956         double adc = aTile->GetIntegratedADC();
1957         double tot = aTile->GetRawTOT();
1958         double toa = aTile->GetRawTOA();
1959         bool hasTOA     = false;
1960         bool hasTOT     = false;
1961         
1962         // check if we have a toa
1963         if (toa > 0)
1964           hasTOA        = true;
1965         // check if we have a tot
1966         if (tot > 0)
1967           hasTOT        = true;
1968         // obtain toa shift corrected values
1969         Int_t nSampTOA  = aTile->GetFirstTOASample();        
1970         double toaNs      = (double)aTile->GetLinearizedRawTOA()*aTile->GetTOATimeResolution();
1971         double toaCorrNs  = toaNs;
1972         Int_t nOffEmpty   = 2;
1973         if (calib.GetToAOff(cellID) != -1000.){
1974           // correct ToA sample and return correct nSampleTOA
1975           nSampTOA      = aTile->SetCorrectedTOA(calib.GetToAOff(cellID)); 
1976           toaCorrNs     = (double)(aTile->GetCorrectedTOA())*aTile->GetTOATimeResolution();;
1977         }
1978         totADCs         = totADCs+adc;
1979         if (adc > 10)
1980           nCellsAboveMADC++; 
1981         if (toa > 0)
1982           nCellsAboveTOA++;
1983         
1984         hspectraADCvsCellID->Fill(cellID,adc);
1985         hspectraADCPedvsCellID->Fill(cellID,aTile->GetPedestal());
1986         if(hasTOT)  hspectraTOTvsCellID->Fill(cellID,tot);
1987         
1988         Int_t asic      = setup->GetROunit(cellID);
1989         Int_t roCh      = setup->GetROchannel(cellID);
1990         if (hasTOA){
1991           hspectraTOAvsCellID->Fill(cellID,toa);
1992           hSampleTOAVsCellID->Fill(cellID,nSampTOA);
1993           hSampleTOA->Fill(nSampTOA);
1994           hTOANsVsCellID->Fill(cellID,toaNs);
1995           hTOACorrNsVsCellID->Fill(cellID,toaCorrNs);
1996           // fill overview hists for half asics
1997           h2DToAvsnSample[asic][int(roCh/36)]->Fill(toa, nSampTOA);
1998           for (int k = 0; k < (int)(aTile->GetADCWaveform()).size(); k++ ){
1999             double timetemp = ((k+nOffEmpty)*1024 + (double)aTile->GetCorrectedTOA())*aTile->GetTOATimeResolution() ;
2000             hWaveFormHalfAsicAll[asic][int(roCh/36)]->Fill(timetemp,(aTile->GetADCWaveform()).at(k)-ped);
2001             h2DWaveFormHalfAsicAll[asic][int(roCh/36)]->Fill(timetemp,(aTile->GetADCWaveform()).at(k)-ped);
2002           }          
2003         }        
2004         
2005         // single tile debug info print
2006         if (debug > 10 ){
2007           aTile->PrintWaveFormDebugInfo(calib.GetPedestalMeanH(cellID), calib.GetPedestalMeanL(cellID), calib.GetPedestalSigL(cellID));
2008         }
2009         // fill spectra histos
2010         if(ithSpectra!=hSpectra.end()){
2011           ithSpectra->second.FillExtHGCROC(adc,toa,tot,nSampTOA,-1);
2012           ithSpectra->second.FillWaveform(aTile->GetADCWaveform(),0);
2013         } else {
2014           RootOutputHist->cd("IndividualCells");
2015           hSpectra[cellID]=TileSpectra("All",2,cellID,calib.GetTileCalib(cellID),event.GetROtype(),debug);
2016           hSpectra[cellID].FillExtHGCROC(adc,toa,tot,nSampTOA,-1);
2017           hSpectra[cellID].FillWaveform(aTile->GetADCWaveform(),0);
2018           RootOutput->cd();
2019         }
2020         // Select only signals with a TOA (cleanup )      
2021         if (hasTOA){      
2022             hHighestADCAbovePedVsLayer->Fill(layer,chInLayer, adc);
2023           
2024           if(ithSpectraTrigg!=hSpectraTrigg.end()){
2025             ithSpectraTrigg->second.FillExtHGCROC(adc,toa,tot,nSampTOA,-1);
2026             ithSpectraTrigg->second.FillWaveform(aTile->GetADCWaveform(),0);
2027           } else {
2028             RootOutputHist->cd("IndividualCellsTrigg");
2029             hSpectraTrigg[cellID]=TileSpectra("signal",2,cellID,calib.GetTileCalib(cellID),event.GetROtype(),debug);
2030             hSpectraTrigg[cellID].FillExtHGCROC(adc,toa,tot,nSampTOA,-1);
2031             hSpectraTrigg[cellID].FillWaveform(aTile->GetADCWaveform(),0);
2032             RootOutput->cd();
2033           }
2034         }
2035       }
2036     }
2037     // summary plot filling HGCROC
2038     if (typeRO == ReadOut::Type::Hgcroc) {
2039       hNCellsWmADCVsTotADC->Fill(nCellsAboveMADC, totADCs);
2040       hNCellsWTOAVsTotADC->Fill(nCellsAboveTOA, totADCs);
2041     }
2042     RootOutput->cd();
2043     // fill tree
2044     if (!bREvent) TdataOut->Fill();
2045   }
2046   // write tree
2047   TdataOut->Write();
2048   TsetupIn->CloneTree()->Write();
2049 
2050   if (EventCleanup == 1){
2051     std::cout << "****************************************************************************************************"<< std::endl; 
2052     std::cout << "****************************************************************************************************"<< std::endl; 
2053     std::cout << rejectedEvents<< "\t/" << maxEvents  << " rejected CAEN events due to corrupted data for single channels!"<< std::endl; 
2054     std::cout << "****************************************************************************************************"<< std::endl; 
2055     std::cout << "****************************************************************************************************"<< std::endl; 
2056   }
2057   //==================================================================================
2058   // Setup general plotting infos
2059   //==================================================================================  
2060   TString outputDirPlots = GetPlotOutputDir();
2061   Double_t textSizeRel = 0.035;
2062 
2063   if (CalcBadChannel > 0 || ExtPlot > 0) {
2064     gSystem->Exec("mkdir -p "+outputDirPlots);
2065     StyleSettingsBasics("pdf");
2066     SetPlotStyle();  
2067   }
2068   
2069   //==================================================================================
2070   // Internal evaluation for bad channels or application of external bad channel map
2071   //==================================================================================
2072   if (CalcBadChannel > 0 ){
2073     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
2074     // Create monitoring histos for BC extraction
2075     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
2076     int maxChannelPerLayer             = (setup->GetNMaxColumn()+1)*(setup->GetNMaxRow()+1)*(setup->GetNMaxModule()+1);
2077     int maxChannelPerLayerSingleMod    = (setup->GetNMaxColumn()+1)*(setup->GetNMaxRow()+1);
2078 
2079     // monitoring applied pedestals
2080     TH1D* hBCvsCellID      = new TH1D( "hBC_vsCellID","Bad Channel vs CellID ; cell ID; BC flag ",
2081                                               setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5);
2082     hBCvsCellID->SetDirectory(0);
2083     TH2D* hBCVsLayer   = new TH2D( "hBCVsLayer","Bad Channel Map; layer; brd channel; BC flag  ",
2084                                               setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
2085     hBCVsLayer->SetDirectory(0);
2086 
2087     int currCells = 0;
2088     if ( debug > 0 && CalcBadChannel == 2)
2089       std::cout << "============================== starting bad channel extraction" << std::endl;
2090     if ( debug > 0 && CalcBadChannel == 1)
2091       std::cout << "============================== setting bad channel according to external map" << std::endl;
2092     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
2093     // evaluate each tile spectrum & set BC flag
2094     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
2095     for(ithSpectra=hSpectra.begin(); ithSpectra!=hSpectra.end(); ++ithSpectra){
2096       if (currCells%20 == 0 && currCells > 0 && debug > 0)
2097         std::cout << "============================== cell " <<  currCells << " / " << hSpectra.size() << " cells" << std::endl;
2098       currCells++;
2099       short bc   = 3;
2100       // evaluate bad channel map internally
2101       if (CalcBadChannel == 2){
2102         bc        = ithSpectra->second.DetermineBadChannel();
2103       // apply external bad channel map
2104       } else if (CalcBadChannel == 1 && bcmap.size() > 0 ) {
2105         bcmapIte  = bcmap.find(ithSpectra->second.GetCellID());
2106         if(bcmapIte!=bcmap.end())
2107           bc        = bcmapIte->second;
2108         else 
2109           bc        = 3;
2110       } 
2111       
2112       long cellID   = ithSpectra->second.GetCellID();
2113       if (CalcBadChannel == 1)
2114         ithSpectra->second.SetBadChannelInCalib(bc);
2115       
2116       // initializing pedestal fits from calib file
2117       ithSpectra->second.InitializeNoiseFitsFromCalib();
2118       
2119       // histo filling
2120       int layer     = setup->GetLayer(cellID);
2121       int chInLayer = setup->GetChannelInLayerFull(cellID,detConf);
2122       if (debug > 0 && bc > -1 && bc < 3)
2123         std::cout << "\t" << cellID << "\t" << layer << "\t" << setup->GetRow(cellID) << "\t" << setup->GetColumn(cellID)<< "\t" << setup->GetModule(cellID) << " - quality flag: " << bc << "\t" << calib.GetBadChannel(cellID) << "\t ped H: " << calib.GetPedestalMeanH(cellID) << "\t ped L: " << calib.GetPedestalMeanL(cellID)<< std::endl;
2124 
2125       hBCvsCellID->SetBinContent(hBCvsCellID->FindBin(cellID), calib.GetBadChannel(cellID));
2126       int bin2D     = hBCVsLayer->FindBin(layer,chInLayer);
2127       hBCVsLayer->SetBinContent(bin2D, calib.GetBadChannel(cellID));
2128       
2129       if (bc < 2 && typeRO == ReadOut::Type::Hgcroc){
2130         hHighestADCAbovePedVsLayer->SetBinContent(bin2D, 0);
2131       }
2132     }
2133     hBCvsCellID->Write();
2134     hBCVsLayer->Write();
2135 
2136     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
2137     // Create canvases for channel overview plotting
2138     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
2139     // Get run info object
2140     // create directory for plot output
2141   
2142     TCanvas* canvas2DCorr = new TCanvas("canvasCorrPlots","",0,0,1450,1300);  // gives the page size
2143     DefaultCanvasSettings( canvas2DCorr, 0.08, 0.13, 0.045, 0.07);
2144 
2145     canvas2DCorr->SetLogz(0);
2146     
2147     PlotSimple2DZRange( canvas2DCorr, hBCVsLayer, -10000, -10000, -0.1, 3.1, textSizeRel, Form("%s/BadChannelMap.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, "colz", true);    
2148     calib.SetBCCalib(true);
2149   }
2150   
2151   //==================================================================================
2152   // write calib output to root-tree output file
2153   //==================================================================================  
2154   RootOutput->cd();
2155   // print calib file to text file
2156   std::cout<<"What is the value? <ped mean high>: "<<calib.GetAveragePedestalMeanHigh() << "\t good channels: " << calib.GetNumberOfChannelsWithBCflag(3) <<std::endl;
2157   if (IsCalibSaveToFile()){
2158     TString fileCalibPrint = RootOutputName;
2159     fileCalibPrint         = fileCalibPrint.ReplaceAll(".root","_calib.txt");
2160     calib.PrintCalibToFile(fileCalibPrint);
2161   }
2162   // write calib output to 
2163   TcalibOut->Fill();
2164   TcalibOut->Write();
2165   // close file
2166   RootOutput->Close();
2167 
2168   //==================================================================================
2169   // write histo output to file as cross check
2170   //==================================================================================    
2171   RootOutputHist->cd();
2172   if (typeRO == ReadOut::Type::Hgcroc){
2173     hSampleTOA->Write();
2174     hSampleTOAVsCellID->Write();
2175     hTOANsVsCellID->Write();
2176     hTOACorrNsVsCellID->Write();
2177     hspectraADCvsCellID->Write();
2178     hspectraADCPedvsCellID->Write();
2179     hspectraTOTvsCellID->Write();
2180     hspectraTOAvsCellID->Write();
2181     hHighestADCAbovePedVsLayer->Write();
2182     hNCellsWmADCVsTotADC->Write();
2183     hNCellsWTOAVsTotADC->Write();
2184     for (Int_t ro = 0; ro < setup->GetNMaxROUnit()+1; ro++){
2185       for (int h = 0; h< 2; h++){
2186         h2DToAvsnSample[ro][h]->Write();
2187         h2DWaveFormHalfAsicAll[ro][h]->Write();
2188         hWaveFormHalfAsicAll[ro][h]->Write();
2189       }
2190     }
2191   }
2192   // save individual cell spectra
2193   RootOutputHist->cd("IndividualCells");
2194   for(ithSpectra=hSpectra.begin(); ithSpectra!=hSpectra.end(); ++ithSpectra){
2195     ithSpectra->second.WriteExt(true);
2196   }
2197   if (typeRO == ReadOut::Type::Hgcroc){
2198     RootOutputHist->cd("IndividualCellsTrigg");
2199     for(ithSpectraTrigg=hSpectraTrigg.begin(); ithSpectraTrigg!=hSpectraTrigg.end(); ++ithSpectraTrigg){
2200       ithSpectraTrigg->second.WriteExt(true);
2201     }
2202   } else if (EventCleanup) {
2203     RootOutputHist->cd("IndividualCellsRejected");
2204     for(ithSpectraTrigg=hSpectraTrigg.begin(); ithSpectraTrigg!=hSpectraTrigg.end(); ++ithSpectraTrigg){
2205       ithSpectraTrigg->second.WriteExt(true);
2206     }
2207   }
2208   // close root histo output file
2209   RootOutputHist->Close();
2210   // close root input file
2211   RootInput->Close();
2212   
2213   //==================================================================================
2214   // Create plots in case extended plotting is enabled for waveforms
2215   //==================================================================================
2216   if (ExtPlot > 0){
2217     if (typeRO == ReadOut::Type::Hgcroc){
2218       TCanvas* canvas2DSigQA = new TCanvas("canvas2DSigQA","",0,0,1450,1300);  // gives the page size
2219       DefaultCanvasSettings( canvas2DSigQA, 0.08, 0.13, 0.045, 0.07);
2220       
2221       PlotSimple2D( canvas2DSigQA, hTOANsVsCellID, -10000, setup->GetMaxCellID()+1, textSizeRel, Form("%s/TOANsvsCellID.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
2222       PlotSimple2D( canvas2DSigQA, hTOACorrNsVsCellID, -10000, setup->GetMaxCellID()+1, textSizeRel, Form("%s/TOACorrNsvsCellID.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
2223       PlotSimple2D( canvas2DSigQA, hSampleTOAVsCellID, (double)it->second.samples,setup->GetMaxCellID()+1, textSizeRel, Form("%s/SampleTOAvsCellID.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
2224 
2225       PlotSimple2D( canvas2DSigQA, hspectraTOTvsCellID, 4096, setup->GetMaxCellID()+1, textSizeRel, Form("%s/TOTvsCellID.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
2226       PlotSimple2D( canvas2DSigQA, hspectraTOAvsCellID, 1024, setup->GetMaxCellID()+1, textSizeRel, Form("%s/TOAvsCellID.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
2227       PlotSimple2D( canvas2DSigQA, hspectraADCvsCellID,  1024, setup->GetMaxCellID()+1, textSizeRel, Form("%s/ADCvsCellID.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
2228 
2229       canvas2DSigQA->SetLogz(1);
2230       PlotSimple2DZRange( canvas2DSigQA, hHighestADCAbovePedVsLayer, -10000, -10000, 0.1, 20000, textSizeRel, Form("%s/MaxADCAboveNoise_vsLayer.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, "colz", true);    
2231       
2232       for (Int_t ro = 0; ro < setup->GetNMaxROUnit()+1; ro++){
2233         for (int h = 0; h< 2; h++){      
2234             PlotSimple2D( canvas2DSigQA, h2DToAvsnSample[ro][h],(double)it->second.samples, -10000, textSizeRel,
2235                               Form("%s/ToaVsNSample_Asic_%d_Half_%d.%s", outputDirPlots.Data(), ro, h, plotSuffix.Data()), 
2236                               it->second, 1, kFALSE, "colz",true, Form("Asic %d, Half %d",ro,h));
2237             h2DWaveFormHalfAsicAll[ro][h]->GetXaxis()->SetRangeUser(-25, (it->second.samples)*25);
2238             Plot2DWithProfile( canvas2DSigQA, h2DWaveFormHalfAsicAll[ro][h], hWaveFormHalfAsicAll[ro][h], -10000, -10000, textSizeRel,
2239                               Form("%s/Waveform_Asic_%d_Half_%d.%s", outputDirPlots.Data(), ro, h, plotSuffix.Data()), 
2240                               it->second, 1, kFALSE, "colz",true, Form("Asic %d, Half %d",ro,h), -1);
2241         }
2242       }
2243 
2244       TCanvas* canvas1DSimple = new TCanvas("canvas1DSimple","",0,0,1450,1300);  // gives the page size
2245       DefaultCanvasSettings( canvas1DSimple, 0.08, 0.03, 0.03, 0.07);
2246 
2247       PlotSimple1D(canvas1DSimple, hSampleTOA, -10000, (double)it->second.samples, textSizeRel, Form("%s/NSampleToA.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1);      
2248     }
2249 
2250     Double_t maxHG = 600;
2251     Double_t maxLG = 200;
2252     // print general calib info
2253     calib.PrintGlobalInfo();  
2254     
2255     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
2256     // Multi panel plotting
2257     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++      
2258     MultiCanvas panelPlot(detConf, "Transfer");
2259     bool init1D = panelPlot.Initialize(1);
2260     MultiCanvas panelPlot2D(detConf, "Transfer2D");
2261     bool init2D = panelPlot2D.Initialize(2);
2262     
2263     if (typeRO == ReadOut::Type::Caen) {
2264       panelPlot2D.PlotCorr2DLayer(hSpectra, 0, -20, 340, 0, 4000,
2265                                   Form("%s/LGHG2D_Corr",outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, 0, -1, skipPlotLayer );
2266       if (EventCleanup) 
2267         panelPlot2D.PlotCorr2DLayer(hSpectraTrigg, 0, -20, 340, 0, 4000,
2268                                     Form("%s/LGHG2DRejected_Corr",outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, 0, -1, skipPlotLayer );
2269       
2270     } else {
2271       panelPlot2D.PlotCorr2DLayer(hSpectra, 1, 0, it->second.samples+1, 0, 1000,
2272                                   Form("%s/Waveform",outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, 0, -1, skipPlotLayer );
2273       panelPlot2D.PlotCorr2DLayer(hSpectraTrigg, 1, 0, it->second.samples+1, 0, 1000,
2274                                   Form("%s/WaveformSignal",outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, 0, -1, skipPlotLayer );  
2275     }
2276         
2277     if (ExtPlot > 1){
2278       panelPlot.PlotNoiseWithFits(hSpectra, 0, -100, maxHG, 1.2, 
2279                                 Form("%s/SpectraWithNoiseFit_HG",outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);
2280       if (typeRO == ReadOut::Type::Caen){
2281         panelPlot.PlotNoiseWithFits(hSpectra, 1, -20, maxLG, 1.2, 
2282                                 Form("%s/SpectraWithNoiseFit_LG",outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);        
2283       }
2284     }
2285   }
2286   
2287   return true;
2288 } // end Analyses::TransferCalib()
2289 
2290 
2291 // ****************************************************************************
2292 // Reevaluate LGHG Corr for CAEN data
2293 // ****************************************************************************
2294 bool Analyses::ReevaluateLGHGCorr(void){
2295   std::cout<<"Reevaluate LG-HG corr for CAEN data"<<std::endl;
2296   int evts=TdataIn->GetEntries();
2297 
2298   // initialize lookup-table run list
2299   std::map<int,RunInfo> ri=readRunInfosFromFile(RunListInputName.Data(),debug,0);
2300   std::map<int,TileSpectra> hSpectra;
2301   std::map<int, TileSpectra>::iterator ithSpectra;
2302   // Find detector config
2303   DetConf::Type detConf = setup->GetDetectorConfig();
2304   
2305   // initialize calib
2306   TcalibIn->GetEntry(0);
2307   // check whether calib should be overwritten based on external text file
2308   if (OverWriteCalib){
2309     calib.ReadCalibFromTextFile(ExternalCalibFile,debug);
2310   }
2311   std::map<int,short> bcmap;
2312   std::map<int,short>::iterator bcmapIte;
2313   if (CalcBadChannel == 1)
2314     bcmap = ReadExternalBadChannelMap();
2315   
2316   // intialize run infos & reset calib object to correct run number
2317   TdataIn->GetEntry(0);     // use first event to get infos
2318   int runNr             = event.GetRunNumber();
2319   ReadOut::Type typeRO  = event.GetROtype();
2320   std::cout<< "original run numbers calib: "<<calib.GetRunNumber() << "\t" << calib.GetRunNumberPed() << "\t" << calib.GetRunNumberMip() << std::endl;
2321   calib.SetRunNumber(runNr);
2322   calib.SetBeginRunTime(event.GetBeginRunTimeAlt());
2323   std::cout<< "reset run numbers calib: "<< calib.GetRunNumber() << "\t" << calib.GetRunNumberPed() << "\t" << calib.GetRunNumberMip() << std::endl;
2324   std::map<int,RunInfo>::iterator it=ri.find(runNr);
2325 
2326   if (typeRO !=  ReadOut::Type::Caen){
2327     std::cout << "This function is not applicable for the given readout type, aborting ReevaluateLGHGCorr" << std::endl;
2328   }
2329   
2330   std::cout << "*****************************************************************" << std::endl;
2331   std::cout << "******************** Original calib *****************************" << std::endl;
2332   std::cout << "*****************************************************************" << std::endl;
2333   calib.PrintDetailedGlobalInfo();
2334   std::cout << "*****************************************************************" << std::endl;
2335   double avHGLGCorrOrg   = calib.GetAverageHGLGCorr();
2336   double avHGLGOffCorrOrg= calib.GetAverageHGLGCorrOff();
2337   double avLGHGCorrOrg   = calib.GetAverageLGHGCorr();
2338   double avLGHGOffCorrOrg= calib.GetAverageLGHGCorrOff();
2339     
2340   //==================================================================================
2341   // create additional output hist 
2342   //==================================================================================
2343   CreateOutputRootHistFile();
2344 
2345   RootOutputHist->mkdir("IndividualCells");
2346   RootOutputHist->cd("IndividualCells");
2347   
2348   ROOT::Math::MinimizerOptions::SetDefaultMinimizer("Minuit2", "Migrad");  
2349   if (maxEvents == -1){
2350     maxEvents = evts;
2351   } else {
2352     std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
2353     std::cout << "ATTENTION: YOU ARE RESETTING THE MAXIMUM NUMBER OF EVENTS TO BE PROCESSED TO: " << maxEvents << ". THIS SHOULD ONLY BE USED FOR TESTING!" << std::endl;
2354     std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
2355   }
2356   
2357   if (EventCleanup == 1){
2358     std::cout << "==============================================================================" << std::endl;
2359     std::cout << "==============================================================================" << std::endl;
2360     if (calib.GetAverageScaleHigh() != -10000 ){
2361       std::cout << "resetting rejection thresholds with average HG Scale" << std::endl;
2362       cleanupLGTh   =  ((calib.GetAverageScaleHigh()-calib.GetAverageLGHGCorrOff())/calib.GetAverageLGHGCorr() )* 2.5;
2363       cleanupHGTh   =  calib.GetAverageScaleHigh()*1.5;
2364     }
2365     std::cout << "Thresholds for rejections: \t LG: " << cleanupLGTh << "\t HG: " << cleanupHGTh << std::endl;
2366     std::cout << "==============================================================================" << std::endl;
2367     std::cout << "==============================================================================" << std::endl;
2368   }
2369   int rejectedEvents  = 0;
2370 
2371   
2372   //==================================================================================
2373   // process events from tree:
2374   // - fill spectra plots for cross checking
2375   //==================================================================================
2376   for(int i=0; i<evts && i < maxEvents ; i++){
2377     if (i%5000 == 0&& i > 0 && debug > 0) std::cout << "Reading " <<  i << "/" << evts << " events"<< std::endl;
2378     if (debug > 2 && typeRO == ReadOut::Type::Hgcroc){
2379       std::cout << "************************************* NEW EVENT " << i << "  *********************************" << std::endl;
2380     }
2381     TdataIn->GetEntry(i);
2382    
2383     bool bREvent = false;
2384     if (EventCleanup == 1){
2385       if (!event.CheckEventIntegrity(calib, cleanupLGTh, cleanupHGTh)){
2386         rejectedEvents++;
2387         bREvent = true;
2388         continue;
2389       }
2390     }
2391 
2392     
2393     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2394     // process tiles in event
2395     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2396     for(int j=0; j<event.GetNTiles(); j++){
2397     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2398     // histo filling for CAEN specific things
2399     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2400       Caen* aTile=(Caen*)event.GetTile(j);
2401       ithSpectra=hSpectra.find(aTile->GetCellID());
2402       double hgCorr = aTile->GetADCHigh()-calib.GetPedestalMeanH(aTile->GetCellID());
2403       double lgCorr = aTile->GetADCLow()-calib.GetPedestalMeanL(aTile->GetCellID());
2404       // fill spectra histos
2405       if(ithSpectra!=hSpectra.end()){
2406         ithSpectra->second.FillExtCAEN(lgCorr,hgCorr, 0., 0.);
2407       } else {
2408         RootOutputHist->cd("IndividualCells");
2409         hSpectra[aTile->GetCellID()]=TileSpectra("All",2,aTile->GetCellID(),calib.GetTileCalib(aTile->GetCellID()),event.GetROtype(),debug);
2410         hSpectra[aTile->GetCellID()].FillExtCAEN(lgCorr,hgCorr, 0., 0.);
2411         RootOutput->cd();
2412       }
2413     }
2414     RootOutput->cd();
2415     // fill tree
2416     if (!bREvent) TdataOut->Fill();
2417   }
2418   // write tree
2419   TdataOut->Write();
2420   TsetupIn->CloneTree()->Write();
2421 
2422   if (EventCleanup == 1){
2423     std::cout << "****************************************************************************************************"<< std::endl; 
2424     std::cout << "****************************************************************************************************"<< std::endl; 
2425     std::cout << rejectedEvents<< "\t/" << maxEvents  << " rejected CAEN events due to corrupted data for single channels!"<< std::endl; 
2426     std::cout << "****************************************************************************************************"<< std::endl; 
2427     std::cout << "****************************************************************************************************"<< std::endl; 
2428   }
2429   
2430   //==================================================================================
2431   // Setup general plotting infos
2432   //==================================================================================  
2433   TString outputDirPlots = GetPlotOutputDir();
2434   Double_t textSizeRel = 0.035;
2435 
2436   if (CalcBadChannel > 0 || ExtPlot > 0) {
2437     gSystem->Exec("mkdir -p "+outputDirPlots);
2438     StyleSettingsBasics("pdf");
2439     SetPlotStyle();  
2440   }
2441   int maxChannelPerLayer             = (setup->GetNMaxColumn()+1)*(setup->GetNMaxRow()+1)*(setup->GetNMaxModule()+1);
2442   int maxChannelPerLayerSingleMod    = (setup->GetNMaxColumn()+1)*(setup->GetNMaxRow()+1);
2443   
2444   //==================================================================================
2445   // Application of external bad channel map
2446   //==================================================================================
2447   if (CalcBadChannel == 1 ){
2448     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
2449     // Create monitoring histos for BC extraction
2450     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
2451 
2452     // monitoring applied pedestals
2453     TH1D* hBCvsCellID      = new TH1D( "hBC_vsCellID","Bad Channel vs CellID ; cell ID; BC flag ",
2454                                               setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5);
2455     hBCvsCellID->SetDirectory(0);
2456     TH2D* hBCVsLayer   = new TH2D( "hBCVsLayer","Bad Channel Map; layer; brd channel; BC flag  ",
2457                                               setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
2458     hBCVsLayer->SetDirectory(0);
2459 
2460     int currCells = 0;
2461     if ( debug > 0 && CalcBadChannel == 1)
2462       std::cout << "============================== setting bad channel according to external map" << std::endl;
2463     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
2464     // evaluate each tile spectrum & set BC flag
2465     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
2466     for(ithSpectra=hSpectra.begin(); ithSpectra!=hSpectra.end(); ++ithSpectra){
2467       if (currCells%20 == 0 && currCells > 0 && debug > 0)
2468         std::cout << "============================== cell " <<  currCells << " / " << hSpectra.size() << " cells" << std::endl;
2469       currCells++;
2470       short bc   = 3;
2471       if ( bcmap.size() > 0 ) {
2472         bcmapIte  = bcmap.find(ithSpectra->second.GetCellID());
2473         if(bcmapIte!=bcmap.end())
2474           bc        = bcmapIte->second;
2475         else 
2476           bc        = 3;
2477       } 
2478       
2479       long cellID   = ithSpectra->second.GetCellID();
2480       ithSpectra->second.SetBadChannelInCalib(bc);
2481       
2482       // initializing pedestal fits from calib file
2483       ithSpectra->second.InitializeNoiseFitsFromCalib();
2484       
2485       // histo filling
2486       int layer     = setup->GetLayer(cellID);
2487       int chInLayer = setup->GetChannelInLayerFull(cellID,detConf);
2488       if (debug > 0 && bc > -1 && bc < 3)
2489         std::cout << "\t" << cellID << "\t" << layer << "\t" << setup->GetRow(cellID) << "\t" << setup->GetColumn(cellID)<< "\t" << setup->GetModule(cellID) << " - quality flag: " << bc << "\t" << calib.GetBadChannel(cellID) << "\t ped H: " << calib.GetPedestalMeanH(cellID) << "\t ped L: " << calib.GetPedestalMeanL(cellID)<< std::endl;
2490 
2491       hBCvsCellID->SetBinContent(hBCvsCellID->FindBin(cellID), calib.GetBadChannel(cellID));
2492       int bin2D     = hBCVsLayer->FindBin(layer,chInLayer);
2493       hBCVsLayer->SetBinContent(bin2D, calib.GetBadChannel(cellID));
2494     }
2495     
2496     hBCvsCellID->Write();
2497     hBCVsLayer->Write();
2498 
2499     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
2500     // Create canvases for channel overview plotting
2501     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
2502     // Get run info object
2503     // create directory for plot output
2504   
2505     TCanvas* canvas2DCorr = new TCanvas("canvasCorrPlots","",0,0,1450,1300);  // gives the page size
2506     DefaultCanvasSettings( canvas2DCorr, 0.08, 0.13, 0.045, 0.07);
2507 
2508     canvas2DCorr->SetLogz(0);
2509     
2510     PlotSimple2DZRange( canvas2DCorr, hBCVsLayer, -10000, -10000, -0.1, 3.1, textSizeRel, Form("%s/BadChannelMap.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, "colz", true);    
2511     calib.SetBCCalib(true);
2512   }
2513 
2514   //==================================================================================
2515   // Reevaluation of LG-HG and HG-LG factors
2516   //==================================================================================
2517   TH2D* hLGHGCorrVsLayer = new TH2D( "hLGHGCorrVsLayer","LG-HG corr; layer; brd channel; a_{LG-HG} (arb. units) ",
2518                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
2519   hLGHGCorrVsLayer->SetDirectory(0);
2520   TH2D* hLGHGCorrRatioVsLayer = new TH2D( "hLGHGCorrRatioVsLayer","LG-HG corr old/new; layer; brd channel; a_{LG-HG} (arb. units) ",
2521                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
2522   hLGHGCorrRatioVsLayer->SetDirectory(0);
2523   TH2D* hLGHGCorrOffsetVsLayer = new TH2D( "hLGHGCorrOffsetVsLayer","LG-HG corr offset; layer; brd channel; b_{LG-HG} (arb. units) ",
2524                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
2525   hLGHGCorrOffsetVsLayer->SetDirectory(0);
2526   TH2D* hLGHGCorrOffsetRatioVsLayer = new TH2D( "hLGHGCorrOffsetRatioVsLayer","LG-HG corr offset old/new; layer; brd channel; b_{LG-HG} (arb. units) ",
2527                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
2528   hLGHGCorrOffsetRatioVsLayer->SetDirectory(0);
2529   
2530   int currCells = 0;
2531   for(ithSpectra=hSpectra.begin(); ithSpectra!=hSpectra.end(); ++ithSpectra){
2532     if (currCells%20 == 0 && currCells > 0 && debug > 0)
2533       std::cout << "============================== cell " <<  currCells << " / " << hSpectra.size() << " cells" << std::endl;
2534     currCells++;
2535     long cellID   = ithSpectra->second.GetCellID();
2536     
2537     // histo filling
2538     int layer     = setup->GetLayer(cellID);
2539     int chInLayer = setup->GetChannelInLayerFull(cellID,detConf);
2540     int bin2D     = hLGHGCorrVsLayer->FindBin(layer,chInLayer);
2541 
2542     double lghgcorrB    = calib.GetLGHGCorr(cellID);
2543     double lghgcorrOffB = calib.GetLGHGCorrOff(cellID);
2544     
2545     // fitting LG-HG, HG-LG
2546     bool isGood=ithSpectra->second.FitLGHGCorr(debug,true);
2547     double lghgcorrA    = calib.GetLGHGCorr(cellID);
2548     double lghgcorrOffA = calib.GetLGHGCorrOff(cellID);
2549     
2550     // fill histos
2551     if (ithSpectra->second.GetCorrModel(0)){
2552       double ratiolghgcorr    = lghgcorrB/lghgcorrA;
2553       double ratiolghgcorrOff = lghgcorrOffB/lghgcorrOffA;
2554       hLGHGCorrVsLayer->SetBinContent(bin2D,ithSpectra->second.GetCorrModel(0)->GetParameter(1));
2555       hLGHGCorrVsLayer->SetBinError(bin2D,ithSpectra->second.GetCorrModel(0)->GetParError(1));
2556       hLGHGCorrOffsetVsLayer->SetBinContent(bin2D,ithSpectra->second.GetCorrModel(0)->GetParameter(0));
2557       hLGHGCorrOffsetVsLayer->SetBinError(bin2D,ithSpectra->second.GetCorrModel(0)->GetParError(0));
2558       hLGHGCorrRatioVsLayer->SetBinContent(bin2D,ratiolghgcorr);
2559       hLGHGCorrOffsetRatioVsLayer->SetBinContent(bin2D,ratiolghgcorrOff);      
2560     }
2561   }
2562   
2563   std::cout << "*****************************************************************" << std::endl;
2564   std::cout << "******************** Modified calib *****************************" << std::endl;
2565   std::cout << "*****************************************************************" << std::endl;
2566   calib.PrintDetailedGlobalInfo();
2567   std::cout << "*****************************************************************" << std::endl;
2568   
2569   
2570   //==================================================================================
2571   // write calib output to root-tree output file
2572   //==================================================================================  
2573   RootOutput->cd();
2574   // print calib file to text file
2575   std::cout<<"What is the value? <ped mean high>: "<<calib.GetAveragePedestalMeanHigh() << "\t good channels: " << calib.GetNumberOfChannelsWithBCflag(3) <<std::endl;
2576   if (IsCalibSaveToFile()){
2577     TString fileCalibPrint = RootOutputName;
2578     fileCalibPrint         = fileCalibPrint.ReplaceAll(".root","_calib.txt");
2579     calib.PrintCalibToFile(fileCalibPrint);
2580   }
2581   // write calib output to 
2582   TcalibOut->Fill();
2583   TcalibOut->Write();
2584   // close file
2585   RootOutput->Close();
2586 
2587   //==================================================================================
2588   // write histo output to file as cross check
2589   //==================================================================================    
2590   RootOutputHist->cd();
2591     hLGHGCorrVsLayer->Write();
2592     hLGHGCorrOffsetVsLayer->Write();
2593     hLGHGCorrRatioVsLayer->Write();
2594     hLGHGCorrOffsetRatioVsLayer->Write();
2595   // save individual cell spectra
2596   RootOutputHist->cd("IndividualCells");
2597   for(ithSpectra=hSpectra.begin(); ithSpectra!=hSpectra.end(); ++ithSpectra){
2598     ithSpectra->second.WriteExt(true);
2599   }
2600   // close root histo output file
2601   RootOutputHist->Close();
2602   // close root input file
2603   RootInput->Close();
2604   
2605   //==================================================================================
2606   // Create plots in case extended plotting is enabled for waveforms
2607   //==================================================================================
2608   if (ExtPlot > 0){
2609     double avHGLGCorr   = calib.GetAverageHGLGCorr();
2610     double avHGLGOffCorr= calib.GetAverageHGLGCorrOff();
2611     double avLGHGCorr   = calib.GetAverageLGHGCorr();
2612     double avLGHGOffCorr= calib.GetAverageLGHGCorrOff();
2613 
2614     TCanvas* canvas2DCorr = new TCanvas("canvasCorrPlots","",0,0,1450,1300);  // gives the page size
2615     DefaultCanvasSettings( canvas2DCorr, 0.08, 0.13, 0.045, 0.07);  
2616     canvas2DCorr->SetLogz(0);
2617   
2618     PlotSimple2D( canvas2DCorr, hLGHGCorrVsLayer, -10000, -10000, textSizeRel, Form("%s/LG_HG_Corr.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true, Form( "#LT a_{LGHG} #GT = %.1f", avLGHGCorr));
2619     PlotSimple2D( canvas2DCorr, hLGHGCorrOffsetVsLayer, -10000, -10000, textSizeRel, Form("%s/LG_HG_CorrOffset.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kTRUE, "colz", true, Form( "#LT b_{LGHG} #GT = %.1f", avLGHGOffCorr));
2620     PlotSimple2D( canvas2DCorr, hLGHGCorrRatioVsLayer, -10000, -10000, textSizeRel, Form("%s/LG_HG_Corr_Ratio.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true, Form( "#LT a_{LGHG} #GT = %.1f", avLGHGCorrOrg/avLGHGCorr));
2621     PlotSimple2D( canvas2DCorr, hLGHGCorrOffsetRatioVsLayer, -10000, -10000, textSizeRel, Form("%s/LG_HG_CorrOffset_Ratio.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true, Form( "#LT b_{LGHG} #GT = %.1f", avLGHGOffCorrOrg/avLGHGOffCorr));
2622     
2623     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
2624     // Multi panel plotting
2625     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++      
2626     MultiCanvas panelPlot2D(detConf, "Transfer2D");
2627     bool init2D = panelPlot2D.Initialize(2);
2628     
2629     panelPlot2D.PlotCorr2DLayer(hSpectra, 0, -20, 340, 0, 4000,
2630                                   Form("%s/LGHG2D_Corr",outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, 0, -1, skipPlotLayer );
2631   }
2632   
2633   return true;
2634 } // end Analyses::ReevaluateLGHGCorr()
2635 
2636 
2637 // ****************************************************************************
2638 // Analyse waveform
2639 // ****************************************************************************
2640 bool Analyses::VisualizeWaveform(void){
2641   std::cout<<"Visualize Waveform"<<std::endl;
2642   int evts=TdataIn->GetEntries();
2643 
2644   // Find detector config
2645   DetConf::Type detConf = setup->GetDetectorConfig();
2646 
2647   std::map<int,RunInfo> ri=readRunInfosFromFile(RunListInputName.Data(),debug,0);
2648   
2649   std::map<int,TileSpectra> hSpectra;
2650   std::map<int, TileSpectra>::iterator ithSpectra;
2651   std::map<int,TileSpectra> hSpectraTrigg;
2652   std::map<int, TileSpectra>::iterator ithSpectraTrigg;
2653   TcalibIn->GetEntry(0);
2654   
2655   // reading first event in tree to extract runnumber & RO-type
2656   TdataIn->GetEntry(0);
2657   Int_t runNr           = event.GetRunNumber();
2658   ReadOut::Type typeRO  = event.GetROtype();
2659   std::cout<< "original run numbers calib: "<<calib.GetRunNumber() << "\t" << calib.GetRunNumberPed() << "\t" << calib.GetRunNumberMip() << std::endl;
2660   calib.SetRunNumber(runNr);
2661   calib.SetBeginRunTime(event.GetBeginRunTimeAlt());
2662   std::cout<< "reset run numbers calib: "<< calib.GetRunNumber() << "\t" << calib.GetRunNumberPed() << "\t" << calib.GetRunNumberMip() << std::endl;
2663 
2664   if (typeRO != ReadOut::Type::Hgcroc){
2665     std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
2666     std::cout << "This routine is not meant to run on CAEN data! Please check you are loading the correct inputs! \n ABORTING!!!" << std::endl;
2667     std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
2668     return false; 
2669   }
2670   
2671   //==================================================================================
2672   // create additional output hist
2673   //==================================================================================
2674   CreateOutputRootHistFile();
2675   
2676   RootOutputHist->mkdir("IndividualCells");
2677   RootOutputHist->mkdir("IndividualCellsTrigg");
2678   RootOutputHist->cd("IndividualCells");
2679   
2680   ROOT::Math::MinimizerOptions::SetDefaultMinimizer("Minuit2", "Migrad");  
2681   if (maxEvents == -1){
2682     maxEvents = evts;
2683   } else {
2684     std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
2685     std::cout << "ATTENTION: YOU ARE RESETTING THE MAXIMUM NUMBER OF EVENTS TO BE PROCESSED TO: " << maxEvents << ". THIS SHOULD ONLY BE USED FOR TESTING!" << std::endl;
2686     std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
2687   }
2688   
2689   //==================================================================================
2690   // process events from tree
2691   //==================================================================================
2692   for(int i=0; i<evts && i < maxEvents ; i++){
2693     if (i%5000 == 0&& i > 0 && debug > 0) std::cout << "Reading " <<  i << "/" << evts << " events"<< std::endl;
2694     if (debug > 2 ){
2695       std::cout << "************************************* NEW EVENT " << i << "  *********************************" << std::endl;
2696     }
2697     TdataIn->GetEntry(i);   
2698     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2699     // process tiles in event
2700     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++    
2701     for(int j=0; j<event.GetNTiles(); j++){
2702       //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
2703       // histo filling for HGCROC specific things 
2704       //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++        
2705       Hgcroc* aTile=(Hgcroc*)event.GetTile(j);
2706       int cellID = aTile->GetCellID();
2707       ithSpectra=hSpectra.find(cellID);
2708       ithSpectraTrigg=hSpectraTrigg.find(cellID);
2709       
2710       // obtain integrated tile quantities for histo filling
2711       double adc = aTile->GetIntegratedADC();
2712       double tot = aTile->GetRawTOT();
2713       double toa = aTile->GetRawTOA();
2714       // obtain samples in which TOA, TOT, maximum ADC are firing
2715       Int_t nSampTOA    = aTile->GetCorrectedFirstTOASample(calib.GetToAOff(cellID));        
2716       Int_t nOffEmpty   = 2;
2717       
2718       // fill spectra histos
2719       if(ithSpectra!=hSpectra.end()){
2720         ithSpectra->second.FillExtHGCROC(adc,toa,tot,nSampTOA,-1);
2721         ithSpectra->second.FillWaveformVsTime(aTile->GetADCWaveform(), aTile->GetCorrectedTOA(), calib.GetPedestalMeanH(cellID),nOffEmpty);
2722       } else {
2723         RootOutputHist->cd("IndividualCells");
2724         hSpectra[cellID]=TileSpectra("full",3,cellID,calib.GetTileCalib(cellID),event.GetROtype(),debug);
2725         hSpectra[cellID].FillExtHGCROC(adc,toa,tot,nSampTOA,-1);
2726         hSpectra[cellID].FillWaveformVsTime(aTile->GetADCWaveform(), aTile->GetCorrectedTOA(), calib.GetPedestalMeanH(cellID),nOffEmpty);
2727       }
2728       // fill spectra histos for signals with ToA
2729       if (toa > 0 ){      // needed for summing tests
2730         if(ithSpectraTrigg!=hSpectraTrigg.end()){
2731           ithSpectraTrigg->second.FillExtHGCROC(adc,toa,tot,nSampTOA,-1);
2732           ithSpectraTrigg->second.FillWaveformVsTime(aTile->GetADCWaveform(), aTile->GetCorrectedTOA(), calib.GetPedestalMeanH(cellID),nOffEmpty);
2733         } else {
2734           RootOutputHist->cd("IndividualCellsTrigg");
2735           hSpectraTrigg[cellID]=TileSpectra("signal",3,cellID,calib.GetTileCalib(cellID),event.GetROtype(),debug);
2736           hSpectraTrigg[cellID].FillExtHGCROC(adc,toa,tot,nSampTOA,-1);
2737           hSpectraTrigg[cellID].FillWaveformVsTime(aTile->GetADCWaveform(), aTile->GetCorrectedTOA(), calib.GetPedestalMeanH(cellID),nOffEmpty);
2738         }
2739       }
2740     }
2741   }
2742 
2743   //==================================================================================
2744   // Setup general plotting infos
2745   //==================================================================================    
2746   std::map<int,RunInfo>::iterator it=ri.find(runNr);
2747   TString outputDirPlots = GetPlotOutputDir();
2748   Double_t textSizeRel = 0.035;
2749 
2750   gSystem->Exec("mkdir -p "+outputDirPlots);
2751   StyleSettingsBasics("pdf");
2752   SetPlotStyle();  
2753   
2754   // print general calib info
2755   calib.PrintGlobalInfo();  
2756 
2757   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
2758   // plot single layers 
2759   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
2760   MultiCanvas panelPlot(detConf, "VisuWave");
2761   bool init1D = panelPlot.Initialize(1);
2762   MultiCanvas panelPlot2D(detConf, "VisuWave2D");
2763   bool init2D = panelPlot2D.Initialize(2);
2764     
2765   panelPlot2D.PlotCorr2DLayer(hSpectra, 1, -25000, (it->second.samples)*25000, 0, 300,
2766                               Form("%s/Waveform",outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, 0, -1, skipPlotLayer  );
2767   panelPlot2D.PlotCorr2DLayer(hSpectra, 2, 0, 1024, 0, 300,
2768                               Form("%s/TOA_ADC",outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, 0, -1, skipPlotLayer );
2769   panelPlot2D.PlotCorr2DLayer(hSpectra, 3, 0, 1024, 0, it->second.samples,
2770                               Form("%s/TOA_Sample",outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, 0, -1, skipPlotLayer );
2771   panelPlot2D.PlotCorr2DLayer(hSpectraTrigg, 1, -25000, (it->second.samples)*25000, 0, 300,
2772                               Form("%s/WaveformSignal",outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, 0, -1, skipPlotLayer );
2773   panelPlot2D.PlotCorr2DLayer(hSpectraTrigg, 2, 0, 1024, 0, 300,
2774                               Form("%s/TOA_ADC_Signal",outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, 0, -1, skipPlotLayer );
2775   panelPlot2D.PlotCorr2DLayer(hSpectraTrigg, 3, 0, 1024, 0, it->second.samples,
2776                               Form("%s/TOA_Sample_Signal",outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, 0, -1, skipPlotLayer );
2777   if (ExtPlot > 1){
2778     panelPlot.PlotSpectra( hSpectra, 0, -100, 1024, 1.2, 
2779                            Form("%s/Spectra_ADC" ,outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);
2780     panelPlot.PlotSpectra( hSpectra, 3, 0, 1024, 1.2, 
2781                            Form("%s/TOA" ,outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);
2782     panelPlot.PlotSpectra( hSpectra, 4, 0, 4096, 1.2, 
2783                            Form("%s/TOT" ,outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);
2784   }
2785   
2786   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
2787   // store individual histogram outputs
2788   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
2789   RootOutputHist->cd();
2790   RootOutputHist->cd("IndividualCells");
2791   for(ithSpectra=hSpectra.begin(); ithSpectra!=hSpectra.end(); ++ithSpectra){
2792     ithSpectra->second.WriteExt(true);
2793   }
2794   RootOutputHist->cd("IndividualCellsTrigg");
2795   if (typeRO == ReadOut::Type::Hgcroc){
2796     for(ithSpectraTrigg=hSpectraTrigg.begin(); ithSpectraTrigg!=hSpectraTrigg.end(); ++ithSpectraTrigg){
2797       ithSpectraTrigg->second.WriteExt(true);
2798     }
2799   }
2800   RootInput->Close();
2801   return true;
2802 } // end Analyses::VisualizeWaveform()
2803 
2804 //***********************************************************************************************
2805 //*********************** intial scaling calculation function *********************************
2806 //***********************************************************************************************
2807 bool Analyses::GetScaling(void){ 
2808   std::cout<<"GetScaling"<<std::endl;
2809   auto start = std::chrono::steady_clock::now();
2810   
2811   std::map<int,RunInfo> ri=readRunInfosFromFile(RunListInputName.Data(),debug,0);
2812   
2813   std::map<int,TileSpectra> hSpectra;
2814   std::map<int,TileSpectra> hSpectraTrigg;
2815   std::map<int, TileSpectra>::iterator ithSpectra;
2816   std::map<int, TileSpectra>::iterator ithSpectraTrigg;
2817 
2818   ROOT::Math::MinimizerOptions::SetDefaultMinimizer("Minuit2", "Migrad");  
2819   CreateOutputRootHistFile();
2820 
2821   // reading calib from file
2822   TcalibIn->GetEntry(0);
2823   // check whether calib should be overwritten based on external text file
2824   if (OverWriteCalib){
2825     calib.ReadCalibFromTextFile(ExternalCalibFile,debug);
2826   }
2827   
2828   // reading first event in tree to extract runnumber & RO-type
2829   TdataIn->GetEntry(0);
2830   int evts=TdataIn->GetEntries();
2831   Int_t runNr           = event.GetRunNumber();
2832   ReadOut::Type typeRO  = event.GetROtype();
2833   std::cout<< "Total number of events: " << evts << std::endl;
2834   std::cout<< "original run numbers calib: "<<calib.GetRunNumber() << "\t" << calib.GetRunNumberPed() << "\t" << calib.GetRunNumberMip() << std::endl;
2835   // reseting run numbers for Mip calib
2836   calib.SetRunNumberMip(runNr);
2837   calib.SetBeginRunTimeMip(event.GetBeginRunTimeAlt());
2838   std::cout<< "reset run numbers calib: "<< calib.GetRunNumber() << "\t" << calib.GetRunNumberPed() << "\t" << calib.GetRunNumberMip() << std::endl;  // Get run info object
2839   std::map<int,RunInfo>::iterator it=ri.find(runNr);
2840   // set year of data taking in case adjustments are necessary
2841   SetYear(it->second.year);
2842   
2843   
2844   
2845   // find detector config
2846   DetConf::Type detConf   = setup->GetDetectorConfig();
2847   
2848   //==================================================================================
2849   // first pass over tree to extract spectra 
2850   //==================================================================================
2851   // entering histoOutput file
2852   RootOutputHist->mkdir("IndividualCells");
2853   RootOutputHist->cd("IndividualCells");
2854 
2855   if (maxEvents == -1){
2856     maxEvents = evts;
2857   } else {
2858     std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
2859     std::cout << "ATTENTION: YOU ARE RESETTING THE MAXIMUM NUMBER OF EVENTS TO BE PROCESSED TO: " << maxEvents << ". THIS SHOULD ONLY BE USED FOR TESTING!" << std::endl;
2860     std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
2861   }
2862   // set debug frequency
2863   int evtDeb = 5000;
2864   if (typeRO != ReadOut::Type::Caen)
2865     evtDeb = 2500;
2866   
2867   for(int i=0; i<evts && i < maxEvents; i++){ // GetScaling() first pass through tree
2868     TdataIn->GetEntry(i);
2869     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2870     // reset calib object info 
2871     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2872     if (i%evtDeb == 0 && i > 0 && debug > 0){
2873       auto end = std::chrono::steady_clock::now();
2874       auto duration = std::chrono::duration_cast<std::chrono::seconds>(end - start);
2875       std::cout << "Step 0: Reading " <<  i << " / " << evts << " events"  << " duration: " << duration.count() << " seconds"<< std::endl;
2876     }
2877     if (i == 0 && debug > 2) std::cout << "decoding cell IDs" << std::endl ;
2878     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2879     // process tiles in event
2880     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2881     for(int j=0; j<event.GetNTiles(); j++){ // loop over tiles in event
2882       //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2883       // CAEN treatment
2884       //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++      
2885       if (typeRO == ReadOut::Type::Caen) {
2886         Caen* aTile=(Caen*)event.GetTile(j);
2887         if (i == 0 && debug > 2) std::cout << ((TString)setup->DecodeCellID(aTile->GetCellID())).Data() << std::endl;
2888         
2889         ithSpectra=hSpectra.find(aTile->GetCellID());
2890         double hgCorr = aTile->GetADCHigh()-calib.GetPedestalMeanH(aTile->GetCellID());
2891         double lgCorr = aTile->GetADCLow()-calib.GetPedestalMeanL(aTile->GetCellID());
2892         
2893         // fill spectra histos    
2894         if(ithSpectra!=hSpectra.end()){
2895           ithSpectra->second.FillSpectraCAEN(lgCorr,hgCorr);
2896           if (hgCorr > 3*calib.GetPedestalSigH(aTile->GetCellID()) && lgCorr > 3*calib.GetPedestalSigL(aTile->GetCellID()) && hgCorr < 3900 )
2897             ithSpectra->second.FillCorrCAEN(lgCorr,hgCorr);
2898         } else {
2899           RootOutputHist->cd("IndividualCells");
2900           hSpectra[aTile->GetCellID()]=TileSpectra("mip1st",aTile->GetCellID(),calib.GetTileCalib(aTile->GetCellID()),event.GetROtype(), debug);
2901           hSpectra[aTile->GetCellID()].FillSpectraCAEN(lgCorr,hgCorr);;
2902           if (hgCorr > 3*calib.GetPedestalSigH(aTile->GetCellID()) && lgCorr > 3*calib.GetPedestalSigL(aTile->GetCellID() && hgCorr < 3900) )
2903             hSpectra[aTile->GetCellID()].FillCorrCAEN(lgCorr,hgCorr);
2904           RootOutput->cd();
2905         }
2906       //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2907       // HGCROC treatment
2908       //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2909       } else if (typeRO == ReadOut::Type::Hgcroc) { 
2910         Hgcroc* aTile=(Hgcroc*)event.GetTile(j);
2911         if (i == 0 && debug > 2) std::cout << ((TString)setup->DecodeCellID(aTile->GetCellID())).Data() << std::endl;
2912         
2913         ithSpectra=hSpectra.find(aTile->GetCellID());
2914         double adc = aTile->GetIntegratedADC();        
2915         double tot = aTile->GetRawTOT();
2916         double toa = aTile->GetRawTOA();
2917 
2918         // for CalibSummary:
2919         // get voltage for the run (Setup?) event.GetVop()
2920         // run number is runNr
2921         
2922         // fill spectra histos    
2923         if(ithSpectra!=hSpectra.end()){
2924           ithSpectra->second.FillHGCROC(adc,toa,tot);
2925         } else {
2926           RootOutputHist->cd("IndividualCells");
2927           hSpectra[aTile->GetCellID()]=TileSpectra("mip1st",aTile->GetCellID(),calib.GetTileCalib(aTile->GetCellID()),event.GetROtype(), debug);
2928           hSpectra[aTile->GetCellID()].FillHGCROC(adc,toa,tot);
2929           RootOutput->cd();
2930         }
2931         
2932       } // end HGCROC treatment
2933     } // end loop over tiles in event 
2934     RootOutput->cd();
2935   } // GetScaling() end first pass through tree (loop over events)
2936   // TdataOut->Write();
2937   TsetupIn->CloneTree()->Write();
2938   
2939   RootOutputHist->cd();
2940  
2941   //==================================================================================
2942   // Monitoring histos for calib parameters & fits results of 1st iteration 
2943   //==================================================================================
2944   int maxChannelPerLayer             = (setup->GetNMaxColumn()+1)*(setup->GetNMaxRow()+1)*(setup->GetNMaxModule()+1);
2945   int maxChannelPerLayerSingleMod    = (setup->GetNMaxColumn()+1)*(setup->GetNMaxRow()+1);
2946 
2947   // monitoring applied pedestals
2948   TH1D* hMeanPedHGvsCellID      = new TH1D( "hMeanPedHG_vsCellID","mean Ped High Gain vs CellID ; cell ID; #mu_{noise, HG} (arb. units) ",
2949                                             setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5);
2950   hMeanPedHGvsCellID->SetDirectory(0);
2951   TH1D* hMeanPedHG              = new TH1D( "hMeanPedHG","mean Ped High Gain ; #mu_{noise, HG} (arb. units); counts ",
2952                                             500, -0.5, 500-0.5);
2953   hMeanPedHG->SetDirectory(0);
2954   TH2D* hspectraHGMeanVsLayer   = new TH2D( "hspectraHGMeanVsLayer","Mean Ped High Gain; layer; brd channel; #mu_{Ped HG} (arb. units) ",
2955                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
2956   hspectraHGMeanVsLayer->SetDirectory(0);
2957   TH2D* hspectraHGSigmaVsLayer  = new TH2D( "hspectraHGSigmaVsLayer","Sigma Ped High Gain; layer; brd channel; #sigma_{Ped HG} (arb. units) ",
2958                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
2959   hspectraHGSigmaVsLayer->SetDirectory(0);
2960   TH1D* hMeanPedLGvsCellID      = new TH1D( "hMeanPedLG_vsCellID","mean Ped Low Gain vs CellID ; cell ID; #mu_{noise, LG} (arb. units) ",
2961                                             setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5);
2962   hMeanPedLGvsCellID->SetDirectory(0);
2963   TH1D* hMeanPedLG             = new TH1D( "hMeanPedLG","mean Ped Low Gain ; #mu_{noise, LG} (arb. units); counts ",
2964                                             500, -0.5, 500-0.5);
2965   hMeanPedLG->SetDirectory(0);
2966   TH2D* hspectraLGMeanVsLayer   = new TH2D( "hspectraLGMeanVsLayer","Mean Ped Low Gain; layer; brd channel; #mu_{PED LG} (arb. units) ",
2967                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
2968   hspectraLGMeanVsLayer->SetDirectory(0);
2969   TH2D* hspectraLGSigmaVsLayer  = new TH2D( "hspectraLGSigmaVsLayer","Sigma Ped Low Gain; layer; brd channel; #sigma_{Ped LG} (arb. units)",
2970                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
2971   hspectraLGSigmaVsLayer->SetDirectory(0);
2972   // monitoring 1st iteration mip fits
2973   TH2D* hspectraHGMaxVsLayer1st   = new TH2D( "hspectraHGMaxVsLayer_1st","Max High Gain; layer; brd channel; Max_{HG, 1^{st}} (arb. units) ",
2974                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
2975   hspectraHGMaxVsLayer1st->SetDirectory(0);
2976   TH2D* hspectraHGFWHMVsLayer1st   = new TH2D( "hspectraHGFWHMVsLayer_1st","FWHM High Gain; layer; brd channel; FWHM_{HG, 1^{st}} (arb. units) ",
2977                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
2978   hspectraHGFWHMVsLayer1st->SetDirectory(0);
2979   TH2D* hspectraHGLMPVVsLayer1st   = new TH2D( "hspectraHGLMPVVsLayer_1st","MPV High Gain; layer; brd channel; MPV_{HG, 1^{st}} (arb. units) ",
2980                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
2981   hspectraHGLMPVVsLayer1st->SetDirectory(0);
2982   TH2D* hspectraHGLSigmaVsLayer1st = new TH2D( "hspectraHGLSigmaVsLayer_1st","Sigma Landau High Gain; layer; brd channel; #sigma_{L,HG, 1^{st}} (arb. units) ",
2983                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
2984   hspectraHGLSigmaVsLayer1st->SetDirectory(0);
2985   TH2D* hspectraHGGSigmaVsLayer1st = new TH2D( "hspectraHGGSigmaVsLayer_1st","Sigma Gauss High Gain; layer; brd channel; #sigma_{G,HG, 1^{st}} (arb. units) ",
2986                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
2987   hspectraHGGSigmaVsLayer1st->SetDirectory(0);
2988   TH2D* hLGHGCorrVsLayer = new TH2D( "hLGHGCorrVsLayer","LG-HG corr; layer; brd channel; a_{LG-HG} (arb. units) ",
2989                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
2990   hLGHGCorrVsLayer->SetDirectory(0);
2991   TH2D* hHGLGCorrVsLayer = new TH2D( "hHGLGCorrVsLayer","HG-LG corr; layer; brd channel; a_{HG-LG} (arb. units) ",
2992                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
2993   hHGLGCorrVsLayer->SetDirectory(0);
2994   TH2D* hLGHGCorrOffsetVsLayer = new TH2D( "hLGHGCorrOffsetVsLayer","LG-HG corr offset; layer; brd channel; b_{LG-HG} (arb. units) ",
2995                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
2996   hLGHGCorrOffsetVsLayer->SetDirectory(0);
2997   TH2D* hHGLGCorrOffsetVsLayer = new TH2D( "hHGLGCorrVsLayer","HG-LG corr offset; layer; brd channel; b_{HG-LG} (arb. units) ",
2998                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
2999   hHGLGCorrOffsetVsLayer->SetDirectory(0);
3000   
3001   TH1D* hMaxHG1st             = new TH1D( "hMaxHG1st","Max High Gain ;Max_{HG, 1^{st}} (arb. units) ; counts ",
3002                                             2000, -0.5, 2000-0.5);
3003   hMaxHG1st->SetDirectory(0);
3004   TH1D* hLGHGCorr             = new TH1D( "hLGHGCorr","LG-HG corr ; a_{LG-HG} (arb. units) ; counts ",
3005                                             400, -20, 20);
3006   hLGHGCorr->SetDirectory(0);
3007   TH1D* hHGLGCorr             = new TH1D( "hHGLGCorr","LG-HG corr ; a_{HG-LG} (arb. units) ; counts ",
3008                                             400, -1., 1.);
3009   hHGLGCorr->SetDirectory(0);
3010 
3011   TH1D* hNPosTrigg            = new TH1D( "hNPosTrigg","Positions triggered ;# Pos_{trig} (arb. units) ; counts ", 
3012                                           maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
3013   hNPosTrigg->SetDirectory(0);
3014   
3015   
3016   // fit pedestal
3017   double* parameters    = new double[6];
3018   double* parErrAndRes  = new double[6];
3019   bool isGood;
3020   int currCells = 0;
3021   if ( debug > 0)
3022     std::cout << "============================== starting fitting 1st iteration" << std::endl;
3023   //==================================================================================
3024   // 1st iteration of fitting of individual cell spectra
3025   //==================================================================================
3026   for(ithSpectra=hSpectra.begin(); ithSpectra!=hSpectra.end(); ++ithSpectra){ // 1st iteration, loop through spectra
3027     if (currCells%20 == 0 && currCells > 0 && debug > 0)
3028       std::cout << "============================== cell " <<  currCells << " / " << hSpectra.size() << " cells" << std::endl;
3029     currCells++;
3030     // reset parameters & errors
3031     for (int p = 0; p < 6; p++){
3032       parameters[p]   = 0;
3033       parErrAndRes[p] = 0;
3034     }
3035     // fit MIP for CAEN HG/ HGCROC ADC
3036     isGood        = ithSpectra->second.FitMipHG(parameters, parErrAndRes, debug, yearData, false, calib.GetVov(), 1);
3037     
3038     // fill cross-check histos
3039     long cellID   = ithSpectra->second.GetCellID();
3040     int layer     = setup->GetLayer(cellID);
3041     int chInLayer = setup->GetChannelInLayerFull(cellID, detConf);
3042     hMeanPedHGvsCellID->SetBinContent(hMeanPedHGvsCellID->FindBin(cellID), calib.GetPedestalMeanH(cellID));
3043     hMeanPedLGvsCellID->SetBinContent(hMeanPedLGvsCellID->FindBin(cellID), calib.GetPedestalMeanL(cellID));
3044     hMeanPedHG->Fill(calib.GetPedestalMeanH(cellID));
3045     hMeanPedLG->Fill(calib.GetPedestalMeanL(cellID));
3046     
3047     int bin2D     = hspectraHGMeanVsLayer->FindBin(layer,chInLayer);
3048     hspectraHGMeanVsLayer->SetBinContent(bin2D, calib.GetPedestalMeanH(cellID));
3049     hspectraHGSigmaVsLayer->SetBinContent(bin2D, calib.GetPedestalSigH(cellID));
3050     hspectraLGMeanVsLayer->SetBinContent(bin2D, calib.GetPedestalMeanL(cellID));
3051     hspectraLGSigmaVsLayer->SetBinContent(bin2D, calib.GetPedestalSigL(cellID));
3052 
3053     if (isGood){
3054       // get uncertainty on HG Max
3055       double rel_err_L_MPV = parErrAndRes[1]/parameters[1]; // Landau MPV error / MPV
3056       double sigma_Max = rel_err_L_MPV * parameters[4]; // relative MPV err * Max ADC value
3057       hspectraHGMaxVsLayer1st->SetBinContent(bin2D, parameters[4]);
3058       hspectraHGMaxVsLayer1st->SetBinError(bin2D, sigma_Max);
3059       hspectraHGFWHMVsLayer1st->SetBinContent(bin2D, parameters[5]);
3060       hspectraHGLMPVVsLayer1st->SetBinContent(bin2D, parameters[1]);
3061       hspectraHGLMPVVsLayer1st->SetBinError(bin2D, parErrAndRes[1]);
3062       hspectraHGLSigmaVsLayer1st->SetBinContent(bin2D, parameters[0]);
3063       hspectraHGLSigmaVsLayer1st->SetBinError(bin2D, parErrAndRes[0]);
3064       hspectraHGGSigmaVsLayer1st->SetBinContent(bin2D, parameters[3]);
3065       hspectraHGGSigmaVsLayer1st->SetBinError(bin2D, parErrAndRes[3]);
3066       
3067       hMaxHG1st->Fill(parameters[4]);
3068     }
3069     
3070     // fit correlation LG-HG, HG-LG for CAEN data and fill histograms
3071     if (typeRO == ReadOut::Type::Caen) {
3072       // fitting LG-HG, HG-LG
3073       isGood=ithSpectra->second.FitCorrCAEN(debug);
3074       // fill histos
3075       if (ithSpectra->second.GetCorrModel(0)){
3076         hLGHGCorrVsLayer->SetBinContent(bin2D,ithSpectra->second.GetCorrModel(0)->GetParameter(1));
3077         hLGHGCorrVsLayer->SetBinError(bin2D,ithSpectra->second.GetCorrModel(0)->GetParError(1));
3078         hLGHGCorrOffsetVsLayer->SetBinContent(bin2D,ithSpectra->second.GetCorrModel(0)->GetParameter(0));
3079         hLGHGCorrOffsetVsLayer->SetBinError(bin2D,ithSpectra->second.GetCorrModel(0)->GetParError(0));
3080         hLGHGCorr->Fill(ithSpectra->second.GetCorrModel(0)->GetParameter(1));
3081       } 
3082       if (ithSpectra->second.GetCorrModel(1)){
3083         hHGLGCorrVsLayer->SetBinContent(bin2D,ithSpectra->second.GetCorrModel(1)->GetParameter(1));
3084         hHGLGCorrVsLayer->SetBinError(bin2D,ithSpectra->second.GetCorrModel(1)->GetParError(1));    
3085         hHGLGCorrOffsetVsLayer->SetBinContent(bin2D,ithSpectra->second.GetCorrModel(1)->GetParameter(0));
3086         hHGLGCorrOffsetVsLayer->SetBinError(bin2D,ithSpectra->second.GetCorrModel(1)->GetParError(0));    
3087         hHGLGCorr->Fill(ithSpectra->second.GetCorrModel(1)->GetParameter(1));
3088       }
3089     }
3090   } // end loop over spectra for 1st fitting iteration
3091   if ( debug > 0)
3092     std::cout << "============================== done fitting 1st iteration" << std::endl;
3093 
3094   //==================================================================================
3095   // setup additional monitoring histos
3096   //==================================================================================  
3097   TH1D* hHGTileSum[100]; // ATTENTION this array needs to be large enough to fit an entire plane 
3098   for (int c = 0; c < maxChannelPerLayer; c++ ){
3099     hHGTileSum[c] = new TH1D( Form("hHGTileSum_absChB%d",c),"av ADC surrounding cells ; ADC (arb. units); counts ",
3100                               4000, -0.5, 4000-0.5);
3101     hHGTileSum[c]->SetDirectory(0);
3102   }
3103   
3104   //==================================================================================
3105   // setup trigger sel & general selection parameters
3106   //==================================================================================
3107   TRandom3* rand    = new TRandom3();
3108   Int_t localTriggerTiles = 4;
3109   double factorMinTrigg   = 0.5;
3110   double factorMaxTrigg   = 4.;
3111   if (typeRO == ReadOut::Type::Caen){
3112     if (yearData == 2023){
3113       localTriggerTiles = 6;
3114       factorMaxTrigg    = 3.;
3115     }
3116   } else if (typeRO == ReadOut::Type::Hgcroc){
3117     localTriggerTiles = 6;
3118     factorMinTrigg    = 0.3;
3119   }
3120   
3121   RootOutputHist->mkdir("IndividualCellsTrigg");
3122   RootOutputHist->cd("IndividualCellsTrigg");  
3123   //==================================================================================
3124   // first fitting for each cell
3125   //==================================================================================
3126   int actCh1st = 0; 
3127   double averageScale = calib.GetAverageScaleHigh(actCh1st);
3128   int actChIalt                  = 0;
3129   double averageNTilesI          = 0.;
3130   double averageScalePerTile     = calib.GetAverageScaleHighPerSingleLayer(actChIalt, averageNTilesI);
3131   
3132   double meanPedSign  = calib.GetAveragePedestalSigHigh();
3133   double meanFWHMHG   = calib.GetAverageScaleWidthHigh();
3134   double avHGLGCorr   = calib.GetAverageHGLGCorr();
3135   double avHGLGOffCorr= calib.GetAverageHGLGCorrOff();
3136   double avLGHGCorr   = calib.GetAverageLGHGCorr();
3137   double avLGHGOffCorr= calib.GetAverageLGHGCorrOff();
3138   if (typeRO == ReadOut::Type::Caen){
3139     std::cout << "average HG mip: " << averageScale << "\t active ch: "<< actCh1st<< std::endl;
3140   } else {
3141     std::cout << "average mip: " << averageScale << " per tile mip: "<< averageScalePerTile << "\t act. ch: "<< actCh1st << "\t av tiles/seg "<< averageNTilesI << std::endl;
3142   }
3143   
3144   std::map<int,int> mapNActiveLayers;
3145   std::map<int,double> chargeTotChInLayer;
3146   
3147   for (int k = 0; k < maxChannelPerLayer;k++){
3148     mapNActiveLayers[k] = 0;
3149   }
3150   int eventsNoClearTrigg = 0;
3151   
3152   for(int i=0; i<evts && i < maxEvents; i++){ // loop over events
3153     TdataIn->GetEntry(i);
3154     if (i%evtDeb == 0 && i > 0 && debug > 0){
3155       auto end = std::chrono::steady_clock::now();
3156       auto duration = std::chrono::duration_cast<std::chrono::seconds>(end - start);
3157       std::cout << "1st step: Reading " <<  i << " / " << evts << " events"  << " duration: " << duration.count() << " seconds"<< std::endl;
3158     }
3159 
3160     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3161     // find likely trigger region
3162     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3163     // CAEN column pre selection
3164     if (typeRO == ReadOut::Type::Caen) {
3165       for (int k = 0; k < maxChannelPerLayer;k++){
3166         chargeTotChInLayer[k] = 0;
3167       }
3168       for(int j=0; j<event.GetNTiles(); j++){
3169         Caen* aTile=(Caen*)event.GetTile(j);
3170         double hgCorr = aTile->GetADCHigh()-calib.GetPedestalMeanH(aTile->GetCellID());
3171         int chInLayer   = setup->GetChannelInLayerFull(aTile->GetCellID(), detConf);
3172         if (i == 0){
3173           if (calib.GetBCCalib()){
3174             if(calib.GetBadChannel(aTile->GetCellID())>1) 
3175               mapNActiveLayers[chInLayer]= mapNActiveLayers[chInLayer]+1;
3176           } else {
3177             mapNActiveLayers[chInLayer]= mapNActiveLayers[chInLayer]+1;
3178           }
3179         }
3180         if (calib.GetBCCalib() && calib.GetBadChannel(aTile->GetCellID())>1){
3181           chargeTotChInLayer[chInLayer] = chargeTotChInLayer[chInLayer]+hgCorr;
3182         } else if (!calib.GetBCCalib()){
3183           chargeTotChInLayer[chInLayer] = chargeTotChInLayer[chInLayer]+hgCorr;
3184         }
3185       }
3186       int nPosTrigg  = 0;
3187       for (int k = 0; k < maxChannelPerLayer;k++){
3188         chargeTotChInLayer[k] = chargeTotChInLayer[k]/(double)mapNActiveLayers[k];
3189         if (chargeTotChInLayer[k] > minFracTriggThre* meanPedSign)
3190           nPosTrigg++;
3191       }
3192       hNPosTrigg->Fill(nPosTrigg);
3193       if (nPosTrigg == 0){
3194         continue;
3195         eventsNoClearTrigg++;
3196       }  
3197     // HGCROC column pre selection
3198     } else if (typeRO == ReadOut::Type::Hgcroc) {
3199       for (int k = 0; k < maxChannelPerLayer;k++){
3200         chargeTotChInLayer[k] = 0;
3201       }
3202       for(int j=0; j<event.GetNTiles(); j++){
3203         Hgcroc* aTile=(Hgcroc*)event.GetTile(j);
3204         double adc      = aTile->GetIntegratedADC();
3205         int chInLayer   = setup->GetChannelInLayerFull(aTile->GetCellID(), detConf);
3206         if (i == 0){
3207           if (calib.GetBCCalib()){
3208             if(calib.GetBadChannel(aTile->GetCellID())>1) 
3209               mapNActiveLayers[chInLayer]= mapNActiveLayers[chInLayer]+1;
3210           } else {
3211             mapNActiveLayers[chInLayer]= mapNActiveLayers[chInLayer]+1;
3212           }
3213         }
3214         if (calib.GetBCCalib() && calib.GetBadChannel(aTile->GetCellID())>1){
3215           chargeTotChInLayer[chInLayer] = chargeTotChInLayer[chInLayer]+adc;
3216         } else if (!calib.GetBCCalib()){
3217           chargeTotChInLayer[chInLayer] = chargeTotChInLayer[chInLayer]+adc;
3218         }
3219       }
3220       int nPosTrigg  = 0;
3221       for (int k = 0; k < maxChannelPerLayer;k++){
3222         chargeTotChInLayer[k] = chargeTotChInLayer[k]/(double)mapNActiveLayers[k];
3223         if (chargeTotChInLayer[k] > minFracTriggThre* meanPedSign)
3224           nPosTrigg++;
3225       }
3226       hNPosTrigg->Fill(nPosTrigg);
3227       if (nPosTrigg == 0){
3228         continue;
3229         eventsNoClearTrigg++;
3230       }
3231     }
3232     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3233     // process tiles in event
3234     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++    
3235     for(int j=0; j<event.GetNTiles(); j++){
3236       //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3237       // histo filling for CAEN specific things
3238       //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++      
3239       if (typeRO == ReadOut::Type::Caen) {
3240         Caen* aTile=(Caen*)event.GetTile(j);
3241         if (i == 0 && debug > 2) std::cout << ((TString)setup->DecodeCellID(aTile->GetCellID())).Data() << std::endl;
3242         long currCellID = aTile->GetCellID();
3243         int chInLayer       = setup->GetChannelInLayerFull(currCellID, detConf);
3244         double triggPrim    = -50.;
3245         bool localMuonTrigg = false;
3246 
3247         // read current tile
3248         ithSpectraTrigg=hSpectraTrigg.find(aTile->GetCellID());
3249         double hgCorr = aTile->GetADCHigh()-calib.GetPedestalMeanH(aTile->GetCellID());
3250         double lgCorr = aTile->GetADCLow()-calib.GetPedestalMeanL(aTile->GetCellID());
3251 
3252         if (chargeTotChInLayer[chInLayer] > minFracTriggThre* meanPedSign){
3253           triggPrim = event.CalculateLocalMuonTrigg(calib, rand, currCellID, localTriggerTiles, avLGHGCorr);
3254           aTile->SetLocalTriggerPrimitive(triggPrim);
3255           localMuonTrigg = event.InspectIfLocalMuonTrigg(currCellID, averageScalePerTile, factorMinTrigg, factorMaxTrigg);
3256         } else {
3257           aTile->SetLocalTriggerPrimitive(triggPrim);
3258         }
3259         
3260         if (triggPrim != -50.){
3261           hHGTileSum[chInLayer]->Fill(aTile->GetLocalTriggerPrimitive());
3262           
3263           if(ithSpectraTrigg!=hSpectraTrigg.end()){
3264             ithSpectraTrigg->second.FillTrigger(aTile->GetLocalTriggerPrimitive());
3265           } else {
3266             RootOutputHist->cd("IndividualCellsTrigg");
3267             hSpectraTrigg[currCellID]=TileSpectra("mipTrigg",currCellID,calib.GetTileCalib(currCellID),event.GetROtype(),debug);
3268             hSpectraTrigg[currCellID].FillTrigger(aTile->GetLocalTriggerPrimitive());;
3269             RootOutput->cd();
3270           }
3271           // only fill tile spectra if 4 surrounding tiles on average are compatible with muon response
3272           if (localMuonTrigg){
3273             aTile->SetLocalTriggerBit(1);
3274             ithSpectraTrigg=hSpectraTrigg.find(aTile->GetCellID());
3275             ithSpectraTrigg->second.FillSpectraCAEN(lgCorr,hgCorr);
3276             if (hgCorr > 3*calib.GetPedestalSigH(currCellID) && lgCorr > 3*calib.GetPedestalSigL(currCellID) && hgCorr < 3900 )
3277               ithSpectraTrigg->second.FillCorrCAEN(lgCorr,hgCorr);
3278           }
3279         }
3280         
3281       //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
3282       // histo filling for HGCROC specific things & resetting of ped
3283       //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++        
3284       } else if (typeRO == ReadOut::Type::Hgcroc) {
3285         Hgcroc* aTile=(Hgcroc*)event.GetTile(j);
3286         if (i == 0 && debug > 2) std::cout << ((TString)setup->DecodeCellID(aTile->GetCellID())).Data() << std::endl;
3287         long currCellID = aTile->GetCellID();
3288         
3289         ithSpectraTrigg=hSpectraTrigg.find(aTile->GetCellID());
3290         // double adc = aTile->GetPedestal()+aTile->GetIntegratedADC();
3291         double adc = aTile->GetIntegratedADC();
3292         double tot = aTile->GetRawTOT();
3293         double toa = aTile->GetRawTOA();
3294         int chInLayer       = setup->GetChannelInLayerFull(currCellID, detConf);
3295         double triggPrim    = -50.;
3296         bool localMuonTrigg = false;
3297         if (chargeTotChInLayer[chInLayer] > minFracTriggThre* meanPedSign){
3298           triggPrim = event.CalculateLocalMuonTrigg(calib, rand, currCellID, localTriggerTiles, 0);
3299           aTile->SetLocalTriggerPrimitive(triggPrim);
3300           localMuonTrigg = event.InspectIfLocalMuonTrigg(currCellID, averageScalePerTile, factorMinTrigg, factorMaxTrigg);
3301         } else {
3302           aTile->SetLocalTriggerPrimitive(triggPrim);
3303         }
3304         // estimate local muon trigger
3305         if (triggPrim != -50.){
3306           hHGTileSum[chInLayer]->Fill(aTile->GetLocalTriggerPrimitive());
3307         
3308           if(ithSpectraTrigg!=hSpectraTrigg.end()){
3309             ithSpectraTrigg->second.FillTrigger(aTile->GetLocalTriggerPrimitive());
3310           } else {
3311             RootOutputHist->cd("IndividualCellsTrigg");
3312             hSpectraTrigg[currCellID]=TileSpectra("mipTrigg",currCellID,calib.GetTileCalib(currCellID),event.GetROtype(),debug);
3313             hSpectraTrigg[currCellID].FillTrigger(aTile->GetLocalTriggerPrimitive());;
3314             RootOutput->cd();
3315           }
3316           // only fill tile spectra if 4 surrounding tiles on average are compatible with muon response
3317           if (localMuonTrigg){
3318             aTile->SetLocalTriggerBit(1);
3319             ithSpectraTrigg=hSpectraTrigg.find(aTile->GetCellID());
3320             ithSpectraTrigg->second.FillHGCROC(adc,toa,tot);
3321             
3322           }
3323         }
3324       }
3325     }
3326     RootOutput->cd();
3327     TdataOut->Fill();
3328   } // end loop over events
3329   TdataOut->Write();
3330   
3331   if (eventsNoClearTrigg > 0){
3332       std::cout << "*********************************************************" << std::endl;
3333       std::cout << "SKIPPED " << eventsNoClearTrigg << " as no clear trigger present" << std::endl;
3334       std::cout << "*********************************************************" << std::endl;
3335   }
3336   
3337   //==================================================================================
3338   // Monitoring histos for fits results of 2nd iteration 
3339   //==================================================================================
3340   RootOutputHist->cd();
3341   
3342   // monitoring trigger 
3343   TH2D* hmipTriggers              = new TH2D( "hmipTriggers","muon triggers; layer; brd channel; counts ",
3344                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
3345   hmipTriggers->SetDirectory(0);
3346   TH2D* hSuppresionNoise          = new TH2D( "hSuppresionNoise","S/B noise region; layer; brd channel; S/B noise region",
3347                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
3348   hSuppresionNoise->SetDirectory(0);
3349   TH2D* hSuppresionSignal         = new TH2D( "hSuppresionSignal","S/B signal region; layer; brd channel; S/B signal region",
3350                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
3351   hSuppresionSignal->SetDirectory(0);
3352 
3353   // monitoring 2nd iteration mip fits
3354   TH2D* hspectraHGMaxVsLayer2nd   = new TH2D( "hspectraHGMaxVsLayer_2nd","Max High Gain; layer; brd channel; Max_{HG, 2^{nd}} (arb. units) ",
3355                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
3356   hspectraHGMaxVsLayer2nd->SetDirectory(0);
3357   TH2D* hspectraHGFWHMVsLayer2nd   = new TH2D( "hspectraHGFWHMVsLayer_2nd","FWHM High Gain; layer; brd channel; FWHM_{HG, 2^{nd}} (arb. units) ",
3358                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
3359   hspectraHGFWHMVsLayer2nd->SetDirectory(0);
3360   TH2D* hspectraHGLMPVVsLayer2nd   = new TH2D( "hspectraHGLMPVVsLayer_2nd","MPV High Gain; layer; brd channel; MPV_{HG, 2^{nd}} (arb. units) ",
3361                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
3362   hspectraHGLMPVVsLayer2nd->SetDirectory(0);
3363   TH2D* hspectraHGLSigmaVsLayer2nd = new TH2D( "hspectraHGLSigmaVsLayer_2nd","Sigma Landau High Gain; layer; brd channel; #sigma_{L,HG, 2^{nd}} (arb. units) ",
3364                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
3365   hspectraHGLSigmaVsLayer2nd->SetDirectory(0);
3366   TH2D* hspectraHGGSigmaVsLayer2nd = new TH2D( "hspectraHGGSigmaVsLayer_2nd","Sigma Gauss High Gain; layer; brd channel; #sigma_{G,HG, 2^{nd}} (arb. units) ",
3367                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
3368   hspectraHGGSigmaVsLayer2nd->SetDirectory(0);
3369   TH2D* hspectraLGMaxVsLayer2nd   = new TH2D( "hspectraLGMaxVsLayer_2nd","Max High Gain; layer; brd channel; Max_{LG, 2^{nd}} (arb. units) ",
3370                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
3371   hspectraLGMaxVsLayer2nd->SetDirectory(0);
3372   TH2D* hspectraLGFWHMVsLayer2nd   = new TH2D( "hspectraLGFWHMVsLayer_2nd","FWHM High Gain; layer; brd channel; FWHM_{LG, 2^{nd}} (arb. units) ",
3373                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
3374   hspectraLGFWHMVsLayer2nd->SetDirectory(0);
3375   TH2D* hspectraLGLMPVVsLayer2nd   = new TH2D( "hspectraLGLMPVVsLayer_2nd","MPV High Gain; layer; brd channel; MPV_{LG, 2^{nd}} (arb. units) ",
3376                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
3377   hspectraLGLMPVVsLayer2nd->SetDirectory(0);
3378   TH2D* hspectraLGLSigmaVsLayer2nd = new TH2D( "hspectraLGLSigmaVsLayer_2nd","Sigma Landau High Gain; layer; brd channel; #sigma_{L,LG, 2^{nd}} (arb. units) ",
3379                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
3380   hspectraLGLSigmaVsLayer2nd->SetDirectory(0);
3381   TH2D* hspectraLGGSigmaVsLayer2nd = new TH2D( "hspectraLGGSigmaVsLayer_2nd","Sigma Gauss High Gain; layer; brd channel; #sigma_{G,LG, 2^{nd}} (arb. units) ",
3382                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
3383   hspectraLGGSigmaVsLayer2nd->SetDirectory(0);
3384 
3385   TH1D* hMaxHG2nd             = new TH1D( "hMaxHG2nd","Max High Gain ;Max_{HG, 2^{nd}} (arb. units) ; counts ",
3386                                             2000, -0.5, 2000-0.5);
3387   hMaxHG2nd->SetDirectory(0);
3388   TH1D* hMaxLG2nd             = new TH1D( "hMaxLG2nd","Max High Gain ;Max_{LG, 2^{nd}} (arb. units) ; counts ",
3389                                             400, -0.5, 400-0.5);
3390   hMaxLG2nd->SetDirectory(0);
3391 
3392   TH2D* hHGscaleChi2VsLayer = new TH2D( "hHGscaleChi2VsLayer", "HG MiP fit #chi^{2}/NDF; layer; brd channel; #chi^{2}/ndf ",    
3393   setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5); // -EP
3394   hHGscaleChi2VsLayer->SetDirectory(0); 
3395 
3396   TH2D* hSNRTriggVsLayer = new TH2D( "hSNRTriggVsLayer", "HG Triggered S/N; layers; brd channel; SNR ",
3397                                 setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5); // -EP
3398   hSNRTriggVsLayer->SetDirectory(0);
3399 
3400   //TH2D* hChi2VsNMipTrigg = new TH2D( "hChi2VsNMipTrigg", "HG MIP fit by stats; Number of MIP triggers; #chi^{2}/ndf; ", 50, 0, 10000, 80, 0, 20); // -EP
3401   //hChi2VsNMipTrigg->SetDirectory(0);
3402 
3403   // 2D beam profile -EP    
3404   int thisbinxmax = setup->GetNMaxColumn()+1;   
3405   int thisbinymax = (int)(setup->GetNMaxRow()+1)*(setup->GetNMaxModule()+1);
3406   TH2D* hMipTriggXY = new TH2D( "hMipTriggXY", "MIP Triggers summed over layers; X (col); Y (row); Num triggers", thisbinxmax, -0.5, thisbinxmax-0.5, thisbinymax, -0.5, thisbinymax-0.5); 
3407   hMipTriggXY->SetDirectory(0);
3408 
3409   // 3D beam profile -EP
3410   int thisbinzmax = (int)setup->GetNMaxLayer()+1;
3411   TH3D *hMipTriggXYZ = new TH3D( "hMipTriggXYZ", "MIP Triggers; X (col); Z (layer); Y (row); Num triggers", thisbinxmax, -0.5, thisbinxmax-0.5, thisbinzmax, -0.5, thisbinzmax-0.5, thisbinymax, -0.5, thisbinymax-0.5);
3412   hMipTriggXYZ->SetDirectory(0);
3413 
3414   TH2D* hMPVvsNoisePeak = new TH2D( "hMPVvsNoisePeak", "Signal to noise peak ADC; noise peak (ADC); MiP MPV (ADC); ", 20, -5, 10, 20, 0, 50); // -EP
3415   hMPVvsNoisePeak->SetDirectory(0);
3416 
3417   //TH1D* hPeakSeparation = new TH1D("hPeakSeparation", "Signal-noise peak separation; MPV - noise peak (ADC); counts", 35, 0, 35); // -EP
3418   //hPeakSeparation->SetDirectory(0);
3419 
3420 
3421   //==================================================================================
3422   // Fitting 2nd iteration for mip fits
3423   //==================================================================================
3424   currCells = 0;
3425   if ( debug > 0)
3426     std::cout << "============================== starting fitting 2nd iteration" << std::endl;
3427   
3428   // define CalibSummary object for this run -EP
3429   CalibSummary tileSum = CalibSummary(calib.GetRunNumber(), calib.GetRunNumber(), calib.GetVop(), it->second.pdg );
3430 
3431   for(ithSpectraTrigg=hSpectraTrigg.begin(); ithSpectraTrigg!=hSpectraTrigg.end(); ++ithSpectraTrigg){ // loop over spectra for 2nd iteration
3432     if (currCells%20 == 0 && currCells > 0 && debug > 0)
3433       std::cout << "============================== cell " <<  currCells << " / " << hSpectraTrigg.size() << " cells" << std::endl;
3434     currCells++;
3435     // reset parameters & errors
3436     for (int p = 0; p < 6; p++){
3437       parameters[p]   = 0;
3438       parErrAndRes[p] = 0;
3439     }
3440     // fit MIP for CAEN HG/ HGCROC ADC 
3441     isGood=ithSpectraTrigg->second.FitMipHG(parameters, parErrAndRes, debug, yearData, false, calib.GetVov(), averageScale);
3442 
3443     long cellID = ithSpectraTrigg->second.GetCellID();
3444     tileSum.Fill(ithSpectraTrigg->second.GetCalib()); // fill tileSum with this tile's TileCalib -EP
3445 
3446     // fill cross-check histos
3447     double redChi2  = parErrAndRes[4] / parErrAndRes[5]; // chi2/ndf
3448     int layer       = setup->GetLayer(cellID);
3449     int chInLayer   = setup->GetChannelInLayerFull(cellID, detConf);
3450     int row                 = setup->GetRow(cellID);
3451     int col                 = setup->GetColumn(cellID);
3452     int mod                 = setup->GetModule(cellID);
3453     int bin2D       = hspectraHGMeanVsLayer->FindBin(layer,chInLayer);
3454     
3455     double pedSigHG = calib.GetPedestalSigH(cellID);
3456     double maxBin   = 0;
3457     if (typeRO == ReadOut::Type::Caen){ 
3458       maxBin   = 3800;
3459     } else {
3460       maxBin   = 1024;
3461     }
3462 
3463     
3464     Int_t binNLow   = ithSpectraTrigg->second.GetHG()->FindBin(-1*pedSigHG);
3465     Int_t binNHigh  = ithSpectraTrigg->second.GetHG()->FindBin(3*pedSigHG);
3466     Int_t binSHigh  = ithSpectraTrigg->second.GetHG()->FindBin(maxBin);
3467     
3468     double S_NoiseR = ithSpectraTrigg->second.GetHG()->Integral(binNLow, binNHigh);
3469     double S_SigR   = ithSpectraTrigg->second.GetHG()->Integral(binNHigh, binSHigh);
3470     
3471     ithSpectra      = hSpectra.find(cellID);
3472     double B_NoiseR = ithSpectra->second.GetHG()->Integral(binNLow , binNHigh);
3473     double B_SigR   = ithSpectra->second.GetHG()->Integral(binNHigh, binSHigh);
3474     
3475     double SB_NoiseR  = (B_NoiseR != 0.) ? S_NoiseR/B_NoiseR : 0;
3476     double SB_SigR    = (B_SigR != 0.) ? S_SigR/B_SigR : 0;
3477     
3478     double SNR_trigg = (S_NoiseR != 0.) ? S_SigR/S_NoiseR : 0;
3479 
3480     hmipTriggers->SetBinContent(bin2D, ithSpectraTrigg->second.GetHG()->GetEntries());
3481     hSuppresionNoise->SetBinContent(bin2D, SB_NoiseR);
3482     hSuppresionSignal->SetBinContent(bin2D, SB_SigR);
3483     hSNRTriggVsLayer->SetBinContent(bin2D, SNR_trigg);
3484 
3485     // get 2D and 3D beam profiles -EP
3486     int thisbinx = col + 1; // the +1s are due to the 0th bin in root being underflow
3487     int thisbiny = (mod*2) + row + 1;
3488     int thisbinz = layer + 1;
3489     int numMipTrig = ithSpectraTrigg->second.GetHG()->GetEntries();
3490     hMipTriggXY->SetBinContent(thisbinx, thisbiny, hMipTriggXY->GetBinContent(thisbinx, thisbiny) + numMipTrig);
3491     hMipTriggXYZ->SetBinContent(thisbinx, thisbinz, thisbiny, numMipTrig);
3492 
3493     // estimate separation between noise and mip peaks
3494     //double peaksep = parameters[1]-ithSpectraTrigg->second.GetMaxXInRangeHG(-1*pedSigHG, 3*pedSigHG); 
3495 
3496     if (isGood){
3497       // get uncertainty on HG Max
3498       double rel_err_L_MPV = parErrAndRes[1]/parameters[1]; // Landau MPV error / MPV
3499       double sigma_Max = rel_err_L_MPV * parameters[4]; // relative MPV err * Max ADC value
3500       hspectraHGMaxVsLayer2nd->SetBinContent(bin2D, parameters[4]);
3501       hspectraHGMaxVsLayer2nd->SetBinError(bin2D, sigma_Max);
3502       hMPVvsNoisePeak->Fill(ithSpectraTrigg->second.GetMaxXInRangeHG(-1*pedSigHG, 3*pedSigHG), parameters[1]);
3503       hHGscaleChi2VsLayer->SetBinContent(bin2D, redChi2);   
3504       hspectraHGFWHMVsLayer2nd->SetBinContent(bin2D, parameters[5]);
3505       hspectraHGLMPVVsLayer2nd->SetBinContent(bin2D, parameters[1]);
3506       hspectraHGLMPVVsLayer2nd->SetBinError(bin2D, parErrAndRes[1]);
3507       hspectraHGLSigmaVsLayer2nd->SetBinContent(bin2D, parameters[0]);
3508       hspectraHGLSigmaVsLayer2nd->SetBinError(bin2D, parErrAndRes[0]);
3509       hspectraHGGSigmaVsLayer2nd->SetBinContent(bin2D, parameters[3]);
3510       hspectraHGGSigmaVsLayer2nd->SetBinError(bin2D, parErrAndRes[3]);
3511       hMaxHG2nd->Fill(parameters[4]);
3512     }
3513     // fit MIP for CAEN LG
3514     if (typeRO == ReadOut::Type::Caen) {
3515       // reset parameters & errors
3516       for (int p = 0; p < 6; p++){
3517         parameters[p]   = 0;
3518         parErrAndRes[p] = 0;
3519       }
3520       // fit MIP for CAEN LG
3521       isGood=ithSpectraTrigg->second.FitMipLG(parameters, parErrAndRes, debug, yearData, false, 1);
3522       /// fill cross-check histos
3523       if (isGood){
3524         hspectraLGMaxVsLayer2nd->SetBinContent(bin2D, parameters[4]);
3525         hspectraLGFWHMVsLayer2nd->SetBinContent(bin2D, parameters[5]);
3526         hspectraLGLMPVVsLayer2nd->SetBinContent(bin2D, parameters[1]);
3527         hspectraLGLMPVVsLayer2nd->SetBinError(bin2D, parErrAndRes[1]);
3528         hspectraLGLSigmaVsLayer2nd->SetBinContent(bin2D, parameters[0]);
3529         hspectraLGLSigmaVsLayer2nd->SetBinError(bin2D, parErrAndRes[0]);
3530         hspectraLGGSigmaVsLayer2nd->SetBinContent(bin2D, parameters[3]);
3531         hspectraLGGSigmaVsLayer2nd->SetBinError(bin2D, parErrAndRes[3]);
3532         hMaxLG2nd->Fill(parameters[4]);
3533       }
3534     }
3535   } // end loop over spectra that passed trigger selection (2nd iteration)
3536   if ( debug > 0)
3537     std::cout << "============================== done fitting 2nd iteration" << std::endl;
3538   
3539   //==================================================================================
3540   // Summarize fitting success & average scales
3541   //==================================================================================    
3542   int actCh2nd = 0;
3543   double averageScaleUpdated    = calib.GetAverageScaleHigh(actCh2nd);
3544   
3545   int actChAalt                  = 0;
3546   double averageNTilesA          = 0.;
3547   double averageScaleUpPerTile   = calib.GetAverageScaleHighPerSingleLayer(actChAalt, averageNTilesA);
3548 
3549   
3550   double meanFWHMHGUpdated      = calib.GetAverageScaleWidthHigh();
3551   double averageScaleLowUpdated = 0.;
3552   double meanFWHMLGUpdated      = 0.;
3553   if (typeRO == ReadOut::Type::Caen){
3554     averageScaleLowUpdated = calib.GetAverageScaleLow();
3555     meanFWHMLGUpdated      = calib.GetAverageScaleWidthLow();
3556   }
3557   
3558   if (typeRO == ReadOut::Type::Caen) {
3559     std::cout << "average 1st iteration HG mip: " << averageScale << "\t act. channels: " <<   actCh1st << std::endl;
3560     std::cout << "average 2nd iteration  HG mip: " << averageScaleUpdated << "\t LG mip: " << averageScaleLowUpdated << "\t act. channels: " <<   actCh2nd << std::endl;
3561   } else {
3562     std::cout << "average input mip: " << averageScale << " per tile mip: "<< averageScalePerTile << "\t act. ch: "<< actCh1st << "\t av tiles/seg "<< averageNTilesI << std::endl;
3563     std::cout << "average updated mip: " << averageScaleUpdated << " per tile mip: "<< averageScaleUpPerTile << "\t act. ch: "<< actCh2nd<< "\t av tiles/seg "<< averageNTilesA << std::endl;    
3564   }
3565   RootOutput->cd();
3566   
3567   if (IsCalibSaveToFile()){
3568     TString fileCalibPrint = RootOutputName;
3569     fileCalibPrint         = fileCalibPrint.ReplaceAll(".root","_calib.txt");
3570     calib.PrintCalibToFile(fileCalibPrint);
3571   }
3572 
3573   //==================================================================================
3574   // Write tree objects and calibs to tree output root file
3575   //==================================================================================
3576   TcalibOut->Fill();
3577   TcalibOut->Write();
3578   // close tree output root file
3579   RootOutput->Close();
3580 
3581   //==================================================================================
3582   // Write histos to histo output root file
3583   //==================================================================================
3584   // write spectra for individual cells
3585   RootOutputHist->cd("IndividualCells");
3586     for(ithSpectra=hSpectra.begin(); ithSpectra!=hSpectra.end(); ++ithSpectra){
3587       ithSpectra->second.Write(true);
3588     }
3589   // write spectra for individual cells with trigger requirement
3590   RootOutputHist->cd("IndividualCellsTrigg");
3591     for(ithSpectra=hSpectraTrigg.begin(); ithSpectra!=hSpectraTrigg.end(); ++ithSpectra){
3592       ithSpectra->second.Write(true);
3593     }
3594   // write summary histograms
3595   RootOutputHist->cd();
3596     hMeanPedHGvsCellID->Write();
3597     hMeanPedHG->Write();
3598     hNPosTrigg->Write();
3599     
3600     hspectraHGMeanVsLayer->Write();
3601     hspectraHGSigmaVsLayer->Write();
3602     hspectraHGMaxVsLayer1st->Write();
3603     hspectraHGFWHMVsLayer1st->Write();
3604     hspectraHGLMPVVsLayer1st->Write();
3605     hspectraHGLSigmaVsLayer1st->Write();
3606     hspectraHGGSigmaVsLayer1st->Write();
3607     hMaxHG1st->Write();
3608     
3609     
3610     hspectraHGMaxVsLayer2nd->Write();
3611     hspectraHGFWHMVsLayer2nd->Write();
3612     hspectraHGLMPVVsLayer2nd->Write();
3613     hspectraHGLSigmaVsLayer2nd->Write();
3614     hspectraHGGSigmaVsLayer2nd->Write();
3615     hMaxHG2nd->Write();
3616 
3617     hHGscaleChi2VsLayer->Write();
3618     //hChi2VsNMipTrigg->Write();    
3619     hMPVvsNoisePeak->Write();
3620     hSNRTriggVsLayer->Write();
3621     //hPeakSeparation->Write();
3622     hMipTriggXY->Write();
3623     hMipTriggXYZ->Write();
3624     // CAEN specific histos
3625     if (typeRO == ReadOut::Type::Caen) {
3626       hMeanPedLGvsCellID->Write();
3627       hMeanPedLG->Write();
3628       hspectraLGMeanVsLayer->Write();
3629       hspectraLGSigmaVsLayer->Write();
3630       hLGHGCorrVsLayer->Write();
3631       hLGHGCorrOffsetVsLayer->Write();
3632       hHGLGCorrVsLayer->Write();
3633       hHGLGCorrOffsetVsLayer->Write();
3634       hLGHGCorr->Write();
3635       hHGLGCorr->Write();
3636       hspectraLGMaxVsLayer2nd->Write();
3637       hspectraLGFWHMVsLayer2nd->Write();
3638       hspectraLGLMPVVsLayer2nd->Write();
3639       hspectraLGLSigmaVsLayer2nd->Write();
3640       hspectraLGGSigmaVsLayer2nd->Write();
3641       hMaxLG2nd->Write();
3642     }
3643     // trigger effectiveness summary histos
3644     for (int c = 0; c< maxChannelPerLayer; c++)
3645       if (hHGTileSum[c]) hHGTileSum[c]->Write();
3646     hmipTriggers->Write();
3647     hSuppresionNoise->Write();
3648     hSuppresionSignal->Write();
3649   // fill calib tree & write it
3650   // close open root files
3651   RootOutputHist->Write();
3652   RootOutputHist->Close();
3653   // close input root file
3654   RootInput->Close();
3655 
3656   //==================================================================================
3657   // Set up general plotting variables
3658   //==================================================================================    
3659   // create directory for plot output
3660   TString outputDirPlots = GetPlotOutputDir();
3661   gSystem->Exec("mkdir -p "+outputDirPlots);
3662   
3663   
3664   Double_t textSizeRel = 0.035;
3665   StyleSettingsBasics("pdf");
3666   SetPlotStyle();
3667   //==================================================================================
3668   // Create canvases for channel overview plotting
3669   //==================================================================================
3670   TCanvas* canvas1DSimple = new TCanvas("canvas1DSimple","",0,0,1450,1300);  // gives the page size
3671   DefaultCanvasSettings( canvas1DSimple, 0.08, 0.03, 0.03, 0.07);
3672   PlotSimple1D(canvas1DSimple, hNPosTrigg, -10000, maxChannelPerLayer, textSizeRel, Form("%s/NPosTriggers.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1);        
3673 
3674 
3675   TCanvas* canvas2DCorr = new TCanvas("canvasCorrPlots","",0,0,1450,1300);  // gives the page size
3676   DefaultCanvasSettings( canvas2DCorr, 0.08, 0.13, 0.045, 0.07);  
3677   canvas2DCorr->SetLogz(0);
3678   PlotSimple2D( canvas2DCorr, hspectraHGMeanVsLayer, -10000, -10000, textSizeRel, Form("%s/HG_NoiseMean.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
3679   PlotSimple2D( canvas2DCorr, hspectraHGSigmaVsLayer,-10000, -10000, textSizeRel, Form("%s/HG_NoiseSigma.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1,  kFALSE, "colz", true);
3680   PlotSimple2D( canvas2DCorr, hspectraHGMaxVsLayer1st, -10000, -10000, textSizeRel, Form("%s/HG_MaxMip_1st.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true, Form( "#LT Max_{HG} #GT = %.1f", averageScale));
3681   PlotSimple2D( canvas2DCorr, hspectraHGFWHMVsLayer1st, -10000, -10000, textSizeRel, Form("%s/HG_FWHMMip_1st.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true, Form( "#LT FWHM_{HG} #GT = %.1f", meanFWHMHG));
3682   PlotSimple2D( canvas2DCorr, hspectraHGLMPVVsLayer1st, -10000, -10000, textSizeRel, Form("%s/HG_LandMPVMip_1st.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
3683   PlotSimple2D( canvas2DCorr, hspectraHGLSigmaVsLayer1st, -10000, -10000, textSizeRel, Form("%s/HG_LandSigMip_1st.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
3684   PlotSimple2D( canvas2DCorr, hspectraHGGSigmaVsLayer1st, -10000, -10000, textSizeRel, Form("%s/HG_GaussSigMip_1st.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
3685   PlotSimple2D( canvas2DCorr, hspectraHGMaxVsLayer2nd, -10000, -10000, textSizeRel, Form("%s/HG_MaxMip_2nd.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true, Form( "#LT Max_{HG} #GT = %.1f", averageScaleUpdated));
3686   PlotSimple2D( canvas2DCorr, hspectraHGFWHMVsLayer2nd, -10000, -10000, textSizeRel, Form("%s/HG_FWHMMip_2nd.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true, Form( "#LT FWHM_{HG} #GT = %.1f", meanFWHMHGUpdated));
3687   PlotSimple2D( canvas2DCorr, hspectraHGLMPVVsLayer2nd, -10000, -10000, textSizeRel, Form("%s/HG_LandMPVMip_2nd.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
3688   PlotSimple2D( canvas2DCorr, hspectraHGLSigmaVsLayer2nd, -10000, -10000, textSizeRel, Form("%s/HG_LandSigMip_2nd.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
3689   PlotSimple2D( canvas2DCorr, hspectraHGGSigmaVsLayer2nd, -10000, -10000, textSizeRel, Form("%s/HG_GaussSigMip_2nd.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
3690   PlotSimple2D( canvas2DCorr, hSNRTriggVsLayer, -10000, -10000, textSizeRel, Form("%s/SNRTriggVsLayer.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
3691   PlotSimple2D( canvas2DCorr, hHGscaleChi2VsLayer, -10000, -10000, textSizeRel, Form("%s/HGscaleChi2VsLayer.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
3692   PlotSimple2D( canvas2DCorr, hMipTriggXY, -10000, -10000, textSizeRel, Form("%s/MipTriggXY.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
3693   canvas2DCorr->SetLogz(1);
3694   TString drawOpt = "colz";
3695   if (yearData == 2023)
3696     drawOpt = "colz,text";
3697   PlotSimple2D( canvas2DCorr, hmipTriggers, -10000, -10000, textSizeRel, Form("%s/MuonTriggers.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, drawOpt, true, Form( "evt. collected = %d", evts));
3698   PlotSimple2D( canvas2DCorr, hSuppresionNoise, -10000, -10000, textSizeRel, Form("%s/SuppressionNoise.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, drawOpt, true);
3699   PlotSimple2D( canvas2DCorr, hSuppresionSignal, -10000, -10000, textSizeRel, Form("%s/SuppressionSignal.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, drawOpt, true);
3700   
3701   canvas2DCorr->SetLogz(0);
3702   
3703   if (typeRO == ReadOut::Type::Caen) {
3704     PlotSimple2D( canvas2DCorr, hspectraLGMeanVsLayer, -10000, -10000, textSizeRel, Form("%s/LG_NoiseMean.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
3705     PlotSimple2D( canvas2DCorr, hspectraLGSigmaVsLayer, -10000, -10000, textSizeRel, Form("%s/LG_NoiseSigma.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
3706     PlotSimple2D( canvas2DCorr, hspectraLGMaxVsLayer2nd, -10000, -10000, textSizeRel, Form("%s/LG_MaxMip_2nd.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true, Form( "#LT Max_{LG} #GT = %.1f", averageScaleLowUpdated));
3707     PlotSimple2D( canvas2DCorr, hspectraLGFWHMVsLayer2nd, -10000, -10000, textSizeRel, Form("%s/LG_FWHMMip_2nd.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true, Form( "#LT FWHM_{LG} #GT = %.1f", meanFWHMLGUpdated));
3708     PlotSimple2D( canvas2DCorr, hspectraLGLMPVVsLayer2nd, -10000, -10000, textSizeRel, Form("%s/LG_LandMPVMip_2nd.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
3709     PlotSimple2D( canvas2DCorr, hspectraLGLSigmaVsLayer2nd, -10000, -10000, textSizeRel, Form("%s/LG_LandSigMip_2nd.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
3710     PlotSimple2D( canvas2DCorr, hspectraLGGSigmaVsLayer2nd, -10000, -10000, textSizeRel, Form("%s/LG_GaussSigMip_2nd.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
3711 
3712     PlotSimple2D( canvas2DCorr, hLGHGCorrVsLayer, -10000, -10000, textSizeRel, Form("%s/LG_HG_Corr.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kTRUE, "colz", true, Form( "#LT a_{LGHG} #GT = %.1f", avLGHGCorr));
3713     PlotSimple2D( canvas2DCorr, hLGHGCorrOffsetVsLayer, -10000, -10000, textSizeRel, Form("%s/LG_HG_CorrOffset.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kTRUE, "colz", true, Form( "#LT b_{LGHG} #GT = %.1f", avLGHGOffCorr));
3714     PlotSimple2D( canvas2DCorr, hHGLGCorrVsLayer, -10000, -10000, textSizeRel, Form("%s/HG_LG_Corr.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kTRUE, "colz", true, Form( "#LT a_{HGLG} #GT = %.1f", avHGLGCorr));
3715     PlotSimple2D( canvas2DCorr, hHGLGCorrOffsetVsLayer, -10000, -10000, textSizeRel, Form("%s/HG_LG_CorrOffset.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kTRUE, "colz", true, Form( "#LT b_{HGLG} #GT = %.1f", avHGLGOffCorr));
3716   }
3717 
3718   // Print calib info
3719   calib.PrintGlobalInfo();  
3720   // setup plotting ranges
3721   Int_t textSizePixel = 30;
3722   Double_t minSpec = -100;
3723   Double_t maxHG = ReturnMipPlotRangeDepVov(calib.GetVov(),true, typeRO);
3724   Double_t maxLG = ReturnMipPlotRangeDepVov(calib.GetVov(),false, typeRO);
3725   std::cout << "plotting single layers" << std::endl;
3726   Double_t maxTriggPPlot = maxHG*2;
3727   if (typeRO != ReadOut::Type::Caen){
3728     maxTriggPPlot = 150;
3729     minSpec = -20;
3730   }
3731 
3732   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
3733   // Single layer plotting
3734   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
3735   MultiCanvas panelPlot(detConf, "MipExt");
3736   bool init1D = panelPlot.Initialize(1);
3737   MultiCanvas panelPlot2D(detConf, "MipExt2D");
3738   bool init2D = panelPlot2D.Initialize(2);
3739     
3740   std::cout << "plotting single layers" << std::endl;
3741   if (ExtPlot > 0){
3742     panelPlot.PlotMipWithFits( hSpectra, hSpectraTrigg, 1, minSpec, maxHG, 1.2, 
3743                                Form("%s/MIP_HG" ,outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);
3744     panelPlot.PlotTriggerPrim( hSpectraTrigg, averageScalePerTile, factorMinTrigg, factorMaxTrigg, 0, maxTriggPPlot, 1.2,
3745                              Form("%s/TriggPrimitive" ,outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);
3746 
3747     if (typeRO == ReadOut::Type::Caen) {
3748       panelPlot.PlotMipWithFits( hSpectra, hSpectraTrigg, 0, minSpec, maxLG, 1.2, 
3749                                  Form("%s/MIP_LG" ,outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);
3750       panelPlot2D.PlotCorrWithFits( hSpectra, 0, -20, 800, 0., 3900,
3751                                     Form("%s/LGHG_Corr",outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);
3752     }
3753   }
3754   if (ExtPlot > 1 && typeRO == ReadOut::Type::Caen){
3755       panelPlot2D.PlotCorrWithFits( hSpectra, 1, minSpec, 4000, 0, 340,
3756                                     Form("%s/HGLG_Corr",outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);
3757   }
3758   std::cout << "done plotting" << std::endl;
3759 
3760   return true;
3761 } // end Analyses::GetScaling()
3762 
3763 //***********************************************************************************************
3764 //*********************** improved scaling calculation function *********************************
3765 //***********************************************************************************************
3766 bool Analyses::GetImprovedScaling(void){
3767   std::cout<<"GetImprovedScaling"<<std::endl;
3768   
3769   // read full run list
3770   std::map<int,RunInfo> ri=readRunInfosFromFile(RunListInputName.Data(),debug,0);
3771   
3772   // create tileSpectra objects
3773   std::map<int,TileSpectra> hSpectra;
3774   std::map<int,TileSpectra> hSpectraTrigg;
3775   std::map<int, TileSpectra>::iterator ithSpectra;
3776   std::map<int, TileSpectra>::iterator ithSpectraTrigg;
3777   
3778   // create output file for histos
3779   CreateOutputRootHistFile();
3780    
3781   // setup general fitting options 
3782   ROOT::Math::MinimizerOptions::SetDefaultMinimizer("Minuit2", "Migrad");
3783   
3784   // reading first event in tree to extract runnumber & RO-type
3785   TdataIn->GetEntry(0);
3786   int evts=TdataIn->GetEntries();
3787   Int_t runNr           = event.GetRunNumber();
3788   ReadOut::Type typeRO  = event.GetROtype();
3789   
3790   // reading calib from file
3791   TcalibIn->GetEntry(0);
3792   //==================================================================================
3793   // extract spectra per tile from event tree
3794   //==================================================================================
3795   // check whether calib should be overwritten based on external text file
3796   if (OverWriteCalib){
3797     calib.ReadCalibFromTextFile(ExternalCalibFile,debug);
3798   }
3799   // read run numbers from calib tree
3800   std::cout<< "original run numbers calib: "<<calib.GetRunNumber() << "\t" << calib.GetRunNumberPed() << "\t" << calib.GetRunNumberMip() << std::endl;
3801   // Get run info object
3802   std::map<int,RunInfo>::iterator it=ri.find(runNr);
3803   // set year of data taking in case adjustments are necessary
3804   SetYear(it->second.year);
3805   
3806   // setup trigger sel
3807   double factorMinTrigg   = 0.8;
3808   double factorMaxTrigg   = 2.5;
3809   
3810   if (  typeRO == ReadOut::Type::Caen ){
3811     if (yearData == 2023){
3812       factorMinTrigg    = 0.9;
3813       factorMaxTrigg    = 2.;
3814     } 
3815   } else if (  typeRO == ReadOut::Type::Hgcroc ){
3816     if (yearData == 2024){
3817       factorMinTrigg    = 0.5;
3818     } else if (yearData == 2025){
3819       factorMinTrigg    = 0.5;
3820     } else if (yearData == 2026){
3821       factorMinTrigg    = 0.8;
3822     }
3823   }
3824   std::cout << "trigger limits set to: " << factorMinTrigg <<"\t" << factorMaxTrigg << std::endl;
3825 
3826   
3827   RootOutputHist->mkdir("IndividualCells");
3828   RootOutputHist->mkdir("IndividualCellsTrigg");
3829   RootOutputHist->cd("IndividualCellsTrigg");  
3830 
3831   // find detector config for plotting
3832   DetConf::Type detConf   = setup->GetDetectorConfig();
3833   
3834   
3835   int evtDeb = 5000;
3836   if (typeRO != ReadOut::Type::Caen){
3837     evtDeb = 2500;    
3838   }
3839   
3840   if (maxEvents == -1){
3841     maxEvents = evts;
3842   } else {
3843     std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
3844     std::cout << "ATTENTION: YOU ARE RESETTING THE MAXIMUM NUMBER OF EVENTS TO BE PROCESSED TO: " << maxEvents << ". THIS SHOULD ONLY BE USED FOR TESTING!" << std::endl;
3845     std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
3846   }
3847   
3848   int actChI  = 0;
3849   double averageScale     = calib.GetAverageScaleHigh(actChI);
3850   double averageScaleLow  = 0.;
3851   
3852   int actChIalt                  = 0;
3853   double averageNTilesI          = 0.;
3854   double averageScalePerTile     = calib.GetAverageScaleHighPerSingleLayer(actChIalt, averageNTilesI);
3855   if (typeRO == ReadOut::Type::Caen) {
3856     averageScaleLow  = calib.GetAverageScaleLow();
3857   }
3858 
3859   if (typeRO == ReadOut::Type::Caen){
3860     std::cout << "average HG mip: " << averageScale << " LG mip: "<< averageScaleLow << "\t act. ch: "<< actChI << std::endl;
3861   } else {
3862     std::cout << "average mip: " << averageScale << " per tile mip: "<< averageScalePerTile << "\t act. ch: "<< actChI << "\t av tiles/seg "<< averageNTilesI << std::endl;
3863   }
3864   //==================================================================================
3865   // process events from tree for mip fitting
3866   //==================================================================================
3867   for(int i=0; i<maxEvents; i++){
3868     TdataIn->GetEntry(i);
3869     if (i%evtDeb == 0 && i > 0 && debug > 0) std::cout << "Reading " <<  i << " / " << maxEvents << " events" << std::endl;
3870     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3871     // process tiles in event
3872     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++    
3873     for(int j=0; j<event.GetNTiles(); j++){
3874       //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3875       // CAEN treatment
3876       //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3877       if (typeRO == ReadOut::Type::Caen) {
3878         Caen* aTile=(Caen*)event.GetTile(j);
3879         if (i == 0 && debug > 2) std::cout << ((TString)setup->DecodeCellID(aTile->GetCellID())).Data() << std::endl;
3880         long currCellID = aTile->GetCellID();
3881         
3882         // read current tile
3883         ithSpectraTrigg=hSpectraTrigg.find(currCellID);
3884         double hgCorr = aTile->GetADCHigh()-calib.GetPedestalMeanH(currCellID);
3885         double lgCorr = aTile->GetADCLow()-calib.GetPedestalMeanL(currCellID);
3886 
3887         // estimate local muon trigger
3888         bool localMuonTrigg = event.InspectIfLocalMuonTrigg(currCellID, averageScalePerTile, factorMinTrigg, factorMaxTrigg);
3889         
3890         if(ithSpectraTrigg!=hSpectraTrigg.end()){
3891           ithSpectraTrigg->second.FillTrigger(aTile->GetLocalTriggerPrimitive());
3892         } else {
3893           RootOutputHist->cd("IndividualCellsTrigg");
3894           hSpectraTrigg[currCellID]=TileSpectra("mipTrigg",currCellID,calib.GetTileCalib(currCellID),event.GetROtype(),debug);
3895           hSpectraTrigg[currCellID].FillTrigger(aTile->GetLocalTriggerPrimitive());;
3896           RootOutput->cd();
3897         }
3898         
3899         ithSpectra=hSpectra.find(currCellID);
3900         if (ithSpectra!=hSpectra.end()){
3901           ithSpectra->second.FillSpectraCAEN(lgCorr,hgCorr);
3902           if (hgCorr > 3*calib.GetPedestalSigH(currCellID) && lgCorr > 3*calib.GetPedestalSigL(currCellID) && hgCorr < 3900 )
3903             ithSpectra->second.FillCorrCAEN(lgCorr,hgCorr);
3904         } else {
3905           RootOutputHist->cd("IndividualCells");
3906           hSpectra[currCellID]=TileSpectra("mip1st",currCellID,calib.GetTileCalib(currCellID),event.GetROtype(),debug);
3907           hSpectra[currCellID].FillSpectraCAEN(lgCorr,hgCorr);;
3908           if (hgCorr > 3*calib.GetPedestalSigH(currCellID) && lgCorr > 3*calib.GetPedestalSigL(currCellID && hgCorr < 3900) )
3909             hSpectra[currCellID].FillCorrCAEN(lgCorr,hgCorr);;
3910 
3911           RootOutput->cd();
3912         }
3913         
3914       
3915         // only fill tile spectra if 4 surrounding tiles on average are compatible with muon response
3916         if (localMuonTrigg){
3917           aTile->SetLocalTriggerBit(1);
3918           ithSpectraTrigg=hSpectraTrigg.find(aTile->GetCellID());
3919           ithSpectraTrigg->second.FillSpectraCAEN(lgCorr,hgCorr);
3920           if (hgCorr > 3*calib.GetPedestalSigH(currCellID) && lgCorr > 3*calib.GetPedestalSigL(currCellID) && hgCorr < 3900 )
3921             ithSpectraTrigg->second.FillCorrCAEN(lgCorr,hgCorr);
3922         }
3923       //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
3924       // HGCROC treatment
3925       //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3926       } else if (typeRO == ReadOut::Type::Hgcroc) {
3927         Hgcroc* aTile=(Hgcroc*)event.GetTile(j);
3928         if (i == 0 && debug > 2) std::cout << ((TString)setup->DecodeCellID(aTile->GetCellID())).Data() << std::endl;
3929         long currCellID = aTile->GetCellID();
3930 
3931         ithSpectraTrigg=hSpectraTrigg.find(currCellID);
3932         // double adc = aTile->GetPedestal()+aTile->GetIntegratedADC();
3933         double adc = aTile->GetIntegratedADC();
3934         double tot = aTile->GetRawTOT();
3935         double toa = aTile->GetRawTOA();
3936         
3937         // estimate local muon trigger
3938         bool localMuonTrigg = event.InspectIfLocalMuonTrigg(currCellID, averageScalePerTile, factorMinTrigg, factorMaxTrigg);
3939         
3940         if(ithSpectraTrigg!=hSpectraTrigg.end()){
3941           ithSpectraTrigg->second.FillTrigger(aTile->GetLocalTriggerPrimitive());
3942         } else {
3943           RootOutputHist->cd("IndividualCellsTrigg");
3944           hSpectraTrigg[currCellID]=TileSpectra("mipTrigg",currCellID,calib.GetTileCalib(currCellID),event.GetROtype(),debug);
3945           hSpectraTrigg[currCellID].FillTrigger(aTile->GetLocalTriggerPrimitive());;
3946           RootOutput->cd();
3947         }
3948 
3949         ithSpectra=hSpectra.find(currCellID);
3950         if (ithSpectra!=hSpectra.end()){
3951           ithSpectra->second.FillHGCROC(adc, toa, tot);
3952         } else {
3953           RootOutputHist->cd("IndividualCells");
3954           hSpectra[currCellID]=TileSpectra("mip1st",currCellID,calib.GetTileCalib(currCellID),event.GetROtype(),debug);
3955           hSpectra[currCellID].FillHGCROC(adc, toa, tot);
3956           RootOutput->cd();
3957         }
3958         
3959         // only fill tile spectra if 4 surrounding tiles on average are compatible with muon response
3960         if (localMuonTrigg){
3961           aTile->SetLocalTriggerBit(1);
3962           ithSpectraTrigg=hSpectraTrigg.find(currCellID);
3963           ithSpectraTrigg->second.FillHGCROC(adc, toa, tot);
3964         }
3965       }
3966     }
3967     RootOutput->cd();
3968     // fill tree
3969     TdataOut->Fill();
3970   }
3971   // write tree
3972   TdataOut->Write();
3973   TsetupIn->CloneTree()->Write();
3974   
3975   //==================================================================================
3976   // Monitoring histos for fits results 
3977   //==================================================================================
3978   RootOutputHist->cd();
3979   int maxChannelPerLayer             = (setup->GetNMaxColumn()+1)*(setup->GetNMaxRow()+1)*(setup->GetNMaxModule()+1);
3980   int maxChannelPerLayerSingleMod    = (setup->GetNMaxColumn()+1)*(setup->GetNMaxRow()+1);
3981 
3982   // monitoring trigger 
3983   TH2D* hmipTriggers              = new TH2D( "hmipTriggers","muon triggers; layer; brd channel; counts ",
3984                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
3985   hmipTriggers->SetDirectory(0);
3986   TH2D* hSuppresionNoise          = new TH2D( "hSuppresionNoise","S/B noise region; layer; brd channel; S/B noise region",
3987                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
3988   hSuppresionNoise->SetDirectory(0);
3989   TH2D* hSuppresionSignal         = new TH2D( "hSuppresionSignal","S/B signal region; layer; brd channel; S/B signal region",
3990                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
3991   hSuppresionSignal->SetDirectory(0);
3992 
3993   // monitoring 2nd iteration mip fits
3994   TH2D* hspectraHGMaxVsLayer   = new TH2D( "hspectraHGMaxVsLayer","Max High Gain; layer; brd channel; Max_{HG, 2^{nd}} (arb. units) ",
3995                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
3996   hspectraHGMaxVsLayer->SetDirectory(0);
3997   TH2D* hspectraHGFWHMVsLayer   = new TH2D( "hspectraHGFWHMVsLayer","FWHM High Gain; layer; brd channel; FWHM_{HG, 2^{nd}} (arb. units) ",
3998                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
3999   hspectraHGFWHMVsLayer->SetDirectory(0);
4000   TH2D* hspectraHGLMPVVsLayer   = new TH2D( "hspectraHGLMPVVsLayer","MPV High Gain; layer; brd channel; MPV_{HG, 2^{nd}} (arb. units) ",
4001                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
4002   hspectraHGLMPVVsLayer->SetDirectory(0);
4003   TH2D* hspectraHGLSigmaVsLayer = new TH2D( "hspectraHGLSigmaVsLayer","Sigma Landau High Gain; layer; brd channel; #sigma_{L,HG, 2^{nd}} (arb. units) ",
4004                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
4005   hspectraHGLSigmaVsLayer->SetDirectory(0);
4006   TH2D* hspectraHGGSigmaVsLayer = new TH2D( "hspectraHGGSigmaVsLayer","Sigma Gauss High Gain; layer; brd channel; #sigma_{G,HG, 2^{nd}} (arb. units) ",
4007                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
4008   hspectraHGGSigmaVsLayer->SetDirectory(0);
4009   TH2D* hspectraLGMaxVsLayer   = new TH2D( "hspectraLGMaxVsLayer","Max High Gain; layer; brd channel; Max_{LG, 2^{nd}} (arb. units) ",
4010                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
4011   hspectraLGMaxVsLayer->SetDirectory(0);
4012   TH2D* hspectraLGFWHMVsLayer   = new TH2D( "hspectraLGFWHMVsLayer","FWHM High Gain; layer; brd channel; FWHM_{LG, 2^{nd}} (arb. units) ",
4013                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
4014   hspectraLGFWHMVsLayer->SetDirectory(0);
4015   TH2D* hspectraLGLMPVVsLayer   = new TH2D( "hspectraLGLMPVVsLayer","MPV High Gain; layer; brd channel; MPV_{LG, 2^{nd}} (arb. units) ",
4016                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
4017   hspectraLGLMPVVsLayer->SetDirectory(0);
4018   TH2D* hspectraLGLSigmaVsLayer = new TH2D( "hspectraLGLSigmaVsLayer","Sigma Landau High Gain; layer; brd channel; #sigma_{L,LG, 2^{nd}} (arb. units) ",
4019                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
4020   hspectraLGLSigmaVsLayer->SetDirectory(0);
4021   TH2D* hspectraLGGSigmaVsLayer = new TH2D( "hspectraLGGSigmaVsLayer","Sigma Gauss High Gain; layer; brd channel; #sigma_{G,LG, 2^{nd}} (arb. units) ",
4022                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
4023   hspectraLGGSigmaVsLayer->SetDirectory(0);
4024 
4025   TH1D* hMaxHG             = new TH1D( "hMaxHG","Max High Gain ;Max_{HG} (arb. units) ; counts ",
4026                                             2000, -0.5, 2000-0.5);
4027   hMaxHG->SetDirectory(0);
4028   TH1D* hMaxLG             = new TH1D( "hMaxLG","Max Low Gain ;Max_{LG} (arb. units) ; counts ",
4029                                             400, -0.5, 400-0.5);
4030   hMaxLG->SetDirectory(0);
4031 
4032   
4033   TH2D* hHGscaleChi2VsLayer = new TH2D( "hHGscaleChi2VsLayer", "HG MIP fit #chi^{2}/NDF; layer; brd channel; #chi^{2}/ndf ", 
4034                                     setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5); // -EP
4035   hHGscaleChi2VsLayer->SetDirectory(0); 
4036 
4037   TH2D* hSNRTriggVsLayer = new TH2D( "hSNRTriggVsLayer", "HG Triggered S/N; layers; brd channel; SNR ", 
4038                                     setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5); // -EP
4039   hSNRTriggVsLayer->SetDirectory(0);
4040 
4041   //TH2D* hChi2VsNMipTrigg = new TH2D( "hChi2VsNMipTrigg", "HG MiP fit by stats; Number of MIP triggers; #chi^{2}/ndf; ", 50, 0, 10000, 80, 0, 20); // -EP
4042   //hChi2VsNMipTrigg->SetDirectory(0);
4043 
4044   //TH1D *hSNRTrigg = new TH1D("hSNRTrigg", "Signal to Noise Ratio; SNR; counts", 100, 0, 50); // -EP
4045   //hSNRTrigg->SetDirectory(0);
4046 
4047   // 2D beam profile -EP 
4048   int thisbinxmax = setup->GetNMaxColumn()+1;
4049   int thisbinymax = (int)(setup->GetNMaxRow()+1)*(setup->GetNMaxModule()+1);
4050   TH2D* hMipTriggXY = new TH2D( "hMipTriggXY", "MIP Triggers summed over layers; X (col); Y (row); Num triggers", thisbinxmax, -0.5, thisbinxmax-0.5, thisbinymax, -0.5, thisbinymax-0.5);
4051   hMipTriggXY->SetDirectory(0);
4052 
4053   // 3D beam profile -EP
4054   int thisbinzmax = (int)setup->GetNMaxLayer()+1;
4055   TH3D *hMipTriggXYZ = new TH3D( "hMipTriggXYZ", "MIP Triggers; X (col); Z (layer); Y (row); Num triggers", thisbinxmax, -0.5, thisbinxmax-0.5, thisbinzmax, -0.5, thisbinzmax-0.5, thisbinymax, -0.5, thisbinymax-0.5);
4056   hMipTriggXYZ->SetDirectory(0);
4057 
4058   TH2D* hMPVvsNoisePeak = new TH2D( "hMPVvsNoisePeak", "Signal to noise peak ADC; noise peak (ADC); MIP MPV (ADC); ", 20, -5, 10, 20, 0, 50); // -EP
4059   hMPVvsNoisePeak->SetDirectory(0);
4060 
4061   //TH1D* hPeakSeparation = new TH1D("hPeakSeparation", "Signal-noise peak separation; MPV - noise peak (ADC); counts", 35, 0, 35); // -EP
4062   ///hPeakSeparation->SetDirectory(0);
4063 
4064   //==================================================================================
4065   // mip fitting spectra for each cell
4066   //==================================================================================
4067   int currCells = 0;
4068   double* parameters    = new double[6];
4069   double* parErrAndRes  = new double[6];
4070   bool isGood;
4071   double meanSB_NoiseR  = 0;
4072   double meanSB_SigR    = 0;
4073   if ( debug > 0){
4074     std::cout << "============================== start fitting improved iteration" << std::endl;  
4075   }
4076 
4077   // define CalibSummary object for this run -EP
4078   CalibSummary tileSum = CalibSummary(calib.GetRunNumber(), calib.GetRunNumber(), calib.GetVop(), it->second.pdg);
4079 
4080   for(ithSpectraTrigg=hSpectraTrigg.begin(); ithSpectraTrigg!=hSpectraTrigg.end(); ++ithSpectraTrigg){ // GetImprovedScaling() spectra loop
4081     if (currCells%20 == 0 && currCells > 0 && debug > 0)
4082       std::cout << "============================== cell " <<  currCells << " / " << hSpectraTrigg.size() << " cells" << std::endl;
4083     currCells++;
4084     long cellID     = ithSpectraTrigg->second.GetCellID();    
4085     ithSpectra      = hSpectra.find(cellID);
4086     // HGCROC data has unphysical bin-to-bin jumps add XX% sys on top of individual for fitting
4087     double relSysF  = 0.10;
4088     if (typeRO == ReadOut::Type::Hgcroc){
4089       // ithSpectra->second.GetHG()->Rebin(2);
4090       // ithSpectraTrigg->second.GetHG()->Rebin(2);
4091       for (Int_t b = 1; b < ithSpectraTrigg->second.GetHG()->GetNbinsX()+1; b++){
4092         double errWithSys= TMath::Sqrt(relSysF*relSysF+TMath::Power(ithSpectra->second.GetHG()->GetBinError(b)/ithSpectra->second.GetHG()->GetBinContent(b),2))*ithSpectra->second.GetHG()->GetBinContent(b);
4093         double errWithSysT= TMath::Sqrt(relSysF*relSysF+TMath::Power(ithSpectraTrigg->second.GetHG()->GetBinError(b)/ithSpectraTrigg->second.GetHG()->GetBinContent(b),2))*ithSpectraTrigg->second.GetHG()->GetBinContent(b);
4094         ithSpectra->second.GetHG()->SetBinError(b,errWithSys);        
4095         ithSpectraTrigg->second.GetHG()->SetBinError(b,errWithSysT);
4096       }
4097     }
4098 
4099     for (int p = 0; p < 6; p++){
4100       parameters[p]   = 0;
4101       parErrAndRes[p] = 0;
4102     }
4103     
4104     isGood=ithSpectraTrigg->second.FitMipHG(parameters, parErrAndRes, debug, yearData, true, calib.GetVov(), averageScale);
4105   
4106     tileSum.Fill(ithSpectraTrigg->second.GetCalib());
4107     
4108     // get reduced chi^2 from mip peak fit
4109     double redChi2 = parErrAndRes[4] / parErrAndRes[5]; // chi2/ndf
4110 
4111     int layer       = setup->GetLayer(cellID);
4112     int chInLayer   = setup->GetChannelInLayerFull(cellID, detConf);
4113     int row         = setup->GetRow(cellID);
4114     int col         = setup->GetColumn(cellID);
4115     int mod         = setup->GetModule(cellID);
4116     int bin2D       = hspectraHGMaxVsLayer->FindBin(layer,chInLayer);
4117   
4118     double pedSigHG = calib.GetPedestalSigH(cellID);
4119     double maxBin   = 0;
4120     if (typeRO == ReadOut::Type::Caen){ 
4121       maxBin   = 3800;
4122     } else {
4123       maxBin   = 1024;
4124     }
4125 
4126     Int_t binNLow   = ithSpectraTrigg->second.GetHG()->FindBin(-1*pedSigHG);
4127     Int_t binNHigh  = ithSpectraTrigg->second.GetHG()->FindBin(3*pedSigHG);
4128     Int_t binSHigh  = ithSpectraTrigg->second.GetHG()->FindBin(maxBin);
4129     
4130         // S ~ mip triggers, B ~ everything
4131     double S_NoiseR = ithSpectraTrigg->second.GetHG()->Integral(binNLow, binNHigh);
4132     double S_SigR   = ithSpectraTrigg->second.GetHG()->Integral(binNHigh, binSHigh);
4133     
4134     double B_NoiseR = ithSpectra->second.GetHG()->Integral(binNLow , binNHigh);
4135     double B_SigR   = ithSpectra->second.GetHG()->Integral(binNHigh, binSHigh);
4136     
4137     double SB_NoiseR  = (B_NoiseR != 0.) ? S_NoiseR/B_NoiseR : 0; // triggered noise / full noise (suppression of noise region from applying mip trigger) 
4138     double SB_SigR    = (B_SigR != 0.) ? S_SigR/B_SigR : 0; // suppression of signal region from applying mip trigger
4139     
4140     meanSB_NoiseR += SB_NoiseR;
4141     meanSB_SigR += SB_SigR;
4142 
4143     double SNR_trigg = (S_NoiseR != 0.) ? S_SigR/S_NoiseR : 0;
4144 
4145     hmipTriggers->SetBinContent(bin2D, ithSpectraTrigg->second.GetHG()->GetEntries());
4146     hSuppresionNoise->SetBinContent(bin2D, SB_NoiseR);
4147     hSuppresionSignal->SetBinContent(bin2D, SB_SigR);
4148     hSNRTriggVsLayer->SetBinContent(bin2D, SNR_trigg);
4149   
4150     // get 2D and 3D beam profiles -EP
4151     // TODO: put this in PlotHelper or something
4152     int thisbinx = col + 1; // the +1s are due to the 0th bin in root being underflow
4153     int thisbiny = (mod*2) + row + 1;
4154     int thisbinz = layer + 1;
4155     int numMipTrig = ithSpectraTrigg->second.GetHG()->GetEntries();
4156     hMipTriggXY->SetBinContent(thisbinx, thisbiny, hMipTriggXY->GetBinContent(thisbinx, thisbiny) + numMipTrig);
4157     hMipTriggXYZ->SetBinContent(thisbinx, thisbinz, thisbiny, numMipTrig);
4158   
4159     // estimate separation between noise and mip peaks
4160     //double peaksep = parameters[1]-ithSpectraTrigg->second.GetMaxXInRangeHG(-1*pedSigHG, 3*pedSigHG);
4161 
4162     if (isGood){
4163       hMPVvsNoisePeak->Fill(ithSpectraTrigg->second.GetMaxXInRangeHG(-1*pedSigHG, 3*pedSigHG), parameters[1]);
4164       //hPeakSeparation->Fill(peaksep);
4165       //hSNRTrigg->Fill(SNR_trigg);
4166       hHGscaleChi2VsLayer->SetBinContent(bin2D, redChi2);
4167       //hChi2VsNMipTrigg->Fill(numMipTrig, redChi2);     
4168       
4169       // get uncertainty on HG Max
4170       double rel_err_L_MPV = parErrAndRes[1]/parameters[1]; // Landau MPV error / MPV
4171       double sigma_Max = rel_err_L_MPV * parameters[4]; // relative MPV err * Max ADC value
4172       hspectraHGMaxVsLayer->SetBinContent(bin2D, parameters[4]);
4173       hspectraHGMaxVsLayer->SetBinError(bin2D, sigma_Max);
4174       hspectraHGFWHMVsLayer->SetBinContent(bin2D, parameters[5]);
4175       hspectraHGLMPVVsLayer->SetBinContent(bin2D, parameters[1]);
4176       hspectraHGLMPVVsLayer->SetBinError(bin2D, parErrAndRes[1]);
4177       hspectraHGLSigmaVsLayer->SetBinContent(bin2D, parameters[0]);
4178       hspectraHGLSigmaVsLayer->SetBinError(bin2D, parErrAndRes[0]);
4179       hspectraHGGSigmaVsLayer->SetBinContent(bin2D, parameters[3]);
4180       hspectraHGGSigmaVsLayer->SetBinError(bin2D, parErrAndRes[3]);
4181       hMaxHG->Fill(parameters[4]);
4182     }
4183     
4184     if (typeRO == ReadOut::Type::Caen) {
4185       for (int p = 0; p < 6; p++){
4186         parameters[p]   = 0;
4187         parErrAndRes[p] = 0;
4188       }
4189       isGood=ithSpectraTrigg->second.FitMipLG(parameters, parErrAndRes, debug, yearData, true, averageScaleLow);
4190       if (isGood){  
4191         hspectraLGMaxVsLayer->SetBinContent(bin2D, parameters[4]);
4192         hspectraLGFWHMVsLayer->SetBinContent(bin2D, parameters[5]);
4193         hspectraLGLMPVVsLayer->SetBinContent(bin2D, parameters[1]);
4194         hspectraLGLMPVVsLayer->SetBinError(bin2D, parErrAndRes[1]);
4195         hspectraLGLSigmaVsLayer->SetBinContent(bin2D, parameters[0]);
4196         hspectraLGLSigmaVsLayer->SetBinError(bin2D, parErrAndRes[0]);
4197         hspectraLGGSigmaVsLayer->SetBinContent(bin2D, parameters[3]);
4198         hspectraLGGSigmaVsLayer->SetBinError(bin2D, parErrAndRes[3]);
4199         hMaxLG->Fill(parameters[4]);
4200       }
4201     }
4202   } // end GetImprovedScaling() spectra loop
4203   if ( debug > 0)
4204     std::cout << "============================== done fitting improved iteration" << std::endl;
4205 
4206   
4207   meanSB_NoiseR = meanSB_NoiseR/hSpectraTrigg.size();
4208   meanSB_SigR   = meanSB_SigR/hSpectraTrigg.size();
4209   //==================================================================================
4210   // write calibration to file
4211   //==================================================================================
4212   RootOutput->cd();
4213   
4214   if (IsCalibSaveToFile()){
4215     TString fileCalibPrint = RootOutputName;
4216     fileCalibPrint         = fileCalibPrint.ReplaceAll(".root","_calib.txt");
4217     calib.PrintCalibToFile(fileCalibPrint);
4218   }
4219   
4220   TcalibOut->Fill();
4221   TcalibOut->Write();
4222   int actChA                     = 0;
4223   double averageScaleUpdated     = calib.GetAverageScaleHigh(actChA);
4224   double averageScaleUpdatedLow  = 0.;
4225   int actChAalt                  = 0;
4226   double averageNTilesA          = 0.;
4227   double averageScaleUpPerTile   = calib.GetAverageScaleHighPerSingleLayer(actChAalt, averageNTilesA);
4228   double meanFWHMHG              = calib.GetAverageScaleWidthHigh();
4229   double meanFWHMLG              = 0.;
4230 
4231   if (typeRO == ReadOut::Type::Caen) {
4232     averageScaleUpdatedLow  = calib.GetAverageScaleLow();
4233     meanFWHMLG              = calib.GetAverageScaleWidthLow();
4234   }
4235   
4236   if (typeRO == ReadOut::Type::Caen) {
4237     std::cout << "average input HG mip: " << averageScale << " LG mip: "<< averageScaleLow << "\t act. ch: "<< actChI<< std::endl;
4238     std::cout << "average updated HG mip: " << averageScaleUpdated << " LG mip: "<< averageScaleUpdatedLow << "\t act. ch: "<< actChA<< std::endl;
4239   } else {
4240     std::cout << "average input mip: " << averageScale << " per tile mip: "<< averageScalePerTile << "\t act. ch: "<< actChI << "\t av tiles/seg "<< averageNTilesI << std::endl;
4241     std::cout << "average updated mip: " << averageScaleUpdated << " per tile mip: "<< averageScaleUpPerTile << "\t act. ch: "<< actChA<< "\t av tiles/seg "<< averageNTilesA << std::endl;
4242   }
4243   RootOutput->Close();
4244   
4245   //==================================================================================
4246   // write hists to histo output file
4247   //==================================================================================
4248   RootOutputHist->cd("IndividualCellsTrigg");
4249     for(ithSpectra=hSpectraTrigg.begin(); ithSpectra!=hSpectraTrigg.end(); ++ithSpectra){
4250       ithSpectra->second.Write(true);
4251     }
4252   RootOutputHist->cd();
4253     
4254     hspectraHGMaxVsLayer->Write();
4255     hspectraHGFWHMVsLayer->Write();
4256     hspectraHGLMPVVsLayer->Write();
4257     hspectraHGLSigmaVsLayer->Write();
4258     hspectraHGGSigmaVsLayer->Write();
4259     hMaxHG->Write();
4260     hHGscaleChi2VsLayer->Write();
4261     //hChi2VsNMipTrigg->Write();
4262     hMPVvsNoisePeak->Write();
4263     hSNRTriggVsLayer->Write();
4264     //hPeakSeparation->Write();
4265     //hSNRTrigg->Write();
4266     hMipTriggXY->Write();
4267     hMipTriggXYZ->Write();
4268     if (typeRO == ReadOut::Type::Caen){
4269       hspectraLGMaxVsLayer->Write();
4270       hspectraLGFWHMVsLayer->Write();
4271       hspectraLGLMPVVsLayer->Write();
4272       hspectraLGLSigmaVsLayer->Write();
4273       hspectraLGGSigmaVsLayer->Write();
4274       hMaxLG->Write();
4275     }
4276     hmipTriggers->Write();
4277     hSuppresionNoise->Write();
4278     hSuppresionSignal->Write();
4279   // fill calib tree & write it
4280   // close open root files
4281   RootOutputHist->Write();
4282   RootOutputHist->Close();
4283 
4284   // close open input root file
4285   RootInput->Close();
4286 
4287   //==================================================================================
4288   // Set up general plotting variables
4289   //==================================================================================  
4290   // create directory for plot output
4291   TString outputDirPlots  = GetPlotOutputDir();
4292   gSystem->Exec("mkdir -p "+outputDirPlots);
4293   
4294   Double_t textSizeRel = 0.035;
4295   StyleSettingsBasics("pdf");
4296   SetPlotStyle();  
4297   //==================================================================================
4298   // Create canvases for channel overview plotting
4299   //==================================================================================
4300   TCanvas* canvas2DCorr = new TCanvas("canvasCorrPlots","",0,0,1450,1300);  // gives the page size
4301   DefaultCanvasSettings( canvas2DCorr, 0.08, 0.13, 0.045, 0.07);
4302 
4303   canvas2DCorr->SetLogz(0);
4304   PlotSimple2D( canvas2DCorr, hspectraHGMaxVsLayer, -10000, -10000, textSizeRel, Form("%s/HG_MaxMip.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true, Form( "#LT Max_{HG} #GT = %.1f", averageScaleUpdated) );
4305   PlotSimple2D( canvas2DCorr, hspectraHGFWHMVsLayer, -10000, -10000, textSizeRel, Form("%s/HG_FWHMMip.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true, Form( "#LT FWHM_{HG} #GT = %.1f", meanFWHMHG));
4306   PlotSimple2D( canvas2DCorr, hspectraHGLMPVVsLayer, -10000, -10000, textSizeRel, Form("%s/HG_LandMPVMip.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
4307   PlotSimple2D( canvas2DCorr, hspectraHGLSigmaVsLayer, -10000, -10000, textSizeRel, Form("%s/HG_LandSigMip.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
4308   PlotSimple2D( canvas2DCorr, hspectraHGGSigmaVsLayer, -10000, -10000, textSizeRel, Form("%s/HG_GaussSigMip.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
4309   PlotSimple2D( canvas2DCorr, hSNRTriggVsLayer, -10000, -10000, textSizeRel, Form("%s/SNRTriggVsLayer.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
4310   PlotSimple2D( canvas2DCorr, hHGscaleChi2VsLayer, -10000, -10000, textSizeRel, Form("%s/HGscaleChi2VsLayer.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
4311   PlotSimple2D( canvas2DCorr, hMipTriggXY, -10000, -10000, textSizeRel, Form("%s/MipTriggXY.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
4312   
4313   canvas2DCorr->SetLogz(1);
4314   TString drawOpt = "colz";
4315   if (yearData == 2023)
4316     drawOpt = "colz,text";
4317   PlotSimple2D( canvas2DCorr, hmipTriggers, -10000, -10000, textSizeRel, Form("%s/MuonTriggers.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, drawOpt, true, Form( "evt. collected = %d", evts));
4318   PlotSimple2D( canvas2DCorr, hSuppresionNoise, -10000, -10000, textSizeRel, Form("%s/SuppressionNoise.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, drawOpt, true, Form( "#LT S/B noise #GT = %.3f", meanSB_NoiseR));
4319   PlotSimple2D( canvas2DCorr, hSuppresionSignal, -10000, -10000, textSizeRel, Form("%s/SuppressionSignal.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, drawOpt, true, Form( "#LT S/B signal #GT = %.3f", meanSB_SigR));
4320 
4321   if (typeRO == ReadOut::Type::Caen){
4322     canvas2DCorr->SetLogz(0);
4323     PlotSimple2D( canvas2DCorr, hspectraLGMaxVsLayer, -10000, -10000, textSizeRel, Form("%s/LG_MaxMip.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true, Form( "#LT Max_{LG} #GT = %.1f", averageScaleUpdatedLow));
4324     PlotSimple2D( canvas2DCorr, hspectraLGFWHMVsLayer, -10000, -10000, textSizeRel, Form("%s/LG_FWHMMip.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true, Form( "#LT FWHM_{LG} #GT = %.1f", meanFWHMLG));
4325     PlotSimple2D( canvas2DCorr, hspectraLGLMPVVsLayer, -10000, -10000, textSizeRel, Form("%s/LG_LandMPVMip.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
4326     PlotSimple2D( canvas2DCorr, hspectraLGLSigmaVsLayer, -10000, -10000, textSizeRel, Form("%s/LG_LandSigMip.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
4327     PlotSimple2D( canvas2DCorr, hspectraLGGSigmaVsLayer, -10000, -10000, textSizeRel, Form("%s/LG_GaussSigMip.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
4328   }
4329 
4330   Double_t maxHG          = ReturnMipPlotRangeDepVov(calib.GetVov(),true, typeRO);
4331   Double_t minHG          = ReturnMipMinPlotRangeDepVov(calib.GetVov(),true, typeRO);
4332   Double_t maxLG          = ReturnMipPlotRangeDepVov(calib.GetVov(),false, typeRO);
4333   Double_t maxTriggPPlot  = maxHG*2;
4334   Int_t textSizePixel     = 30;
4335   if (typeRO != ReadOut::Type::Caen)
4336     maxTriggPPlot = 150;
4337 
4338   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
4339   // Single layer plotting
4340   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
4341   MultiCanvas panelPlot(detConf, "ImpScale");
4342   bool init1D = panelPlot.Initialize(1);
4343     
4344   std::cout << "plotting single layers" << std::endl;
4345   panelPlot.PlotMipWithFits( hSpectra, hSpectraTrigg, 1, minHG, maxHG, 1.2, 
4346                               Form("%s/MIP_HG" ,outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);
4347   panelPlot.PlotTriggerPrim( hSpectraTrigg, averageScalePerTile, factorMinTrigg, factorMaxTrigg, 0, maxTriggPPlot, 1.2,
4348                             Form("%s/TriggPrimitive" ,outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);
4349   if (typeRO == ReadOut::Type::Caen){
4350     panelPlot.PlotMipWithFits( hSpectra, hSpectraTrigg, 0, -20, maxLG, 1.2, 
4351                               Form("%s/MIP_LG" ,outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer );
4352   }
4353   std::cout << "done plotting" << std::endl;
4354 
4355   //==================================================================================
4356   // Single tile plotting
4357   //==================================================================================
4358   if (ExtPlot > 2){
4359     TString outputDirPlotsSingle = Form("%s/SingleTiles",outputDirPlots.Data());
4360     gSystem->Exec("mkdir -p "+outputDirPlotsSingle);
4361 
4362     
4363     TCanvas* canvasSTile = new TCanvas("canvasSignleTile","",0,0,1600,1300);  // gives the page size
4364     DefaultCanvasSettings( canvasSTile, 0.08, 0.01, 0.01, 0.082);
4365 
4366     int counter = 0;
4367     for(ithSpectraTrigg=hSpectraTrigg.begin(); ithSpectraTrigg!=hSpectraTrigg.end(); ++ithSpectraTrigg){
4368       counter++;
4369       long cellID     = ithSpectraTrigg->second.GetCellID();
4370       int row = setup->GetRow(cellID);
4371       int col = setup->GetColumn(cellID);
4372       int lay = setup->GetLayer(cellID);
4373       int mod = setup->GetModule(cellID);
4374 
4375       PlotMipWithFitsSingleTile (canvasSTile, 0.95,  0.95, Double_t(textSizePixel)*2/1600., textSizePixel*2, 
4376                                 hSpectra, hSpectraTrigg, true,  -100, maxHG, 1.2, cellID,  Form("%s/MIP_HG_Tile_M%02d_L%02d_R%02d_C%02d.%s" ,outputDirPlotsSingle.Data(), mod, lay, row, col, plotSuffix.Data()), it->second);
4377     }
4378   }
4379   return true;
4380 } // end GetImprovedScaling()
4381 
4382 //***********************************************************************************************
4383 //*********************** strip noise from sample and fit ***************************************
4384 //***********************************************************************************************
4385 bool Analyses::GetNoiseSampleAndRefitPedestal(void){
4386   std::cout<<"GetNoiseSampleAndRefitPedestal"<<std::endl;
4387   // find detector config
4388   DetConf::Type detConf = setup->GetDetectorConfig();
4389 
4390   std::map<int,RunInfo> ri=readRunInfosFromFile(RunListInputName.Data(),debug,0);
4391   
4392   std::map<int,TileSpectra> hSpectra;
4393   std::map<int,TileSpectra> hSpectraTrigg;
4394   std::map<int, TileSpectra>::iterator ithSpectra;
4395   std::map<int, TileSpectra>::iterator ithSpectraTrigg;
4396   
4397   // create output file for histos
4398   CreateOutputRootHistFile();
4399 
4400   // setup trigger sel
4401   double factorMinTrigg   = 0.5;
4402   if(yearData == 2023)
4403     factorMinTrigg        = 0.1;
4404   // create HG and LG histo's per channel
4405   TH2D* hspectraHGvsCellID      = new TH2D( "hNoiseTriggeredSpectraHG_vsCellID","Noise trigg ADC spectrum High Gain vs CellID; cell ID; ADC_{HG} (arb. units) ",
4406                                             setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 4000,0,4000);
4407   hspectraHGvsCellID->SetDirectory(0);
4408   TH2D* hspectraLGvsCellID      = new TH2D( "hNoiseTriggeredSpectraLG_vsCellID","Noise trigg ADC spectrum Low Gain vs CellID; cell ID; ADC_{LG} (arb. units)  ",
4409                                             setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 4000,0,4000);
4410   hspectraLGvsCellID->SetDirectory(0);
4411   
4412   RootOutputHist->mkdir("IndividualCells");
4413   RootOutputHist->mkdir("IndividualCellsTrigg");
4414   RootOutputHist->cd("IndividualCellsTrigg");  
4415   
4416   //***********************************************************************************************
4417   //************************* first pass over tree to extract spectra *****************************
4418   //***********************************************************************************************  
4419   TcalibIn->GetEntry(0);
4420   // check whether calib should be overwritten based on external text file
4421   if (OverWriteCalib){
4422     calib.ReadCalibFromTextFile(ExternalCalibFile,debug);
4423   }
4424   
4425   int evts=TdataIn->GetEntries();
4426   int runNr = -1;
4427   int actCh = 0;
4428   double averageScale     = calib.GetAverageScaleHigh(actCh);
4429   double averageScaleLow  = calib.GetAverageScaleLow();
4430   std::cout << "average HG mip: " << averageScale << " LG mip: "<< averageScaleLow << std::endl;
4431   for(int i=0; i<evts; i++){
4432     TdataIn->GetEntry(i);
4433     if (i == 0)runNr = event.GetRunNumber();
4434     TdataIn->GetEntry(i);
4435     if (i%5000 == 0 && i > 0 && debug > 0) std::cout << "Reading " <<  i << " / " << evts << " events" << std::endl;
4436     for(int j=0; j<event.GetNTiles(); j++){
4437       Caen* aTile=(Caen*)event.GetTile(j);
4438       if (i == 0 && debug > 2) std::cout << ((TString)setup->DecodeCellID(aTile->GetCellID())).Data() << std::endl;
4439       long currCellID = aTile->GetCellID();
4440       
4441       // read current tile
4442       ithSpectraTrigg=hSpectraTrigg.find(aTile->GetCellID());
4443       // estimate local muon trigger
4444       bool localNoiseTrigg = event.InspectIfNoiseTrigg(currCellID, averageScale, factorMinTrigg);
4445       
4446       if(ithSpectraTrigg!=hSpectraTrigg.end()){
4447         ithSpectraTrigg->second.FillTrigger(aTile->GetLocalTriggerPrimitive());
4448       } else {
4449         RootOutputHist->cd("IndividualCellsTrigg");
4450         hSpectraTrigg[currCellID]=TileSpectra("mipTrigg",currCellID,calib.GetTileCalib(currCellID),event.GetROtype(),debug);
4451         hSpectraTrigg[currCellID].FillTrigger(aTile->GetLocalTriggerPrimitive());;
4452         RootOutput->cd();
4453       }
4454       
4455       ithSpectra=hSpectra.find(aTile->GetCellID());
4456       if (ithSpectra!=hSpectra.end()){
4457         ithSpectra->second.FillSpectraCAEN(aTile->GetADCLow(),aTile->GetADCHigh());
4458       } else {
4459         RootOutputHist->cd("IndividualCells");
4460         hSpectra[currCellID]=TileSpectra("mip1st",currCellID,calib.GetTileCalib(currCellID),event.GetROtype(),debug);
4461         hSpectra[aTile->GetCellID()].FillSpectraCAEN(aTile->GetADCLow(),aTile->GetADCHigh());;
4462 
4463         RootOutput->cd();
4464       }
4465     
4466       // only fill tile spectra if X surrounding tiles on average are compatible with pure noise
4467       if (localNoiseTrigg){
4468         aTile->SetLocalTriggerBit(2);
4469         ithSpectraTrigg=hSpectraTrigg.find(aTile->GetCellID());
4470         ithSpectraTrigg->second.FillSpectraCAEN(aTile->GetADCLow(),aTile->GetADCHigh());
4471         
4472         hspectraHGvsCellID->Fill(aTile->GetCellID(), aTile->GetADCHigh());
4473         hspectraLGvsCellID->Fill(aTile->GetCellID(), aTile->GetADCLow());
4474       }
4475     }
4476     RootOutput->cd();
4477     TdataOut->Fill();
4478   }
4479   TdataOut->Write();
4480   TsetupIn->CloneTree()->Write();
4481   
4482   //***********************************************************************************************
4483   //***** Monitoring histos for fits results of 2nd iteration ******************
4484   //***********************************************************************************************
4485   RootOutputHist->cd();
4486   int maxChannelPerLayer             = (setup->GetNMaxColumn()+1)*(setup->GetNMaxRow()+1)*(setup->GetNMaxModule()+1);
4487   int maxChannelPerLayerSingleMod    = (setup->GetNMaxColumn()+1)*(setup->GetNMaxRow()+1);
4488 
4489   // monitoring trigger 
4490   TH2D* hnoiseTriggers              = new TH2D( "hnoiseTriggers","muon triggers; layer; brd channel; counts ",
4491                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
4492   hnoiseTriggers->SetDirectory(0);
4493   TH1D* hMeanPedHGvsCellID      = new TH1D( "hMeanPedHG_vsCellID","mean Ped High Gain vs CellID ; cell ID; #mu_{noise, HG} (arb. units) ",
4494                                             setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5);
4495   hMeanPedHGvsCellID->SetDirectory(0);
4496   TH2D* hspectraHGMeanVsLayer   = new TH2D( "hspectraHGMeanVsLayer","Mean Ped High Gain vs CellID; layer; brd channel; #mu_{Ped HG} (arb. units) ",
4497                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
4498   hspectraHGMeanVsLayer->SetDirectory(0);
4499   TH2D* hspectraHGSigmaVsLayer  = new TH2D( "hspectraHGSigmaVsLayer","Mean Ped High Gain vs CellID; layer; brd channel; #sigma_{Ped HG} (arb. units) ",
4500                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
4501   hspectraHGSigmaVsLayer->SetDirectory(0);
4502   TH1D* hMeanPedLGvsCellID      = new TH1D( "hMeanPedLG_vsCellID","mean Ped Low Gain vs CellID ; cell ID; #mu_{noise, LG} (arb. units) ",
4503                                             setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5);
4504   hMeanPedLGvsCellID->SetDirectory(0);
4505   TH2D* hspectraLGMeanVsLayer   = new TH2D( "hspectraLGMeanVsLayer","Mean Ped Low Gain vs CellID; layer; brd channel; #mu_{PED LG} (arb. units) ",
4506                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
4507   hspectraLGMeanVsLayer->SetDirectory(0);
4508   TH2D* hspectraLGSigmaVsLayer  = new TH2D( "hspectraLGSigmaVsLayer","Mean Ped Low Gain vs CellID; layer; brd channel; #sigma_{Ped LG} (arb. units)",
4509                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
4510   hspectraLGSigmaVsLayer->SetDirectory(0);
4511 
4512   if ( debug > 0)
4513     std::cout << "============================== starting fitting" << std::endl;
4514 
4515   int currCells = 0;
4516   double* parameters    = new double[6];
4517   for(ithSpectraTrigg=hSpectraTrigg.begin(); ithSpectraTrigg!=hSpectraTrigg.end(); ++ithSpectraTrigg){
4518     for (int p = 0; p < 6; p++){
4519       parameters[p]   = 0;
4520     }
4521 
4522     if (currCells%20 == 0 && currCells > 0 && debug > 0)
4523       std::cout << "============================== cell " <<  currCells << " / " << hSpectraTrigg.size() << " cells" << std::endl;
4524     currCells++;
4525     if ( debug > 2) std::cout << ((TString)setup->DecodeCellID(ithSpectraTrigg->second.GetCellID())).Data() << std::endl;
4526     ithSpectraTrigg->second.FitNoise(parameters, yearData, true);
4527     hMeanPedHGvsCellID->SetBinContent(hMeanPedHGvsCellID->FindBin(ithSpectraTrigg->second.GetCellID()), parameters[4]);
4528     hMeanPedHGvsCellID->SetBinError  (hMeanPedHGvsCellID->FindBin(ithSpectraTrigg->second.GetCellID()), parameters[6]);
4529     hMeanPedLGvsCellID->SetBinContent(hMeanPedLGvsCellID->FindBin(ithSpectraTrigg->second.GetCellID()), parameters[0]);
4530     hMeanPedLGvsCellID->SetBinError  (hMeanPedLGvsCellID->FindBin(ithSpectraTrigg->second.GetCellID()), parameters[2]);
4531     
4532     int layer           = setup->GetLayer(ithSpectraTrigg->second.GetCellID());
4533     int chInLayer       = setup->GetChannelInLayerFull(ithSpectraTrigg->second.GetCellID(),detConf);
4534     hspectraHGMeanVsLayer->SetBinContent(hspectraHGMeanVsLayer->FindBin(layer,chInLayer), parameters[4]);
4535     hspectraHGMeanVsLayer->SetBinError(hspectraHGMeanVsLayer->FindBin(layer,chInLayer), parameters[5]);
4536     hspectraHGSigmaVsLayer->SetBinContent(hspectraHGSigmaVsLayer->FindBin(layer,chInLayer), parameters[6]);
4537     hspectraHGSigmaVsLayer->SetBinError(hspectraHGSigmaVsLayer->FindBin(layer,chInLayer), parameters[7]);
4538     hspectraLGMeanVsLayer->SetBinContent(hspectraLGMeanVsLayer->FindBin(layer,chInLayer), parameters[0]);
4539     hspectraLGMeanVsLayer->SetBinError(hspectraLGMeanVsLayer->FindBin(layer,chInLayer), parameters[1]);
4540     hspectraLGSigmaVsLayer->SetBinContent(hspectraLGSigmaVsLayer->FindBin(layer,chInLayer), parameters[2]);
4541     hspectraLGSigmaVsLayer->SetBinError(hspectraLGSigmaVsLayer->FindBin(layer,chInLayer), parameters[3]);
4542     
4543     hnoiseTriggers->SetBinContent(hnoiseTriggers->FindBin(layer,chInLayer), ithSpectraTrigg->second.GetHG()->GetEntries());
4544   }
4545   if ( debug > 0)
4546     std::cout << "============================== done fitting" << std::endl;
4547   
4548   RootOutput->cd();
4549   
4550   if (IsCalibSaveToFile()){
4551     TString fileCalibPrint = RootOutputName;
4552     fileCalibPrint         = fileCalibPrint.ReplaceAll(".root","_calib.txt");
4553     calib.PrintCalibToFile(fileCalibPrint);
4554   }
4555 
4556 
4557   TcalibOut->Fill();
4558   TcalibOut->Write();
4559   
4560   RootOutput->Write();
4561   RootOutput->Close();
4562 
4563 
4564   RootOutputHist->cd("IndividualCellsTrigg");
4565     for(ithSpectra=hSpectraTrigg.begin(); ithSpectra!=hSpectraTrigg.end(); ++ithSpectra){
4566       ithSpectra->second.Write(true);
4567     }
4568   RootOutputHist->cd();
4569     
4570     hMeanPedHGvsCellID->Write();
4571     hMeanPedLGvsCellID->Write();
4572     hspectraHGMeanVsLayer->Write();
4573     hspectraHGSigmaVsLayer->Write();
4574     hspectraLGMeanVsLayer->Write(); 
4575     hspectraLGSigmaVsLayer->Write();
4576     hspectraHGvsCellID->Write();
4577     hspectraLGvsCellID->Write();
4578         
4579     hnoiseTriggers->Write();
4580   // close open root files
4581   RootOutputHist->Write();
4582   RootOutputHist->Close();
4583 
4584   RootInput->Close();
4585 
4586   // Get run info object
4587   std::map<int,RunInfo>::iterator it=ri.find(runNr);
4588   
4589   // create directory for plot output
4590   TString outputDirPlots = GetPlotOutputDir();
4591   gSystem->Exec("mkdir -p "+outputDirPlots);
4592   
4593   //**********************************************************************
4594   // Create canvases for channel overview plotting
4595   //**********************************************************************
4596   Double_t textSizeRel = 0.035;
4597   StyleSettingsBasics("pdf");
4598   SetPlotStyle();
4599 
4600   TCanvas* canvas2DCorr = new TCanvas("canvasCorrPlots","",0,0,1450,1300);  // gives the page size
4601   DefaultCanvasSettings( canvas2DCorr, 0.08, 0.13, 0.045, 0.07);
4602 
4603   canvas2DCorr->SetLogz(0);
4604   PlotSimple2D( canvas2DCorr, hspectraHGMeanVsLayer, -10000, -10000, textSizeRel, Form("%s/HG_NoiseMean.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true );
4605   PlotSimple2D( canvas2DCorr, hspectraHGSigmaVsLayer, -10000, -10000, textSizeRel, Form("%s/HG_NoiseSigma.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
4606   PlotSimple2D( canvas2DCorr, hspectraLGMeanVsLayer, -10000, -10000, textSizeRel, Form("%s/LG_NoiseMean.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
4607   PlotSimple2D( canvas2DCorr, hspectraLGSigmaVsLayer, -10000, -10000, textSizeRel, Form("%s/LG_NoiseSigma.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
4608   canvas2DCorr->SetLogz(1);
4609   PlotSimple2D( canvas2DCorr, hspectraHGvsCellID, -10000, -10000, textSizeRel, Form("%s/HG_Noise.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
4610   PlotSimple2D( canvas2DCorr, hspectraLGvsCellID, -10000, -10000, textSizeRel, Form("%s/LG_Noise.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
4611   
4612   PlotSimple2D( canvas2DCorr, hnoiseTriggers, -10000, -10000, textSizeRel, Form("%s/LG_Noise.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true, Form( "evt. coll = %d", evts));
4613   
4614   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
4615   // Multipanel plotting
4616   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
4617   MultiCanvas panelPlot(detConf, "NoiseSample");
4618   bool init1D = panelPlot.Initialize(1);
4619     
4620   panelPlot.PlotNoiseAdvWithFits(hSpectra, hSpectraTrigg, 1, 0, 450, 1.2, 
4621                                   Form("%s/NoiseTrigg_HG" ,outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib);
4622   
4623 
4624   
4625   return true;
4626 }
4627 
4628 //***********************************************************************************************
4629 //*********************** Evaluate local triggers only and store ********************************
4630 //***********************************************************************************************
4631 bool Analyses::RunEvalLocalTriggers(void){
4632   std::cout<<"EvalLocalTriggers"<<std::endl;
4633 
4634   // find detector config
4635   DetConf::Type detConf   = setup->GetDetectorConfig();
4636   
4637   // read full run list
4638   std::map<int,RunInfo> ri=readRunInfosFromFile(RunListInputName.Data(),debug,0);
4639 
4640   RootOutput->cd();
4641   // reading calib object
4642   std::cout << "starting to run trigger eval: " << TcalibIn <<  "\t" << TcalibIn->GetEntry(0) << std::endl;
4643   TcalibIn->GetEntry(0);
4644   // check whether calib should be overwritten based on external text file
4645   if (OverWriteCalib){
4646     calib.ReadCalibFromTextFile(ExternalCalibFile,debug);
4647   }
4648   
4649   // reading first event in tree to extract runnumber & RO-type
4650   TdataIn->GetEntry(0);
4651   int evts              = TdataIn->GetEntries();
4652   Int_t runNr           = event.GetRunNumber();
4653   ReadOut::Type typeRO  = event.GetROtype();
4654   // reset calib object event infos
4655   std::cout<< "original run numbers calib: "<<calib.GetRunNumber() << "\t" << calib.GetRunNumberPed() << "\t" << calib.GetRunNumberMip() << std::endl;
4656   calib.SetRunNumber(runNr);
4657   calib.SetBeginRunTime(event.GetBeginRunTimeAlt());
4658   std::cout<< "reset run numbers calib: "<< calib.GetRunNumber() << "\t" << calib.GetRunNumberPed() << "\t" << calib.GetRunNumberMip() << std::endl;
4659   
4660   // getting averages from calib objects
4661   int actCh1st = 0;
4662   double averageScale = calib.GetAverageScaleHigh(actCh1st);
4663   int actChalt                  = 0;
4664   double averageNTiles          = 0.;
4665   double averageScalePerTile    = calib.GetAverageScaleHighPerSingleLayer(actChalt, averageNTiles);
4666   double avLGHGCorr   = calib.GetAverageLGHGCorr();
4667   std::cout << "average HG mip: " << averageScale << "\t per tile: " <<  averageScalePerTile << "\t active ch: "<< actCh1st << "\t av NTiles/seg: " << averageNTiles << std::endl;
4668   
4669   // setup local trigger sel
4670   TRandom3* rand    = new TRandom3();
4671   Int_t localTriggerTiles     = 4;
4672   if (yearData == 2023){
4673     localTriggerTiles         = 6;
4674   }
4675   double factorMinTrigg       = 0.8;
4676   double factorMinTriggNoise  = 0.2;
4677   double factorMaxTrigg       = 2.5;
4678   if (yearData == 2023){
4679     factorMinTrigg            = 0.9;
4680     factorMaxTrigg            = 2.;
4681   }
4682   
4683   // reset maximum number of events if requested
4684   if (maxEvents == -1){
4685     maxEvents = evts;
4686   } else {
4687     std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
4688     std::cout << "ATTENTION: YOU ARE RESETTING THE MAXIMUM NUMBER OF EVENTS TO BE PROCESSED TO: " << maxEvents << ". THIS SHOULD ONLY BE USED FOR TESTING!" << std::endl;
4689     std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
4690   }
4691   
4692   // set cout frequent
4693   int outCount                = 1000;
4694   if (evts < 10000)
4695     outCount  = 500;
4696   if (evts > 100000)
4697     outCount  = 5000;
4698   
4699   //==================================================================================
4700   // Create & setup general monitoring histograms
4701   //==================================================================================  
4702   // create output file for histos
4703   CreateOutputRootHistFile();
4704   // 2D beam profile -EP
4705   int maxChannelPerLayer          = (setup->GetNMaxColumn()+1)*(setup->GetNMaxRow()+1)*(setup->GetNMaxModule()+1);
4706   int maxChannelPerLayerSingleMod = (setup->GetNMaxColumn()+1)*(setup->GetNMaxRow()+1);
4707   int thisbinxmax = setup->GetNMaxColumn()+1;   
4708   int thisbinymax = (int)(setup->GetNMaxRow()+1)*(setup->GetNMaxModule()+1);
4709   int thisbinzmax = (int)setup->GetNMaxLayer()+1;
4710   
4711   RootOutputHist->cd();
4712   // 2D beam profile front view
4713   TH2D* hMipTriggXY               = new TH2D( "hMipTriggXY", "MIP Triggers summed over layers; X (col); Y (row); Num triggers", 
4714                                               thisbinxmax, -0.5, thisbinxmax-0.5, thisbinymax, -0.5, thisbinymax-0.5); 
4715   hMipTriggXY->SetDirectory(0);
4716   // 3D beam profile -EP
4717   TH3D *hMipTriggXYZ              = new TH3D( "hMipTriggXYZ", "MIP Triggers; X (col); Z (layer); Y (row); Num triggers", 
4718                                               thisbinxmax, -0.5, thisbinxmax-0.5, thisbinzmax, -0.5, thisbinzmax-0.5, thisbinymax, -0.5, thisbinymax-0.5);
4719   hMipTriggXYZ->SetDirectory(0);
4720   // monitoring trigger 
4721   TH2D* hmipTriggers              = new TH2D( "hmipTriggers","muon triggers; layer; brd channel; counts ",
4722                                             setup->GetNMaxLayer()+1, -0.5, setup->GetNMaxLayer()+1-0.5, maxChannelPerLayer, -0.5, maxChannelPerLayer-0.5);
4723   hmipTriggers->SetDirectory(0);
4724   // monitoring triggers vs Cell ID
4725   TH1D* hMipTriggersGvsCellID     = new TH1D( "hMipTriggersGvsCellID","mip Triggers vs CellID ; cell ID; Nr. mip trigg ",
4726                                             setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5);
4727   hMipTriggersGvsCellID->SetDirectory(0);
4728 
4729   // create tileSpectra objects
4730   std::map<int,TileSpectra> hSpectra;
4731   std::map<int,TileSpectra> hSpectraTrigg;
4732   std::map<int, TileSpectra>::iterator ithSpectra;
4733   std::map<int, TileSpectra>::iterator ithSpectraTrigg;
4734   RootOutputHist->mkdir("IndividualCells");
4735   RootOutputHist->mkdir("IndividualCellsTrigg");
4736   RootOutputHist->cd("IndividualCellsTrigg");  
4737 
4738   //==================================================================================
4739   // Process input tree & evaulate new triggers
4740   //==================================================================================  
4741   for(int i=0; i<evts && i < maxEvents; i++){
4742     TdataIn->GetEntry(i);
4743     if (i%outCount == 0 && debug > 0) std::cout << "Reading " <<  i << " / " << evts << " events" << std::endl;
4744     
4745     //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4746     // Single tile processing
4747     //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4748     for(int j=0; j<event.GetNTiles(); j++){
4749 
4750       //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4751       // CAEN treatment
4752       //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++      
4753       if (typeRO == ReadOut::Type::Caen) {
4754         Caen* aTile=(Caen*)event.GetTile(j);      
4755         int currCellID = aTile->GetCellID();  
4756         // calculate trigger primitives
4757         if (EvalTriggerPrimitives) aTile->SetLocalTriggerPrimitive(event.CalculateLocalMuonTrigg(calib, rand, currCellID, localTriggerTiles, avLGHGCorr));
4758         bool localMuonTrigg   = event.InspectIfLocalMuonTrigg(currCellID, averageScalePerTile, factorMinTrigg, factorMaxTrigg);
4759         bool localNoiseTrigg  = event.InspectIfNoiseTrigg(currCellID, averageScalePerTile, factorMinTriggNoise);
4760         aTile->SetLocalTriggerBit(0);
4761         if (localMuonTrigg) aTile->SetLocalTriggerBit(1);
4762         if (localNoiseTrigg) aTile->SetLocalTriggerBit(2);
4763         
4764       //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4765       // HGCROC treatment
4766       //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4767       } else if (typeRO == ReadOut::Type::Hgcroc) {
4768         Hgcroc* aTile=(Hgcroc*)event.GetTile(j);
4769         int currCellID = aTile->GetCellID();  
4770         
4771         // calculate trigger primitives
4772         aTile->SetLocalTriggerPrimitive(event.CalculateLocalMuonTrigg(calib, rand, currCellID, localTriggerTiles, 0.));
4773         
4774         bool localMuonTrigg   = event.InspectIfLocalMuonTrigg(currCellID, averageScalePerTile, factorMinTrigg, factorMaxTrigg);
4775         // if (localMuonTrigg) std::cout << " triggered " << std::endl;
4776         bool localNoiseTrigg  = event.InspectIfNoiseTrigg(currCellID, averageScalePerTile, factorMinTriggNoise);
4777         
4778         // reset Local trigger bit
4779         aTile->SetLocalTriggerBit(0);
4780         // set trigger bit to muon
4781         if (localMuonTrigg){
4782           aTile->SetLocalTriggerBit(1);
4783           hMipTriggersGvsCellID->Fill(currCellID);
4784           
4785           int layer       = setup->GetLayer(currCellID);
4786           int chInLayer   = setup->GetChannelInLayerFull(currCellID,detConf);
4787           int row         = setup->GetRow(currCellID);
4788           int col         = setup->GetColumn(currCellID);
4789           int mod         = setup->GetModule(currCellID);
4790           
4791           hmipTriggers->Fill(layer,chInLayer);
4792           hMipTriggXY->Fill(col, (mod*2) + row);
4793           hMipTriggXYZ->Fill(col, layer, (mod*2) + row);
4794         }
4795         // set trigger bit to noise
4796         if (localNoiseTrigg) {
4797           aTile->SetLocalTriggerBit(2);
4798         }
4799           
4800         double adc = aTile->GetIntegratedADC();
4801         double tot = aTile->GetRawTOT();
4802         double toa = aTile->GetRawTOA();
4803 
4804         //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4805         // filling single tile spectra for monitoring
4806         //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4807         ithSpectraTrigg = hSpectraTrigg.find(currCellID);
4808         ithSpectra      = hSpectra.find(currCellID);
4809         
4810         // create tile sprectra object if not yet there for triggered cells & fill trigger primitives
4811         if(ithSpectraTrigg!=hSpectraTrigg.end()){
4812           ithSpectraTrigg->second.FillTrigger(aTile->GetLocalTriggerPrimitive());
4813         } else {
4814           RootOutputHist->cd("IndividualCellsTrigg");
4815           hSpectraTrigg[currCellID]=TileSpectra("mipTrigg",currCellID,calib.GetTileCalib(currCellID),event.GetROtype(),debug);
4816           hSpectraTrigg[currCellID].FillTrigger(aTile->GetLocalTriggerPrimitive());;
4817           RootOutput->cd();
4818         }
4819         // only fill tile spectra if 4 surrounding tiles on average are compatible with muon response
4820         if (localMuonTrigg){
4821           ithSpectraTrigg=hSpectraTrigg.find(currCellID);
4822           ithSpectraTrigg->second.FillHGCROC(adc, toa, tot);
4823         }
4824         
4825         // create tile sprectra object if not yet there for all cells & fill 
4826         if (ithSpectra!=hSpectra.end()){
4827           ithSpectra->second.FillHGCROC(adc, toa, tot);
4828         } else {
4829           RootOutputHist->cd("IndividualCells");
4830           hSpectra[currCellID]=TileSpectra("mip1st",currCellID,calib.GetTileCalib(currCellID),event.GetROtype(),debug);
4831           hSpectra[currCellID].FillHGCROC(adc, toa, tot);
4832           RootOutput->cd();
4833         }
4834       }
4835     }
4836     RootOutput->cd();
4837     TdataOut->Fill();
4838   }
4839   
4840   //==================================================================================
4841   // Write tree output file
4842   //==================================================================================
4843   RootOutput->cd();
4844     TdataOut->Write();
4845     TsetupIn->CloneTree()->Write();
4846     
4847     if (IsCalibSaveToFile()){
4848       TString fileCalibPrint = RootOutputName;
4849       fileCalibPrint         = fileCalibPrint.ReplaceAll(".root","_calib.txt");
4850       calib.PrintCalibToFile(fileCalibPrint);
4851     }
4852     
4853     TcalibOut->Fill();
4854     TcalibOut->Write();
4855   RootOutput->Close();
4856   RootInput->Close();      
4857   
4858   //==================================================================================
4859   // Set up general plotting variables
4860   //==================================================================================
4861   // Get run info object
4862   std::map<int,RunInfo>::iterator it=ri.find(runNr);
4863   // create directory for plot output
4864   TString outputDirPlots  = GetPlotOutputDir();
4865   gSystem->Exec("mkdir -p "+outputDirPlots);
4866   
4867   Double_t textSizeRel = 0.035;
4868   StyleSettingsBasics("pdf");
4869   SetPlotStyle();  
4870 
4871   Double_t maxHG          = ReturnMipPlotRangeDepVov(calib.GetVov(),true, typeRO);
4872   Double_t minHG          = ReturnMipMinPlotRangeDepVov(calib.GetVov(),true, typeRO);
4873   Double_t maxLG          = ReturnMipPlotRangeDepVov(calib.GetVov(),false, typeRO);
4874   Double_t maxTriggPPlot  = maxHG*2;
4875   Int_t textSizePixel     = 30;
4876   if (typeRO != ReadOut::Type::Caen)
4877     maxTriggPPlot = 150;
4878 
4879   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
4880   // Single layer plotting
4881   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
4882   MultiCanvas panelPlot(detConf, "Skim");
4883   bool init1D = panelPlot.Initialize(1);
4884     
4885   std::cout << "plotting single layers" << std::endl;
4886   panelPlot.PlotMipWithFits( hSpectra, hSpectraTrigg, 1, minHG, maxHG, 1.2, 
4887                               Form("%s/MIP_HG" ,outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);
4888   panelPlot.PlotTriggerPrim( hSpectraTrigg, averageScalePerTile, factorMinTrigg, factorMaxTrigg, 0, maxTriggPPlot, 1.2,
4889                             Form("%s/TriggPrimitive" ,outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);
4890   std::cout << "done plotting" << std::endl;
4891 
4892   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
4893   // Overview plots
4894   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
4895   TCanvas* canvas2DCorr = new TCanvas("canvasCorrPlots","",0,0,1450,1300);  // gives the page size
4896   DefaultCanvasSettings( canvas2DCorr, 0.08, 0.13, 0.045, 0.07);
4897   TCanvas* canvas1DSimple = new TCanvas("canvas1DSimple","",0,0,1450,1300);  // gives the page size
4898   DefaultCanvasSettings( canvas1DSimple, 0.08, 0.03, 0.03, 0.07);
4899   
4900   std::cout << "plotting overview" << std::endl;
4901   PlotSimple2D( canvas2DCorr, hmipTriggers, -10000, -10000, textSizeRel, 
4902                 Form("%s/MipTrigger.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
4903   PlotSimple2D( canvas2DCorr, hMipTriggXY, -10000, -10000, textSizeRel, 
4904                 Form("%s/MipTriggerXY.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
4905   PlotSimple1D(canvas1DSimple, hMipTriggersGvsCellID, -10000, -10000, textSizeRel, 
4906               Form("%s/MuonTriggVsCellID.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1);
4907   TH1D* hMipTriggersGvsCellIDPerEvt = (TH1D*)hMipTriggersGvsCellID->Clone("hMipTriggersGvsCellIDPerEvt");
4908   hMipTriggersGvsCellIDPerEvt->Scale(1./evts);
4909   hMipTriggersGvsCellIDPerEvt->GetYaxis()->SetTitle("#mu triggers/event");
4910   PlotSimple1D(canvas1DSimple, hMipTriggersGvsCellIDPerEvt, -10000, -10000, textSizeRel, 
4911               Form("%s/MuonTriggPerEventVsCellID.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1);
4912 
4913   //==================================================================================
4914   // Write output hist file
4915   //==================================================================================
4916   RootOutputHist->cd();
4917     hMipTriggersGvsCellID->Write();
4918     hMipTriggersGvsCellIDPerEvt->Write();
4919     hmipTriggers->Write();
4920     hMipTriggXY->Write();
4921     hMipTriggXYZ->Write();
4922     
4923   RootOutputHist->cd("IndividualCellsTrigg");
4924     for(ithSpectraTrigg=hSpectraTrigg.begin(); ithSpectraTrigg!=hSpectraTrigg.end(); ++ithSpectraTrigg){
4925       ithSpectraTrigg->second.Write(true);
4926     }
4927   RootOutputHist->cd("IndividualCells");
4928     for(ithSpectra=hSpectra.begin(); ithSpectra!=hSpectra.end(); ++ithSpectra){
4929       ithSpectra->second.Write(true);
4930     }
4931   RootOutputHist->Write();
4932   RootOutputHist->Close();
4933   
4934   return true;
4935 
4936 }
4937 
4938 //***********************************************************************************************
4939 //*********************** Calibration routine ***************************************************
4940 //***********************************************************************************************
4941 bool Analyses::Calibrate(void){
4942   std::cout<<"Calibrate"<<std::endl;
4943 
4944   std::map<int,RunInfo> ri=readRunInfosFromFile(RunListInputName.Data(),debug,0);
4945 
4946   // Find detector config
4947   DetConf::Type detConf = setup->GetDetectorConfig();
4948   
4949   //=============================================================================================
4950   // Reset calibs if necessary
4951   //=============================================================================================
4952   std::cout << "starting to run calibration: " << TcalibIn <<  "\t" << TcalibIn->GetEntry(0) << std::endl;
4953   TcalibIn->GetEntry(0);
4954   // check whether calib should be overwritten based on external text file
4955   if (OverWriteCalib){
4956     calib.ReadCalibFromTextFile(ExternalCalibFile,debug);
4957   }
4958   // set external bad channel map
4959   if (CalcBadChannel == 1){
4960     calib.ReadExternalBadChannelMap(ExternalBadChannelMap, debug);
4961   }
4962   // add ToA offsets for half asics to calib objects if available
4963   if (ExternalToACalibOffSetFile.CompareTo("") != 0 ){
4964     calib.ReadExternalToAOffsets(ExternalToACalibOffSetFile,debug);
4965   }
4966 
4967   // reading first event in tree to extract runnumber & RO-type
4968   TdataIn->GetEntry(0);
4969   Int_t runNr           = event.GetRunNumber();
4970   ReadOut::Type typeRO  = event.GetROtype();
4971   std::cout<< "original run numbers calib: "<<calib.GetRunNumber() << "\t" << calib.GetRunNumberPed() << "\t" << calib.GetRunNumberMip() << std::endl;
4972   calib.SetRunNumber(runNr);
4973   calib.SetBeginRunTime(event.GetBeginRunTimeAlt());
4974   std::cout<< "reset run numbers calib: "<< calib.GetRunNumber() << "\t" << calib.GetRunNumberPed() << "\t" << calib.GetRunNumberMip() << std::endl;
4975   
4976   // Get run info object
4977   std::map<int,RunInfo>::iterator it=ri.find(runNr);
4978 
4979   //=============================================================================================
4980   // Create output histos
4981   //=============================================================================================
4982   CreateOutputRootHistFile();
4983   
4984   TH2D* hspectraHGvsCellID          = nullptr;
4985   TH2D* hspectraHGCorrvsCellID      = nullptr;
4986   TH2D* hspectraHGCorrvsCellIDNoise = nullptr;
4987   
4988   // CAEN only
4989   TH2D* hspectraLGvsCellID          = nullptr;
4990   TH2D* hspectraLGCorrvsCellID      = nullptr;
4991   TH2D* hspectraLGCorrvsCellIDNoise = nullptr;
4992 
4993   // HGCROC only
4994   TH2D* hspectraTotvsCellID         = nullptr;
4995   TH2D* hspectraTotvsCellIDNoise    = nullptr;
4996   TH1D* hSaturatedCellID            = nullptr;
4997   TH2D* hspectraTOAvsCellID   =nullptr;   
4998   TH2D* hSampleTOAVsCellID    =nullptr;
4999   TH1D* hSampleTOA            =nullptr;   
5000   TH2D* hTOANsVsCellID        =nullptr;   
5001   TH2D* hTOACorrNsVsCellID    =nullptr;   
5002   TH2D* h2DToAvsnSample[setup->GetNMaxROUnit()+1][2];
5003   TH2D* h2DWaveFormHalfAsicAll[setup->GetNMaxROUnit()+1][2];
5004   TProfile* hWaveFormHalfAsicAll[setup->GetNMaxROUnit()+1][2];  
5005   
5006   // create HG and LG histo's per channel
5007   if (typeRO == ReadOut::Type::Caen) {
5008     hspectraHGvsCellID               = new TH2D( "hspectraHG_vsCellID","ADC spectrum High Gain vs CellID; cell ID; ADC_{HG} (arb. units)   ; counts ",
5009                                                 setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 4000,0,4000);
5010     hspectraHGvsCellID->SetDirectory(0);
5011     hspectraHGCorrvsCellID           = new TH2D( "hspectraHGCorr_vsCellID","ADC spectrum High Gain corrected vs CellID; cell ID; ADC_{HG} (arb. units)  ; counts ",
5012                                                 setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 4000,-200,3800);
5013     hspectraHGCorrvsCellID->SetDirectory(0);
5014     hspectraHGCorrvsCellIDNoise      = new TH2D( "hspectraHGCorr_vsCellID_Noise","ADC spectrum High Gain corrected vs CellID Noise; cell ID; ADC_{HG} (arb. units)  ; counts ",
5015                                                 setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 4000,-200,3800);
5016     hspectraHGCorrvsCellIDNoise->SetDirectory(0);
5017     hspectraLGvsCellID               = new TH2D( "hspectraLG_vsCellID","ADC spectrum Low Gain vs CellID; cell ID; ADC_{LG} (arb. units)  ; counts",
5018                                                 setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 4000,0,4000);
5019     hspectraLGvsCellID->SetDirectory(0);
5020     hspectraLGCorrvsCellID           = new TH2D( "hspectraLGCorr_vsCellID","ADC spectrum Low Gain corrected vs CellID; cell ID; ADC_{LG} (arb. units)  ; counts  ",
5021                                                 setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 4000,-200,3800);
5022     hspectraLGCorrvsCellID->SetDirectory(0);
5023     hspectraLGCorrvsCellIDNoise      = new TH2D( "hspectraLGCorr_vsCellID_Noise","ADC spectrum Low Gain corrected vs CellID Noise; cell ID; ADC_{LG} (arb. units)  ; counts  ",
5024                                                 setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 4000,-200,3800);
5025     hspectraLGCorrvsCellIDNoise->SetDirectory(0);
5026   } else if (typeRO == ReadOut::Type::Hgcroc) {
5027     hspectraHGvsCellID               = new TH2D( "hspectraHG_vsCellID","ADC spectrum vs CellID; cell ID; ADC (arb. units); counts ",
5028                                                 setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 1100,-40.5,1100-40.5);
5029     hspectraHGvsCellID->SetDirectory(0);
5030     hspectraHGCorrvsCellIDNoise      = new TH2D( "hspectraHGCorr_vsCellID_Noise","ADC spectrum vs CellID Noise; cell ID; ADC (arb. units); counts ",
5031                                                 setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 400,-40.5,400-40.5);
5032     hspectraHGCorrvsCellIDNoise->SetDirectory(0);
5033     hspectraTotvsCellID              = new TH2D( "hspectraTot_vsCellID","Tot vs CellID; cell ID; Tot (arb. units); counts  ",
5034                                                 setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 4096,0,4096);
5035     hspectraTotvsCellID->SetDirectory(0);
5036     hspectraTotvsCellIDNoise      = new TH2D( "hspectraTot_vsCellID_Noise","Tot vs CellID Noise; cell ID; Tot (arb. units); counts  ",
5037                                                 setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 4096,0,4096);
5038     hspectraTotvsCellIDNoise->SetDirectory(0);
5039     hSaturatedCellID              = new TH1D( "hSaturatedCellID","Saturared CellID; cell ID; Saturated cells  ",
5040                                                 setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5);
5041     hSaturatedCellID->SetDirectory(0);
5042     
5043     hspectraTOAvsCellID      = new TH2D( "hspectraTOAvsCellID","TOA spectrums CellID; cell ID; TOA (arb. units) ",
5044                                             setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 1024,0,1024);
5045     hspectraTOAvsCellID->SetDirectory(0);
5046     hSampleTOAVsCellID       = new TH2D( "hSampleTOAvsCellID","#sample ToA; cell ID; #sample TOA",
5047                                             setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, it->second.samples,0,it->second.samples);
5048     hSampleTOAVsCellID->SetDirectory(0);
5049     hSampleTOA                = new TH1D( "hSampleTOA","#sample ToA; #sample TOA",
5050                                               it->second.samples,0,it->second.samples);
5051     hSampleTOA->SetDirectory(0);  
5052     hTOANsVsCellID            = new TH2D( "hTOANsVsCellID","ToA (ns); cell ID; ToA (ns)",
5053                                       setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 500,-250,0);
5054     hTOANsVsCellID->SetDirectory(0);
5055     hTOACorrNsVsCellID        = new TH2D( "hTOACorrNsVsCellID","ToA (ns); cell ID; ToA (ns)",
5056                                       setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 500,-250,0);
5057     hTOACorrNsVsCellID->SetDirectory(0);
5058     for (Int_t ro = 0; ro < setup->GetNMaxROUnit()+1; ro++){
5059       for (int h = 0; h< 2; h++){
5060         h2DToAvsnSample[ro][h]    = new TH2D(Form("h2DTOASample_Asic_%d_Half_%d",ro,h),
5061                                               Form("Sample vs TOA %d %d; TOA (arb. units); #sample",ro,h), 1024/8,0,1024,it->second.samples,0,it->second.samples);
5062         h2DToAvsnSample[ro][h]->SetDirectory(0);
5063         hWaveFormHalfAsicAll[ro][h]    = new TProfile(Form("WaveForm_Asic_%d_Half_%d",ro,h),
5064                                           Form("ADC-TOA correlation %d %d;  t (ns) ; ADC (arb. units)",ro,h),550,-50,500);
5065         hWaveFormHalfAsicAll[ro][h]->SetDirectory(0);
5066         h2DWaveFormHalfAsicAll[ro][h]  = new TH2D(Form("h2DWaveForm_Asic_%d_Half_%d",ro,h),
5067                                           Form("2D ADC vs TOA %d %d;  t (ns) ; ADC (arb. units)",ro,h), 
5068                                             550,-50,500, 1044/4, -20, 1024);      
5069         h2DWaveFormHalfAsicAll[ro][h]->SetDirectory(0);
5070       }
5071     }
5072   }
5073   TH2D* hspectraEnergyvsCellID  = new TH2D( "hspectraEnergy_vsCellID","Energy vs CellID; cell ID; E (mip eq./tile); counts",
5074                                             setup->GetMaxCellID()+1, -0.5, setup->GetMaxCellID()+1-0.5, 6000,0,200);
5075   hspectraEnergyvsCellID->SetDirectory(0);
5076   TH2D* hspectraEnergyTotvsNCells  = new TH2D( "hspectraTotEnergy_vsNCells","Energy vs CellID; N_{Cells}; E_{tot} (mip eq./tile); counts",
5077                                             setup->GetNActiveCells()+1, -0.5, setup->GetNActiveCells()+1-0.5, 6000,0,1000);
5078   hspectraEnergyTotvsNCells->SetDirectory(0);
5079   TH2D* hspectraEnergyTotvsNCellsNoNoise  = new TH2D( "hspectraTotEnergy_vsNCells_NoNoise","Energy vs CellID; N_{Cells}; E_{tot} (mip eq./tile); counts",
5080                                             setup->GetNActiveCells()+1, -0.5, setup->GetNActiveCells()+1-0.5, 6000,0,1000);
5081   hspectraEnergyTotvsNCellsNoNoise->SetDirectory(0);
5082   TH2D* hspectraEnergyTotvsNCellsST  = new TH2D( "hspectraTotEnergy_vsNCellsST","Energy vs CellID; N_{Tiles}; E_{tot} (mip eq./tile); counts",
5083                                             (setup->GetNActiveCells()*5)+1, -0.5, (setup->GetNActiveCells()*10)+1-0.5, 6000,0,1000);
5084   hspectraEnergyTotvsNCellsST->SetDirectory(0);
5085   
5086   std::map<int,TileSpectra> hSpectra;
5087   std::map<int, TileSpectra>::iterator ithSpectra;
5088   std::map<int,TileSpectra> hSpectraLocalTrigg;
5089   std::map<int, TileSpectra>::iterator ithSpectraLocalTrigg;
5090   std::map<int,TileSpectra> hSpectraNoise;
5091   std::map<int, TileSpectra>::iterator ithSpectraNoise;
5092   std::map<int,TileSpectra> hSpectraNotNoise;
5093   std::map<int, TileSpectra>::iterator ithSpectraNotNoise;
5094   
5095   // entering histoOutput file
5096   RootOutputHist->mkdir("IndividualCells");
5097   RootOutputHist->cd("IndividualCells");
5098   RootOutputHist->mkdir("IndividualCellsNoise");
5099   RootOutputHist->cd("IndividualCellsNoise");
5100   RootOutputHist->mkdir("IndividualCellsLocalTrigg");
5101   RootOutputHist->cd("IndividualCellsLocalTrigg");
5102 
5103   RootOutput->cd();
5104   
5105   //=============================================================================================
5106   // Setup general variables for analysis
5107   //=============================================================================================
5108   int actCh1st                = 0;
5109   double averageScale         = calib.GetAverageScaleHigh(actCh1st);
5110   int actChalt                = 0;
5111   double averageNTiles        = 0.;
5112   double averageScalePerTile  = calib.GetAverageScaleHighPerSingleLayer(actChalt, averageNTiles);
5113   // variable per single tile for possible summed output
5114   double avLGHGCorr           = calib.GetAverageLGHGCorr();
5115   double avPedMean            = calib.GetAveragePedestalMeanLow();
5116   double avPedSig             = calib.GetAveragePedestalSigHigh();
5117   // print out key calib variables
5118   if (typeRO == ReadOut::Type::Caen)
5119     std::cout << "average HG mip: " << averageScale << "\t active ch: "<< actCh1st<< std::endl;
5120   else if (typeRO == ReadOut::Type::Hgcroc)
5121     std::cout << "average HG mip: " << averageScale << "\t per tile: " << averageScalePerTile << "\t active ch: "<< actCh1st<< "\t average Ntiles for calib: "<< averageNTiles << std::endl;
5122 
5123   // setup local trigger sel
5124   TRandom3* rand    = new TRandom3();
5125   Int_t localTriggerTiles     = 4;
5126   if (yearData == 2023){
5127     localTriggerTiles         = 6;
5128   }
5129   double factorMinTrigg       = 0.8;
5130   double factorMinTriggNoise  = 0.2;
5131   double factorMaxTrigg       = 2.5;
5132   if (yearData == 2023){
5133     factorMinTrigg            = 0.9;
5134     factorMaxTrigg            = 2.;
5135   }
5136   int corrHGADCSwap           = 3500;
5137   int evts=TdataIn->GetEntries();
5138   if (maxEvents == -1){
5139     maxEvents                 = evts;
5140   } else {
5141     std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
5142     std::cout << "ATTENTION: YOU ARE RESETTING THE MAXIMUM NUMBER OF EVENTS TO BE PROCESSED TO: " << maxEvents << ". THIS SHOULD ONLY BE USED FOR TESTING!" << std::endl;
5143     std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
5144   }
5145   int outCount                = 5000;
5146   if (evts < 10000)
5147     outCount                  = 500;
5148   
5149   int nLocalNoiseTriggs       = 0;
5150   int nLocalMuonTriggs        = 0;
5151   
5152   if (EventCleanup == 1){
5153     std::cout << "==============================================================================" << std::endl;
5154     std::cout << "==============================================================================" << std::endl;
5155     if (calib.GetAverageScaleHigh() != -10000 ){
5156       std::cout << "resetting rejection thresholds with average HG Scale" << std::endl;
5157       cleanupLGTh   =  ((calib.GetAverageScaleHigh()-calib.GetAverageLGHGCorrOff())/calib.GetAverageLGHGCorr() )* 2.5;
5158       cleanupHGTh   =  calib.GetAverageScaleHigh()*1.5;
5159     }
5160     std::cout << "Thresholds for rejections: \t LG: " << cleanupLGTh << "\t HG: " << cleanupHGTh << std::endl;
5161     std::cout << "==============================================================================" << std::endl;
5162     std::cout << "==============================================================================" << std::endl;
5163   }
5164   int rejectedEvents  = 0;
5165 
5166   
5167   //==================================================================================
5168   // setup waveform builder for HGCROC data
5169   //==================================================================================
5170   waveform_fit_base *waveform_builder = nullptr;
5171   waveform_builder = new max_sample_fit();
5172   
5173   //=============================================================================================
5174   // Run over all events in tree
5175   //=============================================================================================
5176   for(int i=0; i<evts && i < maxEvents; i++){
5177     if(debug==1000){
5178         std::cerr<<event.GetTimeStamp()<<std::endl;
5179       }
5180     TdataIn->GetEntry(i);
5181     if (i%outCount == 0 && debug > 0) std::cout << "Reading " <<  i << " / " << evts << " events" << std::endl;
5182     
5183     bool bREvent = false;
5184     if (EventCleanup == 1){
5185       if (!event.CheckEventIntegrity(calib, cleanupLGTh, cleanupHGTh)){
5186         rejectedEvents++;
5187         bREvent = true;
5188         continue;
5189       }
5190     }
5191 
5192     double Etot         = 0;
5193     int nCells          = 0;
5194     int nCellsST        = 0;    // Ncells single tile equivalent
5195     double EtotNoNoise  = 0;
5196     int nCellsNoNoise   = 0;
5197     //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5198     // Single tile processing
5199     //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5200     for(int j=0; j<event.GetNTiles(); j++){
5201       // tile energy
5202       double energy = 0;      
5203       // calculate trigger primitives
5204       bool localMuonTrigg   = false;
5205       bool localNoiseTrigg  = false;
5206 
5207       //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5208       // CAEN treatment
5209       //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5210       if (typeRO == ReadOut::Type::Caen) {
5211         Caen* aTile=(Caen*)event.GetTile(j);
5212         // remove bad channels from output
5213         if (calib.GetBCCalib() && calib.GetBadChannel(aTile->GetCellID())!= 3 ){
5214           event.RemoveTile(aTile);
5215           j--;        
5216           continue;
5217         }
5218         
5219         double corrHG = aTile->GetADCHigh()-calib.GetPedestalMeanH(aTile->GetCellID());
5220         double corrLG = aTile->GetADCLow()-calib.GetPedestalMeanL(aTile->GetCellID());
5221         double corrLG_HGeq = corrLG*calib.GetLGHGCorr(aTile->GetCellID()) + calib.GetLGHGCorrOff(aTile->GetCellID());
5222         if(corrHG<corrHGADCSwap){
5223           if(corrHG/calib.GetScaleHigh(aTile->GetCellID()) > minMipFrac){
5224             energy=corrHG/calib.GetScaleHigh(aTile->GetCellID());
5225           }
5226         } else {
5227           energy=corrLG/calib.GetCalcScaleLow(aTile->GetCellID());
5228         }
5229         if (debug > 1 && corrHG >= corrHGADCSwap-100 && corrHG < 4000-calib.GetPedestalMeanH(aTile->GetCellID())){
5230             std::cout << "-> Cell ID: " <<  aTile->GetCellID() << "\t HG\t" << corrHG << "\t" << corrHG/calib.GetScaleHigh(aTile->GetCellID()) << "\t LG \t" << corrLG << "\t" <<  corrLG/calib.GetCalcScaleLow(aTile->GetCellID()) << "\t"<< corrLG/calib.GetScaleLow(aTile->GetCellID()) << "\t delta: \t"<< corrHG/calib.GetScaleHigh(aTile->GetCellID())-(corrLG/calib.GetCalcScaleLow(aTile->GetCellID())) << "\tLGHG\t" << calib.GetLGHGCorr(aTile->GetCellID())<< std::endl;
5231         }
5232 
5233         // check if you need to rerun the trigger
5234         if (!UseLocTriggFromFile()){
5235           aTile->SetLocalTriggerPrimitive(event.CalculateLocalMuonTrigg(calib, rand, aTile->GetCellID(), localTriggerTiles, avLGHGCorr));
5236           aTile->SetLocalTriggerBit(0);
5237           localMuonTrigg   = event.InspectIfLocalMuonTrigg(aTile->GetCellID(), averageScalePerTile, factorMinTrigg, factorMaxTrigg);
5238           localNoiseTrigg  = event.InspectIfNoiseTrigg(aTile->GetCellID(), averageScalePerTile, factorMinTriggNoise);
5239           if (localMuonTrigg) aTile->SetLocalTriggerBit(1);
5240           if (localNoiseTrigg) aTile->SetLocalTriggerBit(2);
5241         // trigger decision taken from inout file
5242         } else {
5243           if (aTile->GetLocalTriggerBit() == 2)  localNoiseTrigg  = true;
5244           // reeval muon trigger based on updated values
5245           localMuonTrigg  = event.InspectIfLocalMuonTrigg(aTile->GetCellID(), averageScalePerTile, factorMinTrigg, factorMaxTrigg);
5246           if (localMuonTrigg) aTile->SetLocalTriggerBit(1);
5247         }
5248         
5249         
5250         hspectraHGvsCellID->Fill(aTile->GetCellID(), aTile->GetADCHigh());
5251         hspectraLGvsCellID->Fill(aTile->GetCellID(), aTile->GetADCLow());
5252         hspectraHGCorrvsCellID->Fill(aTile->GetCellID(), corrHG);
5253         hspectraLGCorrvsCellID->Fill(aTile->GetCellID(), corrLG);
5254         
5255         if (localNoiseTrigg){
5256           hspectraHGCorrvsCellIDNoise->Fill(aTile->GetCellID(), corrHG);
5257           hspectraLGCorrvsCellIDNoise->Fill(aTile->GetCellID(), corrLG);        
5258         }
5259         ithSpectra=hSpectra.find(aTile->GetCellID());
5260         if(ithSpectra!=hSpectra.end()){
5261           ithSpectra->second.FillExtCAEN(corrLG,corrHG,energy,corrLG_HGeq);
5262         } else {
5263           RootOutputHist->cd("IndividualCells");
5264           hSpectra[aTile->GetCellID()]=TileSpectra("Calibrate",1,aTile->GetCellID(),calib.GetTileCalib(aTile->GetCellID()),event.GetROtype(),debug);
5265           hSpectra[aTile->GetCellID()].FillExtCAEN(corrLG,corrHG,energy,corrLG_HGeq);
5266           RootOutput->cd();
5267         }
5268 
5269         if (localMuonTrigg){
5270           nLocalMuonTriggs++;
5271           ithSpectraLocalTrigg=hSpectraLocalTrigg.find(aTile->GetCellID());
5272           if(ithSpectraLocalTrigg!=hSpectraLocalTrigg.end()){
5273             ithSpectraLocalTrigg->second.FillExtCAEN(corrLG,corrHG,energy,corrLG_HGeq);
5274           } else {
5275             RootOutputHist->cd("IndividualCellsLocalTrigg");
5276             hSpectraLocalTrigg[aTile->GetCellID()]=TileSpectra("CalibrateLocalTrigg",1,aTile->GetCellID(),calib.GetTileCalib(aTile->GetCellID()),event.GetROtype(),debug);
5277             hSpectraLocalTrigg[aTile->GetCellID()].FillExtCAEN(corrLG,corrHG,energy,corrLG_HGeq);
5278             RootOutput->cd();
5279           }
5280         }
5281         if (localNoiseTrigg){
5282           nLocalNoiseTriggs++;
5283           ithSpectraNoise=hSpectraNoise.find(aTile->GetCellID());
5284           if(ithSpectraNoise!=hSpectraNoise.end()){
5285             ithSpectraNoise->second.FillExtCAEN(corrLG,corrHG,energy,corrLG_HGeq);
5286           } else {
5287             RootOutputHist->cd("IndividualCellsNoise");
5288             hSpectraNoise[aTile->GetCellID()]=TileSpectra("CalibrateNoise",1,aTile->GetCellID(),calib.GetTileCalib(aTile->GetCellID()),event.GetROtype(),debug);
5289             hSpectraNoise[aTile->GetCellID()].FillExtCAEN(corrLG,corrHG,energy,corrLG_HGeq);
5290             RootOutput->cd();
5291           }
5292         } else {
5293           ithSpectraNotNoise=hSpectraNotNoise.find(aTile->GetCellID());
5294           if(ithSpectraNotNoise!=hSpectraNotNoise.end()){
5295             ithSpectraNotNoise->second.FillExtCAEN(corrLG,corrHG,energy,corrLG_HGeq);
5296           } else {
5297             RootOutputHist->cd("IndividualCellsNoise");
5298             hSpectraNotNoise[aTile->GetCellID()]=TileSpectra("CalibrateNotNoise",1,aTile->GetCellID(),calib.GetTileCalib(aTile->GetCellID()),event.GetROtype(),debug);
5299             hSpectraNotNoise[aTile->GetCellID()].FillExtCAEN(corrLG,corrHG,energy,corrLG_HGeq);
5300             RootOutput->cd();
5301           }          
5302         }
5303         
5304         if (!localNoiseTrigg){
5305         EtotNoNoise  = EtotNoNoise+energy; 
5306         nCellsNoNoise++;
5307         }
5308         // reject cell if not above minimum threshold
5309         if(energy > minMipFrac){ 
5310           aTile->SetE(energy);
5311           hspectraEnergyvsCellID->Fill(aTile->GetCellID(), energy);
5312           Etot=Etot+energy;
5313           nCells++;
5314         } else {
5315           event.RemoveTile(aTile);
5316           j--;
5317         }
5318         
5319       //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5320       // HGCROC treatment
5321       //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5322       } else if (typeRO == ReadOut::Type::Hgcroc){
5323         Hgcroc* aTile=(Hgcroc*)event.GetTile(j);
5324         // remove bad channels from output
5325         if (calib.GetBCCalib() && calib.GetBadChannel(aTile->GetCellID())!= 3 ){
5326           event.RemoveTile(aTile);
5327           j--;        
5328           continue;
5329         }
5330         
5331         // get pedestal values from calib object
5332         double ped = calib.GetPedestalMeanL(aTile->GetCellID()); // ped based on waveform fit
5333         if (ped == -1000){
5334           ped = calib.GetPedestalMeanH(aTile->GetCellID());      // ped based on first sample fit
5335           if (ped == -1000){
5336             ped = aTile->GetPedestal();              // event-by-event first sample
5337           }
5338         }
5339         // reevaluate waveform
5340         waveform_builder->set_waveform(aTile->GetADCWaveform());
5341         waveform_builder->fit_with_average_ped(ped);
5342         aTile->SetIntegratedADC(waveform_builder->get_E());
5343         aTile->SetPedestal(waveform_builder->get_pedestal());
5344 
5345         double adc = aTile->GetIntegratedADC();
5346         double tot = aTile->GetRawTOT();
5347         double toa = aTile->GetRawTOA();
5348         bool hasTOA     = false;
5349         bool hasTOT     = false;
5350         
5351         // check if we have a toa
5352         if (toa > 0)
5353           hasTOA        = true;
5354         // check if we have a tot
5355         if (tot > 0)
5356           hasTOT        = true;
5357         // obtain toa shift corrected values
5358         Int_t nSampTOA  = aTile->GetFirstTOASample();        
5359         double toaNs      = (double)aTile->GetLinearizedRawTOA()*aTile->GetTOATimeResolution();
5360         double toaCorrNs  = toaNs;
5361         Int_t nOffEmpty   = 2;
5362         if (calib.GetToAOff(aTile->GetCellID()) != -1000.){
5363           // correct ToA sample and return correct nSampleTOA
5364           nSampTOA      = aTile->SetCorrectedTOA(calib.GetToAOff(aTile->GetCellID())); 
5365           toaCorrNs     = (double)(aTile->GetCorrectedTOA())*aTile->GetTOATimeResolution();;
5366         }
5367 
5368         // temporarily only calibrate with adc & average Scale
5369         // double tempE = adc/averageScale; 
5370         double energy      = adc/(calib.GetScaleHighPerSingleLayer(aTile->GetCellID()) );
5371         double energySeg  = adc/(calib.GetScaleHigh(aTile->GetCellID()) );
5372 
5373         if (debug > 1 && adc >= 900 ){
5374             std::cout << "----> High ADC Cell ID: " <<  aTile->GetCellID() << "\t ADC\t" << adc << "\t" <<  "\t Tot \t" << tot << "\t toa\t"  <<  toa<< std::endl;
5375         }
5376         if (debug > 1 && tot >= 0 ){
5377             std::cout << "----> Tot fired Cell ID: " <<  aTile->GetCellID() << "\t ADC\t" << adc << "\t" <<  "\t Tot \t" << tot << "\t toa\t"  <<  toa<< std::endl;
5378         }
5379         // calculate local trigger primitives
5380         if (!UseLocTriggFromFile()){
5381           aTile->SetLocalTriggerPrimitive(event.CalculateLocalMuonTrigg(calib, rand, aTile->GetCellID(), localTriggerTiles, 0));
5382           aTile->SetLocalTriggerBit(0);
5383           localMuonTrigg   = event.InspectIfLocalMuonTrigg(aTile->GetCellID(), averageScalePerTile, factorMinTrigg, factorMaxTrigg);
5384           localNoiseTrigg  = event.InspectIfNoiseTrigg(aTile->GetCellID(), averageScalePerTile, factorMinTriggNoise);
5385           if (localMuonTrigg) aTile->SetLocalTriggerBit(1);
5386           if (localNoiseTrigg) aTile->SetLocalTriggerBit(2);
5387         // trigger decision taken from inout file
5388         } else {
5389           if (aTile->GetLocalTriggerBit() == 2)  localNoiseTrigg  = true;
5390           // reeval muon trigger based on updated values
5391           localMuonTrigg  = event.InspectIfLocalMuonTrigg(aTile->GetCellID(), averageScalePerTile, factorMinTrigg, factorMaxTrigg);
5392           if (localMuonTrigg) aTile->SetLocalTriggerBit(1);
5393         }
5394         
5395         hspectraHGvsCellID->Fill(aTile->GetCellID(), adc);
5396         if(hasTOT)  hspectraTotvsCellID->Fill(aTile->GetCellID(), tot);
5397         if(aTile->IsSaturatedADC()) hSaturatedCellID->Fill(aTile->GetCellID());
5398         if (localNoiseTrigg){
5399           hspectraHGCorrvsCellIDNoise->Fill(aTile->GetCellID(), adc);
5400           if(hasTOT) hspectraTotvsCellIDNoise->Fill(aTile->GetCellID(), tot);        
5401         }
5402         
5403         Int_t asic      = setup->GetROunit(aTile->GetCellID());
5404         Int_t roCh      = setup->GetROchannel(aTile->GetCellID());
5405         if (hasTOA){
5406           hspectraTOAvsCellID->Fill(aTile->GetCellID(),toa);
5407           hSampleTOAVsCellID->Fill(aTile->GetCellID(),nSampTOA);
5408           hSampleTOA->Fill(nSampTOA);
5409           hTOANsVsCellID->Fill(aTile->GetCellID(),toaNs);
5410           hTOACorrNsVsCellID->Fill(aTile->GetCellID(),toaCorrNs);
5411           // fill overview hists for half asics
5412           h2DToAvsnSample[asic][int(roCh/36)]->Fill(toa, nSampTOA);
5413           for (int k = 0; k < (int)(aTile->GetADCWaveform()).size(); k++ ){
5414             double timetemp = ((k+nOffEmpty)*1024 + (double)aTile->GetCorrectedTOA())*aTile->GetTOATimeResolution() ;
5415             hWaveFormHalfAsicAll[asic][int(roCh/36)]->Fill(timetemp,(aTile->GetADCWaveform()).at(k)-ped);
5416             h2DWaveFormHalfAsicAll[asic][int(roCh/36)]->Fill(timetemp,(aTile->GetADCWaveform()).at(k)-ped);
5417           }          
5418         }        
5419 
5420         ithSpectra=hSpectra.find(aTile->GetCellID());
5421         if(ithSpectra!=hSpectra.end()){
5422           ithSpectra->second.FillExtHGCROC(adc,toa,tot,nSampTOA,-1);
5423         } else {
5424           RootOutputHist->cd("IndividualCells");
5425           hSpectra[aTile->GetCellID()]=TileSpectra("Calibrated",2,aTile->GetCellID(),calib.GetTileCalib(aTile->GetCellID()),event.GetROtype(),debug);
5426           hSpectra[aTile->GetCellID()].FillExtHGCROC(adc,toa,tot,nSampTOA,-1);
5427           RootOutput->cd();
5428         }
5429 
5430         if(localMuonTrigg) nLocalMuonTriggs++;
5431         
5432         ithSpectraLocalTrigg=hSpectraLocalTrigg.find(aTile->GetCellID());
5433         if(ithSpectraLocalTrigg!=hSpectraLocalTrigg.end()){
5434           if (localMuonTrigg) ithSpectraLocalTrigg->second.FillHGCROC(adc,toa,tot);
5435           ithSpectraLocalTrigg->second.FillTrigger(aTile->GetLocalTriggerPrimitive());
5436         } else {
5437           RootOutputHist->cd("IndividualCellsLocalTrigg");
5438           hSpectraLocalTrigg[aTile->GetCellID()]=TileSpectra("CalibratedLocalTrigg",aTile->GetCellID(),calib.GetTileCalib(aTile->GetCellID()),event.GetROtype(),debug);
5439           if (localMuonTrigg) hSpectraLocalTrigg[aTile->GetCellID()].FillHGCROC(adc,toa,tot);
5440           hSpectraLocalTrigg[aTile->GetCellID()].FillTrigger(aTile->GetLocalTriggerPrimitive());
5441           RootOutput->cd();
5442         }
5443       
5444         if (localNoiseTrigg){
5445           nLocalNoiseTriggs++;
5446           ithSpectraNoise=hSpectraNoise.find(aTile->GetCellID());
5447           if(ithSpectraNoise!=hSpectraNoise.end()){
5448             ithSpectraNoise->second.FillHGCROC(adc,toa,tot);
5449           } else {
5450             RootOutputHist->cd("IndividualCellsNoise");
5451             hSpectraNoise[aTile->GetCellID()]=TileSpectra("CalibratedNoise",2,aTile->GetCellID(),calib.GetTileCalib(aTile->GetCellID()),event.GetROtype(),debug);
5452             hSpectraNoise[aTile->GetCellID()].FillHGCROC(adc,toa,tot);
5453             RootOutput->cd();
5454           }
5455         } else {
5456           ithSpectraNotNoise=hSpectraNotNoise.find(aTile->GetCellID());
5457           if(ithSpectraNotNoise!=hSpectraNotNoise.end()){
5458             ithSpectraNotNoise->second.FillHGCROC(adc,toa,tot);
5459           } else {
5460             RootOutputHist->cd("IndividualCells");
5461             hSpectraNotNoise[aTile->GetCellID()]=TileSpectra("CalibratedNotNoise",2,aTile->GetCellID(),calib.GetTileCalib(aTile->GetCellID()),event.GetROtype(),debug);
5462             hSpectraNotNoise[aTile->GetCellID()].FillHGCROC(adc,toa,tot);
5463             RootOutput->cd();
5464           }
5465           
5466         }
5467         
5468         if (!localNoiseTrigg){
5469         EtotNoNoise  = EtotNoNoise+energy; 
5470         nCellsNoNoise++;
5471         }
5472         
5473         // only save if energy is larger minMip fraction
5474         if(energySeg > minMipFrac){ 
5475           aTile->SetE(energy);
5476           hspectraEnergyvsCellID->Fill(aTile->GetCellID(), energy);
5477           Etot=Etot+energy;
5478           nCells++;
5479           nCellsST= nCellsST+setup->GetLayersInSegment(aTile->GetCellID());
5480         } else {
5481           event.RemoveTile(aTile);
5482           j--;
5483         }
5484       }
5485     }
5486     hspectraEnergyTotvsNCells->Fill(nCells,Etot);
5487     hspectraEnergyTotvsNCellsNoNoise->Fill(nCellsNoNoise,EtotNoNoise);
5488     hspectraEnergyTotvsNCellsST->Fill(nCellsST,Etot);
5489     RootOutput->cd();
5490     if (!bREvent) TdataOut->Fill();
5491   }
5492   
5493   if (EventCleanup == 1){
5494     std::cout << "****************************************************************************************************"<< std::endl; 
5495     std::cout << "****************************************************************************************************"<< std::endl; 
5496     std::cout << rejectedEvents<< "\t/" << maxEvents  << " rejected CAEN events due to corrupted data for single channels!"<< std::endl; 
5497     std::cout << "****************************************************************************************************"<< std::endl; 
5498     std::cout << "****************************************************************************************************"<< std::endl; 
5499   }
5500 
5501 
5502   std::cout << "=======================================================" << std::endl;
5503   std::cout << "Total events processed " << maxEvents << std::endl;
5504   std::cout << "Local muon triggered " << nLocalMuonTriggs << std::endl;
5505   std::cout << "Local noise triggered " << nLocalNoiseTriggs << std::endl;
5506   std::cout << "=======================================================" << std::endl;
5507   //*********************************************************************************************
5508   // Write Output tree
5509   //*********************************************************************************************  
5510   TdataOut->Write();
5511   TsetupIn->CloneTree()->Write();
5512   
5513   if (IsCalibSaveToFile()){
5514     TString fileCalibPrint = RootOutputName;
5515     fileCalibPrint         = fileCalibPrint.ReplaceAll(".root","_calib.txt");
5516     calib.PrintCalibToFile(fileCalibPrint);
5517   }
5518   
5519   TcalibOut->Fill();
5520   TcalibOut->Write();
5521   
5522   
5523   RootOutput->Close();
5524   RootInput->Close();      
5525   
5526   //*********************************************************************************************
5527   // Write Output hist File
5528   //*********************************************************************************************
5529   RootOutputHist->cd();
5530 
5531     hspectraHGvsCellID->Write();
5532     hspectraHGCorrvsCellIDNoise->Write();
5533     if (typeRO == ReadOut::Type::Caen){
5534       hspectraHGCorrvsCellID->Write();
5535       hspectraLGvsCellID->Write();
5536       hspectraLGCorrvsCellID->Write();
5537       hspectraLGCorrvsCellIDNoise->Write();
5538     } else {
5539       hspectraTotvsCellID->Write();
5540       hspectraTotvsCellIDNoise->Write();
5541       hSaturatedCellID->Write();
5542       
5543       hSampleTOA->Write();
5544       hSampleTOAVsCellID->Write();
5545       hTOANsVsCellID->Write();
5546       hTOACorrNsVsCellID->Write();
5547       hspectraTOAvsCellID->Write();
5548       for (Int_t ro = 0; ro < setup->GetNMaxROUnit()+1; ro++){
5549         for (int h = 0; h< 2; h++){
5550           h2DToAvsnSample[ro][h]->Write();
5551           h2DWaveFormHalfAsicAll[ro][h]->Write();
5552           hWaveFormHalfAsicAll[ro][h]->Write();
5553         }
5554       }
5555     }
5556     hspectraEnergyvsCellID->Write();
5557     hspectraEnergyTotvsNCells->Write();
5558     hspectraEnergyTotvsNCellsST->Write();
5559     hspectraEnergyTotvsNCellsNoNoise->Write();
5560     
5561     TH1D* hspectraEnergyTot = (TH1D*)hspectraEnergyTotvsNCells->ProjectionY();
5562     hspectraEnergyTot->SetDirectory(0);
5563     TH1D* hspectraNCells = (TH1D*)hspectraEnergyTotvsNCells->ProjectionX();
5564     hspectraNCells->SetDirectory(0);
5565     TH1D* hspectraNCellsST = (TH1D*)hspectraEnergyTotvsNCellsST->ProjectionX();
5566     hspectraNCellsST->SetDirectory(0);
5567     hspectraEnergyTot->Write("hTotEnergy");
5568     hspectraNCells->Write("hNCells");
5569     hspectraNCellsST->Write("hNCellsST");
5570     
5571     RootOutputHist->cd("IndividualCells");
5572     for(ithSpectra=hSpectra.begin(); ithSpectra!=hSpectra.end(); ++ithSpectra){
5573       if (typeRO == ReadOut::Type::Caen)
5574         ithSpectra->second.FitLGHGCorr(debug,false);
5575       ithSpectra->second.WriteExt(true);
5576     }
5577     for(ithSpectraNotNoise=hSpectraNotNoise.begin(); ithSpectraNotNoise!=hSpectraNotNoise.end(); ++ithSpectraNotNoise){
5578       ithSpectraNotNoise->second.WriteExt(true);
5579     }
5580     RootOutputHist->cd("IndividualCellsNoise");
5581     for(ithSpectraNoise=hSpectraNoise.begin(); ithSpectraNoise!=hSpectraNoise.end(); ++ithSpectraNoise){
5582       ithSpectraNoise->second.WriteExt(true);
5583     }
5584     RootOutputHist->cd("IndividualCellsLocalTrigg");
5585     for(ithSpectraLocalTrigg=hSpectraLocalTrigg.begin(); ithSpectraLocalTrigg!=hSpectraLocalTrigg.end(); ++ithSpectraLocalTrigg){
5586       ithSpectraLocalTrigg->second.WriteExt(true);
5587     }
5588   RootOutputHist->Close();
5589   
5590   //**********************************************************************
5591   //********************* Plotting ***************************************
5592   //**********************************************************************
5593   
5594   TString outputDirPlots = GetPlotOutputDir();
5595   gSystem->Exec("mkdir -p "+outputDirPlots);
5596   
5597   //**********************************************************************
5598   // Create canvases for channel overview plotting
5599   //**********************************************************************
5600   Double_t textSizeRel = 0.035;
5601   StyleSettingsBasics("pdf");
5602   SetPlotStyle();
5603   
5604   TCanvas* canvas2DCorr = new TCanvas("canvasCorrPlots","",0,0,1450,1300);  // gives the page size
5605   DefaultCanvasSettings( canvas2DCorr, 0.08, 0.13, 0.045, 0.07);
5606   canvas2DCorr->SetLogz(1);
5607   PlotSimple2D( canvas2DCorr, hspectraHGvsCellID, -10000, -10000, textSizeRel, Form("%s/HG.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
5608   PlotSimple2D( canvas2DCorr, hspectraHGCorrvsCellIDNoise, -50, 200, -10000, textSizeRel, Form("%s/HGCorr_Noise.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true, "Local Noise triggered");
5609   PlotSimple2D( canvas2DCorr, hspectraEnergyvsCellID, -10000, -10000, textSizeRel, Form("%s/EnergyVsCellID.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
5610   PlotSimple2D( canvas2DCorr, hspectraEnergyTotvsNCells, -10000, -10000, textSizeRel, Form("%s/EnergyTotalVsNCells.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
5611 
5612   if (typeRO == ReadOut::Type::Caen){
5613     PlotSimple2D( canvas2DCorr, hspectraHGCorrvsCellID, -10000, -10000, textSizeRel, Form("%s/HGCorr.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
5614     PlotSimple2D( canvas2DCorr, hspectraHGCorrvsCellID, 300, -10000, textSizeRel, Form("%s/HGCorr_zoomed.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
5615     PlotSimple2D( canvas2DCorr, hspectraLGvsCellID, -10000, -10000, textSizeRel, Form("%s/LG.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
5616     PlotSimple2D( canvas2DCorr, hspectraLGCorrvsCellID, -10000, -10000, textSizeRel, Form("%s/LGCorr.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
5617     PlotSimple2D( canvas2DCorr, hspectraLGCorrvsCellID, 200, -10000, textSizeRel, Form("%s/LGCorr_zoomed.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
5618   } else if (typeRO == ReadOut::Type::Hgcroc){
5619     PlotSimple2D( canvas2DCorr, hspectraTotvsCellID, -10000, -10000, textSizeRel, Form("%s/Tot.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
5620     if(nLocalNoiseTriggs > 1) PlotSimple2D( canvas2DCorr, hspectraTotvsCellIDNoise, -50, 200, -10000, textSizeRel, Form("%s/Tot_Noise.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true, "Local Noise triggered");
5621     
5622     PlotSimple2D( canvas2DCorr, hTOANsVsCellID, -10000, setup->GetMaxCellID()+1, textSizeRel, Form("%s/TOANsvsCellID.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
5623     PlotSimple2D( canvas2DCorr, hTOACorrNsVsCellID, -10000, setup->GetMaxCellID()+1, textSizeRel, Form("%s/TOACorrNsvsCellID.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
5624     PlotSimple2D( canvas2DCorr, hSampleTOAVsCellID, (double)it->second.samples,setup->GetMaxCellID()+1, textSizeRel, Form("%s/SampleTOAvsCellID.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
5625     
5626     PlotSimple2D( canvas2DCorr, hspectraEnergyTotvsNCellsST, -10000, -10000, textSizeRel, Form("%s/EnergyTotalVsNCellsSingleTile.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
5627     if(nLocalNoiseTriggs > 1) PlotSimple2D( canvas2DCorr, hspectraEnergyTotvsNCellsNoNoise, -10000, -10000, textSizeRel, Form("%s/EnergyTotalVsNCellsNoNoise.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, kFALSE, "colz", true);
5628 
5629     
5630     for (Int_t ro = 0; ro < setup->GetNMaxROUnit()+1; ro++){
5631       for (int h = 0; h< 2; h++){      
5632           PlotSimple2D( canvas2DCorr, h2DToAvsnSample[ro][h],(double)it->second.samples, -10000, textSizeRel,
5633                             Form("%s/ToaVsNSample_Asic_%d_Half_%d.%s", outputDirPlots.Data(), ro, h, plotSuffix.Data()), 
5634                             it->second, 1, kFALSE, "colz",true, Form("Asic %d, Half %d",ro,h));
5635           h2DWaveFormHalfAsicAll[ro][h]->GetXaxis()->SetRangeUser(-25, (it->second.samples)*25);
5636           Plot2DWithProfile( canvas2DCorr, h2DWaveFormHalfAsicAll[ro][h], hWaveFormHalfAsicAll[ro][h], -10000, -10000, textSizeRel,
5637                             Form("%s/Waveform_Asic_%d_Half_%d.%s", outputDirPlots.Data(), ro, h, plotSuffix.Data()), 
5638                             it->second, 1, kFALSE, "colz",true, Form("Asic %d, Half %d",ro,h), -1);
5639       }
5640     }
5641   }
5642 
5643   TCanvas* canvas1DSimple = new TCanvas("canvas1DSimple","",0,0,1450,1300);  // gives the page size
5644   DefaultCanvasSettings( canvas1DSimple, 0.08, 0.03, 0.03, 0.07);
5645   hspectraEnergyTot->Scale(1./evts);
5646   hspectraEnergyTot->GetYaxis()->SetTitle("counts/event");
5647   PlotSimple1D(canvas1DSimple, hspectraEnergyTot, -10000, -10000, textSizeRel, Form("%s/EnergyTot.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, Form("#LT E_{Tot} #GT = %.1f (mip/tile eq.)",hspectraEnergyTot->GetMean() ));
5648   hspectraNCells->Scale(1./evts);
5649   hspectraNCells->GetYaxis()->SetTitle("counts/event");
5650   PlotSimple1D(canvas1DSimple, hspectraNCells, -10000, -10000, textSizeRel, Form("%s/NCells.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, Form("#LT N_{Cells} #GT = %.1f",hspectraNCells->GetMean() ));
5651   if (typeRO == ReadOut::Type::Hgcroc){
5652     hSaturatedCellID->Scale(1./evts);
5653     hSaturatedCellID->GetYaxis()->SetTitle("counts/event");
5654     PlotSimple1D(canvas1DSimple, hSaturatedCellID, -10000, -10000, textSizeRel, Form("%s/SaturatedCellsPerEvent.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1);
5655     
5656     PlotSimple1D(canvas1DSimple, hSampleTOA, -10000, (double)it->second.samples, textSizeRel, Form("%s/NSampleToA.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1);
5657     hspectraNCellsST->Scale(1./evts);
5658     
5659     hspectraNCellsST->GetYaxis()->SetTitle("counts/event");
5660     PlotSimple1D(canvas1DSimple, hspectraNCellsST, -10000, -10000, textSizeRel, Form("%s/NCellsSingleTiles.%s", outputDirPlots.Data(), plotSuffix.Data()), it->second, 1, Form("#LT N_{tile} #GT = %.1f",hspectraNCellsST->GetMean() ));
5661   }
5662 
5663   if (ExtPlot > 0){
5664     calib.PrintGlobalInfo();  
5665     double maxADC = 4096;
5666     if (typeRO == ReadOut::Type::Hgcroc)
5667       maxADC = 1024;
5668     
5669     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
5670     // Single layer plotting
5671     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
5672     MultiCanvas panelPlot(detConf, "Calib");
5673     bool init1D = panelPlot.Initialize(1);
5674     MultiCanvas panelPlot2D(detConf, "Calib");
5675     bool init2D = panelPlot2D.Initialize(2);
5676       
5677     
5678     panelPlot.PlotSpectra( hSpectra, 0, -100, maxADC, 1.2, 
5679                           Form("%s/Spectra_HG" ,outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);
5680 
5681     if (typeRO == ReadOut::Type::Caen) {
5682       if(nLocalNoiseTriggs > 1 && ExtPlot > 2) panelPlot.PlotNoiseAdvWithFits(hSpectra, hSpectraNoise, 1, -50, 100, 1.2, 
5683                                                               Form("%s/NoiseTrigg_HG" ,outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);
5684       if(nLocalNoiseTriggs > 1 && ExtPlot > 2) panelPlot.PlotNoiseAdvWithFits(hSpectra, hSpectraNoise, 0, -50, 100, 1.2, 
5685                                                               Form("%s/NoiseTrigg_LG" ,outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);
5686       panelPlot.PlotSpectra( hSpectra, 2, -2, 100, 1.2, 
5687                             Form("%s/Spectra_Comb" ,outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);
5688       if (ExtPlot > 1) panelPlot2D.PlotCorrWithFits( hSpectra, 0, -20, 800, 0., 50.,
5689                                     Form("%s/LGHG_Corr",outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);
5690       if (ExtPlot > 1) panelPlot2D.PlotCorrWithFits( hSpectra, 2, -20, 800, 0., 50.,
5691                                     Form("%s/LGLGhgeq_Corr",outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);
5692       
5693     } else if (typeRO == ReadOut::Type::Hgcroc) {
5694       panelPlot2D.PlotCorr2DLayer(hSpectra, 4, 0, 4096, 0, 1024.,
5695                                 Form("%s/ADCTOT",outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, 0, -1, skipPlotLayer);
5696       panelPlot.PlotSpectra( hSpectra, 4, -100, 4096, 1.2,
5697                             Form("%s/Spectra_Tot" ,outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);
5698       panelPlot.PlotMipWithFits( hSpectra, hSpectraLocalTrigg, 1, -20, maxADC, 1.2, 
5699                                   Form("%s/SpectraWithMipTrigg" ,outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);
5700       if(nLocalNoiseTriggs > 1) panelPlot.PlotNoiseAdvWithFits(hSpectra, hSpectraNoise, 1, -20, 100, 1.2, 
5701                                                               Form("%s/NoiseTrigg" ,outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);
5702       if(nLocalNoiseTriggs > 1) panelPlot.Plot3SpectraOverlay(hSpectra, hSpectraNotNoise, hSpectraNoise,
5703                                                               1, -20, 1024, 1.2, 
5704                                                               Form("%s/NotNoiseTrigg" ,outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib, skipPlotLayer);
5705       panelPlot.PlotTriggerPrim( hSpectraLocalTrigg, averageScalePerTile, factorMinTrigg, factorMaxTrigg, 0, 200, 1.2,
5706                                 Form("%s/TriggPrimitive" ,outputDirPlots.Data()), plotSuffix.Data(), it->second, &calib);
5707     }
5708   }
5709   return true;
5710 } // end Calibrate()
5711 
5712 //***********************************************************************************************
5713 //*********************** Save Noise triggers only ***************************************************
5714 //***********************************************************************************************
5715 bool Analyses::SaveNoiseTriggersOnly(void){
5716   std::cout<<"Save noise triggers into separate file"<<std::endl;
5717   TcalibIn->GetEntry(0);
5718   // check whether calib should be overwritten based on external text file
5719   if (OverWriteCalib){
5720     calib.ReadCalibFromTextFile(ExternalCalibFile,debug);
5721   }
5722   
5723   int evts=TdataIn->GetEntries();
5724   for(int i=0; i<evts; i++){
5725     TdataIn->GetEntry(i);
5726     if (i%5000 == 0 && i > 0 && debug > 0) std::cout << "Reading " <<  i << " / " << evts << " events" << std::endl;
5727     for(int j=0; j<event.GetNTiles(); j++){
5728       Caen* aTile=(Caen*)event.GetTile(j);
5729       // testing for noise trigger
5730       if(aTile->GetLocalTriggerBit()!= (char)2){
5731         event.RemoveTile(aTile);
5732         j--;
5733       }
5734     }
5735     RootOutput->cd();
5736     TdataOut->Fill();
5737   }
5738   TdataOut->Write();
5739   TsetupIn->CloneTree()->Write();
5740   
5741   if (IsCalibSaveToFile()){
5742     TString fileCalibPrint = RootOutputName;
5743     fileCalibPrint         = fileCalibPrint.ReplaceAll(".root","_calib.txt");
5744     calib.PrintCalibToFile(fileCalibPrint);
5745   }
5746 
5747   TcalibOut->Fill();
5748   TcalibOut->Write();
5749   RootOutput->Close();
5750   RootInput->Close();      
5751   
5752   return true;
5753 }
5754 
5755 //***********************************************************************************************
5756 //*********************** Save Noise triggers only ***************************************************
5757 //***********************************************************************************************
5758 bool Analyses::SaveCalibToOutputOnly(void){
5759   std::cout<<"Save calib into separate file: "<< GetRootCalibOutputName().Data() <<std::endl;
5760   RootCalibOutput->cd();
5761   TcalibIn->GetEntry(0);  
5762   TsetupIn->CloneTree()->Write();
5763   
5764   // check whether calib should be overwritten based on external text file
5765   if (OverWriteCalib){
5766     calib.ReadCalibFromTextFile(ExternalCalibFile,debug);
5767   }
5768   
5769   if (IsCalibSaveToFile()){
5770     TString fileCalibPrint = GetRootCalibOutputName();
5771     fileCalibPrint         = fileCalibPrint.ReplaceAll(".root","_calib.txt");
5772     calib.PrintCalibToFile(fileCalibPrint);
5773   }
5774 
5775   TcalibOut->Fill();
5776   TcalibOut->Write();
5777   RootCalibOutput->Close();
5778   
5779   return true;
5780 }
5781 
5782 //***********************************************************************************************
5783 //*********************** Save Noise triggers only ***************************************************
5784 //***********************************************************************************************
5785 bool Analyses::OverWriteSetupTree(void){
5786   std::cout<<"Rewrite original file to new output file with updated setup tree: "<< GetRootOutputName().Data() <<std::endl;
5787   RootOutput->cd();
5788   
5789   if (MapInputName.CompareTo("")== 0) {
5790       std::cerr << "ERROR: No mapping file has been provided, please make sure you do so! Aborting!" << std::endl;
5791       return false;
5792   }
5793   std::cout << "creating mapping " << std::endl;
5794   setup->Initialize(MapInputName.Data(),debug);
5795   
5796   RootSetupWrapper rswtmp=RootSetupWrapper(setup);
5797   rsw=rswtmp;
5798   TsetupOut->Fill();  
5799   TsetupOut->Write();
5800   
5801   // write Data tree to new output
5802   TdataIn->CloneTree()->Write();
5803   
5804   
5805   // check whether calib should be overwritten based on external text file
5806   TcalibIn->GetEntry(0);  
5807   if (OverWriteCalib){
5808     calib.ReadCalibFromTextFile(ExternalCalibFile,debug);
5809   }
5810   
5811   if (IsCalibSaveToFile()){
5812     TString fileCalibPrint = GetRootOutputName();
5813     fileCalibPrint         = fileCalibPrint.ReplaceAll(".root","_calib.txt");
5814     calib.PrintCalibToFile(fileCalibPrint);
5815   }
5816 
5817   TcalibOut->Fill();
5818   TcalibOut->Write();
5819   RootOutput->Close();
5820   
5821   return true;
5822 }
5823 
5824 
5825 //***********************************************************************************************
5826 //*********************** Save local muon triggers only ***************************************************
5827 //***********************************************************************************************
5828 bool Analyses::SaveMuonTriggersOnly(void){
5829   std::cout<<"Save local muon triggers into separate file"<<std::endl;
5830   TcalibIn->GetEntry(0);
5831     // check whether calib should be overwritten based on external text file
5832   if (OverWriteCalib){
5833     calib.ReadCalibFromTextFile(ExternalCalibFile,debug);
5834   }
5835   // Print calib info
5836   calib.PrintGlobalInfo();  
5837 
5838   
5839   ReadOut::Type typeRO = ReadOut::Type::Caen;
5840 
5841   int evts=TdataIn->GetEntries();
5842   for(int i=0; i<evts; i++){
5843     TdataIn->GetEntry(i);
5844     if (i == 0){
5845       typeRO = event.GetROtype();
5846       std::cout<< "Total number of events: " << evts << std::endl;
5847     }    
5848     if (i%5000 == 0 && i > 0 && debug > 0) std::cout << "Reading " <<  i << " / " << evts << " events" << std::endl;
5849     for(int j=0; j<event.GetNTiles(); j++){
5850       if (typeRO == ReadOut::Type::Caen) {
5851         Caen* aTile=(Caen*)event.GetTile(j);
5852         // testing for muon trigger
5853         if(aTile->GetLocalTriggerBit()!= (char)1){
5854           event.RemoveTile(aTile);
5855           j--;
5856         }
5857       } else if (typeRO == ReadOut::Type::Hgcroc){
5858         Hgcroc* aTile=(Hgcroc*)event.GetTile(j);
5859         // testing for muon trigger
5860         if(aTile->GetLocalTriggerBit()!= (char)1){
5861           event.RemoveTile(aTile);
5862           j--;
5863         }
5864       }
5865     }
5866     RootOutput->cd();
5867     TdataOut->Fill();
5868   }
5869   TdataOut->Write();
5870   TsetupIn->CloneTree()->Write();
5871   
5872   if (IsCalibSaveToFile()){
5873     TString fileCalibPrint = RootOutputName;
5874     fileCalibPrint         = fileCalibPrint.ReplaceAll(".root","_calib.txt");
5875     calib.PrintCalibToFile(fileCalibPrint);
5876   }
5877 
5878   // Print calib info
5879   calib.PrintGlobalInfo();  
5880 
5881   
5882   
5883   TcalibOut->Fill();
5884   TcalibOut->Write();
5885   RootOutput->Close();
5886   RootInput->Close();      
5887   
5888   return true;
5889 }
5890 
5891 //***********************************************************************************************
5892 //*********************** Skim HGCROC data ******************************************************
5893 //***********************************************************************************************
5894 bool Analyses::SkimHGCROCData(void){
5895   std::cout<<"Skim HGCROC data from pure noise"<<std::endl;
5896   TcalibIn->GetEntry(0);
5897     // check whether calib should be overwritten based on external text file
5898   if (OverWriteCalib){
5899     calib.ReadCalibFromTextFile(ExternalCalibFile,debug);
5900   }
5901 
5902   int evts=TdataIn->GetEntries();
5903   if (maxEvents == -1){
5904     maxEvents = evts;
5905   } else {
5906     std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
5907     std::cout << "ATTENTION: YOU ARE RESETTING THE MAXIMUM NUMBER OF EVENTS TO BE PROCESSED TO: " << maxEvents << ". THIS SHOULD ONLY BE USED FOR TESTING!" << std::endl;
5908     std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
5909   }
5910 
5911   long evtTrigg = 0;
5912   
5913   for(int i=0; i<evts && i < maxEvents; i++){
5914     TdataIn->GetEntry(i);
5915     if (i%5000 == 0 && i > 0 && debug > 0) std::cout << "Reading " <<  i << " / " << evts << " events" << std::endl;
5916     bool triggered = false;
5917     for(int j=0; j<event.GetNTiles(); j++){
5918       Hgcroc* aTile=(Hgcroc*)event.GetTile(j);
5919       // testing for any signal beyond noise
5920       if (debug > 3){
5921         aTile->PrintWaveFormDebugInfo(calib.GetPedestalMeanH(aTile->GetCellID()), calib.GetPedestalMeanL(aTile->GetCellID()), calib.GetPedestalSigL(aTile->GetCellID()));
5922       }
5923       
5924       if (aTile->GetRawTOA() > 0) triggered= true;
5925       if (aTile->GetLocalTriggerBit()== (char)1) triggered= true;
5926       if( !triggered){
5927         event.RemoveTile(aTile);
5928         j--;
5929       }
5930     }
5931     
5932     if (!triggered && debug == 3){
5933       for(int j=0; j<event.GetNTiles(); j++){
5934         Hgcroc* aTile=(Hgcroc*)event.GetTile(j);
5935         // testing for any signal beyond noise
5936         aTile->PrintWaveFormDebugInfo(calib.GetPedestalMeanH(aTile->GetCellID()), calib.GetPedestalMeanL(aTile->GetCellID()), calib.GetPedestalSigL(aTile->GetCellID()));
5937       }
5938     }
5939     
5940     RootOutput->cd();
5941     if (event.GetNTiles() > 0){
5942       evtTrigg++;
5943       TdataOut->Fill();
5944     }
5945   }
5946   TdataOut->Write();
5947   TsetupIn->CloneTree()->Write();
5948   
5949   std::cout << "Evts in: " << maxEvents << "\t skimmed: " << evtTrigg << std::endl;
5950   
5951   if (IsCalibSaveToFile()){
5952     TString fileCalibPrint = RootOutputName;
5953     fileCalibPrint         = fileCalibPrint.ReplaceAll(".root","_calib.txt");
5954     calib.PrintCalibToFile(fileCalibPrint);
5955   }
5956 
5957   TcalibOut->Fill();
5958   TcalibOut->Write();
5959   RootOutput->Close();
5960   RootInput->Close();      
5961   
5962   return true;
5963 }
5964 
5965 //***********************************************************************************************
5966 //*********************** Create output files ***************************************************
5967 //***********************************************************************************************
5968 bool Analyses::CreateOutputRootFile(void){
5969   if(Overwrite){
5970     std::cout << "overwriting exisiting output file" << std::endl;
5971     RootOutput=new TFile(RootOutputName.Data(),"RECREATE");
5972   } else{
5973     std::cout << "creating output file" << std::endl;
5974     RootOutput = new TFile(RootOutputName.Data(),"CREATE");
5975   }
5976   if(RootOutput->IsZombie()){
5977     std::cout<<"Error opening '"<<RootOutput<<"'no reachable path? Exist without force mode to overwrite?..."<<std::endl;
5978     return false;
5979   }
5980   return true;
5981 }
5982 
5983 //***********************************************************************************************
5984 //*********************** Create output files ***************************************************
5985 //***********************************************************************************************
5986 bool Analyses::CreateOutputRootHistFile(void){
5987   std::cout << "Additional Output with histos being created: " << RootOutputNameHist.Data() << std::endl;
5988   if(Overwrite){
5989     std::cout << "overwriting exisiting output file" << std::endl;
5990     RootOutputHist=new TFile(RootOutputNameHist.Data(),"RECREATE");
5991   } else{
5992     std::cout << "creating output file" << std::endl;
5993     RootOutputHist = new TFile(RootOutputNameHist.Data(),"CREATE");
5994   }
5995   if(RootOutputHist->IsZombie()){
5996     std::cout<<"Error opening '"<<RootOutputHist<<"'no reachable path? Exist without force mode to overwrite?..."<<std::endl;
5997     return false;
5998   }
5999   return true;
6000 }
6001 
6002 //***********************************************************************************************
6003 //*********************** Read external bad channel map *****************************************
6004 //***********************************************************************************************
6005 std::map<int,short> Analyses::ReadExternalBadChannelMap(void){
6006   
6007   std::cout << "Reading in external mapping file" << std::endl;
6008   std::map<int,short> bcmap;
6009   
6010   std::ifstream bcmapFile;
6011   bcmapFile.open(ExternalBadChannelMap,std::ios_base::in);
6012   if (!bcmapFile) {
6013     std::cout << "ERROR: file " << ExternalBadChannelMap.Data() << " not found!" << std::endl;
6014     return bcmap;
6015   }
6016 
6017   for( TString tempLine; tempLine.ReadLine(bcmapFile, kTRUE); ) {
6018     // check if line should be considered
6019     if (tempLine.BeginsWith("%") || tempLine.BeginsWith("#")){
6020       continue;
6021     }
6022     if (debug > 1) std::cout << tempLine.Data() << std::endl;
6023 
6024     // Separate the string according to tabulators
6025     TObjArray *tempArr  = tempLine.Tokenize(" ");
6026     if(tempArr->GetEntries()<2){
6027       if (debug > 1) std::cout << "nothing to be done" << std::endl;
6028       delete tempArr;
6029       continue;
6030     } 
6031     
6032     int mod     = ((TString)((TObjString*)tempArr->At(0))->GetString()).Atoi();
6033     int layer   = ((TString)((TObjString*)tempArr->At(1))->GetString()).Atoi();
6034     int row     = ((TString)((TObjString*)tempArr->At(2))->GetString()).Atoi();
6035     int col     = ((TString)((TObjString*)tempArr->At(3))->GetString()).Atoi();
6036     short bc    = short(((TString)((TObjString*)tempArr->At(4))->GetString()).Atoi());
6037     
6038     int cellID  = setup->GetCellID( row, col, layer, mod);    
6039                 
6040     if (debug > 1) std::cout << "cellID " << cellID << "\t BC status: " << bc<< std::endl;
6041     bcmap[cellID]=bc;
6042   }
6043   std::cout << "registered " << bcmap.size() << " bad channels!" << std::endl;
6044   return bcmap;  
6045   
6046 }