//Helper functions //Yes, they are in a header, because ROOT //Renata Kopecna #ifndef UTILS_HPP #define UTILS_HPP #include "GlobalFunctions.hh" #include "Paths.hpp" #include "MassFit.hpp" #include //I HATE ROOT! It's just way easier for root to have functions defined in a header with cross-references.... sigh //Forward declarations from Paths.hpp string GetInputFile(string year, string magnet, bool preSelected, bool MC, bool ReferenceChannel, bool PHSP, bool B0, bool K1, bool Inc, bool smallSample); string GetBDTinputFile(string year, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo); string GetBDToutputFile(string year, int Run, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo, bool UseLowQ2Range, bool reweighted); string GetBDToutputFile(int Run, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo, bool UseLowQ2Range, bool reweighted); string returnFileAddress(string year, int Run, string magnet, bool Preselected, bool BDTed, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo); ///////////////////////////////////////////// // // Get basic names and trees // ///////////////////////////////////////////// string correct_magnet_string(string magnet){ boost::to_lower(magnet); if (magnet != "both" && magnet != "up" && magnet != "down"){ coutWarning("Wrong magnet polarity used! Setting magnet to both!"); return magnet = "both"; } else return magnet; } string treeName(bool MC, bool Preselected){ if (MC && Preselected) return "DecayTreeTruthMatched"; else if (!Preselected) return "b2KstKpi0mumuResolvedTuple/DecayTree"; else return "DecayTree"; } vector get_magnet_vector(string magnet){ magnet = correct_magnet_string(magnet); if (magnet == "both"){ return {"down","up"}; } else return {magnet}; } TChain *get_basic_TChain(string magnet, vector years, bool Preselected, bool MC, bool ReferenceChannel, bool PHSP, bool B0, bool K1, bool Inc){ TChain* tree = new TChain(treeName(MC,Preselected).c_str()); coutInfo("Reading data from TTree... "); for (auto& yr : years){ for (auto& mag: get_magnet_vector(magnet)){ string path = GetInputFile(yr,mag,Preselected,MC, ReferenceChannel, PHSP, B0, K1, Inc, false); coutDebug("Adding " + path); tree->Add(path.c_str()); //TODO: no acces to not-preselected inclusive sample } } return tree; } TChain *get_weighted_TChain(vector years, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo){ TChain* tree = new TChain(treeName(MC,true).c_str()); for (auto& yr : years){ tree->Add(GetBDTinputFile(yr,MC,ReferenceChannel,PHSP,KshortDecayInVelo).c_str()); coutDebug("Adding " +GetBDTinputFile(yr,MC,ReferenceChannel,PHSP,KshortDecayInVelo)); } return tree; } TChain *get_BDT_TChain(vector years, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo, bool reweighted){ bool UseLowQ2Range = false; TChain* tree = new TChain(treeName(MC,true).c_str()); for (auto& yr : years){ tree->Add(GetBDToutputFile(yr,getRunID(yr),MC,ReferenceChannel,PHSP,KshortDecayInVelo,UseLowQ2Range,reweighted).c_str()); coutDebug("Adding " +GetBDToutputFile(yr,getRunID(yr),MC,ReferenceChannel,PHSP,KshortDecayInVelo,UseLowQ2Range,reweighted)); } return tree; } TChain *get_BDT_TChain(string year, int Run, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo, bool reweighted){ bool UseLowQ2Range = false; vector years; if (Run == 0) years.push_back(year); else years = yearsVector(MC,ReferenceChannel,PHSP,Run); TChain* tree = new TChain(treeName(MC,true).c_str()); for (auto& yr : years){ tree->Add(GetBDToutputFile(yr,getRunID(yr),MC,ReferenceChannel,PHSP,KshortDecayInVelo,UseLowQ2Range,reweighted).c_str()); coutDebug("Adding " +GetBDToutputFile(yr,getRunID(yr),MC,ReferenceChannel,PHSP,KshortDecayInVelo,UseLowQ2Range,reweighted)); } return tree; } TChain *get_FinalOutput_TChain(vector years, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo){ //TODO fix Run vs year TChain* tree = new TChain(treeName(MC,true).c_str()); for (auto& yr : years){ //tree->Add(GetFinalOutputFile(yr,1,MC,ReferenceChannel,PHSP,KshortDecayInVelo).c_str()); } return tree; } /////////////////////////////////////////////// // // Cut functions // /////////////////////////////////////////////// string getTMcut(bool TM,bool notTM, string customTMbranch, bool gammaTM){ string finalCut = ""; if (TM && notTM){ coutERROR("Cannot cut on TM == 1 && TM == 0! Returning an empty string."); return ""; } if (TM){ if (customTMbranch == "") finalCut.append("(" + TMbranch + "==1)"); else finalCut.append("(" + customTMbranch + "==1)"); //Check if the TM branch is not BKGCAT if (finalCut.find("BKGCAT") == string::npos){ //Gamma category: 1: both passed, 2: one passed, one converted, 3: both converted, 4: one passed, one random, 5: one converted, one random, 6: both failed if (gammaTM) finalCut.append(" && (" + gammaTMbranch + "<4)"); else finalCut.append(" && (" + gammaTMbranch + "<6)"); } } if (notTM){ if (customTMbranch == "") finalCut.append("(" + TMbranch + "==0)"); else finalCut.append("(" + customTMbranch + "==0)"); if (finalCut.find("BKGCAT") == string::npos){ //Gamma category: 1: both passed, 2: one passed, one converted, 3: both converted, 4: one passed, one random, 5: one converted, one random, 6: both failed if (gammaTM) finalCut.append(" || (" + gammaTMbranch + ">3)"); else finalCut.append(" || (" + gammaTMbranch + ">5)"); } } coutTest("TM cut:" + finalCut); return finalCut; } string getJpsicut(){ return "(8.68e6 < Q2 && Q2 < 10.09e6)"; //q2Cuts = "nDiMuonMassBin == 9"; } string getMuMucut(){ return "(Q2 < 0.98e6 || (1.1e6 < Q2 && Q2 < 8.0e6) || (11.0e6 < Q2 && Q2 < 12.5e6) || Q2 > 15.0e6)"; } string getFullCut(bool UseOnlyMuMuEvents, bool UseOnlyJpsiEvents, bool SplitInQ2, bool UseLowQ2Range, bool useExtraVar, TMefficiencyClass extraVar,int nExtraBin, double TMVAcut){ string finalCut = ""; string q2Cut = ""; if (UseOnlyMuMuEvents) q2Cut = getMuMucut(); else if (UseOnlyJpsiEvents) q2Cut = getJpsicut(); else if (SplitInQ2){ coutWarning("Using SplitInQ2! Always use with MuMu events!"); if (UseLowQ2Range) q2Cut = "(Q2 < 0.98e6 || (1.1e6 < Q2 && Q2 < 8.0e6))"; //q2Cuts = "nDiMuonMassBin < 9 || nDiMuonMassBin != 2"; else q2Cut = "((11.0e6 < Q2 && Q2 < 12.5e6) || Q2 > 15.0e6)"; //q2Cuts = "nDiMuonMassBin > 9 || nDiMuonMassBin != 12"; } else q2Cut = "(Q2 >0)"; //dummy cut in order to not having to deal with && at a beggining of the string finalCut.append(q2Cut); if (useExtraVar){ string extraVarCut = ""; double lowCut = extraVar.isEquidistant ? extraVar.binEdgesEquidistant.at(nExtraBin) : extraVar.binEdges.at(nExtraBin); double upperCut = extraVar.isEquidistant ? extraVar.binEdgesEquidistant.at(nExtraBin+1) : extraVar.binEdges.at(nExtraBin+1); extraVarCut = "(" + to_string(lowCut) + " < " + extraVar.cut+" && " + extraVar.cut+ "<= " + to_string(upperCut) + ")"; coutDebug(extraVarCut); finalCut.append(" && "); finalCut.append(extraVarCut); } if (TMVAcut > -1.0){ finalCut.append(" && "); finalCut.append(" (" + string(TMVAmethod) + "response > " + to_string(TMVAcut) + ")"); } coutTest("Main cut: " + finalCut); return finalCut ; } string getAloneBranch(bool MC, bool TM, string customTMbranch, bool gammaTM){ string customTag = ""; if (MC){ if (!TM) customTag = "NotTM"; else { if (customTMbranch == "") customTMbranch = TMbranch; if (customTMbranch == "TMedBKGCAT") customTag = ""; if (customTMbranch == "TMed"){ if (gammaTM) customTag = "_TMed"; else customTag = "_TMed_rndGamma"; } } } return "IsAloneAt" + customTag; } string getMultipleCut(bool MC, bool TM, string customTMbranch, bool gammaTM, double TMVAcut){ string aloneBranch = getAloneBranch(MC,TM,customTMbranch, gammaTM); string cut = (TMVAcut > -1.0) ? string("<=" + to_string(TMVAcut)) : "==0.0"; coutTest("Alone cut: " + aloneBranch + cut); return aloneBranch + cut; } string getFinalCut(bool MC, bool TM, bool notTM, string customTMbranch, bool gammaTM, bool UseOnlyMuMuEvents, bool UseOnlyJpsiEvents, bool SplitInQ2, bool UseLowQ2Range, bool useExtraVar, TMefficiencyClass extraVar,int nExtraBin, double TMVAcut, bool removeMultiple){ string fullCut = getFullCut(UseOnlyMuMuEvents, UseOnlyJpsiEvents, SplitInQ2, UseLowQ2Range, useExtraVar, extraVar, nExtraBin, TMVAcut); string TMcut = MC ? getTMcut(TM,notTM,customTMbranch,gammaTM) : ""; if (TMcut != "") TMcut = " && (" + TMcut + ")"; string multipleCut = removeMultiple ? string( " && (" +getMultipleCut(MC,TM,customTMbranch,gammaTM,TMVAcut) + ")") : ""; return fullCut + TMcut + multipleCut; } //Buggy 2015 MC needs to be removed and replaced by 2016 //TODO: make sure it's not loaded twice everywhere string checkIf2015MC(string year, bool MC, bool Reference, bool PHSP){ if (Kst2Kpluspi0Resolved && MC && !Reference && !PHSP && year== "2015") return "2016"; else return year; } /////////////////////////////////////////////// // // Sanity checks // ///////////////////////////////////////////// bool checkMC(bool &MC, bool ReferenceChannel, bool PHSP, bool mutuallyExclusive){ if (!MC && PHSP){//if PHSP or reference channel, set MC to true coutWarning("PHSP or Reference channel option selected, setting MC to true"); MC = true; } if (mutuallyExclusive && ReferenceChannel && PHSP){ coutERROR("You cannot select both Reference channel and PHSP! Abort."); return false; } return true; } bool checkMC(bool ReferenceChannel, bool PHSP){ if (ReferenceChannel && PHSP){ coutERROR("You cannot select both Reference channel and PHSP! Abort."); return false; } return true; } bool checkQ2Range(bool UseOnlyJpsi, bool UseOnlyMuMu){ if (UseOnlyJpsi && UseOnlyMuMu){ coutERROR("Make up your mind! Either Jpsi or mumu channel, it cannot be both! Program failed"); return false; } return true; } bool checkTM(bool MC, bool &TM, bool &nonTM, bool Preselected){ if ( (TM || nonTM) && !MC){ coutWarning("Data is not TruthMatched! Setting TM and nonTM to false!"); TM = false; //Keep nonTM as it is for the MC fit to get the shape } if ( (TM || nonTM) && !Preselected){ coutWarning("Stripped MC is not TruthMatched! Setting TM to false!"); TM = false; nonTM = false; } if (TM && nonTM){ coutERROR("Cannot fit TM==1 and TM==0 data at the same time! Make up your mind. Abort."); return false; } return true; } bool checkKshort(bool &KshortDecaysInVelo){ if (!Kst2Kspiplus && KshortDecaysInVelo){ coutWarning("No LL/DD tracks in KplusPizero channel! Setting KshortDecaysInVelo to false!"); KshortDecaysInVelo = false; } return true; } bool checkRefYear(string year){ if (Kst2Kspiplus && (year == "2015" || year =="2017" || year == "2018" )){ coutERROR("Reference channel is only available for 2011, 2012 and 2016!"); return false; } if (!Kst2Kspiplus && (year =="2017" || year == "2018" )){ coutERROR("Reference channel is only available for 2011, 2012, 2015 and 2016!"); return false; } return true; } bool checkEntries(TTree *tree){ Int_t nEvents = tree->GetEntries(); if(nEvents == 0){ coutERROR("Entries in data TTree " + string(tree->GetName()) + " are empty. Abort!"); return false; } return true; } bool checkYear(int year, bool MC, bool ReferenceChannel, bool PHSP){ bool flag = false; if (!MC){ if (year == 2011 || year == 2012|| year == 2015 || year == 2016 || year == 2017 || year == 2018 ) flag=true; else flag=false; } else{ if (KshortChannel){ //KS if (ReferenceChannel){ if (year == 2011 || year == 2012|| year == 2016) flag=true; else flag=false; } else if (PHSP){ if (year == 2011 || year == 2012|| year == 2015 || year == 2016 || year == 2017 || year == 2018 ) flag=true; else flag=false; } else{ if (year == 2011 || year == 2012|| year == 2015 || year == 2016 || year == 2017 || year == 2018 ) flag=true; else flag=false; } } else{ //K+pi0 if (ReferenceChannel){ if (year == 2011 || year == 2012|| year == 2015 || year == 2016) flag=true; else flag=false; } else if (PHSP){ if (year == 2011 || year == 2012|| year == 2015 || year == 2016 || year == 2017 || year == 2018) flag=true; else flag=false; } else{ if (year == 2011 || year == 2012|| year == 2015 || year == 2016 || year == 2017 || year == 2018) flag=true; else flag=false; } } } if (!flag) coutERROR("Wrong year input! Your input is " + to_string(year)+ ". Abort."); return flag; } bool checkRun(int Run){ if(Run != 1 && Run != 2 && Run != 12){ coutERROR("Invalid Run number given: >> " + to_string( Run) + " << . Use only Run 1, Run 2 or Run 12! Exit now."); return 0; } return 1; } /////////////////////////////////////////////// // // Get correct names and tags // ///////////////////////////////////////////// string getTMtag(string customTMbranch){ if (customTMbranch == "") customTMbranch = TMbranch; if (customTMbranch == "TMedBKGCAT") return "_BKGCAT"; if (customTMbranch == "TMed") return "_IDTM"; if (customTMbranch == "TMed_noPi0") return "_noPi0_IDTM"; coutERROR("Wrong customTM branch! Returning string 'wrong'"); return "wrong"; } string getTMtag(string customTMbranch, bool gammaTM){ if (customTMbranch == "") customTMbranch = TMbranch; if (customTMbranch == "TMedBKGCAT") return "_BKGCAT"; if (customTMbranch == "TMed") return "_IDTM"+ string(gammaTM ? "" : "_rndGamma");; if (customTMbranch == "TMed_noPi0") return "_noPi0_IDTM"+ string(gammaTM ? "" : "_rndGamma");; coutERROR("Wrong customTM branch! Returning string 'wrong'"); return "wrong"; } string getWeightName(string customTMbranch, bool gammaTM){ if (customTMbranch == "") customTMbranch = TMbranch; if (customTMbranch == "TMedBKGCAT") return "weight2D_"+firstMCweight; if (customTMbranch == "TMed") return "weight2D_"+firstMCweight + "_TM" + string(gammaTM ? "" : "_rndGamma"); if (customTMbranch == "TMed_noPi0") return "weight2D_"+firstMCweight + "_noPi0TM"; coutERROR("Wrong customTMbranch name! Returning an empty string."); return ""; } std::string getDataTypeTag(bool MC, bool Reference, bool PHSP, bool B0, bool K1, bool Inc){ if (!MC) return "Data"; else{ if (PHSP) return "MC PHSP"; else{ if (B0) return Reference ? "MC B0toKstJpsi" : "MC B0toKstMuMu"; else if (K1) return Reference ? "MC BtoK1Jpsi" : "MC BtoK1MuMu"; else if (Inc) return Reference ? "MC BtoXJpsi" : "MC BtoXMuMu"; else return Reference ? "Reference MC" : "Signal MC"; } } } string getDataTypeTag(bool MC, bool Reference, bool PHSP){ return getDataTypeTag(MC, Reference, PHSP, false, false, false); } string getYearRunTag(int Run, string year){ if (Run == 0) return "Year " + year; else return "Run " + to_string(Run); } ///////////////////////////////////////////// // // Bin edges for a similarly populated bins // ///////////////////////////////////////////// void getSimilarlyPopulatedBins(TH1D *histogram, int desiredBins, int nBins){ //rebin (THIS ASSUMES THE ORIGINAL BIN WIDTH IS ONE!!!) int maxBinContent = histogram->GetEntries()/desiredBins; TAxis *axis = histogram->GetXaxis(); Double_t xEdges[desiredBins+1]; xEdges[0] = axis->GetBinLowEdge(1); int i = 0; for (int b = 1; b GetBinContent(i); i++; } xEdges[b] = axis->GetBinLowEdge(i); i++; } xEdges[desiredBins] = axis->GetBinUpEdge(nBins); for (int b = 0; b SetOptStat(0); gROOT->SetBatch(kTRUE); TH1::SetDefaultSumw2(kTRUE); //Load all files coutInfo("Opennig the trees"); TChain *tree= new TChain("DecayTreeTruthMatched"); //Open the file(s) if (Run==0){ tree->Add(returnFileAddress(year, getRunID(year), magnet, true, false, true, ReferenceChannel, PHSP, false).c_str()); coutDebug("Adding " + returnFileAddress(year, getRunID(year), magnet, true, false, true, ReferenceChannel, PHSP, false)); } else{ for (auto yr: yearsMC(ReferenceChannel, PHSP, Run)){ tree->Add(returnFileAddress(yr, getRunID(yr), magnet, true, false, true, ReferenceChannel, PHSP, false).c_str()); coutDebug("Adding " + returnFileAddress(yr, getRunID(yr), magnet, true, false, true, ReferenceChannel, PHSP, false)); } } //activate all branches tree->SetBranchStatus("*",1); //Draw the histogram TH1D *h_tmp = new TH1D ("h_tmp", "h_tmp", nBins,lowEdge,highEdge); tree->Draw(Form("%s>>h_tmp",var.c_str())); //Get the binnings getSimilarlyPopulatedBins(h_tmp,desiredBins, nBins); //free da memory delete h_tmp; delete tree; return; } ///////////////////////////////////////////// // // Get result from a fit file // Comment out the content of the functions in order to compile getPathForPython *facepalm // ///////////////////////////////////////////// RooFitResult* getResult(TFile *fitFile){ RooFitResult* fitResult; fitFile->GetObject("fitresult_pdf_data",fitResult); if (verboseLevel < 2) fitResult->Print(); return fitResult; } RooRealVar* getVarFromResult(RooFitResult *fitResult, string name){ RooRealVar *myVar = (RooRealVar*)fitResult->floatParsFinal().find(name.c_str()); return myVar; } double getBplusMeanFromResult(TFile* fitFile){ RooRealVar *mass = getVarFromResult(getResult(fitFile),"sig_mean"); return mass->getVal(); } //Read the yields from a fit file double getSigYield(TFile *fitFile){ TVectorD *yield = (TVectorD*)fitFile->Get("yield"); return (*yield)[0]; } double getSigYieldErr(TFile *fitFile){ TVectorD *yield_err = (TVectorD*)fitFile->Get("yield_err"); return (*yield_err)[0]; } double getBkgYield(TFile *fitFile){ TVectorD *bkg = (TVectorD*)fitFile->Get("background"); return (*bkg)[0]; } double getBkgYieldErr(TFile *fitFile){ TVectorD *bkg_eff = (TVectorD*)fitFile->Get("background_err"); return (*bkg_eff)[0]; } double getEffSigma(TFile *fitFile){ TVectorD *sigma = (TVectorD*)fitFile->Get("sigma_eff"); return (*sigma)[0]; } ///////////////////////////////////////////// // // Histogram/graph helpers // ///////////////////////////////////////////// TH1D *convertTGraph(TGraph *graph){ //Possibly fix tihs at some point to be generally repflecting TMefficiencyClass double binEdges[7] = {0.1e6, 4.0e6, 8.0e6, 11.0e6, 12.5e6, 15.0e6, 20.0e6}; TH1D *hist = new TH1D("hist","hist",6,binEdges); auto nPoints = graph->GetN(); // number of points in your TGraph for(int i=0; i < nPoints; ++i) { double x,y; graph->GetPoint(i, x, y); hist->Fill(x,y); // ? } for (int b=0; b < hist->GetXaxis()->GetNbins(); b++){ hist->SetBinError(b+1,0); } return hist; } ///////////////////////////////////////////// // // Get numbers of MC events // ///////////////////////////////////////////// double generated_basic_events = 10000.0; double generated_basic_events_PHSP = 1000.0; double get_generated_events(bool PHSP){ if (PHSP) return generated_basic_events_PHSP; else return generated_basic_events; } vector generated_signal_events_down = {507551, 514015, 0, 1000281, 1151738, 1235528}; vector generated_signal_events_up = {502787, 500458, 0, 1000281, 1153816, 1196153}; vector generated_reference_events_down = {1011831, 1003888, 1007712, 1010609, 0, 0}; vector generated_reference_events_up = {1007920, 1000278, 1009484, 1000281, 0, 0}; vector generated_PHSP_events_down = {85736, 226933, 95323, 264917, 246457, 291850}; vector generated_PHSP_events_up = {86004, 226430, 94980, 267674, 242673, 299252}; vector gen_tables_signal_efficiency_down = {0.14388, 0.14769, 0.1615, 0.1610, 0.1609, 0.1605};//RUN I taken from Reference Channel vector gen_tables_signal_efficiency_up = {0.14422, 0.14787, 0.1608, 0.1611, 0.1595, 0.1609};//RUN I taken from Reference Channel vector gen_tables_reference_efficiency_down = {0.14388, 0.14769, 0.1581, 0.1585, 0.1585, 0.1585}; //2017+2018 taken as 2016 vector gen_tables_reference_efficiency_up = {0.14422, 0.14787, 0.1574, 0.1590, 0.1590, 0.1590}; //2017+2018 taken as 2016 vector yield_signal_events = {5451, 4906, 4096, 10382, 15994, 14919}; vector yield_signal_events_err = {70, 64, 1, 96, 15, 116}; vector yield_reference_events = {19730, 17579, 18392, 23965, 0, 0}; vector yield_reference_events_err = {135, 127, 130, 149, 0, 0}; vector yield_PHSP_events = {14091, 33086, 13530, 48135, 54030, 61641}; vector yield_PHSP_events_err = {113, 174, 111, 209, 221, 237}; vector yield_signal_events_notTM = {7056, 6587, 6354, 15652, 20207, 19734}; vector yield_signal_events_notTM_err = {456, 61, 81, 55, 368, 222}; vector yield_reference_events_notTM = {24375, 22698, 23403, 30303, 0, 0}; vector yield_reference_events_notTM_err = {236, 123, 143, 12, 0, 0}; vector yield_signal_events_notTM_unique = {5854, 5304, 5155, 13086, 17055, 16374}; vector yield_signal_events_notTM_unique_err = {89, 106, 86, 169, 172, 211}; vector yield_reference_events_notTM_unique = {20564, 18772, 19204, 25140, 0, 0}; vector yield_reference_events_notTM_unique_err = {210, 123, 89, 167, 0, 0}; int get_position_from_year(string year){ int position = year.back() - '0'; //get last char of a string and convert it to an int return position>4 ? position-3 : position-1; //11->0, 12->1, 15->2, 16->3, ... } int get_gen_evts(string year, bool ReferenceChannel, bool PHSP){ int pos = get_position_from_year(year); if (ReferenceChannel) return generated_reference_events_down.at(pos) + generated_reference_events_up.at(pos); if (PHSP) return generated_PHSP_events_down.at(pos) + generated_PHSP_events_up.at(pos); return generated_signal_events_down.at(pos) + generated_signal_events_up.at(pos); } int get_gen_evts(int Run, bool ReferenceChannel, bool PHSP){ int yield = 0; for (auto yr: yearsMC(ReferenceChannel,PHSP,Run)) yield += get_gen_evts(yr,ReferenceChannel,PHSP); return yield; } int get_selected_evts(string year, bool ReferenceChannel, bool PHSP){ int pos = get_position_from_year(year); if (ReferenceChannel) return yield_reference_events.at(pos); if (PHSP) return yield_PHSP_events.at(pos); return yield_signal_events.at(pos); } int get_selected_evts(int Run, bool ReferenceChannel, bool PHSP){ int yield = 0; for (auto yr: yearsMC(ReferenceChannel,PHSP,Run)) yield += get_selected_evts(yr,ReferenceChannel,PHSP); return yield; } int get_selected_evts_err(string year, bool ReferenceChannel, bool PHSP){ int pos = get_position_from_year(year); if (ReferenceChannel) return yield_reference_events_err.at(pos); if (PHSP) return yield_PHSP_events_err.at(pos); return yield_signal_events_err.at(pos); } double get_selection_efficiency(string year, bool ReferenceChannel, bool PHSP){ return double(get_selected_evts(year,ReferenceChannel,PHSP))/double(get_gen_evts(year,ReferenceChannel,PHSP)); } double get_selection_efficiency(int Run, bool ReferenceChannel, bool PHSP){ return double(get_selected_evts(Run,ReferenceChannel,PHSP))/double(get_gen_evts(Run,ReferenceChannel,PHSP)); } double get_tables_eff(string year, bool ReferenceChannel){ //Get efficiency in a year as an average between up and down int pos = get_position_from_year(year); if (ReferenceChannel) return (gen_tables_reference_efficiency_down.at(pos)+gen_tables_reference_efficiency_up.at(pos))/2; else return (gen_tables_signal_efficiency_down.at(pos)+gen_tables_signal_efficiency_up.at(pos))/2; } double get_tables_eff(int Run, bool ReferenceChannel){ //Get efficiency of a run as an average between years double sum = 0; int nEntries = 0; double tmp_eff = 0; for (auto yr: yearsMC(ReferenceChannel,false,Run)){ tmp_eff = get_tables_eff(yr, ReferenceChannel); if (tmp_eff!=0) nEntries++; sum += tmp_eff; } coutDebug("Total eff/nEntries: " + to_string(sum) + "/" + to_string(nEntries) ); if (nEntries == 0) return 0; return sum/nEntries; } void print_all_yields_and_efficiencies(bool ReferenceChannel, bool PHSP){ for (auto yr : yearsMC(ReferenceChannel,PHSP, 12)){ cout << "------ year " << yr << " ------" << endl; cout << "\t\t Generated events:\t" << get_gen_evts(yr, ReferenceChannel, PHSP) << endl; cout << "\t\t Selected events:\t" << get_selected_evts(yr, ReferenceChannel, PHSP) << endl; cout << "\t\t Efficiency: \t" << get_selection_efficiency(yr, ReferenceChannel, PHSP) << endl; } cout << "------ Run 1 ------" << endl; cout << "\t\t Generated events:\t" << get_gen_evts(1, ReferenceChannel, PHSP) << endl; cout << "\t\t Selected events:\t" << get_selected_evts(1, ReferenceChannel, PHSP) << endl; cout << "\t\t Efficiency: \t" << get_selection_efficiency(1, ReferenceChannel, PHSP) << endl; cout << "------ Run 2 ------" << endl; cout << "\t\t Generated events:\t" << get_gen_evts(2, ReferenceChannel, PHSP) << endl; cout << "\t\t Selected events:\t" << get_selected_evts(2, ReferenceChannel, PHSP) << endl; cout << "\t\t Efficiency: \t" << get_selection_efficiency(2, ReferenceChannel, PHSP) << endl; return; } //---------------------------------------------------------------------------------------------------------- #endif // UTILS_HPP