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

  1. //Helper functions
  2. //Yes, they are in a header, because ROOT
  3. //Renata Kopecna
  4. #ifndef UTILS_HPP
  5. #define UTILS_HPP
  6. #include "GlobalFunctions.hh"
  7. #include "Paths.hpp"
  8. #include "MassFit.hpp"
  9. #include <boost/algorithm/string.hpp>
  10. //I HATE ROOT! It's just way easier for root to have functions defined in a header with cross-references.... sigh
  11. //Forward declarations from Paths.hpp
  12. string GetInputFile(string year, string magnet, bool preSelected, bool MC, bool ReferenceChannel, bool PHSP, bool B0, bool K1, bool Inc, bool smallSample);
  13. string GetBDTinputFile(string year, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo);
  14. string GetBDToutputFile(string year, int Run, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo, bool UseLowQ2Range, bool reweighted);
  15. string GetBDToutputFile(int Run, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo, bool UseLowQ2Range, bool reweighted);
  16. string returnFileAddress(string year, int Run, string magnet, bool Preselected, bool BDTed, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo);
  17. /////////////////////////////////////////////
  18. //
  19. // Get basic names and trees
  20. //
  21. /////////////////////////////////////////////
  22. string correct_magnet_string(string magnet){
  23. boost::to_lower(magnet);
  24. if (magnet != "both" && magnet != "up" && magnet != "down"){
  25. coutWarning("Wrong magnet polarity used! Setting magnet to both!");
  26. return magnet = "both";
  27. }
  28. else return magnet;
  29. }
  30. string treeName(bool MC, bool Preselected){
  31. if (MC && Preselected) return "DecayTreeTruthMatched";
  32. else if (!Preselected) return "b2KstKpi0mumuResolvedTuple/DecayTree";
  33. else return "DecayTree";
  34. }
  35. vector <string> get_magnet_vector(string magnet){
  36. magnet = correct_magnet_string(magnet);
  37. if (magnet == "both"){
  38. return {"down","up"};
  39. }
  40. else return {magnet};
  41. }
  42. TChain *get_basic_TChain(string magnet, vector<string> years, bool Preselected, bool MC, bool ReferenceChannel, bool PHSP, bool B0, bool K1, bool Inc){
  43. TChain* tree = new TChain(treeName(MC,Preselected).c_str());
  44. coutInfo("Reading data from TTree... ");
  45. for (auto& yr : years){
  46. for (auto& mag: get_magnet_vector(magnet)){
  47. string path = GetInputFile(yr,mag,Preselected,MC, ReferenceChannel, PHSP, B0, K1, Inc, false);
  48. coutDebug("Adding " + path);
  49. tree->Add(path.c_str()); //TODO: no acces to not-preselected inclusive sample
  50. }
  51. }
  52. return tree;
  53. }
  54. TChain *get_weighted_TChain(vector<string> years, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo){
  55. TChain* tree = new TChain(treeName(MC,true).c_str());
  56. for (auto& yr : years){
  57. tree->Add(GetBDTinputFile(yr,MC,ReferenceChannel,PHSP,KshortDecayInVelo).c_str());
  58. coutDebug("Adding " +GetBDTinputFile(yr,MC,ReferenceChannel,PHSP,KshortDecayInVelo));
  59. }
  60. return tree;
  61. }
  62. TChain *get_BDT_TChain(vector<string> years, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo, bool reweighted){
  63. bool UseLowQ2Range = false;
  64. TChain* tree = new TChain(treeName(MC,true).c_str());
  65. for (auto& yr : years){
  66. tree->Add(GetBDToutputFile(yr,getRunID(yr),MC,ReferenceChannel,PHSP,KshortDecayInVelo,UseLowQ2Range,reweighted).c_str());
  67. coutDebug("Adding " +GetBDToutputFile(yr,getRunID(yr),MC,ReferenceChannel,PHSP,KshortDecayInVelo,UseLowQ2Range,reweighted));
  68. }
  69. return tree;
  70. }
  71. TChain *get_BDT_TChain(string year, int Run, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo, bool reweighted){
  72. bool UseLowQ2Range = false;
  73. vector<string> years;
  74. if (Run == 0) years.push_back(year);
  75. else years = yearsVector(MC,ReferenceChannel,PHSP,Run);
  76. TChain* tree = new TChain(treeName(MC,true).c_str());
  77. for (auto& yr : years){
  78. tree->Add(GetBDToutputFile(yr,getRunID(yr),MC,ReferenceChannel,PHSP,KshortDecayInVelo,UseLowQ2Range,reweighted).c_str());
  79. coutDebug("Adding " +GetBDToutputFile(yr,getRunID(yr),MC,ReferenceChannel,PHSP,KshortDecayInVelo,UseLowQ2Range,reweighted));
  80. }
  81. return tree;
  82. }
  83. TChain *get_FinalOutput_TChain(vector<string> years, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo){ //TODO fix Run vs year
  84. TChain* tree = new TChain(treeName(MC,true).c_str());
  85. for (auto& yr : years){
  86. //tree->Add(GetFinalOutputFile(yr,1,MC,ReferenceChannel,PHSP,KshortDecayInVelo).c_str());
  87. }
  88. return tree;
  89. }
  90. ///////////////////////////////////////////////
  91. //
  92. // Cut functions
  93. //
  94. ///////////////////////////////////////////////
  95. string getTMcut(bool TM,bool notTM, string customTMbranch, bool gammaTM){
  96. string finalCut = "";
  97. if (TM && notTM){
  98. coutERROR("Cannot cut on TM == 1 && TM == 0! Returning an empty string.");
  99. return "";
  100. }
  101. if (TM){
  102. if (customTMbranch == "") finalCut.append("(" + TMbranch + "==1)");
  103. else finalCut.append("(" + customTMbranch + "==1)");
  104. //Check if the TM branch is not BKGCAT
  105. if (finalCut.find("BKGCAT") == string::npos){
  106. //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
  107. if (gammaTM) finalCut.append(" && (" + gammaTMbranch + "<4)");
  108. else finalCut.append(" && (" + gammaTMbranch + "<6)");
  109. }
  110. }
  111. if (notTM){
  112. if (customTMbranch == "") finalCut.append("(" + TMbranch + "==0)");
  113. else finalCut.append("(" + customTMbranch + "==0)");
  114. if (finalCut.find("BKGCAT") == string::npos){
  115. //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
  116. if (gammaTM) finalCut.append(" || (" + gammaTMbranch + ">3)");
  117. else finalCut.append(" || (" + gammaTMbranch + ">5)");
  118. }
  119. }
  120. coutTest("TM cut:" + finalCut);
  121. return finalCut;
  122. }
  123. string getJpsicut(){
  124. return "(8.68e6 < Q2 && Q2 < 10.09e6)"; //q2Cuts = "nDiMuonMassBin == 9";
  125. }
  126. string getMuMucut(){
  127. return "(Q2 < 0.98e6 || (1.1e6 < Q2 && Q2 < 8.0e6) || (11.0e6 < Q2 && Q2 < 12.5e6) || Q2 > 15.0e6)";
  128. }
  129. string getFullCut(bool UseOnlyMuMuEvents, bool UseOnlyJpsiEvents, bool SplitInQ2, bool UseLowQ2Range, bool useExtraVar, TMefficiencyClass extraVar,int nExtraBin, double TMVAcut){
  130. string finalCut = "";
  131. string q2Cut = "";
  132. if (UseOnlyMuMuEvents) q2Cut = getMuMucut();
  133. else if (UseOnlyJpsiEvents) q2Cut = getJpsicut();
  134. else if (SplitInQ2){
  135. coutWarning("Using SplitInQ2! Always use with MuMu events!");
  136. if (UseLowQ2Range) q2Cut = "(Q2 < 0.98e6 || (1.1e6 < Q2 && Q2 < 8.0e6))"; //q2Cuts = "nDiMuonMassBin < 9 || nDiMuonMassBin != 2";
  137. else q2Cut = "((11.0e6 < Q2 && Q2 < 12.5e6) || Q2 > 15.0e6)"; //q2Cuts = "nDiMuonMassBin > 9 || nDiMuonMassBin != 12";
  138. }
  139. else q2Cut = "(Q2 >0)"; //dummy cut in order to not having to deal with && at a beggining of the string
  140. finalCut.append(q2Cut);
  141. if (useExtraVar){
  142. string extraVarCut = "";
  143. double lowCut = extraVar.isEquidistant ? extraVar.binEdgesEquidistant.at(nExtraBin) : extraVar.binEdges.at(nExtraBin);
  144. double upperCut = extraVar.isEquidistant ? extraVar.binEdgesEquidistant.at(nExtraBin+1) : extraVar.binEdges.at(nExtraBin+1);
  145. extraVarCut = "(" + to_string(lowCut) + " < " + extraVar.cut+" && " + extraVar.cut+ "<= " + to_string(upperCut) + ")";
  146. coutDebug(extraVarCut);
  147. finalCut.append(" && ");
  148. finalCut.append(extraVarCut);
  149. }
  150. if (TMVAcut > -1.0){
  151. finalCut.append(" && ");
  152. finalCut.append(" (" + string(TMVAmethod) + "response > " + to_string(TMVAcut) + ")");
  153. }
  154. coutTest("Main cut: " + finalCut);
  155. return finalCut ;
  156. }
  157. string getAloneBranch(bool MC, bool TM, string customTMbranch, bool gammaTM){
  158. string customTag = "";
  159. if (MC){
  160. if (!TM) customTag = "NotTM";
  161. else {
  162. if (customTMbranch == "") customTMbranch = TMbranch;
  163. if (customTMbranch == "TMedBKGCAT") customTag = "";
  164. if (customTMbranch == "TMed"){
  165. if (gammaTM) customTag = "_TMed";
  166. else customTag = "_TMed_rndGamma";
  167. }
  168. }
  169. }
  170. return "IsAloneAt" + customTag;
  171. }
  172. string getMultipleCut(bool MC, bool TM, string customTMbranch, bool gammaTM, double TMVAcut){
  173. string aloneBranch = getAloneBranch(MC,TM,customTMbranch, gammaTM);
  174. string cut = (TMVAcut > -1.0) ? string("<=" + to_string(TMVAcut)) : "==0.0";
  175. coutTest("Alone cut: " + aloneBranch + cut);
  176. return aloneBranch + cut;
  177. }
  178. 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){
  179. string fullCut = getFullCut(UseOnlyMuMuEvents, UseOnlyJpsiEvents, SplitInQ2, UseLowQ2Range, useExtraVar, extraVar, nExtraBin, TMVAcut);
  180. string TMcut = MC ? getTMcut(TM,notTM,customTMbranch,gammaTM) : "";
  181. if (TMcut != "") TMcut = " && (" + TMcut + ")";
  182. string multipleCut = removeMultiple ? string( " && (" +getMultipleCut(MC,TM,customTMbranch,gammaTM,TMVAcut) + ")") : "";
  183. return fullCut + TMcut + multipleCut;
  184. }
  185. //Buggy 2015 MC needs to be removed and replaced by 2016
  186. //TODO: make sure it's not loaded twice everywhere
  187. string checkIf2015MC(string year, bool MC, bool Reference, bool PHSP){
  188. if (Kst2Kpluspi0Resolved && MC && !Reference && !PHSP && year== "2015") return "2016";
  189. else return year;
  190. }
  191. ///////////////////////////////////////////////
  192. //
  193. // Sanity checks
  194. //
  195. /////////////////////////////////////////////
  196. bool checkMC(bool &MC, bool ReferenceChannel, bool PHSP, bool mutuallyExclusive){
  197. if (!MC && PHSP){//if PHSP or reference channel, set MC to true
  198. coutWarning("PHSP or Reference channel option selected, setting MC to true");
  199. MC = true;
  200. }
  201. if (mutuallyExclusive && ReferenceChannel && PHSP){
  202. coutERROR("You cannot select both Reference channel and PHSP! Abort.");
  203. return false;
  204. }
  205. return true;
  206. }
  207. bool checkMC(bool ReferenceChannel, bool PHSP){
  208. if (ReferenceChannel && PHSP){
  209. coutERROR("You cannot select both Reference channel and PHSP! Abort.");
  210. return false;
  211. }
  212. return true;
  213. }
  214. bool checkQ2Range(bool UseOnlyJpsi, bool UseOnlyMuMu){
  215. if (UseOnlyJpsi && UseOnlyMuMu){
  216. coutERROR("Make up your mind! Either Jpsi or mumu channel, it cannot be both! Program failed");
  217. return false;
  218. }
  219. return true;
  220. }
  221. bool checkTM(bool MC, bool &TM, bool &nonTM, bool Preselected){
  222. if ( (TM || nonTM) && !MC){
  223. coutWarning("Data is not TruthMatched! Setting TM and nonTM to false!");
  224. TM = false; //Keep nonTM as it is for the MC fit to get the shape
  225. }
  226. if ( (TM || nonTM) && !Preselected){
  227. coutWarning("Stripped MC is not TruthMatched! Setting TM to false!");
  228. TM = false;
  229. nonTM = false;
  230. }
  231. if (TM && nonTM){
  232. coutERROR("Cannot fit TM==1 and TM==0 data at the same time! Make up your mind. Abort.");
  233. return false;
  234. }
  235. return true;
  236. }
  237. bool checkKshort(bool &KshortDecaysInVelo){
  238. if (!Kst2Kspiplus && KshortDecaysInVelo){
  239. coutWarning("No LL/DD tracks in KplusPizero channel! Setting KshortDecaysInVelo to false!");
  240. KshortDecaysInVelo = false;
  241. }
  242. return true;
  243. }
  244. bool checkRefYear(string year){
  245. if (Kst2Kspiplus && (year == "2015" || year =="2017" || year == "2018" )){
  246. coutERROR("Reference channel is only available for 2011, 2012 and 2016!");
  247. return false;
  248. }
  249. if (!Kst2Kspiplus && (year =="2017" || year == "2018" )){
  250. coutERROR("Reference channel is only available for 2011, 2012, 2015 and 2016!");
  251. return false;
  252. }
  253. return true;
  254. }
  255. bool checkEntries(TTree *tree){
  256. Int_t nEvents = tree->GetEntries();
  257. if(nEvents == 0){
  258. coutERROR("Entries in data TTree " + string(tree->GetName()) + " are empty. Abort!");
  259. return false;
  260. }
  261. return true;
  262. }
  263. bool checkYear(int year, bool MC, bool ReferenceChannel, bool PHSP){
  264. bool flag = false;
  265. if (!MC){
  266. if (year == 2011 || year == 2012|| year == 2015 || year == 2016 || year == 2017 || year == 2018 ) flag=true;
  267. else flag=false;
  268. }
  269. else{
  270. if (KshortChannel){ //KS
  271. if (ReferenceChannel){
  272. if (year == 2011 || year == 2012|| year == 2016) flag=true;
  273. else flag=false;
  274. }
  275. else if (PHSP){
  276. if (year == 2011 || year == 2012|| year == 2015 || year == 2016 || year == 2017 || year == 2018 ) flag=true;
  277. else flag=false;
  278. }
  279. else{
  280. if (year == 2011 || year == 2012|| year == 2015 || year == 2016 || year == 2017 || year == 2018 ) flag=true;
  281. else flag=false;
  282. }
  283. }
  284. else{ //K+pi0
  285. if (ReferenceChannel){
  286. if (year == 2011 || year == 2012|| year == 2015 || year == 2016) flag=true;
  287. else flag=false;
  288. }
  289. else if (PHSP){
  290. if (year == 2011 || year == 2012|| year == 2015 || year == 2016 || year == 2017 || year == 2018) flag=true;
  291. else flag=false;
  292. }
  293. else{
  294. if (year == 2011 || year == 2012|| year == 2015 || year == 2016 || year == 2017 || year == 2018) flag=true;
  295. else flag=false;
  296. }
  297. }
  298. }
  299. if (!flag) coutERROR("Wrong year input! Your input is " + to_string(year)+ ". Abort.");
  300. return flag;
  301. }
  302. bool checkRun(int Run){
  303. if(Run != 1 && Run != 2 && Run != 12){
  304. coutERROR("Invalid Run number given: >> " + to_string( Run) + " << . Use only Run 1, Run 2 or Run 12! Exit now.");
  305. return 0;
  306. }
  307. return 1;
  308. }
  309. ///////////////////////////////////////////////
  310. //
  311. // Get correct names and tags
  312. //
  313. /////////////////////////////////////////////
  314. string getTMtag(string customTMbranch){
  315. if (customTMbranch == "") customTMbranch = TMbranch;
  316. if (customTMbranch == "TMedBKGCAT") return "_BKGCAT";
  317. if (customTMbranch == "TMed") return "_IDTM";
  318. if (customTMbranch == "TMed_noPi0") return "_noPi0_IDTM";
  319. coutERROR("Wrong customTM branch! Returning string 'wrong'");
  320. return "wrong";
  321. }
  322. string getTMtag(string customTMbranch, bool gammaTM){
  323. if (customTMbranch == "") customTMbranch = TMbranch;
  324. if (customTMbranch == "TMedBKGCAT") return "_BKGCAT";
  325. if (customTMbranch == "TMed") return "_IDTM"+ string(gammaTM ? "" : "_rndGamma");;
  326. if (customTMbranch == "TMed_noPi0") return "_noPi0_IDTM"+ string(gammaTM ? "" : "_rndGamma");;
  327. coutERROR("Wrong customTM branch! Returning string 'wrong'");
  328. return "wrong";
  329. }
  330. string getWeightName(string customTMbranch, bool gammaTM){
  331. if (customTMbranch == "") customTMbranch = TMbranch;
  332. if (customTMbranch == "TMedBKGCAT") return "weight2D_"+firstMCweight;
  333. if (customTMbranch == "TMed") return "weight2D_"+firstMCweight + "_TM" + string(gammaTM ? "" : "_rndGamma");
  334. if (customTMbranch == "TMed_noPi0") return "weight2D_"+firstMCweight + "_noPi0TM";
  335. coutERROR("Wrong customTMbranch name! Returning an empty string.");
  336. return "";
  337. }
  338. std::string getDataTypeTag(bool MC, bool Reference, bool PHSP, bool B0, bool K1, bool Inc){
  339. if (!MC) return "Data";
  340. else{
  341. if (PHSP) return "MC PHSP";
  342. else{
  343. if (B0) return Reference ? "MC B0toKstJpsi" : "MC B0toKstMuMu";
  344. else if (K1) return Reference ? "MC BtoK1Jpsi" : "MC BtoK1MuMu";
  345. else if (Inc) return Reference ? "MC BtoXJpsi" : "MC BtoXMuMu";
  346. else return Reference ? "Reference MC" : "Signal MC";
  347. }
  348. }
  349. }
  350. string getDataTypeTag(bool MC, bool Reference, bool PHSP){
  351. return getDataTypeTag(MC, Reference, PHSP, false, false, false);
  352. }
  353. string getYearRunTag(int Run, string year){
  354. if (Run == 0) return "Year " + year;
  355. else return "Run " + to_string(Run);
  356. }
  357. /////////////////////////////////////////////
  358. //
  359. // Bin edges for a similarly populated bins
  360. //
  361. /////////////////////////////////////////////
  362. void getSimilarlyPopulatedBins(TH1D *histogram, int desiredBins, int nBins){
  363. //rebin (THIS ASSUMES THE ORIGINAL BIN WIDTH IS ONE!!!)
  364. int maxBinContent = histogram->GetEntries()/desiredBins;
  365. TAxis *axis = histogram->GetXaxis();
  366. Double_t xEdges[desiredBins+1];
  367. xEdges[0] = axis->GetBinLowEdge(1);
  368. int i = 0;
  369. for (int b = 1; b <desiredBins+1; b++){
  370. int content = 0;
  371. while (content < maxBinContent){
  372. content = content+histogram->GetBinContent(i);
  373. i++;
  374. }
  375. xEdges[b] = axis->GetBinLowEdge(i);
  376. i++;
  377. }
  378. xEdges[desiredBins] = axis->GetBinUpEdge(nBins);
  379. for (int b = 0; b<desiredBins+1; b++){
  380. cout << xEdges[b] << endl;
  381. }
  382. return;
  383. }
  384. void getSimilarlyPopulatedBinsVar(string var, int nBins, double lowEdge, double highEdge, int desiredBins, string year, string magnet, int Run, bool ReferenceChannel, bool PHSP){
  385. gStyle -> SetOptStat(0);
  386. gROOT->SetBatch(kTRUE);
  387. TH1::SetDefaultSumw2(kTRUE);
  388. //Load all files
  389. coutInfo("Opennig the trees");
  390. TChain *tree= new TChain("DecayTreeTruthMatched");
  391. //Open the file(s)
  392. if (Run==0){
  393. tree->Add(returnFileAddress(year, getRunID(year), magnet, true, false, true, ReferenceChannel, PHSP, false).c_str());
  394. coutDebug("Adding " + returnFileAddress(year, getRunID(year), magnet, true, false, true, ReferenceChannel, PHSP, false));
  395. }
  396. else{
  397. for (auto yr: yearsMC(ReferenceChannel, PHSP, Run)){
  398. tree->Add(returnFileAddress(yr, getRunID(yr), magnet, true, false, true, ReferenceChannel, PHSP, false).c_str());
  399. coutDebug("Adding " + returnFileAddress(yr, getRunID(yr), magnet, true, false, true, ReferenceChannel, PHSP, false));
  400. }
  401. }
  402. //activate all branches
  403. tree->SetBranchStatus("*",1);
  404. //Draw the histogram
  405. TH1D *h_tmp = new TH1D ("h_tmp", "h_tmp", nBins,lowEdge,highEdge);
  406. tree->Draw(Form("%s>>h_tmp",var.c_str()));
  407. //Get the binnings
  408. getSimilarlyPopulatedBins(h_tmp,desiredBins, nBins);
  409. //free da memory
  410. delete h_tmp;
  411. delete tree;
  412. return;
  413. }
  414. /////////////////////////////////////////////
  415. //
  416. // Get result from a fit file
  417. // Comment out the content of the functions in order to compile getPathForPython *facepalm
  418. //
  419. /////////////////////////////////////////////
  420. RooFitResult* getResult(TFile *fitFile){
  421. RooFitResult* fitResult;
  422. fitFile->GetObject("fitresult_pdf_data",fitResult);
  423. if (verboseLevel < 2) fitResult->Print();
  424. return fitResult;
  425. }
  426. RooRealVar* getVarFromResult(RooFitResult *fitResult, string name){
  427. RooRealVar *myVar = (RooRealVar*)fitResult->floatParsFinal().find(name.c_str());
  428. return myVar;
  429. }
  430. double getBplusMeanFromResult(TFile* fitFile){
  431. RooRealVar *mass = getVarFromResult(getResult(fitFile),"sig_mean");
  432. return mass->getVal();
  433. }
  434. //Read the yields from a fit file
  435. double getSigYield(TFile *fitFile){
  436. TVectorD *yield = (TVectorD*)fitFile->Get("yield");
  437. return (*yield)[0];
  438. }
  439. double getSigYieldErr(TFile *fitFile){
  440. TVectorD *yield_err = (TVectorD*)fitFile->Get("yield_err");
  441. return (*yield_err)[0];
  442. }
  443. double getBkgYield(TFile *fitFile){
  444. TVectorD *bkg = (TVectorD*)fitFile->Get("background");
  445. return (*bkg)[0];
  446. }
  447. double getBkgYieldErr(TFile *fitFile){
  448. TVectorD *bkg_eff = (TVectorD*)fitFile->Get("background_err");
  449. return (*bkg_eff)[0];
  450. }
  451. double getEffSigma(TFile *fitFile){
  452. TVectorD *sigma = (TVectorD*)fitFile->Get("sigma_eff");
  453. return (*sigma)[0];
  454. }
  455. /////////////////////////////////////////////
  456. //
  457. // Histogram/graph helpers
  458. //
  459. /////////////////////////////////////////////
  460. TH1D *convertTGraph(TGraph *graph){
  461. //Possibly fix tihs at some point to be generally repflecting TMefficiencyClass
  462. double binEdges[7] = {0.1e6, 4.0e6, 8.0e6, 11.0e6, 12.5e6, 15.0e6, 20.0e6};
  463. TH1D *hist = new TH1D("hist","hist",6,binEdges);
  464. auto nPoints = graph->GetN(); // number of points in your TGraph
  465. for(int i=0; i < nPoints; ++i) {
  466. double x,y;
  467. graph->GetPoint(i, x, y);
  468. hist->Fill(x,y); // ?
  469. }
  470. for (int b=0; b < hist->GetXaxis()->GetNbins(); b++){
  471. hist->SetBinError(b+1,0);
  472. }
  473. return hist;
  474. }
  475. /////////////////////////////////////////////
  476. //
  477. // Get numbers of MC events
  478. //
  479. /////////////////////////////////////////////
  480. double generated_basic_events = 10000.0;
  481. double generated_basic_events_PHSP = 1000.0;
  482. double get_generated_events(bool PHSP){
  483. if (PHSP) return generated_basic_events_PHSP;
  484. else return generated_basic_events;
  485. }
  486. vector<int> generated_signal_events_down = {507551, 514015, 0, 1000281, 1151738, 1235528};
  487. vector<int> generated_signal_events_up = {502787, 500458, 0, 1000281, 1153816, 1196153};
  488. vector<int> generated_reference_events_down = {1011831, 1003888, 1007712, 1010609, 0, 0};
  489. vector<int> generated_reference_events_up = {1007920, 1000278, 1009484, 1000281, 0, 0};
  490. vector<int> generated_PHSP_events_down = {85736, 226933, 95323, 264917, 246457, 291850};
  491. vector<int> generated_PHSP_events_up = {86004, 226430, 94980, 267674, 242673, 299252};
  492. 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
  493. 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
  494. vector<double> gen_tables_reference_efficiency_down = {0.14388, 0.14769, 0.1581, 0.1585, 0.1585, 0.1585}; //2017+2018 taken as 2016
  495. vector<double> gen_tables_reference_efficiency_up = {0.14422, 0.14787, 0.1574, 0.1590, 0.1590, 0.1590}; //2017+2018 taken as 2016
  496. vector<int> yield_signal_events = {5451, 4906, 4096, 10382, 15994, 14919};
  497. vector<int> yield_signal_events_err = {70, 64, 1, 96, 15, 116};
  498. vector<int> yield_reference_events = {19730, 17579, 18392, 23965, 0, 0};
  499. vector<int> yield_reference_events_err = {135, 127, 130, 149, 0, 0};
  500. vector<int> yield_PHSP_events = {14091, 33086, 13530, 48135, 54030, 61641};
  501. vector<int> yield_PHSP_events_err = {113, 174, 111, 209, 221, 237};
  502. vector<int> yield_signal_events_notTM = {7056, 6587, 6354, 15652, 20207, 19734};
  503. vector<int> yield_signal_events_notTM_err = {456, 61, 81, 55, 368, 222};
  504. vector<int> yield_reference_events_notTM = {24375, 22698, 23403, 30303, 0, 0};
  505. vector<int> yield_reference_events_notTM_err = {236, 123, 143, 12, 0, 0};
  506. vector<int> yield_signal_events_notTM_unique = {5854, 5304, 5155, 13086, 17055, 16374};
  507. vector<int> yield_signal_events_notTM_unique_err = {89, 106, 86, 169, 172, 211};
  508. vector<int> yield_reference_events_notTM_unique = {20564, 18772, 19204, 25140, 0, 0};
  509. vector<int> yield_reference_events_notTM_unique_err = {210, 123, 89, 167, 0, 0};
  510. int get_position_from_year(string year){
  511. int position = year.back() - '0'; //get last char of a string and convert it to an int
  512. return position>4 ? position-3 : position-1; //11->0, 12->1, 15->2, 16->3, ...
  513. }
  514. int get_gen_evts(string year, bool ReferenceChannel, bool PHSP){
  515. int pos = get_position_from_year(year);
  516. if (ReferenceChannel) return generated_reference_events_down.at(pos) + generated_reference_events_up.at(pos);
  517. if (PHSP) return generated_PHSP_events_down.at(pos) + generated_PHSP_events_up.at(pos);
  518. return generated_signal_events_down.at(pos) + generated_signal_events_up.at(pos);
  519. }
  520. int get_gen_evts(int Run, bool ReferenceChannel, bool PHSP){
  521. int yield = 0;
  522. for (auto yr: yearsMC(ReferenceChannel,PHSP,Run)) yield += get_gen_evts(yr,ReferenceChannel,PHSP);
  523. return yield;
  524. }
  525. int get_selected_evts(string year, bool ReferenceChannel, bool PHSP){
  526. int pos = get_position_from_year(year);
  527. if (ReferenceChannel) return yield_reference_events.at(pos);
  528. if (PHSP) return yield_PHSP_events.at(pos);
  529. return yield_signal_events.at(pos);
  530. }
  531. int get_selected_evts(int Run, bool ReferenceChannel, bool PHSP){
  532. int yield = 0;
  533. for (auto yr: yearsMC(ReferenceChannel,PHSP,Run)) yield += get_selected_evts(yr,ReferenceChannel,PHSP);
  534. return yield;
  535. }
  536. int get_selected_evts_err(string year, bool ReferenceChannel, bool PHSP){
  537. int pos = get_position_from_year(year);
  538. if (ReferenceChannel) return yield_reference_events_err.at(pos);
  539. if (PHSP) return yield_PHSP_events_err.at(pos);
  540. return yield_signal_events_err.at(pos);
  541. }
  542. double get_selection_efficiency(string year, bool ReferenceChannel, bool PHSP){
  543. return double(get_selected_evts(year,ReferenceChannel,PHSP))/double(get_gen_evts(year,ReferenceChannel,PHSP));
  544. }
  545. double get_selection_efficiency(int Run, bool ReferenceChannel, bool PHSP){
  546. return double(get_selected_evts(Run,ReferenceChannel,PHSP))/double(get_gen_evts(Run,ReferenceChannel,PHSP));
  547. }
  548. double get_tables_eff(string year, bool ReferenceChannel){ //Get efficiency in a year as an average between up and down
  549. int pos = get_position_from_year(year);
  550. if (ReferenceChannel) return (gen_tables_reference_efficiency_down.at(pos)+gen_tables_reference_efficiency_up.at(pos))/2;
  551. else return (gen_tables_signal_efficiency_down.at(pos)+gen_tables_signal_efficiency_up.at(pos))/2;
  552. }
  553. double get_tables_eff(int Run, bool ReferenceChannel){ //Get efficiency of a run as an average between years
  554. double sum = 0;
  555. int nEntries = 0;
  556. double tmp_eff = 0;
  557. for (auto yr: yearsMC(ReferenceChannel,false,Run)){
  558. tmp_eff = get_tables_eff(yr, ReferenceChannel);
  559. if (tmp_eff!=0) nEntries++;
  560. sum += tmp_eff;
  561. }
  562. coutDebug("Total eff/nEntries: " + to_string(sum) + "/" + to_string(nEntries) );
  563. if (nEntries == 0) return 0;
  564. return sum/nEntries;
  565. }
  566. void print_all_yields_and_efficiencies(bool ReferenceChannel, bool PHSP){
  567. for (auto yr : yearsMC(ReferenceChannel,PHSP, 12)){
  568. cout << "------ year " << yr << " ------" << endl;
  569. cout << "\t\t Generated events:\t" << get_gen_evts(yr, ReferenceChannel, PHSP) << endl;
  570. cout << "\t\t Selected events:\t" << get_selected_evts(yr, ReferenceChannel, PHSP) << endl;
  571. cout << "\t\t Efficiency: \t" << get_selection_efficiency(yr, ReferenceChannel, PHSP) << endl;
  572. }
  573. cout << "------ Run 1 ------" << endl;
  574. cout << "\t\t Generated events:\t" << get_gen_evts(1, ReferenceChannel, PHSP) << endl;
  575. cout << "\t\t Selected events:\t" << get_selected_evts(1, ReferenceChannel, PHSP) << endl;
  576. cout << "\t\t Efficiency: \t" << get_selection_efficiency(1, ReferenceChannel, PHSP) << endl;
  577. cout << "------ Run 2 ------" << endl;
  578. cout << "\t\t Generated events:\t" << get_gen_evts(2, ReferenceChannel, PHSP) << endl;
  579. cout << "\t\t Selected events:\t" << get_selected_evts(2, ReferenceChannel, PHSP) << endl;
  580. cout << "\t\t Efficiency: \t" << get_selection_efficiency(2, ReferenceChannel, PHSP) << endl;
  581. return;
  582. }
  583. //----------------------------------------------------------------------------------------------------------
  584. #endif // UTILS_HPP