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.

347 lines
14 KiB

  1. //training and testing of BDT for B2Kstplusmumu
  2. //different BDTs are created for the subdecays
  3. //1) Kst -> Kplus pi0
  4. //2) Kst -> Kshort pi+
  5. //later one is further split into DD and LL tracks
  6. //David Gerick
  7. //Renata Kopecna
  8. #include "GlobalFunctions.hh"
  9. #include "Paths.hpp"
  10. #include "MVAclass.hpp"
  11. #include "PlotTMVA.cpp"
  12. #include "TMVA/MethodBase.h"
  13. #include "TMVA/MethodCategory.h"
  14. //#include "../TMVA/TMVA-v4.2.0/TMVA/Data.h"
  15. #include "TMVA/TMVAGui.h"
  16. #if not defined(__CINT__) || defined(__MAKECINT__)
  17. #include "TMVA/Factory.h"
  18. #include "TMVA/Tools.h"
  19. #endif
  20. //////////////////////////////////////////////////////
  21. /// MVA_b2kmm()
  22. /// training and testing of the BDT for final signal selection
  23. /// the variables used for the BDT are defined from line 142 on.
  24. /// one can seperate the years 2011 & 2012 for individual
  25. /// training and testing or use the combined data-set. The Kshort
  26. /// channel may be split up into DD and LL tracks
  27. /// One can include the B+ -> Jpsi K*+ MC (reference channel) into
  28. /// the signal Factory. Don't know why... just to try it out.
  29. /// The results of the BDT training are saved in an .XML file and
  30. /// read-in by TMVAClassificationApplication_b2kmm.cc
  31. ///
  32. ///
  33. /// RunMVA()
  34. /// Function to perform the complete MVA training and testing
  35. /// with the given configurations in the functions defined in the
  36. /// lines above. Can choose between Kshort and PizeroResolved
  37. /// subdecays.
  38. ///
  39. Int_t MVA_b2kmm() {
  40. //limit the number of signal events; default = 0 : no limit
  41. Int_t nSignal = 0;
  42. bool use2Dweight = true;
  43. //use also the reference channel MC (B -> K*+ J/Psi)
  44. bool IncludeRefMC = false;
  45. //Should we cut away outliners in the training?
  46. bool cutOutliners = false;
  47. //Should we cut away multiple candidates?
  48. bool cutMultipleCandidates = false;
  49. //separate dataset if the kshort decays within the velo or not
  50. //LL tracks: 1
  51. //DD tracks: 0
  52. //Check MVAcongif
  53. if(MVAconfig.Run != 1 && MVAconfig.Run != 2 && MVAconfig.Run != 12){
  54. coutERROR("Invaliad Run ID chosen: >> " + to_string(MVAconfig.Run) + " << . Exit!");
  55. return 0;
  56. }
  57. if(MVAconfig.Run == 12)coutInfo("Evaluate both Run 1 & 2 in one GO (train together Run 1 and Run 2)!");
  58. if(MVAconfig.years.size() == 0 && MVAconfig.SplitYears){
  59. coutERROR("No year given for the MVA configuration! Please fix before executing the MVA_b2kmm() function.");
  60. return 0;
  61. }
  62. if (MVAconfig.customTMbranch == "") MVAconfig.customTMbranch = TMbranch;
  63. TMVA::Tools::Instance();
  64. TString signalTree= "DecayTreeTruthMatched";
  65. TString bkgTree="DecayTree";
  66. TString targetFile = GetBDTConfigFile(MVAconfig.SplitYears,MVAconfig.years.at(0),MVAconfig.Run,MVAconfig.KShortDecaysInVelo,MVAconfig.nConfiguration,MVAconfig.UseLowQ2Range, MVAconfig.customTMbranch, MVAconfig.gammaTM);
  67. TFile* outputFile = TFile::Open(targetFile,"RECREATE" );
  68. TChain* signal = new TChain(signalTree);
  69. TChain* background= new TChain(bkgTree);
  70. // Factory
  71. TString factoryOptions = "!V:!Silent:Color:Transformations=I;N:AnalysisType=Classification:DrawProgressBar";
  72. TMVA::Factory *factory;
  73. TString factoryName = (MVAconfig.SplitYears ? (to_string(MVAconfig.years.at(0)) + "_") : "") + "B2Kstmumu_" + TheDecay + (SplitDDandLL ? (MVAconfig.KShortDecaysInVelo ? "_LL" : "_DD") : "")
  74. + (!MVAconfig.SplitYears ? ("_Run" + to_string(MVAconfig.Run)) : "") + (MVAconfig.SplitInQ2Range ? (MVAconfig.UseLowQ2Range ? "_lowQ2" : "_highQ2") : "");
  75. factory = new TMVA::Factory( factoryName, outputFile , factoryOptions);
  76. //add variables used in training
  77. string DL = "";
  78. if(Kst2Kspiplus && SplitDDandLL) DL = MVAconfig.KShortDecaysInVelo ? "LL" : "DD";
  79. //Read MVA variables from file
  80. MVA_variables InputVariables(DL);
  81. InputVariables.print();
  82. //and feed them to the reader
  83. for (vector<MVA_def>::iterator tracksIter1 = InputVariables.AllVariables.begin(); tracksIter1 !=InputVariables.AllVariables.end();++tracksIter1){
  84. factory->AddVariable( (*tracksIter1).ReaderName,(*tracksIter1).LaTeXName,(*tracksIter1).Unit,(*tracksIter1).DataType);
  85. }
  86. //set MVAconfig.years accordingly to the chosen Run
  87. if(!MVAconfig.SplitYears){
  88. MVAconfig.years.clear();
  89. MVAconfig.years = yearsVectorInt(false, false, false, MVAconfig.Run);
  90. coutInfo("Load files for Run ");
  91. std::cout << (MVAconfig.Run == 12 ? "1 & 2" : std::to_string(MVAconfig.Run).c_str()) << ": Years ";
  92. for(UInt_t y = 0; y < MVAconfig.years.size(); y++){
  93. if(y == MVAconfig.years.size() - 1) std::cout << "and " << MVAconfig.years.at(y) << "." << std::endl;
  94. else std::cout << MVAconfig.years.at(y) << ", ";
  95. }
  96. }
  97. if(MVAconfig.SplitYears && MVAconfig.years.size() > 1){
  98. coutERROR("Vector with years cannot be larger 1 for the SplitYears configuration!");
  99. return 0;
  100. }
  101. //load data to trees
  102. for(UInt_t y = 0; y < MVAconfig.years.size(); y++){
  103. if (MVAconfig.years.at(y) != 2015 && Kst2Kpluspi0Resolved) signal->Add(GetBDTinputFile(MVAconfig.years.at(y),true,false,false,MVAconfig.KShortDecaysInVelo).c_str()); //I feel dirty by doing this, hardcoded, disgusting
  104. if(IncludeRefMC) signal->Add(GetBDTinputFile(MVAconfig.years.at(y),true,true,false,MVAconfig.KShortDecaysInVelo).c_str());
  105. background->Add(GetBDTinputFile(MVAconfig.years.at(y),false,false,false,MVAconfig.KShortDecaysInVelo).c_str());
  106. }
  107. // check the files
  108. for(UInt_t y = 0; y < MVAconfig.years.size(); y++){
  109. if (MVAconfig.years.at(y) != 2015 && Kst2Kpluspi0Resolved) coutDebug("Opening signal file " + GetBDTinputFile(MVAconfig.years.at(y),true,false,false,MVAconfig.KShortDecaysInVelo));
  110. if(IncludeRefMC) coutDebug("Opening signal file " + GetBDTinputFile(MVAconfig.years.at(y),true,true,false,MVAconfig.KShortDecaysInVelo));
  111. coutDebug("Opening background file " + GetBDTinputFile(MVAconfig.years.at(y),false,false,false,MVAconfig.KShortDecaysInVelo));
  112. }
  113. factory->AddSignalTree(signal,1.);
  114. factory->AddBackgroundTree(background,1.);
  115. string weightName = getWeightName(MVAconfig.customTMbranch,MVAconfig.gammaTM);
  116. if (use2Dweight) factory->SetSignalWeightExpression(weightName.c_str()); //2D weights
  117. else factory->SetSignalWeightExpression(weightName.c_str()); //1D weights
  118. TCut cutsS;
  119. TCut cutsB;
  120. string sVariable = UseDTF ? "B_plus_M_DTF" : "B_plus_M";
  121. if(Kst2Kspiplus){
  122. //mass range:
  123. cutsS = Form("%s < 5379 && %s > 5179", sVariable.c_str(), sVariable.c_str()); //cut +/- 100MeV on signal MC
  124. cutsB = Form("%s > 5400", sVariable.c_str()); //upper mass sideband of data
  125. //DD and LL split?
  126. if(SplitDDandLL){
  127. cutsS += Form("KshortDecayInVeLo == %i", MVAconfig.KShortDecaysInVelo);
  128. cutsB += Form("KshortDecayInVeLo == %i", MVAconfig.KShortDecaysInVelo);
  129. }
  130. //Q2 range:
  131. if(MVAconfig.SplitInQ2Range){
  132. if(MVAconfig.UseLowQ2Range){
  133. cutsS += "Q2 < 8.68e6";
  134. cutsB += "Q2 < 8.68e6";
  135. }
  136. else{
  137. cutsS += "(Q2 > 10.09e6 && Q2 < 12.9e6) || Q2 > 14.4e6)";
  138. cutsB += "(Q2 > 10.09e6 && Q2 < 12.9e6) || Q2 > 14.4e6)";
  139. }
  140. }
  141. else{
  142. cutsS += "(Q2 < 8.68e6 || (Q2 > 10.09e6 && Q2 < 12.9e6) || Q2 > 14.4e6)";
  143. cutsB += "(Q2 < 8.68e6 || (Q2 > 10.09e6 && Q2 < 12.9e6) || Q2 > 14.4e6)";
  144. }
  145. cutsS += TCut(getTMcut(true,false,MVAconfig.customTMbranch,MVAconfig.gammaTM).c_str());
  146. }
  147. else{ //pi0 channel
  148. cutsS = Form("%s < 5379 && %s > 5179", sVariable.c_str(), sVariable.c_str()); // for signal use MC data from B mass window only (+-100MeV)
  149. cutsB = Form("%s > 5700", sVariable.c_str()); // for background far upper sideband of data
  150. //Q2 range: //TODO: check
  151. if(MVAconfig.SplitInQ2Range){
  152. if(MVAconfig.UseLowQ2Range){
  153. cutsS += "Q2 < 8.68e6";
  154. cutsB += "Q2 < 8.68e6";
  155. }
  156. else{
  157. cutsS += "((Q2 > 10.09e6 && Q2 < 12.9e6) || Q2 > 14.4e6)";
  158. cutsB += "((Q2 > 10.09e6 && Q2 < 12.9e6) || Q2 > 14.4e6)";
  159. }
  160. }
  161. else{
  162. //cutsS += "(Q2 < 8.68e6 || (Q2 > 10.09e6 && Q2 < 12.9e6) || Q2 > 14.4e6)";
  163. //cutsB += "(Q2 < 8.68e6 || (Q2 > 10.09e6 && Q2 < 12.9e6) || Q2 > 14.4e6)";
  164. cutsS += TCut(getMuMucut().c_str()); //TODO: check
  165. cutsB += TCut(getMuMucut().c_str()); //TODO: check
  166. }
  167. //cut outliners
  168. if (cutOutliners){
  169. TCut outliners = "";
  170. if (MVAconfig.Run == 1){
  171. outliners += "B_plus_IP_OWNPV<0.1";
  172. outliners += "TMath::Abs(pi_zero_resolved_ETA_DTF-K_plus_ETA_DTF)<1";
  173. outliners += "TMath::Log(B_plus_PT_DTF)<10";
  174. outliners += "TMath::Log(1.0-B_plus_DIRA_OWNPV)>-18";
  175. outliners += "TMath::Log(K_plus_PT_DTF)<9.5";
  176. outliners += "TMath::Log(mu_minus_IPCHI2_OWNPV)<11";
  177. outliners += "gamma1_PT_DTF<3000";
  178. outliners += "gamma2_PT_DTF<4000";
  179. }
  180. else if (MVAconfig.Run == 2){
  181. outliners += "TMath::Max(TMath::Log(gamma1_PT_DTF),TMath::Log(gamma2_PT_DTF))<8.5";
  182. outliners += "B_plus_IP_OWNPV<0.1";
  183. outliners += "TMath::Abs(pi_zero_resolved_ETA_DTF-K_plus_ETA_DTF)<1";
  184. outliners += "TMath::Log(B_plus_PT_DTF)<10.25";
  185. outliners += "TMath::Log(K_plus_PT_DTF)<9.0";
  186. outliners += "TMath::Log(K_plus_PT_DTF)>6.0";
  187. outliners += "TMath::Log(1.0-B_plus_DIRA_OWNPV)>-18";
  188. outliners += "TMath::Log(mu_minus_IPCHI2_OWNPV)<10";
  189. outliners += "gamma1_PT_DTF<3000";
  190. outliners += "gamma2_PT_DTF<4000";
  191. }
  192. cutsS+= outliners;
  193. cutsB+= outliners;
  194. }
  195. if (cutMultipleCandidates){
  196. cutsS += "totCandidates == 1";
  197. cutsB += "totCandidates == 1";
  198. }
  199. cutsS += TCut(getTMcut(true,false,MVAconfig.customTMbranch,MVAconfig.gammaTM).c_str());
  200. coutDebug("Using cut ");
  201. if (verboseLevel < 3) cutsS.Print();
  202. }
  203. coutInfo("nEntries in signal tree: " + to_string(signal->GetEntries()));
  204. coutInfo("nEntries in bckgnd tree: " + to_string(background->GetEntries()));
  205. // Tell the factory how to use the training and testing events
  206. factory->PrepareTrainingAndTestTree(cutsS, cutsB, Form("nTrain_Signal=%i:nTrain_Background=0:nTest_Signal=%i:nTest_Background=0:SplitMode=Random:NormMode=NumEvents:SplitSeed=500:!V", nSignal, nSignal));
  207. // MVA methods: book BDT as default
  208. if (Kst2Kspiplus){
  209. factory->BookMethod( TMVA::Types::kBDT, "BDT", "!H:!V:NTrees=300:MaxDepth=3:BoostType=AdaBoost:AdaBoostBeta=0.5:SeparationType=GiniIndex:nCuts=12:PruneMethod=NoPruning");
  210. factory->BookMethod( TMVA::Types::kBDT, "BDTG", "!H:!V:NTrees=450:MaxDepth=2:MinNodeSize=1.5%:BoostType=Grad:Shrinkage=0.10:UseBaggedBoost:BaggedSampleFraction=0.5:nCuts=14" );
  211. }
  212. else if (Kst2Kpluspi0Resolved){
  213. factory->BookMethod( TMVA::Types::kBDT, "BDT", "!H:!V:NTrees=300:MaxDepth=2:BoostType=AdaBoost:AdaBoostBeta=0.26:SeparationType=GiniIndex:nCuts=12:PruneMethod=NoPruning");
  214. factory->BookMethod( TMVA::Types::kBDT, "BDTG", "!H:!V:NTrees=450:MaxDepth=2:MinNodeSize=1.5%:BoostType=Grad:Shrinkage=0.10:UseBaggedBoost:BaggedSampleFraction=0.5:nCuts=14" );
  215. factory->BookMethod( TMVA::Types::kMLP, "MLP", "H:!V:VarTransform=N:NCycles=750:HiddenLayers=N+5:TestRate=10:!UseRegulator" );//IgnoreNegWeightsInTraining=True
  216. }
  217. // Train and test MVAs
  218. factory->TrainAllMethods();
  219. factory->TestAllMethods();
  220. // Evaluate performances
  221. factory->EvaluateAllMethods();
  222. outputFile->Close();
  223. delete factory;
  224. // Launch the GUI for the root macros
  225. //if (!gROOT->IsBatch()) TMVA::TMVAGui( targetFile );
  226. //Plot everything TODO: fix year and add gammaTM
  227. SaveAllFromOneFile(2011,MVAconfig.Run,MVAconfig.SplitYears,MVAconfig.KShortDecaysInVelo,MVAconfig.nConfiguration,MVAconfig.UseLowQ2Range, MVAconfig.customTMbranch, MVAconfig.gammaTM);
  228. coutInfo("MVA training done!");
  229. return 1;
  230. }
  231. //Ks only
  232. Int_t RunMore(Int_t Run = 1){
  233. MVAconfig.Run = Run;
  234. MVAconfig.SplitYears = false;
  235. MVAconfig.SplitInQ2Range = false;
  236. MVAconfig.nConfiguration = 1;
  237. MVAconfig.KShortDecaysInVelo = 1;
  238. if (MVA_b2kmm() == 0) return 0;
  239. MVAconfig.KShortDecaysInVelo = 0;
  240. if (MVA_b2kmm() == 0) return 0;
  241. MVAconfig.SplitInQ2Range = true;
  242. MVAconfig.UseLowQ2Range = true;
  243. MVAconfig.nConfiguration = 2;
  244. MVAconfig.KShortDecaysInVelo = 1;
  245. if (MVA_b2kmm() == 0) return 0;
  246. MVAconfig.KShortDecaysInVelo = 0;
  247. if (MVA_b2kmm() == 0) return 0;
  248. MVAconfig.UseLowQ2Range = false;
  249. MVAconfig.nConfiguration = 3;
  250. MVAconfig.KShortDecaysInVelo = 1;
  251. if (MVA_b2kmm() == 0) return 0;
  252. MVAconfig.KShortDecaysInVelo = 0;
  253. if (MVA_b2kmm() == 0) return 0;
  254. return 1;
  255. }
  256. Int_t RunDDandLLKshort(Int_t Run = 1){
  257. MVAconfig.Run = Run;
  258. MVAconfig.SplitYears = false;
  259. MVAconfig.SplitInQ2Range = false;
  260. MVAconfig.nConfiguration = 1;
  261. MVAconfig.KShortDecaysInVelo = 1;
  262. if (MVA_b2kmm() == 0) return 0;
  263. MVAconfig.KShortDecaysInVelo = 0;
  264. if (MVA_b2kmm() == 0) return 0;
  265. return 1;
  266. }
  267. Int_t RunKplusPizeroResolved(Int_t Run = 1, int config=0, string customTMbranch ="", bool gammaTM = false){
  268. MVAconfig.Run = Run;
  269. MVAconfig.nConfiguration = config;
  270. MVAconfig.KShortDecaysInVelo = false;
  271. MVAconfig.SplitYears = false;
  272. MVAconfig.SplitInQ2Range = false;
  273. MVAconfig.UseLowQ2Range = false;
  274. MVAconfig.customTMbranch = customTMbranch;
  275. MVAconfig.gammaTM = gammaTM;
  276. if (MVA_b2kmm() == 0) return 0;
  277. return 1;
  278. }
  279. Int_t RunMVA(Int_t Run = 1){
  280. if(Kst2Kspiplus)return RunDDandLLKshort(Run);
  281. if(Kst2Kpluspi0Resolved){
  282. //RunKplusPizeroResolved(Run,1,"TMedBKGCAT",false);
  283. RunKplusPizeroResolved(Run,0,"TMed",false);
  284. //RunKplusPizeroResolved(Run,2,"TMed",true);
  285. }
  286. return 0;
  287. }