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.
 
 
 
 

385 lines
16 KiB

//Class containing value and errors used for efficienceis
//Renata Kopecna
#include "GlobalFunctions.hh"
#include "Paths.hpp"
#include "Design.hpp"
#include "MassFit.cpp"
using namespace std;
using namespace RooFit;
using namespace RooStats;
//////////////////////////////////////////////////////
/// class EffandError()
//////////////////////////////////////////////////////
///
/// Used for storing efficiency + hiighError - lowError
///
///
/////////////////////////////////////////////////////////
/// GetEfficiency
//////////////////////////////////////////////////////
///
/// Reads two given files, reads the yields (TVectorDouble) from them
///
///
/////////////////////////////////////////////////////////
/// getTruthMatchingEfficiencySimple
//////////////////////////////////////////////////////
///
/// Returns EffAndError for Truthmatching/selected,
/// either per year or per run
///
///
/////////////////////////////////////////////////////////
/// getBDTEfficiencySimple
//////////////////////////////////////////////////////
///
/// Returns EffAndError for a given TMVAresponse cut,
/// done not by fitting the mass peak but by a simple count,
/// either per year or per run
///
///
/////////////////////////////////////////////////////////
/// getSelectionEfficiencySimple
//////////////////////////////////////////////////////
///
/// Returns EffAndError for a given year and Run
/// from generated and selected TM events
///
///
//Define EffAndError class
//----------------------------------------------------------------------------------------------------------
class EffAndError{
public:
double value;
double highError;
double lowError;
EffAndError(){ //default constructor
value = 0;
highError = 0;
lowError = 0;
}
EffAndError(double val){ //default constructor
value = val;
highError = 0;
lowError = 0;
}
EffAndError(double val,double highErr, double lowErr){ //default constructor
value = val;
highError = highErr;
lowError = lowErr;
}
~EffAndError(); //destuctor
};
EffAndError::~EffAndError(){//destuctor
}
string mainSignalShape = "OneCB";
//Calculate efficiency from two files
//----------------------------------------------------------------------------------------------------------
EffAndError GetEfficiency(TFile *fitFileNumerator, string nameNumerator, TFile *fitFileDenominator, string nameDenominator){
if (fitFileNumerator == NULL){
coutERROR("File " + string(fitFileNumerator->GetPath()) + " not opened!");
return EffAndError(0,0,0);
}
if (fitFileDenominator == NULL){
coutERROR("File " + string(fitFileDenominator->GetPath()) + " not opened!");
return EffAndError(0,0,0);
}
// Get yield for numerator data
TVectorD *SigYieldNumeratorVec = (TVectorD*)fitFileNumerator->Get("yield");
double SigYieldNumerator = (*SigYieldNumeratorVec)[0];
// Get yield for denominator data
TVectorD *SigYieldDenominatorVec = (TVectorD*)fitFileDenominator->Get("yield");
double SigYieldDenominator = (*SigYieldDenominatorVec)[0];
double efficiency = SigYieldNumerator/SigYieldDenominator;
coutDebug("Yield from " + nameNumerator + " fit:\t" + to_string(SigYieldNumerator));
coutDebug("Yield from " + nameDenominator + " fit:\t" + to_string(SigYieldDenominator));
coutInfo("Efficiency:\t" + to_string(efficiency));
//EffAndError result = EffAndError(efficiency,EffErrHi,EffErrLo);
EffAndError result = EffAndError(efficiency,0.0,0.0);
coutDebug("Efficiency succesfully calculated" );
return result;
}
//Get efficiency from counts in MC (TM is possible since background in non-TMed sample is hard to model anyway)
//----------------------------------------------------------------------------------------------------------
EffAndError getTMEfficiencySimple(string year, int Run, bool UseOnlyMuMuEvents, bool PHSP, bool KshortDecaysInVelo, bool RemoveMultiple, bool weighted, string sExtraVar, int nExtraBin, string customTMbranch, bool gammaTM){ //TODO: add customTMbranch and gammaTM
gROOT->SetBatch(); //ROOT stops plotting canvases
EffAndError eff = EffAndError(1.0,0.0,0.0);
bool useRefChannel = !PHSP && !UseOnlyMuMuEvents;
//check if using reference channel for not available years
if (!checkYear(std::stoi(year),true,useRefChannel,PHSP)) return eff;
//load the tree from the file
TChain * T = new TChain("DecayTreeTruthMatched");
std::vector<string> years;
if (Run == 0)years.push_back(year); //If Run==0, calculate efficiecny for separate year
else years = yearsMC(useRefChannel,PHSP,Run); //Otherwise combine the years together
for (auto& yr : years){
T->Add(GetBDToutputFile(yr,getRunID(yr),true,useRefChannel,PHSP,KshortDecaysInVelo,false,false).c_str());
coutDebug("Adding " + GetBDToutputFile(yr,getRunID(yr),true,useRefChannel,PHSP,KshortDecaysInVelo,false,false));
}
bool useExtraVar = useExtraVarBool(sExtraVar); //perform once so it doesn't have to run through all the ifs every time
TMefficiencyClass extraVar = useExtraVar ? TMefficiencyClass(sExtraVar) : TMefficiencyClass();
// Set cuts on the tree
string massCut = "";
if (UseDTF) massCut = " ( B_plus_M_DTF > " + to_string(PDGMASS.B_PLUS-100) +" && B_plus_M_DTF <" + to_string(PDGMASS.B_PLUS+100)+ ") ";
else massCut = " ( B_plus_M > " + to_string(PDGMASS.B_PLUS-100) +" && B_plus_M <" + to_string(PDGMASS.B_PLUS+100)+ ") ";
coutDebug("Mass cut: " +massCut);
string sCut = getFinalCut(true, false, false, customTMbranch, gammaTM, UseOnlyMuMuEvents, useRefChannel, false, false, useExtraVar, extraVar, nExtraBin, -1, RemoveMultiple);
coutDebug("sCut: " + sCut);
sCut.append(" && ");
sCut.append(massCut);
if (weighted) sCut = getWeightName(customTMbranch,gammaTM)+"*(" + sCut + ")";
coutDebug("First cut: " + sCut);
//Get number of entries before TM
TH1F *h_noTM = new TH1F("h_noTM","h_noTM",1002,-1.0,1.0);
T->Draw(TMVAmethod+"response >> h_noTM", sCut.c_str());
sCut = getFinalCut(true, true, false, customTMbranch, gammaTM, UseOnlyMuMuEvents, useRefChannel, false, false, useExtraVar, extraVar, nExtraBin, -1, RemoveMultiple);
sCut.append(" && ");
sCut.append(massCut);
if (weighted) sCut = getWeightName(customTMbranch,gammaTM)+ "*(" + sCut + ")";
coutDebug("Second cut: " + sCut);
//Get number of entries after the BDT cut
TH1F *h_TM = new TH1F("h_TM","h_TM",1002,-1.0,1.0);
T->Draw(TMVAmethod+"response >>h_TM", sCut.c_str());
//Calculate efficiency and its binomial error
double passEntries = h_TM->Integral();
double nentries = h_noTM->Integral();
double effErrHi = TMath::Sqrt(passEntries*(1.0-passEntries/nentries))/nentries;
eff.value = passEntries/ nentries;
coutDebug("All MC entries: " + to_string(nentries));
coutDebug("MC entries passing TM: " + to_string(passEntries));
coutDebug("TM efficiency: " + to_string(eff.value));
eff.highError = effErrHi;
eff.lowError = effErrHi;
h_noTM->Clear();
h_TM->Clear();
delete T;
return eff;
}
EffAndError getBDTEfficiencySimple(string year, Double_t TMVAcut, int Run, bool UseOnlyMuMuEvents,bool PHSP,
bool KshortDecaysInVelo, bool IncludeMultipleEff, bool weighted, string sExtraVar, int nExtraBin){ //TODO: check weight
EffAndError eff = EffAndError(1.0,0.0,0.0);
bool useRefChannel = !PHSP && !UseOnlyMuMuEvents;
//check if using reference channel for not available years
if (!checkYear(std::stoi(year),true,useRefChannel,PHSP)) return eff;
//Get low TMVA response lower boundary
double lowBDTcut = -1.0; //check if at lower limit
if (TMVAmethod == "MLP") lowBDTcut = 0.0;
if (TMVAcut == lowBDTcut){
coutERROR("BDT cut is 100% effective at "+ to_string(lowBDTcut) + "! returning efficiency 1+-0.");
return eff;
}
//load the tree from the file
TChain * T = new TChain("DecayTreeTruthMatched");
std::vector<string> years;
if (Run == 0){ //If Run==0, calculate efficiecny for separate year
years.push_back(year);
}
else years = yearsMC(useRefChannel,PHSP,Run); //Otherwise combine the years together
for (auto& yr : years){
int RunID = (yr == "2011" || yr == "2012") ? 1:2;
T->Add(GetBDToutputFile(yr,RunID,true,useRefChannel,PHSP,KshortDecaysInVelo,false,false).c_str());
}
bool useExtraVar = useExtraVarBool(sExtraVar); //perform once so it doesn't have to run through all the ifs every time
TMefficiencyClass extraVar = useExtraVar ? TMefficiencyClass(sExtraVar) : TMefficiencyClass();
gROOT->SetBatch(); //ROOT stops plotting canvases
// Set cuts on the tree
TString massCut = "";
if (UseDTF) massCut = " ( B_plus_M_DTF > " + to_string(PDGMASS.B_PLUS-100) +" && B_plus_M_DTF <" + to_string(PDGMASS.B_PLUS+100)+ ") ";
else massCut = " ( B_plus_M > " + to_string(PDGMASS.B_PLUS-100) +" && B_plus_M <" + to_string(PDGMASS.B_PLUS+100)+ ") ";
//add vetos
string sCut = getFinalCut(true, true, false, "", gammaTMdefault, UseOnlyMuMuEvents, useRefChannel, false, false, useExtraVar, extraVar, nExtraBin, lowBDTcut, !IncludeMultipleEff);
string LLorDD = string("&& (KshortDecayInVeLo == ") + (KshortDecaysInVelo ? "1":"0") + ")";
sCut.append(" && ");
sCut.append(massCut);
if(Kst2Kspiplus) sCut.append(LLorDD);
if (weighted) sCut = getWeightName("",gammaTMdefault)+"*(" + sCut + ")";
coutDebug("Using cut: "+sCut);
//TODO!!!!! Naming convension for including multiple efficiency!!!!!
//Get number of entries before the BDT cut
TH1F *h_BDTresponseMCAll = new TH1F("h_"+TMVAmethod+"responseAll","h_"+TMVAmethod+"responseAll",1002,lowBDTcut,1.0);
T->Draw(TMVAmethod+"response >> h_"+TMVAmethod+"responseAll", sCut.c_str());
sCut = getFinalCut(true, true, false, "", gammaTMdefault, UseOnlyMuMuEvents, useRefChannel, false, false, useExtraVar, extraVar, nExtraBin, TMVAcut, true);
sCut.append(" && ");
sCut.append(massCut);
if (Kst2Kspiplus) sCut.append(LLorDD);
if (weighted) sCut = getWeightName("",gammaTMdefault)+"*(" + sCut + ")";
coutDebug("Using cut: "+sCut);
//Get number of entries after the BDT cut
TH1F *h_BDTresponseMCtmp = new TH1F("h_"+TMVAmethod+"response","h_"+TMVAmethod+"response",1002,lowBDTcut,1.0);
T->Draw(TMVAmethod+"response >> h_"+TMVAmethod+"response", sCut.c_str());
//Calculate efficiency and its binomial error
double passEntries = h_BDTresponseMCtmp->Integral();
double nentries = h_BDTresponseMCAll->Integral();
double effErrHi = TMath::Sqrt(passEntries*(1.0-passEntries/nentries))/nentries;
eff.value = passEntries/ nentries;
coutDebug("All MC entries: " + to_string(nentries));
coutDebug("MC entries passing TMVA cut " + to_string(TMVAcut) + ": " + to_string(passEntries));
coutDebug("TMVA cut" + to_string(TMVAcut) + " efficiency: " + to_string(eff.value));
eff.highError = effErrHi;
eff.lowError = effErrHi;
h_BDTresponseMCAll->Clear();
h_BDTresponseMCtmp->Clear();
delete T;
coutDebug("BDT efficiency for cut at " + to_string(TMVAcut) + " calculated!" );
return eff;
}
//Get selection efficiency from counts in MC
//----------------------------------------------------------------------------------------------------------
EffAndError getSelectionEfficiencySimple(bool full, string year, int Run, bool UseOnlyMuMuEvents, bool useRefChannel, bool PHSP, bool KshortDecaysInVelo, bool RemoveMultiple, bool weighted, string sExtraVar, int nExtraBin, string customTMbranch, bool gammaTM){ //For studies on variables
gROOT->SetBatch(); //ROOT stops plotting canvases
EffAndError eff = EffAndError(1.0,0.0,0.0);
//check if using reference channel for not available years
if (!checkYear(std::stoi(year),true,useRefChannel,PHSP)) return eff;
//Scaling factor, pretty much the number of generated events
//For easier division it's a double right away
double scale = get_generated_events(PHSP);
std::vector<string> years;
if (Run == 0)years.push_back(year); //If Run==0, calculate efficiecny for separate year
else years = yearsMC(useRefChannel,PHSP,Run); //Otherwise combine the years together
//load the tree from the file
TChain * T = new TChain("DecayTreeTruthMatched");
for (auto& yr : years){
T->Add(GetBDToutputFile(yr,getRunID(yr),true,useRefChannel,PHSP,KshortDecaysInVelo,false,false).c_str());
coutDebug("Adding " + GetBDToutputFile(yr,getRunID(yr),true,useRefChannel,PHSP,KshortDecaysInVelo,false,false));
}
//Kst2Kpluspi0Resolved case
TChain* OG = 0;
if(Kst2Kpluspi0Resolved){
OG=new TChain("DecayTree");
OG->Add(GetGenLevelFile(useRefChannel,PHSP).c_str());
coutDebug("Adding " + GetGenLevelFile(useRefChannel,PHSP));
}
else{
coutERROR("Not implemented yet.");
return EffAndError();
}
bool useExtraVar = useExtraVarBool(sExtraVar); //perform once so it doesn't have to run through all the ifs every time
TMefficiencyClass extraVar = useExtraVar ? TMefficiencyClass(sExtraVar) : TMefficiencyClass();
// Set cuts on the tree
string massCut = "";
if (UseDTF) massCut = " ( B_plus_M_DTF > " + to_string(PDGMASS.B_PLUS-100) +" && B_plus_M_DTF <" + to_string(PDGMASS.B_PLUS+100)+ ") ";
else massCut = " ( B_plus_M > " + to_string(PDGMASS.B_PLUS-100) +" && B_plus_M <" + to_string(PDGMASS.B_PLUS+100)+ ") ";
coutDebug("Mass cut: " +massCut);
string sCut = getFinalCut(true, true, false, customTMbranch, gammaTM, UseOnlyMuMuEvents, useRefChannel, false, false, useExtraVar, extraVar, nExtraBin, -1, RemoveMultiple);
sCut.append(" && ");
sCut.append(massCut);
if (weighted) sCut = getWeightName(customTMbranch,gammaTM)+ "*(" + sCut + ")";
coutDebug("Full cut: " + sCut);
string minCut = getFinalCut(true,false,false,"",false,UseOnlyMuMuEvents,useRefChannel,false,false, useExtraVar, extraVar, nExtraBin, -1.0, false);
//Get number of entries before anything
coutDebug("Minimal cut: " + minCut);
TH1F *h_OG = new TH1F("h_OG","h_OG",5,5270.0,5290.0); //The B_plus mass is at PDG value in the sample
//coutDebug("Entries in h_OG: "+to_string(OG->GetEntries()));
OG->Draw("B_plus_M >> h_OG", minCut.c_str());
//Get number of entries after the BDT cut
TH1F *h_TM = new TH1F("h_TM","h_TM",1002,-1.0,1.0);;
T->Draw(TMVAmethod+"response >>h_TM", sCut.c_str());
//Calculate efficiency and its binomial error
double passEntries = h_TM->Integral();
double nentries = h_OG->Integral();
int totalEntries = Run == 0? get_gen_evts(year,useRefChannel,PHSP) : get_gen_evts(Run,useRefChannel,PHSP);
nentries = nentries*totalEntries/scale;
double effErrHi = TMath::Sqrt(passEntries*(1.0-passEntries/nentries))/nentries; //TODO error calculation
eff.value = passEntries/ nentries;
//Multiply by generator-level efficiency if requested
if (full) {
double genEvtEff = (Run==0) ? get_tables_eff(year,useRefChannel) : get_tables_eff(Run,useRefChannel);
if (genEvtEff==0.0) genEvtEff = 1.0;
eff.value = eff.value*genEvtEff;
effErrHi = effErrHi*genEvtEff;
}
coutDebug("All EvtGen entries: " + to_string(h_OG->Integral()));;
coutDebug("All EvtGen scaled entries: " + to_string(nentries));
coutDebug("MC entries passing TM: " + to_string(passEntries));
coutDebug("Selection efficiency: " + to_string(eff.value));
eff.highError = effErrHi;
eff.lowError = effErrHi;
h_OG->Clear();
h_TM->Clear();
delete T;
delete OG;
return eff;
}