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.

355 lines
16 KiB

  1. /**
  2. * @file toystudy.cc
  3. * @author Renata Kopecna (cause I find 500 lines functioned defined in a header disgusting)
  4. * @date 2021-02-25
  5. *
  6. */
  7. #include <toystudy.hh>
  8. #include <iostream>
  9. #include <event.hh>
  10. #include <parameters.hh>
  11. #include <funcs.hh>
  12. #include <pdf.hh>
  13. #include <options.hh>
  14. #include <fitter.hh>
  15. #include <generator.hh>
  16. #include <multifit.hh>
  17. void fcnc::toystudy::toy(unsigned int nevents, unsigned int nruns, pdf* prob, parameters* params, generator* gen){
  18. std::vector<unsigned int> the_nevents;
  19. the_nevents.push_back(nevents);
  20. std::vector<pdf*> probs;
  21. probs.push_back(prob);
  22. std::vector<parameters*> the_params;
  23. the_params.push_back(params);
  24. std::vector<generator*> gens;
  25. gens.push_back(gen);
  26. toy(the_nevents, nruns, probs, the_params, gens);
  27. }
  28. void fcnc::toystudy::toy(std::vector<unsigned int> nevents, unsigned int nruns, std::vector<pdf*> pdfs, std::vector<parameters*> params, std::vector<generator*> gens){
  29. //Open texFile
  30. std::ofstream myFile;
  31. open_Latex_noteFile(latex_toyFile(), myFile);
  32. spdlog::info("Starting toy study on toy data");
  33. //unsigned int run_no = 0;
  34. spdlog::info("Will run over {0:d} runs with {1:d}", nruns, nevents.at(0));
  35. if (spdlog_info()){
  36. for (unsigned int i=1; i<nevents.size(); i++) std::cout << "/" << nevents.at(i);
  37. }
  38. spdlog::info(" events each.");
  39. //need this for jitter on constraints
  40. TRandom3* rnd = new TRandom3();
  41. rnd->SetSeed(0);//non-static seed
  42. //initialisation for histos and arrrays
  43. unsigned int nparams = 0;
  44. for (unsigned int i=0; i<params.size(); i++){
  45. nparams += params.at(i)->nparameters();
  46. }
  47. std::vector<double> pull_width(nparams, 0.0);
  48. std::vector<double> pull_mean(nparams, 0.0);
  49. std::vector<double> pull_width_sigma(nparams, 0.0);
  50. std::vector<double> pull_mean_sigma(nparams, 0.0);
  51. std::vector<double> pull_chisquared(nparams, 0.0);
  52. std::vector<double> value_width(nparams, 0.0);
  53. std::vector<double> value_mean(nparams, 0.0);
  54. std::vector<double> value_width_sigma(nparams, 0.0);
  55. std::vector<double> value_mean_sigma(nparams, 0.0);
  56. std::vector<double> value_chisquared(nparams, 0.0);
  57. std::vector<double> error_width(nparams, 0.0);
  58. std::vector<double> error_mean(nparams, 0.0);
  59. std::vector<double> error_width_sigma(nparams, 0.0);
  60. std::vector<double> error_mean_sigma(nparams, 0.0);
  61. std::vector<double> error_chisquared(nparams, 0.0);
  62. std::vector<std::vector<double> > errors(nparams, std::vector<double>());
  63. std::vector<std::vector<double> > errors_up(nparams, std::vector<double>());
  64. std::vector<std::vector<double> > errors_down(nparams, std::vector<double>());
  65. std::vector<std::vector<double> > values(nparams, std::vector<double>());
  66. std::vector<std::vector<double> > nominal_errors(nparams, std::vector<double>());
  67. std::vector<std::vector<double> > nominal_values(nparams, std::vector<double>());
  68. std::vector<int> return_values(nruns);
  69. std::vector<std::vector<std::vector<double> > > corrs(nparams, std::vector<std::vector<double> >());
  70. fcnc::fitter fit(opts);
  71. for (unsigned int i=0; i<pdfs.size(); i++){
  72. pdfs.at(i)->init(params.at(i));
  73. }
  74. fit.set_common_parameters(common_params);
  75. for (unsigned int i=0; i < nruns; i++) {
  76. spdlog::info("Starting run no. {0:d}", i + 1);
  77. //run_no = i;
  78. std::vector< std::vector<event> > temp_events;
  79. for (unsigned int j=0; j<gens.size(); j++){
  80. std::vector<event> ev = gens.at(j)->generate(nevents.at(j), params.at(j), pdfs.at(j));
  81. temp_events.push_back(ev);
  82. }
  83. std::vector< std::vector<event>* > events;
  84. for (unsigned int j=0; j<gens.size(); j++){
  85. events.push_back(&temp_events.at(j));
  86. }
  87. std::string num;
  88. std::stringstream out;
  89. out << (i+1);
  90. num = out.str();
  91. int result = 0;
  92. //in the case of constraints, jitter the mean value
  93. for (unsigned int j = 0; j < params.size(); j++){
  94. for (unsigned int k = 0; k < params.at(j)->nparameters(); k++){
  95. parameter* param = params.at(j)->get_parameter(k);
  96. double shift = rnd->Rndm() > 0.5 ? -fabs(rnd->Gaus(0.0, param->get_previous_error_low())) : fabs(rnd->Gaus(0.0, param->get_previous_error_high()));//TODO, actually should probably use PDG method
  97. if (param->get_gaussian_constraint()){
  98. param->set_previous_measurement(param->get_start_value() + shift);//rnd->Gaus(0.0, sigma));
  99. }
  100. }
  101. }
  102. if (opts->eos_bsz_ff){
  103. TMatrixD mU = fcnc::get_bsz_mu_invcov();
  104. std::vector<double> rndvec(21, 0.0);
  105. for (unsigned int i=0; i<21; i++){
  106. rndvec.at(i) = rnd->Gaus(0.0, 1.0);
  107. }
  108. std::vector<double> shiftvec(21, 0.0);
  109. for (unsigned int i=0; i<21; i++){
  110. for (unsigned int j=0; j<21; j++){
  111. shiftvec.at(i) += mU(j,i)*rndvec.at(j);//new order, corrected and tested
  112. }
  113. }
  114. for (unsigned int j = 0; j < params.size(); j++){
  115. if (params.at(j)->get_parameter("a0_0") != 0){
  116. //TODO: jitter according to covariance matrix given
  117. //std::vector<double> coeffvec(21, 0.0);// = nominal;//fcnc::legendre_coefficients_nominal;
  118. for (unsigned int i=0; i<21; i++){
  119. parameter* param = 0;
  120. switch (i) {
  121. case 0 : param = params.at(j)->get_parameter("a0_0"); break;
  122. case 1 : param = params.at(j)->get_parameter("a0_1"); break;
  123. case 2 : param = params.at(j)->get_parameter("a0_2"); break;
  124. case 3 : param = params.at(j)->get_parameter("a1_0"); break;
  125. case 4 : param = params.at(j)->get_parameter("a1_1"); break;
  126. case 5 : param = params.at(j)->get_parameter("a1_2"); break;
  127. //case 6 : param = params.at(j)->get_parameter(""); break;
  128. case 7 : param = params.at(j)->get_parameter("a12_1"); break;
  129. case 8 : param = params.at(j)->get_parameter("a12_2"); break;
  130. case 9 : param = params.at(j)->get_parameter("v_0"); break;
  131. case 10 : param = params.at(j)->get_parameter("v_1"); break;
  132. case 11 : param = params.at(j)->get_parameter("v_2"); break;
  133. case 12 : param = params.at(j)->get_parameter("t1_0"); break;
  134. case 13 : param = params.at(j)->get_parameter("t1_1"); break;
  135. case 14 : param = params.at(j)->get_parameter("t1_2"); break;
  136. //case 15 : param = params.at(j)->get_parameter(""); break;
  137. case 16 : param = params.at(j)->get_parameter("t2_1"); break;
  138. case 17 : param = params.at(j)->get_parameter("t2_2"); break;
  139. case 18 : param = params.at(j)->get_parameter("t23_0"); break;
  140. case 19 : param = params.at(j)->get_parameter("t23_1"); break;
  141. case 20 : param = params.at(j)->get_parameter("t23_2"); break;
  142. };
  143. if (param != 0){
  144. param->set_previous_measurement(param->get_start_value() + shiftvec.at(i));
  145. }
  146. }
  147. }
  148. }
  149. }
  150. //perform the actual fit
  151. result = fit.fit(pdfs, params, events, num);
  152. return_values.at(i) = result;
  153. if (result != 300 && opts->repeat_on_fail) {
  154. spdlog::error("Fit failed, repeating run");
  155. for (unsigned int j = 0; j < params.size(); j++){
  156. params.at(j)->reset_parameters();
  157. }
  158. i--;
  159. continue;
  160. }
  161. //extract the parameters from the fit
  162. unsigned int start_param = 0;
  163. for (unsigned int j = 0; j < params.size(); j++) {
  164. for (unsigned int k = 0; k < params.at(j)->nparameters(); k++){
  165. parameter* param = params.at(j)->get_parameter(k);
  166. unsigned int idx = start_param+k;
  167. values.at(idx).push_back(param->get_value());
  168. errors.at(idx).push_back(param->get_error());
  169. errors_up.at(idx).push_back(param->get_error_up());
  170. errors_down.at(idx).push_back(param->get_error_down());
  171. corrs.at(idx).push_back(param->correlations);//for some, this is empty
  172. }
  173. start_param += params.at(j)->nparameters();
  174. }
  175. //todo whats this? //I don't know, David. Sincerely, Renata
  176. for (unsigned int j = 0; j < nparams; j++){
  177. nominal_values.at(j).push_back(0.0);
  178. nominal_errors.at(j).push_back(0.0);
  179. }
  180. //Update pull histos every 10 steps or when finished.
  181. //if ((i+1 >= 100) && (((i+1)%100 == 0) || (i+1 == nruns)))
  182. if (i+1 == nruns) {
  183. //This should be done a little differently:
  184. //recreate histos every time, use min and max values as axis.
  185. start_param = 0;
  186. for (unsigned int j = 0; j < params.size(); j++){//this plots the pull histos
  187. for (unsigned int k = 0; k < params.at(j)->nparameters(); k++){//this plots the pull histos
  188. parameter* par = params.at(j)->get_parameter(k);
  189. if (par->get_step_size() != 0.0) {
  190. unsigned int idx = start_param+k;
  191. update_pull(par, values.at(idx),
  192. errors.at(idx),
  193. pull_mean[idx], pull_mean_sigma[idx],
  194. pull_width[idx], pull_width_sigma[idx],
  195. pull_chisquared[idx]);
  196. update_value(par, values.at(idx), errors.at(idx),
  197. value_mean[idx], value_mean_sigma[idx],
  198. value_width[idx], value_width_sigma[idx],
  199. value_chisquared[idx]);
  200. update_error(par, values.at(idx), errors.at(idx),
  201. error_mean[idx], error_mean_sigma[idx],
  202. error_width[idx], error_width_sigma[idx],
  203. error_chisquared[idx]);
  204. }
  205. }
  206. start_param += params.at(j)->nparameters();
  207. }
  208. }
  209. for (unsigned int j = 0; j < params.size(); j++){
  210. params.at(j)->reset_parameters();
  211. }
  212. spdlog::info("Run {0:d} finished", i + 1);
  213. }
  214. //delete rnd;
  215. //save result trees to root file
  216. //TFile* output;
  217. output->cd();
  218. int param_index = 0;
  219. unsigned int start_param = 0;
  220. for (unsigned int j = 0; j < params.size(); j++){
  221. for (unsigned int k = 0; k < params.at(j)->nparameters(); k++){
  222. parameter* param = params.at(j)->get_parameter(k);
  223. unsigned int idx = start_param+k;
  224. //for (unsigned int j = 0; j < nparams; j++)//this gives nice output
  225. if (param->get_step_size() != 0.0) {//todo common parameters, only save once...
  226. std::string parname(param->get_name());
  227. std::string pardesc(param->get_description());
  228. TTree* t = new TTree(parname.c_str(), pardesc.c_str());
  229. double value, error, error_up, error_down, start_value, nominal_value, nominal_error;
  230. int run, migrad, status_cov;
  231. double tmp_corr[corrs.at(idx).at(0).size()];
  232. t->Branch("run",&run,"run/I");
  233. t->Branch("value",&value,"value/D");
  234. t->Branch("error",&error,"error/D");
  235. t->Branch("error_up",&error_up,"error_up/D");
  236. t->Branch("error_down",&error_down,"error_down/D");
  237. t->Branch("start_value",&start_value,"start_value/D");
  238. t->Branch("migrad",&migrad,"migrad/I");
  239. t->Branch("status_cov",&status_cov,"status_cov/I");
  240. t->Branch("nominal_value",&nominal_value,"nominal_value/D");
  241. t->Branch("nominal_error",&nominal_error,"nominal_error/D");
  242. t->Branch("index",&param_index, "index/I");
  243. std::string corr_string = "correlations";
  244. std::stringstream corr_stream;
  245. corr_stream << "correlations[" << corrs.at(idx).at(0).size() << "]/D";
  246. t->Branch("correlations",&tmp_corr,corr_stream.str().c_str());
  247. for (unsigned int i=0; i<nruns; i++){
  248. run = i;
  249. if (param->is_blind()){
  250. value = values.at(idx).at(i) + param->get_blinding_delta();//TODO add delta
  251. }
  252. else{
  253. value = values.at(idx).at(i);//TODO add delta
  254. }
  255. error = errors.at(idx).at(i);
  256. if (param->is_blind()){
  257. nominal_value = nominal_values.at(idx).at(i) + param->get_blinding_delta();
  258. }
  259. else{
  260. nominal_value = nominal_values.at(idx).at(i);
  261. }
  262. nominal_error = nominal_errors.at(idx).at(i);
  263. error_up = errors_up.at(idx).at(i);
  264. error_down = errors_down.at(idx).at(i);
  265. if (param->is_blind()){
  266. start_value = param->get_start_value() + param->get_blinding_delta();
  267. }
  268. else{
  269. start_value = param->get_start_value();
  270. }
  271. migrad = return_values.at(i) % 100;
  272. status_cov = return_values.at(i) / 100;
  273. //corr = corrs.at(idx).at(i);
  274. for (unsigned int l = 0; l < corrs.at(idx).at(i).size(); l++){
  275. tmp_corr[l] = corrs.at(idx).at(i).at(l);
  276. }
  277. t->Fill();
  278. }
  279. t->Write();
  280. delete t;
  281. param_index++;
  282. }
  283. }
  284. start_param += params.at(j)->nparameters();
  285. }
  286. //latex output
  287. bool blind = false;
  288. for (unsigned int j = 0; j < params.size(); j++){
  289. if (!params.at(j)->is_blind()) blind = true;
  290. }
  291. spdlog::info("Toy Study results");
  292. if (!blind){
  293. myFile <<"\\begin{tabular}{|cccccccc|}\\hline" << std::endl;
  294. myFile <<"\\# & parameter & Mean Value & Mean Width & Mean Error & Error Width & Pull Mean & Pull Width \\\\ \\hline \\hline" << std::endl;
  295. start_param = 0;
  296. for (unsigned int j = 0; j < params.size(); j++)
  297. {
  298. for (unsigned int k = 0; k < params.at(j)->nparameters(); k++)
  299. {
  300. parameter* param = params.at(j)->get_parameter(k);
  301. unsigned int idx = start_param+k;
  302. if (param->get_step_size() != 0.0){
  303. std::string partex = param->get_description();
  304. myFile <<std::setw(2) << idx << " & $" << std::setw(22) << partex << "$ & $"
  305. << std::fixed << std::setprecision(4)
  306. << std::setw(7) << value_mean[idx] << " \\pm " << std::setw(7) << value_mean_sigma[idx] << "$ & $"
  307. << std::setw(7) << value_width[idx] << " \\pm " << std::setw(7) << value_width_sigma[idx] << "$ & $"
  308. << std::setw(7) << error_mean[idx] << " \\pm " << std::setw(7) << error_mean_sigma[idx] << "$ & $"
  309. << std::setw(7) << error_width[idx] << " \\pm " << std::setw(7) << error_width_sigma[idx] << "$ & $"
  310. << std::setw(7) << pull_mean[idx] << " \\pm " << std::setw(7) << pull_mean_sigma[idx] << "$ & $"
  311. << std::setw(7) << pull_width[idx] << " \\pm " << std::setw(7) << pull_width_sigma[idx] << "$ \\\\"
  312. << std::endl;
  313. }
  314. }
  315. start_param += params.at(j)->nparameters();
  316. }
  317. myFile <<"\\hline\\end{tabular}" << std::endl;
  318. }
  319. delete rnd;
  320. //Close Latex file
  321. myFile.close();
  322. }