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.

421 lines
16 KiB

  1. //Renata Kopecna
  2. #include <backgroundfit.hh>
  3. #include <fstream>
  4. #include <sstream> // std::istringstream
  5. #include <bu2kstarmumu_parameters.hh>
  6. #include <bu2kstarmumu_plotter.hh>
  7. #include <bu2kstarmumu_pdf.hh>
  8. #include <folder.hh>
  9. #include <fitter.hh>
  10. #include <paths.hh>
  11. #include <design.hh>
  12. #include <helpers.hh>
  13. #include <event.hh>
  14. #include <spdlog.h>
  15. #include <TStyle.h>
  16. #include <TH2D.h>
  17. #include <TLatex.h>
  18. #include <TCanvas.h>
  19. #include <TROOT.h>
  20. //Do the actuall background fit
  21. int backgroundfit(fcnc::options opts,
  22. bool fitReference, bool LowMassFit, bool HighMassFit, bool fitKpi,
  23. bool Use2DAngularBins, basic_params params){
  24. //params now only used to tag nBins in the names
  25. //Technically, this should be simFit between Run 1 and 2, but since we need it only for the toys atm, no need for it
  26. gROOT->SetBatch(kTRUE);
  27. gROOT->SetStyle("Plain");
  28. set_gStyle();
  29. //Open texFile
  30. std::ofstream myFile;
  31. open_Latex_noteFile(latex_bkgFit(), myFile);
  32. spdlog::info("[FIT]\t\tFit only angular and m(Kpi) background");
  33. //Used to check whether the background is "correlated" between each other
  34. //TODO: not needed atm, maybe fix later
  35. /* 1D angular bins
  36. 1: ctl < -0.5
  37. 2: -0.5 < ctl < 0.0
  38. 3: 0.0 < ctl < 0.5
  39. 4: 0.5 < ctl
  40. 5: ctk < -0.5
  41. 6: -0.5 < ctk < 0.0
  42. 7: 0.0 < ctk < 0.5
  43. 8: 0.5 < ctk
  44. */
  45. /* 2D angular bins
  46. 1: ctl < 0.0 && ctk < 0.0
  47. 2: ctl < 0.0 && ctk > 0.0
  48. 3: ctl > 0.0 && ctk < 0.0
  49. 4: ctl > 0.0 && ctk > 0.0
  50. */
  51. double HighBpeakCut = fitReference ? B_MASS_HIGH_BKG_REF : B_MASS_HIGH_BKG;
  52. double LowBpeakCut = fitReference ? B_MASS_LOW_BKG_REF : B_MASS_LOW_BKG;
  53. assert(!(HighMassFit && LowMassFit));
  54. opts.fit_full_angular_bkg = true;
  55. opts.only_angles = !(HighMassFit || LowMassFit); //Fit mass only if one sideband is selected
  56. opts.only_Bmass = false;
  57. opts.only_mkpi = false;
  58. opts.swave = false;
  59. opts.bkg_order_costhetak = 5;
  60. opts.shift_lh = false; //keep it, it was there before
  61. opts.weighted_fit = true;
  62. opts.squared_hesse = true;
  63. opts.minos_errors = false;
  64. opts.asymptotic = false;
  65. opts.flat_bkg = false;
  66. opts.fit_mkpi = false; //set to true only later
  67. opts.use_mkpi = false;
  68. opts.simple_mkpi = false; //S-wave model
  69. opts.isobar = false; //S-wave model
  70. //Plotting options
  71. opts.plot_chi2 = false;
  72. opts.plots_m_bins = 20;
  73. opts.plots_mkpi_bins = 20;
  74. //load events from data tuple
  75. std::vector<std::vector<fcnc::event>>events;
  76. std::vector<int> run_idx;
  77. if (opts.run == 1 || opts.run == 12){
  78. std::vector<fcnc::event> tmp = fcnc::load_events(get_theFCNCpath(0,1), "Events", -1);
  79. if (!fitReference) events.push_back(fcnc::filterResonances(tmp));
  80. else events.push_back(tmp);
  81. run_idx.push_back(1);
  82. }
  83. if (opts.run == 2 || opts.run == 12){
  84. std::vector<fcnc::event> tmp = fcnc::load_events(get_theFCNCpath(0,2), "Events", -1);
  85. if (!fitReference) events.push_back(fcnc::filterResonances(tmp));
  86. else events.push_back(tmp);
  87. run_idx.push_back(2);
  88. }
  89. std::vector<int> fitresults;
  90. //determine number of bins:
  91. const UInt_t nBins = opts.TheQ2binsmin.size();
  92. //current fitter, plotter, parameteres and pdfs:
  93. fcnc::fitter f(&opts);
  94. fcnc::folder fldr(&opts);
  95. fcnc::bu2kstarmumu_plotter thePlotter(&opts);
  96. fcnc::bu2kstarmumu_parameters * theParams[nBins];
  97. fcnc::bu2kstarmumu_pdf * theProb[nBins];
  98. std::vector<fcnc::event> * theEvents[nBins];
  99. for(UInt_t b = 0; b < nBins; b++){
  100. theParams[b] = new fcnc::bu2kstarmumu_parameters(&opts);
  101. theProb[b] = new fcnc::bu2kstarmumu_pdf(&opts, theParams[b]);
  102. theEvents[b] = new std::vector<fcnc::event>();
  103. //Init parameters
  104. theParams[b]->f_sig.init_fixed(0.0);
  105. theParams[b]->m_b.init(PDGMASS_B, HighMassFit ? HighBpeakCut : B_MASS_LOW, LowMassFit ? LowBpeakCut : B_MASS_HIGH, 0.0);
  106. //The rest of the mass parameters can be left to default values
  107. //They are defined in bu2kstamumu_parameters
  108. //Init the bkg shape
  109. theParams[b]->init_angular_background_parameters(fitReference,0.1);
  110. //Init the mass bkg shape
  111. theParams[b]->init_mass_background_parameters(nBins,b,true);
  112. //theParams[b]->cbkgctk3.init_fixed(-2.5);
  113. //Select events
  114. for_indexed(auto evts: events){
  115. //update weights according to sub-set for all events
  116. opts.run = run_idx.at(i);
  117. opts.update_efficiencies = true;
  118. theProb[b]->load_coeffs_eff_phsp_4d();
  119. theProb[b]->update_cached_normalization(theParams[b]);
  120. theProb[b]->update_cached_efficiencies(theParams[b], &evts);
  121. opts.update_angle_ranges(); //Update angles to get rid of events that cannot be folded
  122. //select events
  123. spdlog::debug("Loop over {0:d} events and select the suitable ones", evts.size());
  124. for(auto meas: evts){
  125. if(meas.q2 < opts.TheQ2binsmin.at(b) || meas.q2 > opts.TheQ2binsmax.at(b)) continue;
  126. if(meas.m < opts.m_low || meas.m > opts.m_high) continue;
  127. if(LowMassFit && meas.m > LowBpeakCut) continue;
  128. else if(HighMassFit && meas.m < HighBpeakCut) continue;
  129. else if(meas.m > LowBpeakCut && meas.m < HighBpeakCut) continue;
  130. if(meas.mkpi < opts.mkpi_min || meas.mkpi > opts.mkpi_max) continue;
  131. if(params.bin > 1){
  132. bool keep_event = true;
  133. if(Use2DAngularBins){
  134. switch(params.bin){
  135. case 2:
  136. if(meas.costhetal > 0.0 || meas.costhetak > 0.0) keep_event = false;
  137. break;
  138. case 3:
  139. if(meas.costhetal > 0.0 || meas.costhetak < 0.0) keep_event = false;
  140. break;
  141. case 4:
  142. if(meas.costhetal < 0.0 || meas.costhetak > 0.0) keep_event = false;
  143. break;
  144. case 5:
  145. if(meas.costhetal < 0.0 || meas.costhetak < 0.0) keep_event = false;
  146. break;
  147. }
  148. }
  149. else{ //1D angular bins
  150. switch(params.bin){
  151. case 2:
  152. if(meas.costhetal > -0.5) keep_event = false;
  153. break;
  154. case 3:
  155. if(meas.costhetal < -0.5 || meas.costhetal > 0.0) keep_event = false;;
  156. break;
  157. case 4:
  158. if(meas.costhetal < 0.0 || meas.costhetal > 0.5) keep_event = false;;
  159. break;
  160. case 5:
  161. if(meas.costhetal > 0.5) keep_event = false;;
  162. break;
  163. case 6:
  164. if(meas.costhetak > -0.5) keep_event = false;;
  165. break;
  166. case 7:
  167. if(meas.costhetak < -0.5 || meas.costhetak > 0.0) keep_event = false;;
  168. break;
  169. case 8:
  170. if(meas.costhetak < 0.0 || meas.costhetak > 0.5) keep_event = false;;
  171. break;
  172. case 9:
  173. if(meas.costhetak > 0.5) keep_event = false;;
  174. break;
  175. }
  176. }
  177. if(!keep_event) continue;
  178. }
  179. if(!filterFldFour(&meas, &opts)) continue;
  180. fldr.fold(&meas);
  181. //only one combined event vector
  182. theEvents[b]->push_back(meas);
  183. }
  184. spdlog::debug("Selected {0:d} events.", theEvents[b]->size());
  185. }
  186. spdlog::info("[BIN {0:d}]\tDone!",b);
  187. }//end loop over bins
  188. //do not update cached efficiencies anyomre, to keep individual ones for four sub-sets
  189. opts.update_efficiencies = false;
  190. //create 2D correlation plots for all angles (3) and all bins (8): 3! * 8 = 24
  191. const unsigned int nANGLES = 3;
  192. double hmin[nANGLES] = {CTL_MIN, CTK_MIN, PHI_MIN};
  193. double hmax[nANGLES] = {CTL_MAX, CTK_MAX, PHI_MAX};
  194. double corrfactor[nBins][nANGLES][nANGLES];
  195. const int nCorrBins = 10;
  196. for(UInt_t b = 0; b < nBins; b++){
  197. spdlog::info("[START]\tStart the background 2D correlation plotting for bin #{0:d}", b);
  198. for(UInt_t a = 0; a < nANGLES - 1; a++){
  199. for(UInt_t aa = a + 1; aa < nANGLES; aa++){
  200. std::string mainName = "bckgnd_correl_"+ANGLES[a]+"_"+ANGLES[aa]+"_q2bin"+std::to_string(b);
  201. TCanvas * cAngCorr = new TCanvas(("c"+mainName).c_str(),
  202. ("c"+mainName).c_str(), 1400, 1200);
  203. cAngCorr->cd()->SetMargin(0.1,0.125,0.125,0.125);
  204. cAngCorr->cd();
  205. TH2D * h = new TH2D((mainName).c_str(),
  206. (mainName+";"+latex_angles[a]+";"+latex_angles[aa]).c_str(),
  207. nCorrBins, hmin[a], hmax[a], nCorrBins, hmin[aa], hmax[aa]);
  208. for(UInt_t e = 0; e < theEvents[b]->size(); e++){
  209. fcnc::event meas = theEvents[b]->at(e);
  210. double x=0.0, y=0.0;
  211. switch(a){ //TODO: make a function in helpers
  212. case 0:
  213. x = meas.costhetal;
  214. break;
  215. case 1:
  216. x = meas.costhetak;
  217. break;
  218. }
  219. switch(aa){
  220. case 1:
  221. y = meas.costhetak;
  222. break;
  223. case 2:
  224. y = meas.phi;
  225. break;
  226. }
  227. h->Fill(x, y);
  228. }
  229. h->GetZaxis()->SetRangeUser(0, fitReference ? 25 : 5);
  230. h->GetZaxis()->SetTitle("Number of entries");
  231. h->GetXaxis()->SetTitleSize(0.05);
  232. h->GetXaxis()->SetLabelSize(0.05);
  233. h->GetXaxis()->SetTitleOffset(0.95);
  234. h->GetYaxis()->SetTitleSize(0.05);
  235. h->GetYaxis()->SetLabelSize(0.05);
  236. h->GetYaxis()->SetTitleOffset(0.75);
  237. h->GetZaxis()->SetTitleSize(0.05);
  238. h->GetZaxis()->SetLabelSize(0.05);
  239. h->GetZaxis()->SetTitleOffset(0.75);
  240. h->SetTitle("");
  241. h->Draw("COLZ");
  242. corrfactor[b][a][aa] = h->GetCorrelationFactor();
  243. TLatex * leg = getPrettyTex(0.06,13);
  244. leg->SetTextColor(kBlack);
  245. std::ostringstream sCorrout; //TODO: move the path
  246. sCorrout << std::fixed << std::setprecision(2) << "corr(" << latex_angles[a] << ", " << latex_angles[aa] <<") = " << corrfactor[b][a][aa]*100. << "\%";
  247. leg->DrawLatex(0.22,0.98, sCorrout.str().c_str());
  248. leg->SetTextSize(0.04);
  249. leg->DrawLatex(0.25,0.92, ("Events: "+std::to_string((int) h->GetEntries())).c_str());
  250. cAngCorr->Print(get_bkgCorrPlot_path(ANGLES[a],ANGLES[aa],b,nBins,fitReference, LowMassFit, HighMassFit, fitKpi, params).c_str(), "eps");
  251. }
  252. }
  253. //Save the correlations s
  254. myFile << "\\begin{tabular}{r|ccc}\\hline" << std::endl;
  255. myFile << std::fixed << std::setprecision(2) << "[" << opts.TheQ2binsmin.at(b) << ", " << opts.TheQ2binsmax.at(b) << "]";
  256. for(UInt_t a = 0; a < nANGLES; a++) myFile << "\t&" << latex_2angles[a];
  257. myFile << "\\\\" << std::endl;
  258. myFile << "\\hline\\hline" << std::endl;
  259. for(UInt_t a = 0; a < nANGLES; a++){
  260. myFile << latex_2angles[a];
  261. for(UInt_t aa = 0; aa < nANGLES; aa++){
  262. myFile << "\t&";
  263. if(aa > a) myFile << std::setprecision(3) << std::fixed << corrfactor[b][a][aa];
  264. else if(aa == a) myFile << "1.00";
  265. else if(aa < a) myFile << " ";
  266. }
  267. myFile << "\\\\" << std::endl;
  268. }
  269. myFile << "\\hline" << std::endl;
  270. myFile << "\\end{tabular}"<< std::endl;
  271. myFile << std::endl;
  272. }
  273. //FIT ANGULAR BACKGROUND + B mass
  274. opts.update_angle_ranges(); //Just in case
  275. //fit all bins:
  276. for(UInt_t b = 0; b < nBins; b++){
  277. spdlog::info("[START]\tStart the fit for bin #{0:d}", b);
  278. //fit the events:
  279. int fitresult = f.fit(theProb[b], theParams[b], theEvents[b]);
  280. fitresults.push_back(fitresult);
  281. spdlog::info("[BIN{0:d}]:\tFitresult: {1:d}", b, fitresult);
  282. //plot pdf with the data points:
  283. opts.plot_label = "LHCb data";
  284. opts.q2_label = q2_label(opts.TheQ2binsmin.at(b), opts.TheQ2binsmax.at(b));
  285. if(opts.write_eps){
  286. std::string label = get_bkg_tag(b,nBins,fitReference, LowMassFit, HighMassFit, false, params);
  287. spdlog::info("[PLOT]\t" + label);
  288. thePlotter.plot_data(theProb[b], theParams[b], theEvents[b], get_bkgFitPlot_path(), label, false);
  289. }
  290. //print all parameters
  291. std::string fitResultTxt = get_bkgFitResult_path()+ "fitresult_" + get_bkg_tag(b,nBins,fitReference, LowMassFit, HighMassFit, false, params);
  292. spdlog::debug("Saving into "+fitResultTxt);
  293. print_all_parameters(nBins, theParams, 2, fitResultTxt);
  294. }
  295. //print all fitresults
  296. print_fit_results(nBins, fitresults);
  297. //Save results to root file
  298. std::string results_file = final_result_name_bkg(nBins, fitReference, LowMassFit, HighMassFit, false, params);
  299. save_results(results_file, nBins, params.Run, fitresults, theParams, &opts);
  300. //FIT M(KPI) BACKGROUND
  301. if (!fitKpi){ //first check if you really want to fit M(KPI) :)
  302. //Close Latex file
  303. myFile.close();
  304. return 0;
  305. }
  306. //Reset the options
  307. opts.only_angles = false;
  308. opts.only_mkpi = true;
  309. opts.fit_mkpi = true;
  310. //fit all bins:
  311. spdlog::info("[BKGFIT]\tFit the Kpi mass");
  312. for(UInt_t b = 0; b < nBins; b++){
  313. theParams[b]->use_default_bkg();
  314. //null the lambda(s) and taus
  315. theParams[b]->m_lambda.init_fixed(0.0);
  316. theParams[b]->m_lambda_2.init_fixed(0.0);
  317. theParams[b]->m_tau.init_fixed(0.0);
  318. theParams[b]->m_tau_2.init_fixed(0.0);
  319. //Init the floating parameters
  320. theParams[b]->init_kpi_background_parameters(fitReference,0.01);
  321. spdlog::info("[START]\tStart the fit for bin #{0:d}", b);
  322. //fit the events:
  323. fitresults.push_back(f.fit(theProb[b], theParams[b], theEvents[b]));
  324. spdlog::info("[BIN{0:d} ]:\tFitresult: {1:d}",b, fitresults.at(b));
  325. //plot pdf with the data points:
  326. opts.q2_label = q2_label(opts.TheQ2binsmin.at(b), opts.TheQ2binsmax.at(b));
  327. if(opts.write_eps){
  328. std::string label = get_bkg_tag(b,nBins,fitReference, LowMassFit, HighMassFit, false, params);
  329. spdlog::info("[PLOT]\t" + label);
  330. thePlotter.plot_data(theProb[b], theParams[b], theEvents[b], get_bkgFitPlot_path(), label, false);
  331. }
  332. //Print all parameters, but don't save
  333. print_all_parameters(nBins, theParams, 2, "");
  334. //print all parameters to txt file
  335. std::string fitResultTxt = get_bkgFitResult_path()+ "fitresult_" + get_bkg_tag(b,nBins,fitReference, LowMassFit, HighMassFit, true, params);
  336. spdlog::debug("Saving into "+fitResultTxt);
  337. print_all_parameters(nBins, theParams, 2, fitResultTxt);
  338. }
  339. spdlog::info("[BKGFIT]\tDone with Kpi fit.");
  340. //Save results to root file
  341. results_file = final_result_name_bkg(nBins, fitReference, LowMassFit, HighMassFit, true, params);
  342. save_results(results_file, nBins, params.Run, fitresults, theParams, &opts);
  343. //Close Latex file
  344. myFile.close();
  345. spdlog::info("[BKGFIT]\tFinished.");
  346. return 0;
  347. }