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.

445 lines
18 KiB

  1. //Libraries used for the B+ mass fit model
  2. //Renata Kopecna
  3. #ifndef MASSFIT_HPP
  4. #define MASSFIT_HPP
  5. #include "GlobalFunctions.hh"
  6. #include "RooFit/RooDoubleCB/RooDoubleCB.h"
  7. #include "BmassShape/SignalPdf.hpp"
  8. using namespace std;
  9. using namespace RooFit;
  10. using namespace RooStats;
  11. //////////////////////////////////////////////////////
  12. /// \brief GetsWeightPlots()
  13. //////////////////////////////////////////////////////
  14. ///
  15. /// Returns path where the sWeighting control plots are stored
  16. ///
  17. //////////////////////////////////////////////////////
  18. /// \brief massFit()
  19. //////////////////////////////////////////////////////
  20. /// Based on quickFit in nTrackWeights.cc, but made into a seperate file
  21. /// in on order to be able to be run as a standalone code
  22. ///
  23. /// Main purpose is to fit the Bmass distribution and save the yield of the fit.
  24. /// the fitted B+ mass spectrum may be saved in pdf and root files
  25. ///
  26. ///
  27. /// FEATURES:
  28. /// - choose your background and signal model:
  29. /// signal: (double) Gaussian, left/right/double/two-tailed CrystalBall function
  30. /// background: (double) Exponential, Exponential plus RooExpGaus or no background
  31. /// - get signal shape from MC data if needed and restrict shape to these parameters
  32. /// - choose if fit all data, Jpsi q^2 region or q^2 region without resonances
  33. /// - choose if fit low/high q^2 region
  34. /// - choose to fit LL/DD Kshort sample
  35. /// - choose to fit up/down/both
  36. /// - choose to fit per year or per run///
  37. ///
  38. /// OPTIONAL:
  39. /// - cut on TMVAresponse
  40. /// - fit only randomly selected half of the data sample
  41. /// - Calculate yield in a 2sigma/fixed window
  42. /// - Calculate yield over the full region
  43. /// - Turn off the fit of MC needed to get the shape parameters (usefull in loops)
  44. /// - Save the mass plots in efficiency file
  45. /// - Fit in bins of selected variable
  46. ///
  47. /// - from the fit to the B+ mass distribution, a sPlot weight is calculated and saved to a new Branch in this merged file.
  48. /// If only Jpsi is selected, Reference channel is used and if sWeight==true,
  49. /// J/psi data only is saved
  50. ///
  51. //////////////////////////////////////////////////////
  52. /// \brief quickFit()
  53. //////////////////////////////////////////////////////
  54. ///
  55. /// massFit() with simplified options
  56. /// suitable for reweighting MC and creating sPlots
  57. ///
  58. /////////////////////////////////////////////////////////
  59. /// efficiencyFit()
  60. //////////////////////////////////////////////////////
  61. ///
  62. /// \brief massFit() with simplified options
  63. /// suitable for efficiency estimation fits
  64. ///
  65. /////////////////////////////////////////////////////////
  66. /// \brief basicYieldFit()
  67. //////////////////////////////////////////////////////
  68. ///
  69. /// massFit() with simplified options
  70. /// suitable for getting yield information
  71. ///
  72. /// Available also to be done for:
  73. /// All years
  74. /// All years and q2 regions
  75. /// Both Runs
  76. ///
  77. /////////////////////////////////////////////////////////
  78. /// \brief massFitTestAll()
  79. //////////////////////////////////////////////////////
  80. ///
  81. /// Fits given data sample with different
  82. /// signal and background shapes, useful
  83. /// when deciding what shape describes
  84. /// the data the best
  85. ///
  86. //////////////////////////////////////////////////////
  87. /// \brief PrintFitResults()
  88. //////////////////////////////////////////////////////
  89. /// Takes RooFitResult as an iput and prints its content
  90. ///
  91. ///
  92. ///
  93. //////////////////////////////////////////////////////
  94. /// TODO at some point
  95. /// \param year
  96. /// \param UseOnlyJpsiEvents
  97. /// \param UseOnlyMuMuEvents
  98. /// \param KshortDecaysInVelo
  99. /// \param GetShapeFromMC
  100. /// \param SigType
  101. /// \param BckGndType
  102. /// \param ConstrainParameters
  103. ///
  104. ///
  105. ///
  106. class TMefficiencyClass{
  107. public:
  108. string sVariable;
  109. std::vector<string> sBranchName;
  110. Int_t Bins;
  111. Float_t Range[2];
  112. std::vector<std::array<double, 2>> vVarRange;
  113. std::vector<double> binEdges;
  114. std::vector<double> binEdgesEquidistant;
  115. bool isEquidistant;
  116. Float_t Step;
  117. string cut;
  118. TMefficiencyClass(){ //default constructor
  119. sVariable = "";
  120. sBranchName = {};
  121. Bins = 0;
  122. Range[0] = 0.;
  123. Range[1] = 0.;
  124. vVarRange = {};
  125. binEdges = {};
  126. binEdgesEquidistant = {};
  127. cut = "";
  128. }
  129. void fillBinEdges(){
  130. double step = (Range[1] - Range[0]) / Bins;
  131. for (int i = 0; i <= Bins; i++){
  132. binEdgesEquidistant.push_back(Range[0]+i*step);
  133. }
  134. return;
  135. }
  136. void isEq(string &varName){ //'_equal' has to appear at the end of the variable!
  137. //See if the '_equal' is present
  138. size_t found = varName.find("_equal");
  139. if (found != string::npos) isEquidistant = true;
  140. else isEquidistant = false;
  141. //Remove '_equal' from the string
  142. replace(varName,"_equal","");
  143. }
  144. bool check_vector_size(bool isEqui){
  145. if (!isEqui){
  146. if (int(binEdges.size()) != Bins+1){
  147. coutDebug("Bins edges should be " + to_string(Bins+1) + " and are " + to_string(binEdges.size()));
  148. coutERROR("Wrong number of bin edges! Check " + sVariable);
  149. return false;
  150. }
  151. else return true;
  152. }
  153. else{
  154. if (int(binEdgesEquidistant.size()) != Bins+1){
  155. coutDebug("Bins edges should be " + to_string(Bins+1) + " and are " + to_string(binEdgesEquidistant.size()));
  156. coutERROR("Wrong number of bin edges! Check " + sVariable);
  157. return false;
  158. }
  159. else return true;
  160. }
  161. }
  162. TMefficiencyClass(string varName){ // constructor
  163. //first, replace the variable name
  164. isEq(varName);
  165. coutDebug("Is equidistant? " + to_string(isEquidistant));
  166. //q^2:
  167. if (varName == "q2"){
  168. sVariable = "q^{2} [MeV^{2}]";
  169. sBranchName = {"Q2"};
  170. Bins = 10;
  171. Range[0] = 0.; // in MeV^2
  172. Range[1] = 20000000.; // in MeV^2
  173. vVarRange = {{Range[0],Range[1]}};
  174. fillBinEdges();
  175. binEdges = {};
  176. cut = sBranchName.at(0);
  177. }
  178. else if (varName == "q2_binned"){ //binned as in the analysis
  179. sVariable = "q^{2} [GeV^{2}]";
  180. sBranchName = {"Q2"};
  181. Bins = 11;
  182. Range[0] = 0.1e6; // in MeV^2
  183. Range[1] = 20e6;
  184. vVarRange = {{Range[0],Range[1]}};
  185. fillBinEdges();
  186. binEdges = {0.1e6, 0.98e6, 1.1e6, 2.5e6, 4.0e6, 6.0e6, 8.0e6, 11.0e6, 12.5e6, 15.0e6, 17.0e6, 20.0e6};
  187. cut = sBranchName.at(0);
  188. }
  189. else if (varName == "q2_binned_fit"){ //binned as in the analysis
  190. sVariable = "q^{2} [GeV^{2}]";
  191. sBranchName = {"Q2"};
  192. Bins = 6;
  193. Range[0] = 1.1e6; // in MeV^2
  194. Range[1] = 20e6;
  195. vVarRange = {{Range[0],Range[1]}};
  196. fillBinEdges();
  197. binEdges = {0.1e6, 4.0e6, 8.0e6, 11.0e6, 12.5e6, 15.0e6, 20.0e6};
  198. cut = sBranchName.at(0);
  199. }
  200. //cos(Theta_k):
  201. else if (varName == "thetak"){
  202. sVariable = "cos(#theta_{k})";
  203. sBranchName = {"B_plus_ThetaK"};
  204. Bins = 10;
  205. Range[0] = -1.0;
  206. Range[1] = 1.0;
  207. //Range[0] = 0.;
  208. //Range[1] = 3.142;
  209. Step = (Range[1] - Range[0]) / Bins;
  210. fillBinEdges();
  211. binEdges = {0.000, 1.053, 1.294, 1.488, 1.662, 1.827, 1.993, 2.163, 2.353, 2.585, 3.150};
  212. vVarRange = {{0.,3.142}};
  213. cut = "cos(B_plus_ThetaK)";
  214. }
  215. //cos(Theta_l):
  216. else if (varName == "thetal"){
  217. sVariable = "cos(#theta_{l})";
  218. sBranchName = {"B_plus_ThetaL"};
  219. Bins = 10;
  220. Range[0] = -1.0;
  221. Range[1] = 1.0;
  222. //Range[0] = 0.;
  223. //Range[1] = 3.142;
  224. Step = (Range[1] - Range[0]) / Bins;
  225. fillBinEdges();
  226. binEdges = {0.000, 0.630, 0.896, 1.110, 1.302, 1.486, 1.670, 1.866, 2.086, 2.368, 3.150};
  227. vVarRange = {{0.,3.142}};
  228. cut = "cos(B_plus_ThetaL)";
  229. }
  230. //phi
  231. else if (varName == "phi"){
  232. sVariable = "#phi";
  233. sBranchName = {"B_plus_Phi"};
  234. Bins = 10;
  235. Range[0] = -3.15;
  236. Range[1] = 3.15;
  237. Step = (Range[1] - Range[0]) / Bins;
  238. fillBinEdges();
  239. binEdges = {-3.150, -2.476, -1.832, -1.207, -0.593, 0.015, 0.624, 1.241, 1.870, 2.517, 3.150};
  240. vVarRange = {{Range[0],Range[1]}};
  241. cut = sBranchName.at(0);
  242. }
  243. else if (varName == "pi_zero_ETA"){
  244. sVariable = "#eta(#pi^{0})";
  245. sBranchName = {"pi_zero_resolved_ETA_DTF"};
  246. Bins = 10;
  247. Range[0] = 1.5;
  248. Range[1] = 4.5;
  249. Step = (Range[1] - Range[0]) / Bins;
  250. fillBinEdges();
  251. binEdges = {};
  252. vVarRange = {{Range[0],Range[1]}};
  253. cut = sBranchName.at(0);
  254. }
  255. else if (varName == "pi_zero_ETA-K_plus_ETA"){
  256. sVariable = "|#eta(#pi^{0})-#eta(K^{+})|";
  257. sBranchName = {"pi_zero_resolved_ETA_DTF","K_plus_ETA_DTF"};
  258. Bins = 15;
  259. Range[0] = 0.0;
  260. Range[1] = 1.0;
  261. Step = (Range[1] - Range[0]) / Bins;
  262. fillBinEdges();
  263. binEdges = {};
  264. vVarRange = {{0.0,5.0},{0.0,5.0}};
  265. cut = "TMath::Abs(pi_zero_resolved_ETA_DTF-K_plus_ETA_DTF)";
  266. }
  267. else if (varName == "pi_zero_P"){
  268. sVariable = "log(P(#pi^{0}))";
  269. sBranchName = {"pi_zero_resolved_P"};
  270. Bins = 10;
  271. Range[0] = 2980; //not log!
  272. Range[1] = 100000;//not log!
  273. Step = (Range[1] - Range[0]) / Bins;
  274. fillBinEdges();
  275. binEdges = {8.0, 8.75367, 9.01297, 9.21333, 9.38583, 9.55554, 9.72447, 9.90965, 10.1241, 10.405, 11.5};
  276. vVarRange = {{Range[0],Range[1]}};
  277. cut = "log(pi_zero_resolved_P)";//TODO fix equidistant binning, now based on 2016 PHSP
  278. }
  279. else if (varName == "pi_zero_P_DTF"){
  280. sVariable = "log(P(#pi^{0}^{DTF}})";
  281. sBranchName = {"pi_zero_resolved_P_DTF"};
  282. Bins = 10;
  283. Range[0] = 2980; //not log!
  284. Range[1] = 100000;//not log!
  285. Step = (Range[1] - Range[0]) / Bins;
  286. fillBinEdges();
  287. binEdges = {8.0, 8.7508, 9.01136, 9.20829, 9.38185, 9.55001, 9.723, 9.90559, 10.1195, 10.4024, 11.5};
  288. vVarRange = {{Range[0],Range[1]}};
  289. cut = "log(pi_zero_resolved_P_DTF)";//TODO fix equidistant binning, now based on 2016 PHSP
  290. }
  291. else if (varName == "pi_zero_PT"){
  292. sVariable = "log(P_{T}(#pi^{0}))";
  293. sBranchName = {"pi_zero_resolved_PT"};
  294. Bins = 10;
  295. Range[0] = 800; //not log!
  296. Range[1] = 8000;//not log!
  297. Step = (Range[1] - Range[0]) / Bins;
  298. fillBinEdges();
  299. binEdges = {6.5, 6.81709, 6.91294, 7.01023, 7.11076, 7.21995, 7.34191, 7.48141, 7.64965, 7.88324, 9.0};
  300. vVarRange = {{Range[0],Range[1]}};
  301. cut = "log(pi_zero_resolved_PT)"; //TODO fix equidistant binning, now based on 2016 PHSP
  302. }
  303. else if (varName == "pi_zero_PT_DTF"){
  304. sVariable = "log(P_{T}(#pi^{0})^{DTF})";
  305. sBranchName = {"pi_zero_resolved_PT_DTF"};
  306. Bins = 10;
  307. Range[0] = 800; //not log!
  308. Range[1] = 8000;//not log!
  309. Step = (Range[1] - Range[0]) / Bins;
  310. fillBinEdges();
  311. binEdges = {6.5, 6.8152, 6.91109, 7.00766, 7.10771, 7.21609, 7.33793, 7.47641, 7.64706, 7.88087, 9.0};
  312. vVarRange = {{Range[0],Range[1]}};
  313. cut = "log(pi_zero_resolved_PT_DTF)";//TODO fix equidistant binning, now based on 2016 PHSP
  314. }
  315. else if (varName == "K_plus_PT"){
  316. sVariable = "log(P_{T} (K^{+})) [MeV^{2}]";
  317. sBranchName = {"K_plus_PT"};
  318. Bins = 10;
  319. Range[0] = 270; //not log!
  320. Range[1] = 16000;//not log!
  321. Step = (Range[1] - Range[0]) / Bins;
  322. fillBinEdges();
  323. binEdges = {5.6, 6.658, 6.91969, 7.12516, 7.30566, 7.47015, 7.64604, 7.8327, 8.04823, 8.35614, 9.7};
  324. vVarRange = {{Range[0],Range[1]}};
  325. cut = "log(K_plus_PT)";
  326. }
  327. else{
  328. sVariable = "";
  329. sBranchName = {};
  330. Bins = 1;
  331. Range[0] = 0.;
  332. Range[1] = 0.;
  333. vVarRange = {};
  334. fillBinEdges();
  335. binEdges={Range[0],Range[1]};
  336. Step = 0;
  337. cut = "";
  338. isEquidistant = false;
  339. }
  340. if (!check_vector_size(isEquidistant)){
  341. sVariable = "";
  342. sBranchName = {};
  343. Bins = 0;
  344. Range[0] = 0.;
  345. Range[1] = 0.;
  346. vVarRange = {};
  347. fillBinEdges();
  348. Step = 0;
  349. cut = "";
  350. }
  351. }
  352. ~TMefficiencyClass(); //destuctor
  353. };
  354. TMefficiencyClass::~TMefficiencyClass(){}//destuctor
  355. bool useExtraVarBool(string extraVar);
  356. string GetsWeightPlots(string year, bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, bool KshortDecaysInVelo, bool GetShapeFromMC, string SignalType, string BkgType, bool ConstrainParameters);
  357. double massFit(string year, string magnet, int Run,
  358. bool MC, bool Preselected, bool TM, bool PHSP, //input/output file selection
  359. bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, //signal/reference
  360. bool GetShapeFromMC, string SigType, string BkgType, bool ConstrainParameters, //shape
  361. bool KshortDecaysInVelo, bool UseLowQ2Range, //LL/DD? q2range?
  362. Double_t TMVAcut, int randomSubset, //TMVA options
  363. bool fixedMassRegion, bool yieldOverFullRange, //yield calculation region
  364. bool sWeight, //sWeight data?
  365. bool loopFit, bool IsEfficiency, //additional options
  366. string sExtraVar, int nExtraBin, //fit in bins of extra variable
  367. bool removeMultiple, //Remove multiple candidates?
  368. bool weighted, bool weightedFromPi0, string whichWeight, //use weight in the fit?
  369. bool nonTM, string customTMbranch, bool gammaTM, //TM options
  370. bool InclusiveSample);
  371. int quickFit(string year, bool MC, bool sWeight, bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, bool KshortDecaysInVelo, bool GetShapeFromMC, string SigType, string BkgType, bool ConstrainParameters);
  372. int efficiencyFit(std::string year, string magnet, int Run ,
  373. bool Preselected, bool TM, bool PHSP, //input/output file selection
  374. bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, //signal/reference
  375. bool GetShapeFromMC, std::string SigType , std::string BckGndType , bool ConstrainParameters, //shape
  376. bool KshortDecaysInVelo, //LL/DD?
  377. Double_t TMVAcut, //TMVA options
  378. bool fixedMassRegion, //yield calculation region
  379. bool UseLowQ2Range, //q2 ranges
  380. string sExtraVar, int nExtraBin, bool removeMultiple,
  381. bool weighted, bool weightedFromPi0, string whichWeight, string customTMbranch, bool gammaTM);
  382. int basicYieldFit(std::string year, int Run ,
  383. bool MC, bool PHSP, //input/output file selection
  384. bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, //signal/reference
  385. bool GetShapeFromMC, std::string SigType , std::string BckGndType , bool ConstrainParameters, //shape
  386. bool KshortDecaysInVelo, bool UseLowQ2Range , //LL/DD? q2range?
  387. Double_t TMVAcut, //TMVA options
  388. bool fixedMassRegion, bool loopFit, bool removeMultiple);
  389. int basicYieldFitAllYears(bool MC, bool PHSP, //input/output file selection
  390. bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, //signal/reference
  391. bool GetShapeFromMC, std::string SigType , std::string BckGndType , bool ConstrainParameters, //shape
  392. bool KshortDecaysInVelo, bool UseLowQ2Range , //LL/DD? q2range?
  393. Double_t TMVAcut, //TMVA options
  394. bool fixedMassRegion, bool loopFit, bool removeMultiple);
  395. int basicFitAllYearsAndRegions(bool MC, bool PHSP, //input/output file selection
  396. bool GetShapeFromMC, std::string SigType , std::string BckGndType , bool ConstrainParameters, //shape
  397. bool KshortDecaysInVelo, bool UseLowQ2Range , //LL/DD? q2range?
  398. Double_t TMVAcut, bool removeMultiple //TMVA options, remove multiple
  399. );
  400. int basicYieldFitAllRuns(
  401. bool MC, //input/output file selection
  402. bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, //signal/reference
  403. bool GetShapeFromMC, std::string SigType , std::string BckGndType , bool ConstrainParameters, //shape
  404. bool KshortDecaysInVelo, bool UseLowQ2Range , //LL/DD? q2range?
  405. Double_t TMVAcut, //TMVA options
  406. bool fixedMassRegion, bool loopFit,bool removeMultiple//yield calculation region
  407. );
  408. //Print efficiencies and fit parameters
  409. int PrintFitResults(RooFitResult* fitRes);
  410. int fitJpsi(string year, bool MC, double TMVAcut, bool RemoveMultiple);
  411. #endif // MASSFIT_HPP