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.

628 lines
28 KiB

  1. //Renata Kopecna
  2. #include <pulls.hh>
  3. #include <string>
  4. #include <sstream>
  5. #include <iostream>
  6. #include "folder.hh"
  7. #include <fitter.hh>
  8. #include <bu2kstarmumu_plotter.hh>
  9. #include <bu2kstarmumu_generator.hh>
  10. #include <bu2kstarmumu_pdf.hh>
  11. #include <bu2kstarmumu_parameters.hh>
  12. #include <paths.hh>
  13. #include <helpers.hh>
  14. #include <event.hh>
  15. #include <TTree.h>
  16. #include <spdlog.h>
  17. //////////////////////////
  18. // INIT VALUES FOR FITS //
  19. //////////////////////////
  20. //Do they change anywhere or can I set them in a header?
  21. //TODO replace by the parameters->init
  22. double f_m_B[4] = {5282.32, 5282.08, 5278.57, 5279.48};
  23. double f_lambda1[4] = {-0.00386, -0.00610, -0.00362, -0.00578};
  24. double f_lambda2[4] = {-0.03320, -0.00120, -0.04600, -0.00100};
  25. double f_alpha_1[4] = { 1.7910, 1.8000, 1.6510, 1.5400};
  26. double f_alpha_2[4] = { 2.3200, 2.4300, 2.0100, 2.2500};
  27. double f_n_1[4] = { 1.4400, 1.4900, 1.6800, 1.6100};
  28. double f_n_2[4] = { 2.8900, 3.7000, 3.8700, 3.7000};
  29. double f_sigma_1[4] = {14.8300, 15.4800, 14.8400, 14.4};
  30. double f_sigma_2[4] = {14.0700, 13.1000, 15.6200, 13.3};
  31. double f_f_CB[4] = { 0.6360, 0.3600, 0.3040, 0.6200};
  32. double f_m_scale[4] = { 1.1814, 1.0648, 1.1547, 1.1168};
  33. //TODO posibly to be deleted so ignoring for now!
  34. void do_pulls(fcnc::options opts, bool doToyPulls, bool doMCPulls, int job_id, double SwaveFraction, UInt_t nPulls, Double_t nToyEvents, UInt_t nMCEvents ,std::string angularsuffix, bool Fit1bin, bool Fit2bins, bool FitAllbins ){ //TODO: change to int and return some errors possibly
  35. //TODO: figure out jobs_to_do and job_id, but there is no manipulation with it, so so far so good
  36. //Why is it not opts.job_id?
  37. if(doToyPulls)std::cout << "[INFO]\t\tGetting pull distributions and test fits from Toy Events!" << std::endl;
  38. //disable eps output if job_id is larger than -1. This is needed for HD cluster jobs:
  39. if(job_id > -1)opts.write_eps = false;
  40. //have extra option for the usage of binning:
  41. const bool UseBinnedFit = false;
  42. opts.fit_fl = false;
  43. opts.fit_afb = false;
  44. opts.only_angles = false;
  45. opts.only_Bmass = false;
  46. if(opts.only_Bmass) opts.only_angles = false;
  47. opts.use_angular_acc = true;
  48. opts.use_weighted_bkg = true;
  49. opts.fit_full_angular_bkg = true;
  50. opts.always_generate_full_angular = true;
  51. opts.weighted_fit = true;
  52. opts.swave = true;
  53. opts.shift_lh = false;
  54. opts.squared_hesse = true;
  55. opts.minos_errors = false;
  56. opts.generate_mkpi = true;
  57. opts.fit_mkpi = false;
  58. opts.use_mkpi = true;
  59. opts.flat_bkg = false;
  60. //change the label of the produced plots:
  61. opts.plot_label = "LHCb toys";
  62. //SM
  63. std::vector<double> s1s, s1c, s2s, s2c, s3, s4, s5, s6s, s6c, s7, s8, s9;
  64. std::vector<double> f_signal, f_bckgnd, f_bckcoeff;
  65. double f_sig_norm = 0.0;
  66. std::vector<UInt_t> events_per_bin;
  67. //determine number of bins:
  68. const UInt_t nBins = UseBinnedFit ? opts.TheQ2binsmin.size() : 1;
  69. if(!UseBinnedFit){
  70. opts.TheQ2binsmin = {8.68};
  71. opts.TheQ2binsmax = {10.09};
  72. }
  73. //create TTree to save pull values
  74. double treeValue, treeStart, treeError, treeErrorUp, treeErrorDown;
  75. UInt_t treeBin, treeFitNumber, treeFitResult, treeIndex;
  76. TTree * T = nullptr;
  77. if(doToyPulls || doMCPulls){
  78. T = new TTree("PullTree", "PullTree");
  79. T->Branch("v", &treeValue, "v/D");
  80. T->Branch("i", &treeIndex, "i/i");
  81. T->Branch("s", &treeStart, "s/D");
  82. T->Branch("e", &treeError, "e/D");
  83. T->Branch("eu", &treeErrorUp, "eu/D");
  84. T->Branch("ed", &treeErrorDown, "ed/D");
  85. T->Branch("b", &treeBin , "b/i");
  86. T->Branch("f", &treeFitNumber, "f/i");
  87. T->Branch("r", &treeFitResult, "r/i");
  88. T->Branch("fs", &SwaveFraction, "fs/D");
  89. }
  90. //TODO: fix the name of the genLvl root file
  91. basic_params params_genLvl = basic_params();
  92. params_genLvl.Run = 2;
  93. params_genLvl.year = 2017;
  94. params_genLvl.nBins = nBins;
  95. std::string genPath = final_result_name_genLvlMC(params_genLvl, nBins, false, true, false);
  96. s1s = load_param_values_into_vector("S1s",genPath);
  97. s3 = load_param_values_into_vector("S3", genPath);
  98. s4 = load_param_values_into_vector("S4", genPath);
  99. s5 = load_param_values_into_vector("S5", genPath);
  100. s6s = load_param_values_into_vector("S6s",genPath);
  101. s7 = load_param_values_into_vector("S7", genPath);
  102. s8 = load_param_values_into_vector("S8", genPath);
  103. s9 = load_param_values_into_vector("S9", genPath);
  104. if(UseBinnedFit){
  105. if(nBins == 8){
  106. f_signal = {101., 61., 62., 96., 125., 124., 129., 69.};
  107. f_bckgnd = {131., 206., 279., 358., 358., 247., 158., 93.};
  108. f_bckcoeff = {-0.0052, -0.0084, -0.0088, -0.0031, -0.0028, -0.0158, -0.0079, -0.0058}; //for notation: exp(lambda * x)
  109. //results from Signal channel generator level MC fits:
  110. s1c = { 0.2450, 0.6996, 0.7993, 0.7384, 0.6414, 0.4201, 0.3513, 0.3344};
  111. s2s = { 0.1448, 0.0749, 0.0514, 0.0662, 0.0900, 0.1449, 0.1620, 0.1662};
  112. s2c = {-0.1953,-0.6639,-0.7774,-0.7254,-0.6334,-0.4171,-0.3497,-0.3332};
  113. s3 = { 0.0000, 0.0020,-0.0080,-0.0120,-0.0240,-0.0620,-0.1520,-0.2330};
  114. s4 = { 0.0870, 0.0040,-0.1080,-0.1950,-0.2510,-0.2770,-0.2900,-0.3040};
  115. s5 = { 0.2440, 0.0950,-0.1590,-0.3050,-0.4140,-0.4210,-0.3400,-0.2490};
  116. s6s = {-0.1270,-0.2070,-0.0860, 0.0950, 0.3020, 0.5140, 0.5570, 0.4700};
  117. s6c = { 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000};
  118. s7 = {-0.0060,-0.0100,-0.0030, 0.0020, 0.0030,-0.0020,-0.0020, 0.0050};
  119. s8 = { 0.0010,-0.0030,-0.0040,-0.0030,-0.0010, 0.0030,-0.0010, 0.0030};
  120. s9 = {-0.0020, 0.0000, 0.0020, 0.0040,-0.0020,-0.0010,-0.0010, 0.0010};
  121. }
  122. else if(nBins == 4){
  123. spdlog::error("YOU NEED TO UPDATE THESE FIRTS!");
  124. assert(0);
  125. f_signal = {101., 61., 62., 96.};
  126. f_bckgnd = {131., 206., 279., 358.};
  127. f_bckcoeff = {-0.0052, -0.0084, -0.0088, -0.0031}; //for notation: exp(lambda * x)
  128. //results from Signal channel generator level MC fits:
  129. s1s = { 0.5120, 0.1800, 0.1370, 0.1930};
  130. s1c = { 0.2450, 0.6996, 0.7993, 0.7384};
  131. s2s = { 0.1448, 0.0749, 0.0514, 0.0662};
  132. s2c = {-0.1953,-0.6639,-0.7774,-0.7254};
  133. s3 = { 0.0000, 0.0020,-0.0080,-0.0120};
  134. s4 = { 0.0870, 0.0040,-0.1080,-0.1950};
  135. s5 = { 0.2440, 0.0950,-0.1590,-0.3050};
  136. s6s = {-0.1270,-0.2070,-0.0860, 0.0950};
  137. s6c = { 0.0000, 0.0000, 0.0000, 0.0000};
  138. s7 = {-0.0060,-0.0100,-0.0030, 0.0020};
  139. s8 = { 0.0010,-0.0030,-0.0040,-0.0030};
  140. s9 = {-0.0020, 0.0000, 0.0020, 0.0040};
  141. }
  142. else if(nBins == 2){
  143. f_signal = { 61.+ 62.+ 96.+125., 129.+69.};
  144. f_bckgnd = {206.+279.+358.+358., 158.+93.};
  145. f_bckcoeff = {-0.0064, -0.0065};
  146. s1s = { 0.1959, 0.4917};
  147. s1c = { 0.7441, 0.3447};
  148. s2s = { 0.0646, 0.1636};
  149. s2c = {-0.7217, -0.3432};
  150. s3 = {-0.0042, -0.1747};
  151. s4 = { 0.1033, 0.2929};
  152. s5 = {-0.1458, -0.3157};
  153. s6s = { 0.0652, -0.5338};
  154. s6c = { 0.0000, 0.0000};
  155. s7 = { 0.0340, -0.0000};
  156. s8 = {-0.0115, -0.0002};
  157. s9 = { 0.0003, 0.0003};
  158. }
  159. else {
  160. spdlog::error("No SM values given for binning scheme with {0:d} q2 bins. Exit", nBins);
  161. assert(0);
  162. }
  163. }
  164. else{
  165. f_signal = {0.5};
  166. f_bckgnd = {0.5};
  167. f_bckcoeff = {-2.835e-3}; //for notation: exp(lambda * x)
  168. s1s = { 0.2372};
  169. s1c = { 0.6863};
  170. s2s = { 0.0};
  171. s2c = {-0.6760};
  172. s3 = {-0.0107};
  173. s4 = { 0.2163};
  174. s5 = {-0.3806};
  175. s6s = {-0.1957};
  176. s6c = { 0.0};
  177. s7 = { 0.0290};
  178. s8 = {-0.0113};
  179. s9 = { 0.0003};
  180. }
  181. assert(f_signal.size() == f_bckgnd.size());
  182. f_sig_norm = std::accumulate(f_signal.begin(), f_signal.end(), 0.0)
  183. + std::accumulate(f_bckgnd.begin(), f_bckgnd.end(), 0.0);
  184. for(UInt_t i = 0; i < f_signal.size(); i++){
  185. f_signal.at(i) /= f_sig_norm;
  186. f_bckgnd.at(i) /= f_sig_norm;
  187. }
  188. fcnc::folder fldr(&opts);
  189. fcnc::fitter f(&opts);
  190. fcnc::bu2kstarmumu_plotter thePlotter(&opts);
  191. std::vector< std::vector<fcnc::bu2kstarmumu_parameters*> >theParameters;
  192. std::vector< std::vector<fcnc::bu2kstarmumu_pdf*> > thePDFs;
  193. for(UInt_t c = 0; c < nBins; c++){
  194. //add vector of params to matrix:
  195. std::vector<fcnc::bu2kstarmumu_parameters*> params_per_bin;
  196. params_per_bin.clear();
  197. theParameters.push_back(params_per_bin);
  198. //add vector of pdfs to matrix:
  199. std::vector<fcnc::bu2kstarmumu_pdf*> pdf_per_bin;
  200. pdf_per_bin.clear();
  201. thePDFs.push_back(pdf_per_bin);
  202. }
  203. assert(theParameters.size() == nBins);
  204. assert(thePDFs.size() == nBins);
  205. //pointers to current parameter, pdf and generator:
  206. fcnc::bu2kstarmumu_parameters * params[nBins];
  207. fcnc::bu2kstarmumu_pdf * prob[nBins];
  208. fcnc::bu2kstarmumu_generator * gen = nullptr;
  209. std::vector<int> fitresults;
  210. std::vector<fcnc::event>selection;
  211. //number of fits is either determined by the larger number of pulls or fits requested
  212. UInt_t nFits = nPulls;
  213. //vectors to save values for pull plots:
  214. std::vector<int>var_indexs;
  215. std::vector< std::vector< std::vector<double> > >pull_values;
  216. std::vector< std::vector< std::vector<double> > >pull_errors;
  217. std::vector< std::vector<double> >pull_starts;
  218. //initialize parameters, events and fitter for every FitTest:
  219. for(UInt_t n = 0; n < nFits; n++){
  220. //if binning is used, loop over the number of q2 bins, else only run loop once!
  221. for(UInt_t b = 0; b < nBins; b++){
  222. std::cout << std::endl;
  223. std::cout << "****************************************" << std::endl;
  224. std::cout << "[FIT]\t\tStarting fit >> " << n << " <<" << std::endl;
  225. std::cout << "[FIT]\t\tIn bin >> " << b << " <<" << std::endl;
  226. std::cout << "****************************************" << std::endl;
  227. std::cout << std::endl;
  228. opts.swave = true;
  229. opts.q2_min = UseBinnedFit ? opts.TheQ2binsmin.at(b) : opts.TheQ2binsmin.front();
  230. opts.q2_max = UseBinnedFit ? opts.TheQ2binsmax.at(b) : opts.TheQ2binsmax.back();
  231. if(n == 0){
  232. //initiate parameters for mass fit
  233. params[b] = new fcnc::bu2kstarmumu_parameters(&opts);
  234. params[b]->f_sig.init(f_signal.at(b)/(f_signal.at(b)+f_bckgnd.at(b)), 0.0, 1.0, 0.01);
  235. if(params[b]->f_sig.get_value() == 0.0)
  236. params[b]->m_b.init(PDGMASS_B, B_MASS_LOW, B_MASS_HIGH, 0.0);
  237. else
  238. params[b]->m_b.init(PDGMASS_B, B_MASS_LOW, B_MASS_HIGH, 0.01);
  239. if(opts.twotailedcrystalball)
  240. params[b]->m_res_1.init(1.0, 0.0, 1.0, 0.0);
  241. else
  242. params[b]->m_res_1.init(0.391, 0.0, 1.0, 0.0);// 0.01);
  243. params[b]->fm_tau.init(1.0, 0.0, 1.0, 0.0);
  244. if(opts.fit_lambda){
  245. if(params[b]->f_sig.get_value() == 1.0)
  246. params[b]->m_lambda.init(f_bckcoeff.at(b), -1.0e-1, -1.0e-6, 0);
  247. else
  248. params[b]->m_lambda.init(f_bckcoeff.at(b), -1.0e-1, -1.0e-6, 1.0e-5);
  249. params[b]->m_lambda_2.init(-1.664e-3, -1.0e-1, -1.0e-6, 0.0);
  250. params[b]->m_tau.init( 1./2.835e-3, 100.0, 1.0e+4, 0.0);
  251. params[b]->m_tau_2.init(1./1.664e-3, 0.0, 1.0e+4, 0.0);
  252. }
  253. else{
  254. params[b]->m_lambda.init(-1.0e-3, -1.0e-1, -1.0e-6, 0.0);
  255. params[b]->m_lambda_2.init(-1.5e-3, -1.0e-1, -1.0e-6, 0.0);
  256. params[b]->m_tau.init(-1./f_bckcoeff.at(b), 100.0, 1.0e+4, 1.0);
  257. params[b]->m_tau_2.init(6.01e+2, 0.0, 1.0e+4, 0.0);
  258. }
  259. if(opts.twotailedcrystalball)
  260. params[b]->m_sigma_1.init(f_sigma_1[n], 5.0, 200.0, 0.0);//, 0.1);
  261. else{
  262. params[b]->m_sigma_1.init(f_sigma_1[n], 5.0, 200.0, 0.0);//, 0.1);
  263. params[b]->m_sigma_2.init(f_sigma_2[n], 5.0, 200.0, 0.0);//, 0.1);
  264. }
  265. params[b]->alpha_1.init(f_alpha_1[n], 0.1, 10.0, 0.0);//, 0.15);
  266. params[b]->alpha_2.init(f_alpha_2[n], 0.1, 10.0, 0.0);//, 0.20);
  267. params[b]->n_1.init(f_n_1[n], 0.1, 15.0, 0.0);//, 2.0);
  268. params[b]->n_2.init(f_n_2[n], 0.1, 10.0, 0.0);//, 0.16);
  269. params[b]->m_scale.init(f_m_scale[n], 0.0, 2.0, 0.0);
  270. params[b]->load_only_Bmass_param_values("fitresult_SignalFit_MC_SimultaneousFit_2Dfit_bin"+std::to_string(b)+"_pdf"+std::to_string(n)+".txt");
  271. //S-wave
  272. double sWaveStepSize = 0.01;
  273. params[b]->FS.init(SwaveFraction, 0.0, 1.0, sWaveStepSize);
  274. //B0 fit results
  275. params[b]->SS1.init(-0.231, -1.0, 1.0, (opts.full_angular || opts.folding != 4 ? sWaveStepSize : 0.0));
  276. params[b]->SS2.init( 0.023, -1.0, 1.0, (opts.full_angular || opts.folding == 1 ? sWaveStepSize : 0.0));
  277. params[b]->SS3.init( 0.003, -1.0, 1.0, (opts.full_angular || opts.folding == 2 ? sWaveStepSize : 0.0));
  278. params[b]->SS4.init( 0.001, -1.0, 1.0, (opts.full_angular || opts.folding > 2 ? sWaveStepSize : 0.0));
  279. params[b]->SS5.init(-0.068, -1.0, 1.0, (opts.full_angular ? sWaveStepSize : 0.0));
  280. if(opts.fit_mkpi || opts.use_mkpi){
  281. params[b]->gammakstar.init(0.0503, 0.01, 0.8, 0.001); //PDG value
  282. params[b]->mkstar.init(PDGMASS_K_STAR_PLUS / 1000., 0.7, 1.2, 0.001); //PDG value
  283. params[b]->gammakstarplus.init(0.236, 0.1, 1.0, 0.0); //PDG value
  284. params[b]->mkstarplus.init(1.41, 1.2, 1.6, 0.0); //PDG value
  285. params[b]->asphase.init(TMath::Pi(), 0.0, 2.0*TMath::Pi(), 0.0);
  286. params[b]->a.init(1.95, 0.001, 20.0, 0.0);
  287. params[b]->r.init(1.78, 0.001, 10.0, 0.0);
  288. //background parameter
  289. if(params[b]->f_sig() != 1.0){
  290. params[b]->cbkgmkpi0.init(1.0, -1.0, 1.0, 0.0);
  291. params[b]->cbkgmkpi1.init(0.0, -1.0, 1.0, 0.01);
  292. params[b]->cbkgmkpi2.init(0.0, -1.0, 1.0, 0.0);
  293. params[b]->cbkgmkpi3.init(0.0, -1.0, 1.0, 0.0);
  294. params[b]->cbkgmkpi4.init(0.0, -1.0, 1.0, 0.0);
  295. opts.mkpi_threshold = false;
  296. params[b]->nthreshold.init(1.5, 0.0, 15.0, 0.0);
  297. }
  298. }
  299. //define center of q2bin as effective q2:
  300. params[b]->eff_q2.init((UseBinnedFit ? 0.5*(opts.TheQ2binsmin.at(b)+opts.TheQ2binsmax.at(b)) : 6.0), opts.TheQ2binsmin.front(), opts.TheQ2binsmax.back(), 0.0);
  301. //if only mass fit: do not active angles in fit, i.e. set stepsize to 0.0
  302. double angleStepSize = opts.only_Bmass ? 0.0 : 0.001;
  303. if(params[b]->f_sig.get_value() == 0.0)
  304. angleStepSize = 0.0;
  305. if(opts.fit_fl)
  306. //params[b]->Fl.init(3.0/4.0*(s1c[b]-s2c[b]/3.0), 0.0, 1.0, angleStepSize);
  307. params[b]->Fl.init(1.0-4.0/3.0*s1s[b], 0.0, 1.0, angleStepSize);
  308. else
  309. params[b]->S1s.init(s1s[b], -1.0, 1.0, angleStepSize);
  310. params[b]->S3.init(s3[b], -1.0, 1.0, angleStepSize/10.);
  311. params[b]->S4.init(s4[b], -1.0, 1.0, (opts.full_angular || opts.folding == 1 ? angleStepSize : 0.0));
  312. params[b]->S5.init(s5[b], -1.0, 1.0, (opts.full_angular || opts.folding == 2 ? angleStepSize : 0.0));
  313. if(opts.fit_afb)
  314. params[b]->Afb.init(3.0/4.0*s6s[b], -0.75, 0.75, (opts.full_angular || opts.folding == 0 ? angleStepSize: 0.0));
  315. else
  316. params[b]->S6s.init(s6s[b], -1.0, 1.0, (opts.full_angular || opts.folding == 0 ? angleStepSize : 0.0));
  317. params[b]->S7.init(s7[b], -1.0, 1.0, (opts.full_angular || opts.folding == 3 ? angleStepSize/10. : 0.0));
  318. params[b]->S8.init(s8[b], -1.0, 1.0, (opts.full_angular || opts.folding == 4 ? angleStepSize/10. : 0.0));
  319. params[b]->S9.init(s9[b], -1.0, 1.0, (opts.full_angular || opts.folding == 0 ? angleStepSize/100. : 0.0));
  320. if(!opts.flat_bkg){
  321. //ctl
  322. params[b]->cbkgctl0.init(1.0, -1.0, 1.0, 0.0);
  323. params[b]->cbkgctl2.init(0.0, -1.0, 1.0, 0.01);
  324. params[b]->cbkgctl4.init(0.0, -1.0, 1.0, 0.0);
  325. if(opts.full_angular || opts.folding == 0){
  326. params[b]->cbkgctl1.init(0.0, -1.0, 1.0, 0.01);
  327. params[b]->cbkgctl3.init(0.0, -1.0, 1.0, 0.0);
  328. }
  329. else{
  330. params[b]->cbkgctl1.init(0.0, -1.0, 1.0, 0.0);
  331. params[b]->cbkgctl3.init(0.0, -1.0, 1.0, 0.0);
  332. }
  333. //ctk
  334. params[b]->cbkgctk0.init(1.0, -1.0, 1.0, 0.0);
  335. params[b]->cbkgctk2.init(0.05, -1.0, 1.0, 0.01);
  336. params[b]->cbkgctk4.init(0.0, -1.0, 1.0, 0.0);
  337. if(opts.full_angular || opts.folding != 4){
  338. params[b]->cbkgctk1.init(0.1, -1.0, 1.0, 0.01);
  339. params[b]->cbkgctk3.init(0.0, -1.0, 1.0, 0.0);
  340. }
  341. else{
  342. params[b]->cbkgctk1.init(0.0, -1.0, 1.0, 0.0);
  343. params[b]->cbkgctk3.init(0.0, -1.0, 1.0, 0.0);
  344. }
  345. //phi
  346. params[b]->cbkgphi0.init(1.0, -1.0, 1.0, 0.0);
  347. params[b]->cbkgphi2.init(0.0, -1.0, 1.0, 0.0);
  348. params[b]->cbkgphi4.init(0.0, -1.0, 1.0, 0.0);
  349. if(opts.full_angular || opts.folding == 0 || opts.folding == 3 || opts.folding == 4){
  350. params[b]->cbkgphi1.init(0.0, -1.0, 1.0, 0.0);
  351. params[b]->cbkgphi3.init(0.0, -1.0, 1.0, 0.0);
  352. }
  353. else{
  354. params[b]->cbkgphi1.init(0.0, -1.0, 1.0, 0.0);
  355. params[b]->cbkgphi3.init(0.0, -1.0, 1.0, 0.0);
  356. }
  357. params[b]->load_only_bckgnd_param_values(("fitresult_OnlyBckgnd_bin"+std::to_string(b)+".txt").c_str());
  358. }
  359. }
  360. else{
  361. //S-wave
  362. double sWaveStepSize = 0.01;
  363. params[b]->FS.init(SwaveFraction, 0.0, 1.0, sWaveStepSize);
  364. /*
  365. //JPSI Fit results
  366. params[b]->SS1.init( 0.549, -1.0, 1.0, (opts.full_angular || opts.folding != 4 ? sWaveStepSize : 0.0));
  367. params[b]->SS2.init(-0.128, -1.0, 1.0, (opts.full_angular || opts.folding == 1 ? sWaveStepSize : 0.0));
  368. params[b]->SS3.init( 0.003, -1.0, 1.0, (opts.full_angular || opts.folding == 2 ? sWaveStepSize : 0.0));
  369. params[b]->SS4.init(-0.006, -1.0, 1.0, (opts.full_angular || opts.folding > 2 ? sWaveStepSize : 0.0));
  370. params[b]->SS5.init(-0.149, -1.0, 1.0, (opts.full_angular ? sWaveStepSize : 0.0));
  371. */
  372. //B0 fit results
  373. params[b]->SS1.init(-0.231, -1.0, 1.0, (opts.full_angular || opts.folding != 4 ? sWaveStepSize : 0.0));
  374. params[b]->SS2.init( 0.023, -1.0, 1.0, (opts.full_angular || opts.folding == 1 ? sWaveStepSize : 0.0));
  375. params[b]->SS3.init( 0.003, -1.0, 1.0, (opts.full_angular || opts.folding == 2 ? sWaveStepSize : 0.0));
  376. params[b]->SS4.init( 0.001, -1.0, 1.0, (opts.full_angular || opts.folding > 2 ? sWaveStepSize : 0.0));
  377. params[b]->SS5.init(-0.068, -1.0, 1.0, (opts.full_angular ? sWaveStepSize : 0.0));
  378. params[b]->reset_parameters();
  379. }
  380. //create vectors to save parameter values for pull plots:
  381. if(n == 0){
  382. if(doToyPulls || doMCPulls){
  383. UInt_t pp = 0;
  384. for(UInt_t p = 0; p < params[b]->nparameters(); p++){
  385. if(params[b]->get_parameter(p)->get_step_size() != 0.0){
  386. if(b == 0){
  387. std::vector< std::vector<double> >pulls_per_parameter;
  388. pull_values.push_back(pulls_per_parameter);
  389. std::vector< std::vector<double> >errors_per_parameter;
  390. pull_errors.push_back(errors_per_parameter);
  391. std::vector<double>starts_per_parameter;
  392. pull_starts.push_back(starts_per_parameter);
  393. var_indexs.push_back(p);
  394. }
  395. //check that vectors have same size and that no alloc error occurs:
  396. assert(pp < pull_values.size());
  397. assert(var_indexs.size() == pull_values.size());
  398. assert(pp < pull_errors.size());
  399. assert(var_indexs.size() == pull_errors.size());
  400. assert(pp < pull_starts.size());
  401. assert(var_indexs.size() == pull_starts.size());
  402. //save vectors for values and start values to matrices
  403. std::vector<double>pulls_per_param_per_bin;
  404. pull_values.at(pp).push_back(pulls_per_param_per_bin);
  405. std::vector<double>errors_per_param_per_bin;
  406. pull_errors.at(pp).push_back(errors_per_param_per_bin);
  407. pull_starts.at(pp).push_back(params[b]->get_parameter(p)->get_start_value());
  408. //increase parameter index:
  409. pp++;
  410. }
  411. }
  412. }
  413. }
  414. //pdf
  415. prob[b] = new fcnc::bu2kstarmumu_pdf(&opts, params[b]);
  416. if(opts.use_angular_acc || opts.weighted_fit){
  417. prob[b]->load_coeffs_eff_phsp_4d();
  418. }
  419. prob[b]->update_cached_normalization(params[b]);
  420. //create vector with events according to the requested fits/pulls
  421. selection.clear();
  422. Double_t nEvents = 0.;
  423. if(UseBinnedFit){
  424. nEvents *= f_signal.at(b)+f_bckgnd.at(b);
  425. }
  426. else
  427. nEvents = nToyEvents;
  428. std::cout << "Generate " << nEvents << " events!" << std::endl;
  429. gen = new fcnc::bu2kstarmumu_generator(&opts);
  430. selection = gen->generate(nEvents, params[b], prob[b]);
  431. //delete gen;
  432. if(!opts.full_angular && opts.always_generate_full_angular){
  433. for(UInt_t ee = 0; ee < selection.size(); ee++){
  434. fldr.fold(&selection.at(ee));
  435. }
  436. }
  437. //check if all angles are almost 0.0
  438. if(false){
  439. for(UInt_t i = 0; i < selection.size(); i++)
  440. if((fabs(selection.at(i).costhetak) < 0.001) && (fabs(selection.at(i).costhetal) < 0.001) && (fabs(selection.at(i).phi) < 0.001))
  441. std::cout << "[WARNING]\tEvent" << i << "\tctk: " << selection.at(i).costhetak << "\tctl: " << selection.at(i).costhetal << "\tphi: " << selection.at(i).phi << std::endl;
  442. }
  443. if(n == 0)events_per_bin.push_back(selection.size());
  444. //deactive the S-wave for the fit!
  445. /*
  446. opts.swave = false;
  447. params[b]->FS.init(0.0, 0.0, 1.0, 0.0);
  448. params[b]->SS1.init( 0.0, -1.0, 1.0, 0.0);
  449. params[b]->SS2.init( 0.0, -1.0, 1.0, 0.0);
  450. params[b]->SS3.init( 0.0, -1.0, 1.0, 0.0);
  451. params[b]->SS4.init( 0.0, -1.0, 1.0, 0.0);
  452. params[b]->SS5.init( 0.0, -1.0, 1.0, 0.0);
  453. */
  454. //set values to jpsi results for the fit!
  455. params[b]->FS.init(0.0, 0.0, 1.0, 0.0);
  456. params[b]->SS1.init( 0.549, -1.0, 1.0, 0.0);
  457. params[b]->SS2.init(-0.128, -1.0, 1.0, 0.0);
  458. params[b]->SS3.init( 0.003, -1.0, 1.0, 0.0);
  459. params[b]->SS4.init(-0.006, -1.0, 1.0, 0.0);
  460. params[b]->SS5.init(-0.149, -1.0, 1.0, 0.0);
  461. //make sure that the correct coefficients are chosen for the fit:
  462. if(!opts.full_angular && (opts.use_angular_acc || opts.weighted_fit) && opts.always_generate_full_angular){
  463. prob[b]->load_coeffs_eff_phsp_4d();
  464. prob[b]->update_cached_normalization(params[b]);
  465. }
  466. //fit the events:
  467. bool do_fit = true;
  468. int fitresult = 0;
  469. if(do_fit){
  470. fitresult = f.fit(prob[b], params[b], &selection);
  471. }
  472. else{ //don't fit, just update the efficiencies
  473. fitresult = 300;
  474. if(opts.use_angular_acc || opts.weighted_fit){
  475. prob[b]->update_cached_efficiencies(params[b], &selection);
  476. }
  477. }
  478. fitresults.push_back(fitresult);
  479. //nametag per bin!
  480. std::string plotname;
  481. plotname = "ToyGen_"+std::to_string(nToyEvents)+"ToyEvents_FS_"+std::to_string(SwaveFraction)+"_";
  482. plotname.append(angularsuffix);
  483. if(UseBinnedFit){
  484. plotname.append("_bin"+std::to_string(b));
  485. if(Fit1bin)
  486. plotname.append("_1BIN");
  487. if(Fit2bins)
  488. plotname.append("_2BINS");
  489. if(FitAllbins)
  490. plotname.append("_9BINS");
  491. }
  492. //plot the current pdf with event data:
  493. if(n == 0 && opts.write_eps){
  494. std::cout << "PLOT: " << selection.size() << " events" << std::endl;
  495. thePlotter.plot_data(prob[b], params[b], &selection, get_PullPlot_path(), plotname+"_Fit"+std::to_string(n), true);
  496. //add pdfs for all binning:
  497. thePDFs.at(b).push_back(prob[b]);
  498. theParameters.at(b).push_back(params[b]);
  499. }
  500. //save param values to pull_values vector:
  501. if(doToyPulls){
  502. for(UInt_t p = 0; p < var_indexs.size(); p++){
  503. int index = var_indexs.at(p);
  504. double val = params[b]->get_parameter(index)->get_value();
  505. double err = params[b]->get_parameter(index)->get_error();
  506. pull_values.at(p).at(b).push_back(val);
  507. pull_errors.at(p).at(b).push_back(err);
  508. //save values to tree:
  509. treeValue = params[b]->get_parameter(index)->get_value();
  510. treeStart = params[b]->get_parameter(index)->get_start_value();
  511. treeError = params[b]->get_parameter(index)->get_error();
  512. treeErrorUp = params[b]->get_parameter(index)->get_error_up();
  513. treeErrorDown = params[b]->get_parameter(index)->get_error_down();
  514. treeIndex = index;
  515. treeBin = b;
  516. treeFitNumber = n;
  517. treeFitResult = fitresult;
  518. //treeVarName = params[b]->get_parameter(index)->get_name();
  519. //treeVarDesc = params[b]->get_parameter(index)->get_description();
  520. T->Fill();
  521. }
  522. }
  523. }
  524. }
  525. //save TTree to .root file:
  526. if(doToyPulls){
  527. TFile * F = new TFile(("PullResults_"
  528. +std::to_string(job_id == -10 ? nMCEvents : nToyEvents)
  529. +(job_id == -10 ? "_MC_" : "_Toys_")
  530. +std::to_string(nPulls)+"_Fits_"
  531. +angularsuffix
  532. +"_F_S_"+std::to_string(SwaveFraction)
  533. +(job_id >= 0 ? "_job"+std::to_string(job_id) : "")
  534. +".root").c_str(), "RECREATE");
  535. F->cd();
  536. T->Write();
  537. F->Close();
  538. delete T;
  539. }
  540. }