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.

932 lines
43 KiB

  1. //create MC weights for B+->Kst+mumu
  2. //signal B+ mass is fitted to generate sPlots
  3. //david gerick
  4. //Renata Kopecna
  5. #include "GlobalFunctions.hh"
  6. #include "MassFit.cpp"
  7. #include "Paths.hpp"
  8. #include "Utils.hpp"
  9. #include "BmassShape/ParamValues.hpp"
  10. using namespace std;
  11. using namespace RooFit ;
  12. using namespace RooStats;
  13. //////////////////////////////////////////////////////
  14. /// quickFit()
  15. //////////////////////////////////////////////////////
  16. /// Function is imported from MassFit.hpp
  17. ///
  18. /// the function merges up and down events into a new file.
  19. /// from the fit to the B+ mass distribution, a sPlot weight is saved to a new Branch in this merged file.
  20. /// the fitted B+ mass spectrum may be saved in pdf and root files
  21. ///
  22. /// FEATURES:
  23. /// - choose your background and signal model:
  24. /// signal: (double) Gaussian, left/right/double CrystalBall function
  25. /// background: (double) Exponential, Exponential plus RooExpGaus or no background
  26. /// - get signal shape from MC data if needed and restrict shape to these parameters
  27. ///
  28. /// OPTIONAL:
  29. /// To determine the signal yield of the reference/resonance channel, the boolean UseOnlyJpsiEvents can be set.
  30. /// Then only B+ -> J/psi K*+ events are fitted for S and B. The Q^2 bin #9 is taken, with 8.0 GeV^2 < Q^2 < 11.0 GeV^2
  31. /// Also the seperation into DD and LL tracks for the Kshort Channel is possible!
  32. ///
  33. ///
  34. ///
  35. //////////////////////////////////////////////////////
  36. /// quickFitAll()
  37. //////////////////////////////////////////////////////
  38. ///
  39. /// Function to fit all years, sWeights all data years
  40. /// Possible for data or MC. Most options of quickFit() are identically choosable
  41. ///
  42. ///
  43. ///
  44. //////////////////////////////////////////////////////
  45. /// NtrackWeight()
  46. //////////////////////////////////////////////////////
  47. ///
  48. /// the sPlot results from the quickFit() function are used to weight the nTrack signal distribution.
  49. /// the ratio of MC / data of this nTrack distribution is used to create 1D weights for the MC sample,
  50. /// which is later used as input for the BDT selection///
  51. ///
  52. /// MC can be reweighted also without sWeights!
  53. ///
  54. /// NEWLY ADDED: the sPlot results from the quickFit() function are used to 2 * 1D-weight the MC sample.
  55. /// It will be weighted in nTracks first and then in the transverse momentum of the B+ (B_plus_PT)
  56. ///
  57. /// Weight branches can be re-defined in GlobalFunctions.hh (see firstMCweight and seconMCweight)
  58. ///
  59. ///
  60. ///
  61. //////////////////////////////////////////////////////
  62. /// WeightAll()
  63. //////////////////////////////////////////////////////
  64. ///
  65. /// run the quickFit for both years, then apply NtrackWeights to both years.
  66. ///
  67. ///
  68. ///
  69. //////////////////////////////////////////////////////
  70. /// ReweightMCOnly()
  71. //////////////////////////////////////////////////////
  72. ///
  73. /// Do not fit the data but use the sWeighted data to re-weight the MC.
  74. /// Including options to re-weight Reference channel MC and PHSP MC.
  75. ///
  76. ///
  77. //////////////////////////////////////////////////////
  78. /// GetSignalAndBckgndEstimation()
  79. ///
  80. /// Uses the quickFit() function with the optional boolean to only fit the Jpsi events to get the estimation of
  81. /// signal candidates for the reference channel before pre-selection. Via the PDG Branching Ratios, the signal
  82. /// yield of the signal channel is calculated. From the total number of candidates for the signal channel within
  83. /// the B-plus mass window estimated as 2*sigma window
  84. /// the background is determined via B = N - S, with S the calculated signal estimation from
  85. /// first part
  86. ///
  87. /// (not very suitable for pi0)
  88. ///
  89. //Initilize MC tracks histograms
  90. TH1D *get_hist_MC_w(TH1D *hist, string name, bool is2D){
  91. TH1D* hist_nTracks_MC_w = (TH1D*) hist->Clone((is2D ? seconMCweight : firstMCweight+name).c_str());
  92. if (is2D) hist_nTracks_MC_w->SetTitle((seconMCweight+" MC 2D weights [norm.]").c_str());
  93. else hist_nTracks_MC_w->SetTitle((firstMCweight+" MC weights [norm.]").c_str());
  94. return hist_nTracks_MC_w;
  95. }
  96. //Initialize
  97. TH1D *get_hist(string name, bool is2D, bool isMC){
  98. TH1D* hist = NULL;
  99. if (!isMC){
  100. if (is2D) hist = new TH1D(seconMCweight.c_str(), (seconMCweight+" Yield [norm.]").c_str(), secondnBins, seconMCrange[0], seconMCrange[1]);
  101. else hist = new TH1D(firstMCweight.c_str() ,(firstMCweight+" Yield [norm.]").c_str(), firstnBins, firstMCrange[0], firstMCrange[1]);
  102. }
  103. else{
  104. if (is2D) hist = new TH1D((seconMCweight+name).c_str(),(seconMCweight+" MC weighted by "+firstMCweight+" [norm.]").c_str(), secondnBins, seconMCrange[0], seconMCrange[1]);
  105. else hist = new TH1D((firstMCweight+name).c_str(),(firstMCweight+" MC [norm.]").c_str(), firstnBins, firstMCrange[0], firstMCrange[1]);
  106. }
  107. coutDebug("Hist name: " + string(hist->GetName()));
  108. return hist;
  109. }
  110. //Get MC weights
  111. void getWeightHist(TChain *tree, string weightName, TH1D *hist, TH1D *hist_w, string TMmethod, bool KshortDecayInVelo, bool gammaTM){
  112. tree->SetBranchStatus("*",0);
  113. //activate needed branches
  114. tree->SetBranchStatus(TMmethod.c_str(),1);
  115. tree->SetBranchStatus(weightName.c_str(),1);
  116. if(Kst2Kspiplus)tree->SetBranchStatus("KshortDecayInVeLo",1);
  117. //assign variables
  118. Double_t weight = 0;
  119. Int_t weight_I = 0;
  120. bool isInt = false;
  121. if (weightName.find("Track") != std::string::npos) isInt = true; //check if the value is integer or not
  122. Int_t KshortDecayInVeLo = 0;
  123. Int_t TMed = 0;
  124. Int_t TMed_gammas = 0;
  125. tree->SetBranchAddress(TMmethod.c_str(), &TMed);
  126. tree->SetBranchAddress("TM_gammas",&TMed_gammas);
  127. if (isInt) tree->SetBranchAddress(weightName.c_str() , &weight_I);
  128. else tree->SetBranchAddress(weightName.c_str() , &weight);
  129. if(Kst2Kspiplus)tree->SetBranchAddress("KshortDecayInVeLo" , &KshortDecayInVeLo);
  130. int nEvts = tree->GetEntries();
  131. for(int i=0; i < nEvts ; i++){
  132. if (0ul == (i % 10000ul) || nEvts == i + 1) coutDebug("Read MC event " + to_string(i) + "/" + to_string(nEvts));
  133. tree->GetEntry(i);
  134. if (!isTM(TMmethod,TMed,gammaTM,TMed_gammas)) continue;
  135. //only write the correct DD or LL tracks into the histogram!
  136. if(Kst2Kspiplus && SplitDDandLL){
  137. if (KshortDecayInVelo ^ KshortDecayInVeLo) continue; //^ is a xor operator
  138. }
  139. isInt ? hist->Fill(weight_I) : hist->Fill(TMath::Log(weight));
  140. }
  141. //normalize the histogram by its integral
  142. hist->Sumw2();
  143. hist->Scale(1./hist->Integral());
  144. //divide histograms (hist_w = clone of hist_data)
  145. hist_w->Divide(hist);
  146. //reset branch links because root is stupid
  147. tree->ResetBranchAddresses();
  148. return;
  149. }
  150. //Find the weight for each event
  151. void fillWeightHist(double &w, double &delta_w, int bin, bool TM, TH1D *h_w){
  152. if (TM){
  153. w = h_w->GetBinContent(bin);
  154. delta_w = h_w->GetBinError(bin);
  155. }
  156. else{
  157. w = 1.0;
  158. delta_w = -1.0;
  159. }
  160. return;
  161. }
  162. double getDelta_w2D(double w, double delta_w, double w2D, double delta_w2D){
  163. if(delta_w < 0.0 || delta_w2D < 0.0)//keep delta_w2D negative, if both deltas are negative
  164. return (-TMath::Sqrt(TMath::Power(delta_w*w2D,2)+TMath::Power(delta_w2D*w,2)));
  165. else
  166. return (TMath::Sqrt(TMath::Power(delta_w*w2D,2)+TMath::Power(delta_w2D*w,2)));
  167. }
  168. int quickFitAll(string SignalShape = "OneCB", string BckShape = "SingleExponential", bool sWeight=true, bool GetShapeFromMC = true,
  169. bool ConstrainParameters = true, int Run = 1){
  170. //Creates sWeights in data
  171. bool UseOnlyJpsiEvents = true; //Set based on if reweighted by Jpsi or not
  172. bool UseOnlyMuMuEvents = false;
  173. std::vector<string> years = yearsMC(false,UseOnlyJpsiEvents,Run);
  174. for(unsigned int y = 0; y < years.size(); y++){
  175. if(Kst2Kspiplus && SplitDDandLL){
  176. if(quickFit(years.at(y), false, sWeight, UseOnlyJpsiEvents, UseOnlyMuMuEvents, true, GetShapeFromMC, SignalShape, BckShape, ConstrainParameters) == 0){
  177. coutERROR("Failed quickFit() for " + years.at(y) + " (LL tracks). Exit!");
  178. return 0;
  179. }
  180. if(quickFit(years.at(y), false, sWeight, UseOnlyJpsiEvents, UseOnlyMuMuEvents, false, GetShapeFromMC, SignalShape, BckShape, ConstrainParameters) == 0){
  181. coutERROR("Failed quickFit() for " + years.at(y) + " (DD tracks). Exit!");
  182. return 0;
  183. }
  184. }
  185. else{
  186. if(quickFit(years.at(y), false, sWeight, UseOnlyJpsiEvents, UseOnlyMuMuEvents, false, GetShapeFromMC, SignalShape, BckShape, ConstrainParameters) == 0){
  187. coutERROR("Failed quickFit() for " + years.at(y) + ". Exit!");
  188. return 0;
  189. }
  190. }
  191. }
  192. return 1;
  193. }
  194. int NtrackWeight(string year = "2011", const bool ReferenceChannel = false, bool PHSP = false, bool ReweightInBplusPT = true, bool KshortDecayInVelo = true, bool sWeightUse = true) {
  195. //the bollean is called sWeightUse in order not to be confused with sWeight branches
  196. coutInfo("Start MonteCarlo re-weighting: " + year + string(Kst2Kspiplus && SplitDDandLL ? (KshortDecayInVelo ? " (LL tracks)" : " (DD tracks)") : ""));
  197. if (!checkMC(ReferenceChannel,PHSP)) return false;
  198. //Make ROOT shutup
  199. gStyle -> SetOptStat(0);
  200. LHCbStyle();
  201. gROOT->SetBatch(kTRUE);
  202. //get data and MC file(s)
  203. TChain * tree = new TChain("DecayTree");
  204. TChain * treeMCTM = new TChain("DecayTreeTruthMatched");
  205. TFile * output;
  206. bool GetWeightsFromJpsiChannel = ReweightByRefChannel;
  207. string MCyear = year;
  208. if(KshortChannel){
  209. if(ReweightByRefChannel && !checkRefYear(year))
  210. GetWeightsFromJpsiChannel = false;
  211. }
  212. else{ //K+ pi0 channel
  213. if (GetWeightsFromJpsiChannel && !checkRefYear(year)) MCyear = "2016"; //Use 2016 MC for reweighting 2017 and 2018 signal MC
  214. }
  215. //Decide if reweighting by Reference channel or not
  216. bool loadRefChannel = (AlwaysUseRefChannelData || GetWeightsFromJpsiChannel || ReferenceChannel);
  217. ///DATA
  218. //load sWeighted OnlyJpsi data OR load the full data-set of Jpsi and non-resonant mumu data events (sWeighted)
  219. tree->Add(GetBDTinputFile(year,false,loadRefChannel,false,KshortDecayInVelo).c_str());
  220. coutDebug("Adding " + GetBDTinputFile(year,false,loadRefChannel,false,KshortDecayInVelo));
  221. ///MC
  222. //load MonteCarlo sample of up and down type. truthmatched and non-truthmatched
  223. treeMCTM->Add(GetInputFile(MCyear,"down",true, true, loadRefChannel, false, false).c_str());
  224. treeMCTM->Add(GetInputFile(MCyear,"up", true, true, loadRefChannel, false, false).c_str());
  225. coutDebug("Adding " + GetInputFile(MCyear,"down",true, true, loadRefChannel, false, false));
  226. coutDebug("Adding " + GetInputFile(MCyear,"up", true, true, loadRefChannel, false, false));
  227. checkEntries(tree);
  228. checkEntries(treeMCTM);
  229. //deactivate all other branches
  230. tree->SetBranchStatus("*",0);
  231. tree->SetBranchStatus(firstMCweight.c_str(),1);
  232. tree->SetBranchStatus(seconMCweight.c_str(),1);
  233. if (sWeightUse) tree->SetBranchStatus("N_Bplus_sw",1);
  234. //assign variables
  235. Int_t nTracks = 0;
  236. Double_t sWeights = 1.0;
  237. Double_t B_plus_PT = 0.0;
  238. //link variables to branches
  239. tree->SetBranchAddress(firstMCweight.c_str() , &nTracks);
  240. tree->SetBranchAddress(seconMCweight.c_str() , &B_plus_PT);
  241. if (sWeightUse) tree->SetBranchAddress("N_Bplus_sw",&sWeights);
  242. //Make histograms
  243. TH1::SetDefaultSumw2();
  244. TH2::SetDefaultSumw2();
  245. TH1D* hist_nTracks = get_hist("",false,false);
  246. TH1D* hist_nTracks_MC = get_hist("_MC",false,true);
  247. TH1D* hist_nTracks_MC_TM = get_hist("_MC_TM",false,true);
  248. TH1D* hist_nTracks_MC_TM_rndGamma = get_hist("_MC_TM_rndGamma",false,true);
  249. TH1D* hist_nTracks_MC_noPi0TM = get_hist("_MC_noPi0TM",false,true);
  250. TH1D* hist_BplusPT = get_hist("",true,false);
  251. TH1D* hist_BplusPT_MC = get_hist("_weighted",true,true);
  252. TH1D* hist_BplusPT_MC_TM = get_hist("_weighted_TM",true,true);
  253. TH1D* hist_BplusPT_MC_TM_rndGamma = get_hist("_weighted_TM_rndGamma",true,true);
  254. TH1D* hist_BplusPT_MC_noPi0TM = get_hist("_weighted_noPi0TM",true,true);
  255. //histogram to check correlations between nTracks and B_plus_PT
  256. TH2D* hCorrelationCheck = new TH2D((firstMCweight+"_"+seconMCweight+"_correlation").c_str(),("correlation between "+firstMCweight+" and "+seconMCweight).c_str(),
  257. firstnBins,firstMCrange[0], firstMCrange[1], secondnBins, seconMCrange[0], seconMCrange[1]);
  258. ///-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/
  259. /// load data (nTracks and B_plus_PT) into histograms
  260. ///-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/
  261. Int_t nEvents = tree->GetEntries();
  262. Int_t nEventsMCTM = treeMCTM->GetEntries();
  263. //loop over data events
  264. coutInfo("Loop over data sample from " + year + TheDecay + " to fill histogram!");
  265. if (sWeightUse){
  266. for(int i=0; i < nEvents; i++){
  267. if (0ul == (i % 10000ul) || nEvents == i + 1) coutDebug("Read data event " + to_string(i) + "/" + to_string(nEvents));
  268. tree->GetEntry(i);
  269. hist_nTracks->Fill(nTracks, sWeights);
  270. hist_BplusPT->Fill(TMath::Log(B_plus_PT), sWeights);
  271. hCorrelationCheck->Fill(nTracks, TMath::Log(B_plus_PT), sWeights);
  272. }
  273. }
  274. else {
  275. for(int i=0; i < nEvents; i++){
  276. if (0ul == (i % 10000ul) || nEvents == i + 1) coutDebug("Read data event " + to_string(i) + "/" + to_string(nEvents));
  277. tree->GetEntry(i);
  278. hist_nTracks->Fill(nTracks);
  279. hist_BplusPT->Fill(TMath::Log(B_plus_PT));
  280. hCorrelationCheck->Fill(nTracks, TMath::Log(B_plus_PT));
  281. }
  282. }
  283. Double_t CorrelationCoefficent = hCorrelationCheck->GetCorrelationFactor();
  284. coutDebug("The correlation coefficient between " + firstMCweight + " and " + seconMCweight + " is: " + to_string(CorrelationCoefficent));
  285. //normalize histograms by its integral
  286. hist_nTracks->Scale(1./hist_nTracks->Integral());
  287. hist_BplusPT->Scale(1./hist_BplusPT->Integral());
  288. //clone normalized histogram for determining the ratio between data/MC of nTracks string
  289. //Make three histograms, each for given TM method
  290. TH1D* hist_nTracks_MC_w = get_hist_MC_w(hist_nTracks,"_MC_weights", false);
  291. TH1D* hist_nTracks_MC_w_TM = get_hist_MC_w(hist_nTracks,"_MC_weights_TM", false);
  292. TH1D* hist_nTracks_MC_w_TM_rndGamma = get_hist_MC_w(hist_nTracks,"_MC_weights_TM_rndGamma", false);
  293. TH1D* hist_nTracks_MC_w_noPi0TM = get_hist_MC_w(hist_nTracks,"_MC_weights_noPi0TM", false);
  294. //clone normalized histogram for determining the ratio between data/MC
  295. TH1D* hist_BplusPT_MC_w2D = get_hist_MC_w(hist_BplusPT,"_MC_weights", true);
  296. TH1D* hist_BplusPT_MC_w2D_TM = get_hist_MC_w(hist_BplusPT,"_MC_weights_TM", true);
  297. TH1D* hist_BplusPT_MC_w2D_TM_rndGamma = get_hist_MC_w(hist_BplusPT,"_MC_weights_TM_rndGamma", true);
  298. TH1D* hist_BplusPT_MC_w2D_noPi0TM = get_hist_MC_w(hist_BplusPT,"_MC_weights_noPi0TM", true);
  299. ///////////////////////////////
  300. /// reweight in nTracks
  301. ///////////////////////////////
  302. treeMCTM->GetEntry(0);
  303. coutInfo("Loop over MC sample from " + year + TheDecay + " to fill histogram for 1D reweighting in " + firstMCweight + "!");
  304. getWeightHist(treeMCTM,firstMCweight,hist_nTracks_MC,hist_nTracks_MC_w,"TMedBKGCAT",KshortDecayInVelo, false);
  305. getWeightHist(treeMCTM,firstMCweight,hist_nTracks_MC_TM,hist_nTracks_MC_w_TM,"TMed",KshortDecayInVelo, true);
  306. if (!Kst2Kspiplus){
  307. getWeightHist(treeMCTM,firstMCweight,hist_nTracks_MC_TM_rndGamma,hist_nTracks_MC_w_TM_rndGamma,"TMed",KshortDecayInVelo, false);
  308. getWeightHist(treeMCTM,firstMCweight,hist_nTracks_MC_noPi0TM,hist_nTracks_MC_w_noPi0TM,"TMed_noPi0",KshortDecayInVelo, true);
  309. }
  310. ///////////////////////////////
  311. /// reweight in B_plus_PT
  312. ///////////////////////////////
  313. if(ReweightInBplusPT){
  314. coutInfo("Loop over MC sample from " + year + TheDecay + " to fill histogram for 1D reweighting in " + seconMCweight + "!");
  315. getWeightHist(treeMCTM,seconMCweight,hist_BplusPT_MC,hist_BplusPT_MC_w2D,"TMedBKGCAT",KshortDecayInVelo, false);
  316. getWeightHist(treeMCTM,seconMCweight,hist_BplusPT_MC_TM,hist_BplusPT_MC_w2D_TM,"TMed",KshortDecayInVelo, true);
  317. if (!Kst2Kspiplus){
  318. getWeightHist(treeMCTM,seconMCweight,hist_BplusPT_MC_TM_rndGamma,hist_BplusPT_MC_w2D_TM_rndGamma,"TMed",KshortDecayInVelo, false);
  319. getWeightHist(treeMCTM,seconMCweight,hist_BplusPT_MC_noPi0TM,hist_BplusPT_MC_w2D_noPi0TM,"TMed_noPi0",KshortDecayInVelo, true);
  320. }
  321. }
  322. ////////////////////////////////////////////////////////////////////
  323. /// Plot the histograms to canvases
  324. ////////////////////////////////////////////////////////////////////
  325. string canvasPath = "";
  326. if(!PHSP && !ReferenceChannel){
  327. canvasPath = GetControlPlots(year,ReferenceChannel,false,KshortDecayInVelo,sWeightUse,1).c_str();
  328. drawKolmogorovTest(hist_nTracks, hist_nTracks_MC, canvasPath,"_BKGCAT");
  329. drawKolmogorovTest(hist_nTracks, hist_nTracks_MC_TM, canvasPath,"_TM");
  330. drawKolmogorovTest(hist_nTracks, hist_nTracks_MC_TM_rndGamma, canvasPath,"_TM_rndGamma");
  331. //Plot correlation between B_plus and nTracks
  332. canvasPath = GetControlPlots(year,ReferenceChannel,PHSP,KshortDecayInVelo,sWeightUse,4).c_str();
  333. drawWeightCorrelation(hCorrelationCheck, CorrelationCoefficent, canvasPath);
  334. }
  335. //Plot the ratio
  336. canvasPath = GetControlPlots(year,ReferenceChannel,PHSP,KshortDecayInVelo,sWeightUse,2).c_str();
  337. drawWeightRatio(hist_nTracks_MC_w, canvasPath, false, "_BKGCAT");
  338. drawWeightRatio(hist_nTracks_MC_w_TM, canvasPath, false, "_TM");
  339. drawWeightRatio(hist_nTracks_MC_w_TM_rndGamma, canvasPath, false,"_TM_rndGamma");
  340. //Plot the ratio for B_plus_PT
  341. canvasPath = GetControlPlots(year,ReferenceChannel,PHSP,KshortDecayInVelo,sWeightUse,3).c_str();
  342. drawWeightRatio(hist_BplusPT_MC_w2D, canvasPath, true, "_BKGCAT");
  343. drawWeightRatio(hist_BplusPT_MC_w2D_TM, canvasPath, true, "_TM");
  344. drawWeightRatio(hist_BplusPT_MC_w2D_TM_rndGamma, canvasPath, true,"_TM_rndGamma");
  345. //////////////////////////////////
  346. /// SAVE WEIGHTS TO MC
  347. //////////////////////////////////
  348. treeMCTM->ResetBranchAddresses();
  349. treeMCTM->SetBranchStatus("*",1);
  350. coutInfo("Copy MC Trees... ");
  351. if (!ReferenceChannel && !PHSP && year=="2015") return 1; //Skip 2015 signal MC
  352. TTree * newtreeMCTM;
  353. TChain * reweightedTreeMCTM;
  354. //if ReweightByRefChannel == true, the ratios above have been created with Jpsi data and MC
  355. //but if we don't run for the ReferenceChannel, we want to load the correct Tree (so delete previous treeMCTM and treeMC and load new (Signal MC or PHSP)
  356. if(GetWeightsFromJpsiChannel && !ReferenceChannel){
  357. //to be safe, close trees of reference channel MC:
  358. delete treeMCTM;
  359. reweightedTreeMCTM = new TChain("DecayTreeTruthMatched");
  360. if (reweightedTreeMCTM == NULL) coutERROR("Failed to create your new tree!");
  361. //load trees from Signal MC files:
  362. reweightedTreeMCTM ->Add(GetInputFile(year,"down",true,true,ReferenceChannel,PHSP,false).c_str());
  363. reweightedTreeMCTM ->Add(GetInputFile(year,"up", true,true,ReferenceChannel,PHSP,false).c_str());
  364. coutDebug("Loading " + GetInputFile(year,"down",true,true,ReferenceChannel,PHSP,false) );
  365. coutDebug("Loading " + GetInputFile(year,"up", true,true,ReferenceChannel,PHSP,false) );
  366. //remove an old BDTresponse branch, that might still be active in the tree after pre-selection:
  367. TBranch * bTM = (TBranch *)reweightedTreeMCTM->GetBranch(TMVAmethod+"response");
  368. if(bTM != NULL) reweightedTreeMCTM->SetBranchStatus("*response", 0);
  369. //Get new event numbers for the Signal or PHSP trees:
  370. nEventsMCTM = reweightedTreeMCTM->GetEntries();
  371. //copy the loaded tree according to the cuts
  372. if(Kst2Kspiplus && SplitDDandLL){
  373. coutDebug("Apply track cut on MC Tree: " + string(KshortDecayInVelo ? "LL tracks!" : "DD tracks!"));
  374. newtreeMCTM = reweightedTreeMCTM->CopyTree(Form("KshortDecayInVeLo == %i", KshortDecayInVelo ? 1 : 0));
  375. }
  376. else{
  377. newtreeMCTM = reweightedTreeMCTM->CopyTree("");
  378. }
  379. coutDebug("Truthmatched Tree completed!");
  380. }
  381. else{ //if not forced to be reweighted from Jpsi channel, just copy the tree used above for the ratio:
  382. //remove an old BDTresponse branch, that might still be active in the tree after pre-selection:
  383. TBranch * bTM = (TBranch *)treeMCTM->GetBranch(TMVAmethod+"response");
  384. if(bTM != NULL){
  385. treeMCTM->SetBranchStatus("*response", 0);
  386. }
  387. if(Kst2Kspiplus && SplitDDandLL){
  388. coutDebug("Apply track cut on MC Tree: " +string(KshortDecayInVelo ? "LL tracks!" : "DD tracks!"));
  389. newtreeMCTM = treeMCTM->CopyTree(Form("KshortDecayInVeLo == %i", KshortDecayInVelo ? 1 : 0));
  390. }
  391. else{
  392. coutDebug("Copying tree...");
  393. newtreeMCTM = treeMCTM->CloneTree();
  394. }
  395. coutDebug("Truthmatched Tree completed!");
  396. }
  397. coutDebug("Old TM Tree entries:\t" + to_string(nEventsMCTM));
  398. coutDebug("Copied TM Tree entries:\t" + to_string(newtreeMCTM->GetEntries()));
  399. coutInfo("Adding branches to MC tree.");
  400. //create new TBranches: each for different TM method and coresponding weight error branch
  401. double w = 1., w2D = 1., delta_w = 0., delta_w2D = 0.;
  402. double w_TM = 1., w2D_TM = 1., delta_w_TM = 0., delta_w2D_TM = 0.;
  403. double w_noPi0TM = 1., w2D_noPi0TM = 1., delta_w_noPi0TM = 0., delta_w2D_noPi0TM = 0.;
  404. double w_TM_rndGamma = 1., w2D_TM_rndGamma = 1., delta_w_TM_rndGamma = 0., delta_w2D_TM_rndGamma = 0.;
  405. TBranch* Bra_w = newtreeMCTM->Branch(Form("weight_%s", firstMCweight.c_str()),&w, Form("weight_%s/D", firstMCweight.c_str()));
  406. TBranch* Bra_w2D = newtreeMCTM->Branch(Form("weight2D_%s", firstMCweight.c_str()),&w2D,Form("weight2D_%s/D",firstMCweight.c_str()));
  407. TBranch* Bra_delta_w = newtreeMCTM->Branch(Form("delta_weight_%s", firstMCweight.c_str()),&delta_w, Form("delta_weight_%s/D", firstMCweight.c_str()));
  408. TBranch* Bra_delta_w2D= newtreeMCTM->Branch(Form("delta_weight2D_%s",firstMCweight.c_str()),&delta_w2D,Form("delta_weight2D_%s/D", firstMCweight.c_str()));
  409. TBranch* Bra_w_TM = newtreeMCTM->Branch(Form("weight_%s_TM", firstMCweight.c_str()),&w_TM , Form("weight_%s_TM/D", firstMCweight.c_str()));
  410. TBranch* Bra_w2D_TM = newtreeMCTM->Branch(Form("weight2D_%s_TM", firstMCweight.c_str()),&w2D_TM ,Form("weight2D_%s_TM/D",firstMCweight.c_str()));
  411. TBranch* Bra_delta_w_TM = newtreeMCTM->Branch(Form("delta_weight_%s_TM", firstMCweight.c_str()),&delta_w_TM , Form("delta_weight_%s_TM/D", firstMCweight.c_str()));
  412. TBranch* Bra_delta_w2D_TM= newtreeMCTM->Branch(Form("delta_weight2D_%s_TM",firstMCweight.c_str()),&delta_w2D_TM ,Form("delta_weight2D_%s_TM/D",firstMCweight.c_str()));
  413. TBranch* Bra_w_noPi0TM = newtreeMCTM->Branch(Form("weight_%s_noPi0TM", firstMCweight.c_str()),&w_noPi0TM, Form("weight_%s_noPi0TM/D", firstMCweight.c_str()));
  414. TBranch* Bra_w2D_noPi0TM = newtreeMCTM->Branch(Form("weight2D_%s_noPi0TM", firstMCweight.c_str()),&w2D_noPi0TM,Form("weight2D_%s_noPi0TM/D",firstMCweight.c_str()));
  415. TBranch* Bra_delta_w_noPi0TM = newtreeMCTM->Branch(Form("delta_weight_%s_noPi0TM", firstMCweight.c_str()),&delta_w_noPi0TM, Form("delta_weight_%s_noPi0TM/D", firstMCweight.c_str()));
  416. TBranch* Bra_delta_w2D_noPi0TM= newtreeMCTM->Branch(Form("delta_weight2D_%s_noPi0TM", firstMCweight.c_str()),&delta_w2D_noPi0TM,Form("delta_weight2D_%s_noPi0TM/D",firstMCweight.c_str()));
  417. TBranch* Bra_w_TM_rndGamma = newtreeMCTM->Branch(Form("weight_%s_TM_rndGamma", firstMCweight.c_str()),&w_TM_rndGamma , Form("weight_%s_TM_rndGamma/D", firstMCweight.c_str()));
  418. TBranch* Bra_w2D_TM_rndGamma = newtreeMCTM->Branch(Form("weight2D_%s_TM_rndGamma", firstMCweight.c_str()),&w2D_TM_rndGamma ,Form("weight2D_%s_TM_rndGamma/D",firstMCweight.c_str()));
  419. TBranch* Bra_delta_w_TM_rndGamma = newtreeMCTM->Branch(Form("delta_weight_%s_TM_rndGamma", firstMCweight.c_str()),&delta_w_TM_rndGamma , Form("delta_weight_%s_TM_rndGamma/D", firstMCweight.c_str()));
  420. TBranch* Bra_delta_w2D_TM_rndGamma= newtreeMCTM->Branch(Form("delta_weight2D_%s_TM_rndGamma",firstMCweight.c_str()),&delta_w2D_TM_rndGamma ,Form("delta_weight2D_%s_TM_rndGamma/D",firstMCweight.c_str()));
  421. nEventsMCTM = newtreeMCTM->GetEntries();
  422. coutInfo("Looping over MC tree with " + to_string(nEventsMCTM) + " entries.");
  423. //renew links to branches in new tree:
  424. //status is already set to 1 for all
  425. Int_t TMedBKGCAT, TMed, TMed_noPi0;
  426. Int_t gammaTMed;
  427. Int_t nTracksMC;
  428. Double_t B_plus_PTMC;
  429. newtreeMCTM->SetBranchAddress("TMedBKGCAT" , &TMedBKGCAT);
  430. newtreeMCTM->SetBranchAddress("TMed" , &TMed);
  431. if (!Kst2Kspiplus){
  432. newtreeMCTM->SetBranchAddress("TMed_noPi0", &TMed_noPi0);
  433. newtreeMCTM->SetBranchAddress(gammaTMbranch.c_str() , &gammaTMed);
  434. }
  435. newtreeMCTM->SetBranchAddress((firstMCweight).c_str() , &nTracksMC);
  436. newtreeMCTM->SetBranchAddress((seconMCweight).c_str() , &B_plus_PTMC);
  437. Int_t nTrackBin = 1, nBplusBin = 1;
  438. //loop over MC events (Only the TruthMatched events get weights!)
  439. coutInfo("Loop over MC data from " + year + TheDecay + " to get weights for MC");
  440. for(int i=0; i < nEventsMCTM; i++)
  441. {
  442. if (0ul == (i % 10000ul) || nEventsMCTM == i + 1) coutDebug("Read MC event " + to_string(i) + "/" + to_string(nEventsMCTM));
  443. newtreeMCTM->GetEntry(i);
  444. //1D weights
  445. if(nTracksMC < firstMCrange[0] || nTracksMC > firstMCrange[1]){
  446. coutInfo(firstMCweight + " out of range: " + to_string(nTracksMC) + " in event: " + to_string(i));
  447. w = 1.0;
  448. delta_w = -1.0; //set negative for when no value could be obtained
  449. w_TM = 1.0;
  450. delta_w_TM = -1.0;
  451. w_TM_rndGamma = 1.0;
  452. delta_w_TM_rndGamma = -1.0;
  453. w_noPi0TM = 1.0;
  454. delta_w_noPi0TM = -1.0;
  455. }
  456. else{
  457. nTrackBin = hist_nTracks->FindBin(nTracksMC);
  458. fillWeightHist(w, delta_w, nTrackBin, TMedBKGCAT, hist_nTracks_MC_w);
  459. fillWeightHist(w_TM, delta_w_TM, nTrackBin, isTM("TMed",TMed,true, gammaTMed), hist_nTracks_MC_w_TM);
  460. fillWeightHist(w_TM_rndGamma, delta_w_TM_rndGamma, nTrackBin, isTM("TMed",TMed,false,gammaTMed), hist_nTracks_MC_w_TM_rndGamma);
  461. fillWeightHist(w_noPi0TM, delta_w_noPi0TM, nTrackBin, isTM("TMed",TMed,true, gammaTMed), hist_nTracks_MC_w_noPi0TM);
  462. }
  463. //2 x 1D weights
  464. B_plus_PTMC = TMath::Log(B_plus_PTMC);
  465. if(B_plus_PTMC < seconMCrange[0] || B_plus_PTMC > seconMCrange[1]){
  466. coutInfo(seconMCweight + " out of range: " + to_string(B_plus_PTMC) + " in event: " + to_string(i));
  467. w2D = 1.0;
  468. delta_w2D = -1.0; //set negative for when no value could be obtained
  469. w2D_TM = 1.0;
  470. delta_w2D_TM = -1.0;
  471. w2D_noPi0TM = 1.0;
  472. delta_w2D_noPi0TM = -1.0;
  473. }
  474. else{
  475. nBplusBin = hist_BplusPT->FindBin(B_plus_PTMC);
  476. fillWeightHist(w2D, delta_w2D, nBplusBin, TMedBKGCAT, hist_BplusPT_MC_w2D);
  477. fillWeightHist(w2D_TM, delta_w2D_TM, nBplusBin, isTM("TMed",TMed,true,gammaTMed), hist_BplusPT_MC_w2D_TM);
  478. fillWeightHist(w2D_TM_rndGamma, delta_w2D_TM_rndGamma, nBplusBin, isTM("TMed",TMed,false,gammaTMed), hist_BplusPT_MC_w2D_TM_rndGamma);
  479. fillWeightHist(w2D_noPi0TM, delta_w2D_noPi0TM, nBplusBin, isTM("TMed",TMed,true,gammaTMed), hist_BplusPT_MC_w2D_noPi0TM);
  480. }
  481. //save uncertainties on weights BEFORE weights, as w2D gets overwritten later on:
  482. delta_w2D = getDelta_w2D(w, delta_w, w2D, delta_w2D);
  483. delta_w2D_TM = getDelta_w2D(w_TM, delta_w_TM, w2D_TM, delta_w2D_TM);
  484. delta_w2D_TM_rndGamma = getDelta_w2D(w_TM_rndGamma, delta_w_TM_rndGamma, w2D_TM_rndGamma, delta_w2D_TM_rndGamma);
  485. delta_w2D_noPi0TM = getDelta_w2D(w_noPi0TM, delta_w_noPi0TM, w2D_noPi0TM, delta_w2D_noPi0TM);
  486. //Fill the branches with uncertainties on weights
  487. Bra_delta_w->Fill();
  488. Bra_delta_w2D->Fill();
  489. Bra_delta_w_TM->Fill();
  490. Bra_delta_w2D_TM->Fill();
  491. Bra_delta_w_TM_rndGamma->Fill();
  492. Bra_delta_w2D_TM_rndGamma->Fill();
  493. Bra_delta_w_noPi0TM->Fill();
  494. Bra_delta_w2D_noPi0TM->Fill();
  495. //prevent weight <= 0!
  496. if(w<=0.)w=1.;
  497. if(w2D<=0.)w2D=1.;
  498. if(w_TM<=0.)w_TM=1.;
  499. if(w2D_TM<=0.)w2D_TM=1.;
  500. if(w_TM_rndGamma<=0.)w_TM_rndGamma=1.;
  501. if(w2D_TM_rndGamma<=0.)w2D_TM_rndGamma=1.;
  502. if(w_noPi0TM<=0.)w_noPi0TM=1.;
  503. if(w2D_noPi0TM<=0.)w2D_noPi0TM=1.;
  504. //Recalculate 2D weights
  505. w2D*=w;
  506. w2D_TM*=w_TM;
  507. w2D_TM_rndGamma*=w_TM_rndGamma;
  508. w2D_noPi0TM*=w_noPi0TM;
  509. //Fill weights
  510. Bra_w->Fill();
  511. Bra_w2D->Fill();
  512. Bra_w_TM->Fill();
  513. Bra_w2D_TM->Fill();
  514. Bra_w_TM_rndGamma->Fill();
  515. Bra_w2D_TM_rndGamma->Fill();
  516. Bra_w_noPi0TM->Fill();
  517. Bra_w2D_noPi0TM->Fill();
  518. }
  519. //create output file for re-weighted and combined trees (truthmatched and non-truthmatched)
  520. coutInfo("Save re-weighted tree to file: " + GetBDTinputFile(year,true,ReferenceChannel,PHSP,KshortDecayInVelo));
  521. output = new TFile(GetBDTinputFile(year,true,ReferenceChannel,PHSP,KshortDecayInVelo).c_str(),"RECREATE");
  522. if(!output->IsOpen()){
  523. coutERROR("Could not create output file. Abort!");
  524. return 0;
  525. }
  526. output->cd();
  527. coutInfo("Saving new tree of MC data " + year + TheDecay + " to file!");
  528. newtreeMCTM->Write("",TObject::kWriteDelete);
  529. hist_nTracks_MC_w->Clear();
  530. hist_nTracks_MC_w_TM->Clear();
  531. hist_nTracks_MC_w_TM_rndGamma->Clear();
  532. hist_nTracks_MC_w_noPi0TM->Clear();
  533. hist_nTracks->Clear();
  534. hist_nTracks_MC->Clear();
  535. hist_nTracks_MC_TM->Clear();
  536. hist_nTracks_MC_TM_rndGamma->Clear();
  537. hist_nTracks_MC_noPi0TM->Clear();
  538. hist_BplusPT->Clear();
  539. hist_BplusPT_MC->Clear();
  540. hist_BplusPT_MC_TM->Clear();
  541. hist_BplusPT_MC_TM_rndGamma->Clear();
  542. hist_BplusPT_MC_noPi0TM->Clear();
  543. hist_BplusPT_MC_w2D->Clear();
  544. hist_BplusPT_MC_w2D_TM->Clear();
  545. hist_BplusPT_MC_w2D_TM_rndGamma->Clear();
  546. hist_BplusPT_MC_w2D_noPi0TM->Clear();
  547. output->Close();
  548. gROOT->Reset();
  549. return 1;
  550. }
  551. int NtrackWeightAllKplus(const bool ReferenceChannel = false, bool PHSP = false, bool ReweightInBplusPT = true){
  552. vector <string> years = yearsVector(true,ReferenceChannel,PHSP,12);
  553. for (auto year: years)
  554. if (NtrackWeight(year, ReferenceChannel, PHSP, ReweightInBplusPT, false, true)==0) return 0;
  555. return 1;
  556. }
  557. int WeightYear(string year = "2011", bool WeightBplusPT = true, bool GetShapeFromMC = true, bool sWeight = true){
  558. bool ConstrainParameters = KshortChannel ? false : true;
  559. string SignalFunction = Kst2Kspiplus ? "OneCB" : "OneCB";
  560. string BackGroundFunction = Kst2Kspiplus ? "SingleExponential" : "SingleExponential";
  561. if((ReweightByRefChannel && (checkRefYear(year) || !KshortChannel)) || AlwaysUseRefChannelData){ //reweight data by RefChannel MC, for Kshort only Run1
  562. if(Kst2Kspiplus && SplitDDandLL){
  563. //fit Jpsi channel only (create sWeights)
  564. if(quickFit(year, false, sWeight, true, false, true, GetShapeFromMC, SignalFunction, BackGroundFunction, ConstrainParameters) == 0){
  565. coutERROR("Fitting the B+ mass for " + year + " Jpsi data (LL tracks) failed!");
  566. return 0;
  567. }
  568. if(quickFit(year, false, sWeight, true, false, false, GetShapeFromMC, SignalFunction, BackGroundFunction, ConstrainParameters) == 0){
  569. coutERROR("Fitting the B+ mass for " + year + " Jpsi data (DD tracks) failed!");
  570. return 0;
  571. }
  572. //fit all events (Jpsi + non-resonant, but no sWeights!)
  573. if(quickFit(year, false, sWeight, false, false, true, GetShapeFromMC, SignalFunction, BackGroundFunction, ConstrainParameters) == 0){
  574. coutERROR("Fitting the B+ mass for " + year + " data (LL tracks) failed!");
  575. return 0;
  576. }
  577. if(quickFit(year, false, sWeight, false, false, false, GetShapeFromMC, SignalFunction, BackGroundFunction, ConstrainParameters) == 0){
  578. coutERROR("Fitting the B+ mass for " + year + " data (DD tracks) failed!");
  579. return 0;
  580. }
  581. //Apply sWeights from Jpsi channel to MC
  582. if(NtrackWeight(year, false, false, WeightBplusPT, true, sWeight) == 0){
  583. coutERROR("Creating weights for nTrack distribution for " + year + " MC (LL tracks) failed!");
  584. return 0;
  585. }
  586. if(NtrackWeight(year, false, false, WeightBplusPT, false, sWeight) == 0){
  587. coutERROR("Creating weights for nTrack distribution for " + year + " MC (DD tracks) failed!");
  588. return 0;
  589. }
  590. }
  591. else{
  592. //fit Jpsi channel only (create sWeights) for pi0 or don't split LL/DD
  593. if(quickFit(year, false, true, true, false, false, GetShapeFromMC, SignalFunction, BackGroundFunction, ConstrainParameters) == 0){
  594. coutERROR("Fitting the B+ mass for " + year + " Jpsi data failed!");
  595. return 0;
  596. }
  597. //fit all events (Jpsi + non-resonant, but no sWeights!)
  598. if(quickFit(year, false, true, false, false, false, GetShapeFromMC, SignalFunction, BackGroundFunction, ConstrainParameters) == 0){
  599. coutERROR("Fitting the B+ mass for " + year + " data failed!");
  600. return 0;
  601. }
  602. //Apply sWeights from Jpsi channel to MC (and no need to add RefChannel, since the weights are aded automatically there
  603. if(NtrackWeight(year, false, false, WeightBplusPT, false, sWeight) == 0){
  604. coutERROR("Creating weights for nTrack distribution for " + year + " MC failed!");
  605. return 0;
  606. }
  607. }
  608. }
  609. else{ //reweight data by signal MC
  610. if(Kst2Kspiplus && SplitDDandLL){
  611. if(quickFit(year, false, sWeight, false, false, true, GetShapeFromMC, SignalFunction, BackGroundFunction, ConstrainParameters) == 0){
  612. coutERROR("Fitting the B+ mass for " + year + " data (LL tracks) failed!");
  613. return 0;
  614. }
  615. if(quickFit(year, false, sWeight, false, false, false, GetShapeFromMC, SignalFunction, BackGroundFunction, ConstrainParameters) == 0){
  616. coutERROR("Fitting the B+ mass for " + year + " data (DD tracks) failed!");
  617. return 0;
  618. }
  619. if(NtrackWeight(year, false, false, WeightBplusPT, true, sWeight) == 0){
  620. coutERROR("Creating weights for nTrack distribution for " + year + " MC (LL tracks) failed!");
  621. return 0;
  622. }
  623. if(NtrackWeight(year, false, false, WeightBplusPT, false, sWeight) == 0){
  624. coutERROR("Creating weights for nTrack distribution for " + year + " MC (DD tracks) failed!");
  625. return 0;
  626. }
  627. }
  628. else{
  629. //signal channel
  630. if(quickFit(year, false, sWeight, false, false, false, GetShapeFromMC, SignalFunction, BackGroundFunction, ConstrainParameters) == 0){
  631. coutERROR("Fitting the B+ mass for " + year + " data failed!");
  632. return 0;
  633. }
  634. if(NtrackWeight(year, false, false, WeightBplusPT, false, sWeight) == 0){
  635. coutERROR("Creating weights for nTrack distribution for " + year + " MC failed!");
  636. return 0;
  637. }
  638. //reference channel
  639. if(quickFit(year,false, sWeight, true, false, false, GetShapeFromMC, SignalFunction, BackGroundFunction, ConstrainParameters) == 0){
  640. coutERROR("Fitting the B+ mass for " + year + " data failed!");
  641. return 0;
  642. }
  643. if(NtrackWeight(year, true, false, WeightBplusPT, false, sWeight) == 0){
  644. coutERROR("Creating weights for nTrack distribution for " + year + " MC failed!");
  645. return 0;
  646. }
  647. }
  648. }
  649. coutInfo("COMPLETED WEIGHTS FOR YEAR " + year);
  650. return 1;
  651. }
  652. int WeightAll(bool WeightBplusPT = true, Int_t Run = 1, bool sWeight = true){
  653. bool GetShapeFromMC = true;
  654. std::vector<string> years = yearsVector(false,false,false, Run);
  655. for(unsigned int y = 0; y < years.size(); y++){
  656. if(WeightYear(years.at(y), WeightBplusPT, GetShapeFromMC, sWeight) == 0){
  657. coutERROR("sWeighting of the year " + years.at(y) + "did not succeed!");
  658. return 0;
  659. }
  660. }
  661. coutInfo("Weighting of all data and re-weighting of all signalMC was done!");
  662. return 1;
  663. }
  664. int ReweightMCOnly(string year = "2011", bool ReferenceChannel = false, bool PHSP = false, bool WeightBplusPT = true, bool sWeight = true){
  665. if (checkMC(ReferenceChannel,PHSP)==false) return 0;
  666. if(NtrackWeight(year, ReferenceChannel, PHSP, WeightBplusPT, false, sWeight) == 0){
  667. coutERROR("Creating weights for nTrack distribution for " + year + string(Kst2Kspiplus && SplitDDandLL ? " (DD tracks) " : "") + " MC failed!");
  668. return 0;
  669. }
  670. if(Kst2Kspiplus && SplitDDandLL){
  671. if(NtrackWeight(year, ReferenceChannel, PHSP, WeightBplusPT, true, sWeight) == 0){
  672. coutERROR("Creating weights for nTrack distribution for " + year + " (LL tracks) MC failed!");
  673. return 0;
  674. }
  675. }
  676. return 1;
  677. }
  678. int ReweightSignalMC(bool WeightBplusPT = true, Int_t Run = 1, bool sWeight = true){
  679. std::vector<string> years = yearsMC(false,false,Run);
  680. for(unsigned int y = 0; y < years.size(); y++){
  681. if(ReweightMCOnly(years.at(y), false, false, WeightBplusPT, sWeight) == 0){
  682. coutERROR("Could not reweight signal MC for " + years.at(y) + ".Exit program");
  683. return 0;
  684. }
  685. }
  686. return 1;
  687. }
  688. int ReweightPHSPMC(bool WeightBplusPT = true, Int_t Run = 1, bool sWeight = true){
  689. std::vector<string> years = yearsMC(false,true,Run);
  690. for(unsigned int y = 0; y < years.size(); y++){
  691. if(ReweightMCOnly(years.at(y), false, true, WeightBplusPT, sWeight) == 0){
  692. coutERROR("Could not reweight PHSP MC for " + years.at(y) + ".Exit program");
  693. return 0;
  694. }
  695. }
  696. return 1;
  697. }
  698. int ReweightReferenceMC(bool WeightBplusPT = true, Int_t Run = 1, bool sWeight = true){
  699. std::vector<string> years = yearsMC(true,false,Run);
  700. for(unsigned int y = 0; y < years.size(); y++){
  701. if(ReweightMCOnly(years.at(y), true, false, WeightBplusPT, sWeight) == 0){
  702. coutERROR("Could not reweight Reference MC for " + years.at(y) + ".Exit program");
  703. return 0;
  704. }
  705. }
  706. return 1;
  707. }
  708. int ReweightAllMC(bool WeightBplusPT = true, Int_t Run = 1, bool sWeight = true){
  709. if (ReweightSignalMC(WeightBplusPT,Run,sWeight) == 0) return 0;
  710. if (ReweightReferenceMC(WeightBplusPT,Run,sWeight) == 0) return 0;
  711. if (ReweightPHSPMC(WeightBplusPT,Run,sWeight) == 0) return 0;
  712. return 1;
  713. }
  714. int ReweightAll(bool WeightBplusPT = true, Int_t Run = 1, bool sWeight = true){
  715. if (WeightAll(WeightBplusPT,Run,sWeight) == 0) return 0;
  716. if (ReweightAllMC(WeightBplusPT,Run,sWeight) == 0) return 0;
  717. return 1;
  718. }
  719. int GetSignalAndBckgndEstimation(bool KshortDecaysInVelo = true, Int_t Run = 1){ //assumes S = N - B
  720. std::vector<string> years = yearsData(Run);
  721. gStyle -> SetOptStat(0);
  722. LHCbStyle();
  723. gROOT->SetBatch(kTRUE);
  724. //lhcbStyle->SetOptTitle(1);
  725. bool ConstrainParameters = false; //maybe not needed for signal estimation
  726. if(Kst2Kspiplus){
  727. ConstrainParameters = true;
  728. }
  729. string SignalFunction = "OneCB";
  730. string BackGroundFunction;
  731. if(Kst2Kspiplus){
  732. if(KshortDecaysInVelo) BackGroundFunction = "SingleExponential";
  733. else BackGroundFunction = "DoubleExponential";
  734. }
  735. else BackGroundFunction = "SingleExponential";
  736. //Get the yield of the reference channel from the quickfit, then scale it via the Branching Ratios of both decays
  737. Int_t SignalYield = 0;
  738. for(unsigned int y = 0; y < years.size(); y++)
  739. SignalYield += quickFit(years.at(y).c_str(), true, false, true, false, KshortDecaysInVelo, false, SignalFunction, BackGroundFunction, ConstrainParameters) * BR_sig / BR_ref;
  740. //get number of candidates in the signal channel within the B_plus mass window
  741. TChain * tree = new TChain("DecayTree");
  742. for(unsigned int y = 0; y < years.size(); y++) tree->Add(GetBDTinputFile(years.at(y),false,false,false,KshortDecaysInVelo).c_str());
  743. string q2Cuts = getMuMucut();
  744. string sVariable = (UseDTF ? "B_plus_M_DTF" : "B_plus_M");
  745. string massCuts = sVariable + "> " + to_string(FitValuesSignal.sig_mean.val - SignalRegionNsigma * FitValuesSignal.sig_effSigma.val)
  746. + " && " +
  747. sVariable + " < " +to_string(FitValuesSignal.sig_mean.val + SignalRegionNsigma * FitValuesSignal.sig_effSigma.val);
  748. string cut = "(" + q2Cuts + ") && (" + massCuts + ")";
  749. //data: create histograms from tree
  750. TCanvas * c1 = new TCanvas("c1", "c1");
  751. tree->Draw(Form("%s>>B_plus_M_plot", sVariable.c_str()), cut.c_str());
  752. TH1 * histo = ((TH1 *) gPad->GetPrimitive("B_plus_M_plot"));
  753. //... get number of entries from histogram as N = B + S (!!!)
  754. Int_t EventsAfterPreSelection = histo->GetEntries();
  755. //correct title and axis labels and save histogram to PDF
  756. string title = "B^{+} mass after preselection";
  757. if(Kst2Kspiplus && SplitDDandLL)title.append(KshortDecaysInVelo ? " [LL tracks]" : " [DD tracks]");
  758. histo->GetXaxis()->SetTitle("m(B^{+}) ( MeV/c^{2} )");
  759. histo->GetYaxis()->SetTitle(Form("Events / ( %.1f MeV/c^{2} )", histo->GetBinWidth(1)));
  760. histo->SetTitle(title.c_str());
  761. histo->Draw();
  762. if(Kst2Kpluspi0Resolved || Kst2Kpluspi0Merged){
  763. c1->Print(Form("%s/SignalYieldHistos/%s_Run%i_SignalYield.eps", path_to_output_KplusPizero.c_str(), TheDecay.c_str(), Run));
  764. c1->SaveAs(Form("%s/SignalYieldHistos/%s_Run%i_SignalYield.root", path_to_output_KplusPizero.c_str(), TheDecay.c_str(), Run));
  765. }
  766. else{
  767. c1->Print(Form("%s/SignalYieldHistos/%s%s_Run%i_SignalYield.eps", path_to_output_KshortPiplus.c_str(), TheDecay.c_str(),(SplitDDandLL ? (KshortDecaysInVelo ? "_LL" : "_DD") : ""), Run));
  768. c1->SaveAs(Form("%s/SignalYieldHistos/%s%s_Run%i_SignalYield.root", path_to_output_KshortPiplus.c_str(), TheDecay.c_str(),(SplitDDandLL ? (KshortDecaysInVelo ? "_LL" : "_DD") : ""), Run));
  769. }
  770. delete c1;
  771. delete histo;
  772. if (Kst2Kspiplus){
  773. coutInfo("[SIGNAL]: " + string(Kst2Kspiplus && SplitDDandLL ? (KshortDecaysInVelo ? "LL Tracks: " : "DD Tracks: ") : "") + to_string(SignalYield));
  774. coutInfo("[BCKGND]: " + string(Kst2Kspiplus && SplitDDandLL ? (KshortDecaysInVelo ? "LL Tracks: " : "DD Tracks: ") : "") + to_string(EventsAfterPreSelection - SignalYield));
  775. }
  776. else{
  777. coutInfo(TheDecay + "[SIGNAL]: " + to_string(SignalYield));
  778. coutInfo(TheDecay + "[BCKGND]: " + to_string(EventsAfterPreSelection - SignalYield));
  779. }
  780. return 1;
  781. }