Angular analysis of B+->K*+(K+pi0)mumu
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

684 lines
27 KiB

//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 <boost/algorithm/string.hpp>
//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 <string> 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<string> 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<string> 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<string> 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<string> 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<string> 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 <desiredBins+1; b++){
int content = 0;
while (content < maxBinContent){
content = content+histogram->GetBinContent(i);
i++;
}
xEdges[b] = axis->GetBinLowEdge(i);
i++;
}
xEdges[desiredBins] = axis->GetBinUpEdge(nBins);
for (int b = 0; b<desiredBins+1; b++){
cout << xEdges[b] << endl;
}
return;
}
void getSimilarlyPopulatedBinsVar(string var, int nBins, double lowEdge, double highEdge, int desiredBins, string year, string magnet, int Run, bool ReferenceChannel, bool PHSP){
gStyle -> 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<int> generated_signal_events_down = {507551, 514015, 0, 1000281, 1151738, 1235528};
vector<int> generated_signal_events_up = {502787, 500458, 0, 1000281, 1153816, 1196153};
vector<int> generated_reference_events_down = {1011831, 1003888, 1007712, 1010609, 0, 0};
vector<int> generated_reference_events_up = {1007920, 1000278, 1009484, 1000281, 0, 0};
vector<int> generated_PHSP_events_down = {85736, 226933, 95323, 264917, 246457, 291850};
vector<int> generated_PHSP_events_up = {86004, 226430, 94980, 267674, 242673, 299252};
vector<double> gen_tables_signal_efficiency_down = {0.14388, 0.14769, 0.1615, 0.1610, 0.1609, 0.1605};//RUN I taken from Reference Channel
vector<double> gen_tables_signal_efficiency_up = {0.14422, 0.14787, 0.1608, 0.1611, 0.1595, 0.1609};//RUN I taken from Reference Channel
vector<double> gen_tables_reference_efficiency_down = {0.14388, 0.14769, 0.1581, 0.1585, 0.1585, 0.1585}; //2017+2018 taken as 2016
vector<double> gen_tables_reference_efficiency_up = {0.14422, 0.14787, 0.1574, 0.1590, 0.1590, 0.1590}; //2017+2018 taken as 2016
vector<int> yield_signal_events = {5451, 4906, 4096, 10382, 15994, 14919};
vector<int> yield_signal_events_err = {70, 64, 1, 96, 15, 116};
vector<int> yield_reference_events = {19730, 17579, 18392, 23965, 0, 0};
vector<int> yield_reference_events_err = {135, 127, 130, 149, 0, 0};
vector<int> yield_PHSP_events = {14091, 33086, 13530, 48135, 54030, 61641};
vector<int> yield_PHSP_events_err = {113, 174, 111, 209, 221, 237};
vector<int> yield_signal_events_notTM = {7056, 6587, 6354, 15652, 20207, 19734};
vector<int> yield_signal_events_notTM_err = {456, 61, 81, 55, 368, 222};
vector<int> yield_reference_events_notTM = {24375, 22698, 23403, 30303, 0, 0};
vector<int> yield_reference_events_notTM_err = {236, 123, 143, 12, 0, 0};
vector<int> yield_signal_events_notTM_unique = {5854, 5304, 5155, 13086, 17055, 16374};
vector<int> yield_signal_events_notTM_unique_err = {89, 106, 86, 169, 172, 211};
vector<int> yield_reference_events_notTM_unique = {20564, 18772, 19204, 25140, 0, 0};
vector<int> 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