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

  1. //Class containing value and errors used for efficienceis
  2. //Renata Kopecna
  3. #include "GlobalFunctions.hh"
  4. #include "Paths.hpp"
  5. #include "Design.hpp"
  6. #include "MassFit.cpp"
  7. using namespace std;
  8. using namespace RooFit;
  9. using namespace RooStats;
  10. //////////////////////////////////////////////////////
  11. /// class EffandError()
  12. //////////////////////////////////////////////////////
  13. ///
  14. /// Used for storing efficiency + hiighError - lowError
  15. ///
  16. ///
  17. /////////////////////////////////////////////////////////
  18. /// GetEfficiency
  19. //////////////////////////////////////////////////////
  20. ///
  21. /// Reads two given files, reads the yields (TVectorDouble) from them
  22. ///
  23. ///
  24. /////////////////////////////////////////////////////////
  25. /// getTruthMatchingEfficiencySimple
  26. //////////////////////////////////////////////////////
  27. ///
  28. /// Returns EffAndError for Truthmatching/selected,
  29. /// either per year or per run
  30. ///
  31. ///
  32. /////////////////////////////////////////////////////////
  33. /// getBDTEfficiencySimple
  34. //////////////////////////////////////////////////////
  35. ///
  36. /// Returns EffAndError for a given TMVAresponse cut,
  37. /// done not by fitting the mass peak but by a simple count,
  38. /// either per year or per run
  39. ///
  40. ///
  41. /////////////////////////////////////////////////////////
  42. /// getSelectionEfficiencySimple
  43. //////////////////////////////////////////////////////
  44. ///
  45. /// Returns EffAndError for a given year and Run
  46. /// from generated and selected TM events
  47. ///
  48. ///
  49. //Define EffAndError class
  50. //----------------------------------------------------------------------------------------------------------
  51. class EffAndError{
  52. public:
  53. double value;
  54. double highError;
  55. double lowError;
  56. EffAndError(){ //default constructor
  57. value = 0;
  58. highError = 0;
  59. lowError = 0;
  60. }
  61. EffAndError(double val){ //default constructor
  62. value = val;
  63. highError = 0;
  64. lowError = 0;
  65. }
  66. EffAndError(double val,double highErr, double lowErr){ //default constructor
  67. value = val;
  68. highError = highErr;
  69. lowError = lowErr;
  70. }
  71. ~EffAndError(); //destuctor
  72. };
  73. EffAndError::~EffAndError(){//destuctor
  74. }
  75. string mainSignalShape = "OneCB";
  76. //Calculate efficiency from two files
  77. //----------------------------------------------------------------------------------------------------------
  78. EffAndError GetEfficiency(TFile *fitFileNumerator, string nameNumerator, TFile *fitFileDenominator, string nameDenominator){
  79. if (fitFileNumerator == NULL){
  80. coutERROR("File " + string(fitFileNumerator->GetPath()) + " not opened!");
  81. return EffAndError(0,0,0);
  82. }
  83. if (fitFileDenominator == NULL){
  84. coutERROR("File " + string(fitFileDenominator->GetPath()) + " not opened!");
  85. return EffAndError(0,0,0);
  86. }
  87. // Get yield for numerator data
  88. TVectorD *SigYieldNumeratorVec = (TVectorD*)fitFileNumerator->Get("yield");
  89. double SigYieldNumerator = (*SigYieldNumeratorVec)[0];
  90. // Get yield for denominator data
  91. TVectorD *SigYieldDenominatorVec = (TVectorD*)fitFileDenominator->Get("yield");
  92. double SigYieldDenominator = (*SigYieldDenominatorVec)[0];
  93. double efficiency = SigYieldNumerator/SigYieldDenominator;
  94. coutDebug("Yield from " + nameNumerator + " fit:\t" + to_string(SigYieldNumerator));
  95. coutDebug("Yield from " + nameDenominator + " fit:\t" + to_string(SigYieldDenominator));
  96. coutInfo("Efficiency:\t" + to_string(efficiency));
  97. //EffAndError result = EffAndError(efficiency,EffErrHi,EffErrLo);
  98. EffAndError result = EffAndError(efficiency,0.0,0.0);
  99. coutDebug("Efficiency succesfully calculated" );
  100. return result;
  101. }
  102. //Get efficiency from counts in MC (TM is possible since background in non-TMed sample is hard to model anyway)
  103. //----------------------------------------------------------------------------------------------------------
  104. 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
  105. gROOT->SetBatch(); //ROOT stops plotting canvases
  106. EffAndError eff = EffAndError(1.0,0.0,0.0);
  107. bool useRefChannel = !PHSP && !UseOnlyMuMuEvents;
  108. //check if using reference channel for not available years
  109. if (!checkYear(std::stoi(year),true,useRefChannel,PHSP)) return eff;
  110. //load the tree from the file
  111. TChain * T = new TChain("DecayTreeTruthMatched");
  112. std::vector<string> years;
  113. if (Run == 0)years.push_back(year); //If Run==0, calculate efficiecny for separate year
  114. else years = yearsMC(useRefChannel,PHSP,Run); //Otherwise combine the years together
  115. for (auto& yr : years){
  116. T->Add(GetBDToutputFile(yr,getRunID(yr),true,useRefChannel,PHSP,KshortDecaysInVelo,false,false).c_str());
  117. coutDebug("Adding " + GetBDToutputFile(yr,getRunID(yr),true,useRefChannel,PHSP,KshortDecaysInVelo,false,false));
  118. }
  119. bool useExtraVar = useExtraVarBool(sExtraVar); //perform once so it doesn't have to run through all the ifs every time
  120. TMefficiencyClass extraVar = useExtraVar ? TMefficiencyClass(sExtraVar) : TMefficiencyClass();
  121. // Set cuts on the tree
  122. string massCut = "";
  123. if (UseDTF) massCut = " ( B_plus_M_DTF > " + to_string(PDGMASS.B_PLUS-100) +" && B_plus_M_DTF <" + to_string(PDGMASS.B_PLUS+100)+ ") ";
  124. else massCut = " ( B_plus_M > " + to_string(PDGMASS.B_PLUS-100) +" && B_plus_M <" + to_string(PDGMASS.B_PLUS+100)+ ") ";
  125. coutDebug("Mass cut: " +massCut);
  126. string sCut = getFinalCut(true, false, false, customTMbranch, gammaTM, UseOnlyMuMuEvents, useRefChannel, false, false, useExtraVar, extraVar, nExtraBin, -1, RemoveMultiple);
  127. coutDebug("sCut: " + sCut);
  128. sCut.append(" && ");
  129. sCut.append(massCut);
  130. if (weighted) sCut = getWeightName(customTMbranch,gammaTM)+"*(" + sCut + ")";
  131. coutDebug("First cut: " + sCut);
  132. //Get number of entries before TM
  133. TH1F *h_noTM = new TH1F("h_noTM","h_noTM",1002,-1.0,1.0);
  134. T->Draw(TMVAmethod+"response >> h_noTM", sCut.c_str());
  135. sCut = getFinalCut(true, true, false, customTMbranch, gammaTM, UseOnlyMuMuEvents, useRefChannel, false, false, useExtraVar, extraVar, nExtraBin, -1, RemoveMultiple);
  136. sCut.append(" && ");
  137. sCut.append(massCut);
  138. if (weighted) sCut = getWeightName(customTMbranch,gammaTM)+ "*(" + sCut + ")";
  139. coutDebug("Second cut: " + sCut);
  140. //Get number of entries after the BDT cut
  141. TH1F *h_TM = new TH1F("h_TM","h_TM",1002,-1.0,1.0);
  142. T->Draw(TMVAmethod+"response >>h_TM", sCut.c_str());
  143. //Calculate efficiency and its binomial error
  144. double passEntries = h_TM->Integral();
  145. double nentries = h_noTM->Integral();
  146. double effErrHi = TMath::Sqrt(passEntries*(1.0-passEntries/nentries))/nentries;
  147. eff.value = passEntries/ nentries;
  148. coutDebug("All MC entries: " + to_string(nentries));
  149. coutDebug("MC entries passing TM: " + to_string(passEntries));
  150. coutDebug("TM efficiency: " + to_string(eff.value));
  151. eff.highError = effErrHi;
  152. eff.lowError = effErrHi;
  153. h_noTM->Clear();
  154. h_TM->Clear();
  155. delete T;
  156. return eff;
  157. }
  158. EffAndError getBDTEfficiencySimple(string year, Double_t TMVAcut, int Run, bool UseOnlyMuMuEvents,bool PHSP,
  159. bool KshortDecaysInVelo, bool IncludeMultipleEff, bool weighted, string sExtraVar, int nExtraBin){ //TODO: check weight
  160. EffAndError eff = EffAndError(1.0,0.0,0.0);
  161. bool useRefChannel = !PHSP && !UseOnlyMuMuEvents;
  162. //check if using reference channel for not available years
  163. if (!checkYear(std::stoi(year),true,useRefChannel,PHSP)) return eff;
  164. //Get low TMVA response lower boundary
  165. double lowBDTcut = -1.0; //check if at lower limit
  166. if (TMVAmethod == "MLP") lowBDTcut = 0.0;
  167. if (TMVAcut == lowBDTcut){
  168. coutERROR("BDT cut is 100% effective at "+ to_string(lowBDTcut) + "! returning efficiency 1+-0.");
  169. return eff;
  170. }
  171. //load the tree from the file
  172. TChain * T = new TChain("DecayTreeTruthMatched");
  173. std::vector<string> years;
  174. if (Run == 0){ //If Run==0, calculate efficiecny for separate year
  175. years.push_back(year);
  176. }
  177. else years = yearsMC(useRefChannel,PHSP,Run); //Otherwise combine the years together
  178. for (auto& yr : years){
  179. int RunID = (yr == "2011" || yr == "2012") ? 1:2;
  180. T->Add(GetBDToutputFile(yr,RunID,true,useRefChannel,PHSP,KshortDecaysInVelo,false,false).c_str());
  181. }
  182. bool useExtraVar = useExtraVarBool(sExtraVar); //perform once so it doesn't have to run through all the ifs every time
  183. TMefficiencyClass extraVar = useExtraVar ? TMefficiencyClass(sExtraVar) : TMefficiencyClass();
  184. gROOT->SetBatch(); //ROOT stops plotting canvases
  185. // Set cuts on the tree
  186. TString massCut = "";
  187. if (UseDTF) massCut = " ( B_plus_M_DTF > " + to_string(PDGMASS.B_PLUS-100) +" && B_plus_M_DTF <" + to_string(PDGMASS.B_PLUS+100)+ ") ";
  188. else massCut = " ( B_plus_M > " + to_string(PDGMASS.B_PLUS-100) +" && B_plus_M <" + to_string(PDGMASS.B_PLUS+100)+ ") ";
  189. //add vetos
  190. string sCut = getFinalCut(true, true, false, "", gammaTMdefault, UseOnlyMuMuEvents, useRefChannel, false, false, useExtraVar, extraVar, nExtraBin, lowBDTcut, !IncludeMultipleEff);
  191. string LLorDD = string("&& (KshortDecayInVeLo == ") + (KshortDecaysInVelo ? "1":"0") + ")";
  192. sCut.append(" && ");
  193. sCut.append(massCut);
  194. if(Kst2Kspiplus) sCut.append(LLorDD);
  195. if (weighted) sCut = getWeightName("",gammaTMdefault)+"*(" + sCut + ")";
  196. coutDebug("Using cut: "+sCut);
  197. //TODO!!!!! Naming convension for including multiple efficiency!!!!!
  198. //Get number of entries before the BDT cut
  199. TH1F *h_BDTresponseMCAll = new TH1F("h_"+TMVAmethod+"responseAll","h_"+TMVAmethod+"responseAll",1002,lowBDTcut,1.0);
  200. T->Draw(TMVAmethod+"response >> h_"+TMVAmethod+"responseAll", sCut.c_str());
  201. sCut = getFinalCut(true, true, false, "", gammaTMdefault, UseOnlyMuMuEvents, useRefChannel, false, false, useExtraVar, extraVar, nExtraBin, TMVAcut, true);
  202. sCut.append(" && ");
  203. sCut.append(massCut);
  204. if (Kst2Kspiplus) sCut.append(LLorDD);
  205. if (weighted) sCut = getWeightName("",gammaTMdefault)+"*(" + sCut + ")";
  206. coutDebug("Using cut: "+sCut);
  207. //Get number of entries after the BDT cut
  208. TH1F *h_BDTresponseMCtmp = new TH1F("h_"+TMVAmethod+"response","h_"+TMVAmethod+"response",1002,lowBDTcut,1.0);
  209. T->Draw(TMVAmethod+"response >> h_"+TMVAmethod+"response", sCut.c_str());
  210. //Calculate efficiency and its binomial error
  211. double passEntries = h_BDTresponseMCtmp->Integral();
  212. double nentries = h_BDTresponseMCAll->Integral();
  213. double effErrHi = TMath::Sqrt(passEntries*(1.0-passEntries/nentries))/nentries;
  214. eff.value = passEntries/ nentries;
  215. coutDebug("All MC entries: " + to_string(nentries));
  216. coutDebug("MC entries passing TMVA cut " + to_string(TMVAcut) + ": " + to_string(passEntries));
  217. coutDebug("TMVA cut" + to_string(TMVAcut) + " efficiency: " + to_string(eff.value));
  218. eff.highError = effErrHi;
  219. eff.lowError = effErrHi;
  220. h_BDTresponseMCAll->Clear();
  221. h_BDTresponseMCtmp->Clear();
  222. delete T;
  223. coutDebug("BDT efficiency for cut at " + to_string(TMVAcut) + " calculated!" );
  224. return eff;
  225. }
  226. //Get selection efficiency from counts in MC
  227. //----------------------------------------------------------------------------------------------------------
  228. 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
  229. gROOT->SetBatch(); //ROOT stops plotting canvases
  230. EffAndError eff = EffAndError(1.0,0.0,0.0);
  231. //check if using reference channel for not available years
  232. if (!checkYear(std::stoi(year),true,useRefChannel,PHSP)) return eff;
  233. //Scaling factor, pretty much the number of generated events
  234. //For easier division it's a double right away
  235. double scale = get_generated_events(PHSP);
  236. std::vector<string> years;
  237. if (Run == 0)years.push_back(year); //If Run==0, calculate efficiecny for separate year
  238. else years = yearsMC(useRefChannel,PHSP,Run); //Otherwise combine the years together
  239. //load the tree from the file
  240. TChain * T = new TChain("DecayTreeTruthMatched");
  241. for (auto& yr : years){
  242. T->Add(GetBDToutputFile(yr,getRunID(yr),true,useRefChannel,PHSP,KshortDecaysInVelo,false,false).c_str());
  243. coutDebug("Adding " + GetBDToutputFile(yr,getRunID(yr),true,useRefChannel,PHSP,KshortDecaysInVelo,false,false));
  244. }
  245. //Kst2Kpluspi0Resolved case
  246. TChain* OG = 0;
  247. if(Kst2Kpluspi0Resolved){
  248. OG=new TChain("DecayTree");
  249. OG->Add(GetGenLevelFile(useRefChannel,PHSP).c_str());
  250. coutDebug("Adding " + GetGenLevelFile(useRefChannel,PHSP));
  251. }
  252. else{
  253. coutERROR("Not implemented yet.");
  254. return EffAndError();
  255. }
  256. bool useExtraVar = useExtraVarBool(sExtraVar); //perform once so it doesn't have to run through all the ifs every time
  257. TMefficiencyClass extraVar = useExtraVar ? TMefficiencyClass(sExtraVar) : TMefficiencyClass();
  258. // Set cuts on the tree
  259. string massCut = "";
  260. if (UseDTF) massCut = " ( B_plus_M_DTF > " + to_string(PDGMASS.B_PLUS-100) +" && B_plus_M_DTF <" + to_string(PDGMASS.B_PLUS+100)+ ") ";
  261. else massCut = " ( B_plus_M > " + to_string(PDGMASS.B_PLUS-100) +" && B_plus_M <" + to_string(PDGMASS.B_PLUS+100)+ ") ";
  262. coutDebug("Mass cut: " +massCut);
  263. string sCut = getFinalCut(true, true, false, customTMbranch, gammaTM, UseOnlyMuMuEvents, useRefChannel, false, false, useExtraVar, extraVar, nExtraBin, -1, RemoveMultiple);
  264. sCut.append(" && ");
  265. sCut.append(massCut);
  266. if (weighted) sCut = getWeightName(customTMbranch,gammaTM)+ "*(" + sCut + ")";
  267. coutDebug("Full cut: " + sCut);
  268. string minCut = getFinalCut(true,false,false,"",false,UseOnlyMuMuEvents,useRefChannel,false,false, useExtraVar, extraVar, nExtraBin, -1.0, false);
  269. //Get number of entries before anything
  270. coutDebug("Minimal cut: " + minCut);
  271. 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
  272. //coutDebug("Entries in h_OG: "+to_string(OG->GetEntries()));
  273. OG->Draw("B_plus_M >> h_OG", minCut.c_str());
  274. //Get number of entries after the BDT cut
  275. TH1F *h_TM = new TH1F("h_TM","h_TM",1002,-1.0,1.0);;
  276. T->Draw(TMVAmethod+"response >>h_TM", sCut.c_str());
  277. //Calculate efficiency and its binomial error
  278. double passEntries = h_TM->Integral();
  279. double nentries = h_OG->Integral();
  280. int totalEntries = Run == 0? get_gen_evts(year,useRefChannel,PHSP) : get_gen_evts(Run,useRefChannel,PHSP);
  281. nentries = nentries*totalEntries/scale;
  282. double effErrHi = TMath::Sqrt(passEntries*(1.0-passEntries/nentries))/nentries; //TODO error calculation
  283. eff.value = passEntries/ nentries;
  284. //Multiply by generator-level efficiency if requested
  285. if (full) {
  286. double genEvtEff = (Run==0) ? get_tables_eff(year,useRefChannel) : get_tables_eff(Run,useRefChannel);
  287. if (genEvtEff==0.0) genEvtEff = 1.0;
  288. eff.value = eff.value*genEvtEff;
  289. effErrHi = effErrHi*genEvtEff;
  290. }
  291. coutDebug("All EvtGen entries: " + to_string(h_OG->Integral()));;
  292. coutDebug("All EvtGen scaled entries: " + to_string(nentries));
  293. coutDebug("MC entries passing TM: " + to_string(passEntries));
  294. coutDebug("Selection efficiency: " + to_string(eff.value));
  295. eff.highError = effErrHi;
  296. eff.lowError = effErrHi;
  297. h_OG->Clear();
  298. h_TM->Clear();
  299. delete T;
  300. delete OG;
  301. return eff;
  302. }