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.

1053 lines
46 KiB

  1. //Functions used for the B plus mass fit
  2. //Renata Kopecna
  3. #include "GlobalFunctions.hh"
  4. #include "MassFit.hpp"
  5. #include "BmassShape/BackgroundPdf.hpp"
  6. #include "BmassShape/SignalPdf.hpp"
  7. #include "Paths.hpp"
  8. #include "MVAclass.hpp"
  9. #include "RooFit/RooDoubleCB/RooDoubleCB.h"
  10. #include "Design.hpp"
  11. #include "Utils.hpp"
  12. using namespace std;
  13. using namespace RooFit;
  14. using namespace RooStats;
  15. bool useExtraVarBool(string extraVar){ //Shoudl be easy to add others
  16. vector<string> allVars {"q2", "q2_binned", "q2_binned_fit", "thetak", "thetal", "phi", "pi_zero_ETA", "pi_zero_ETA-K_plus_ETA", "pi_zero_P", "pi_zero_P_DTF", "pi_zero_PT", "pi_zero_PT_DTF","K_plus_P","K_plus_PT"};
  17. for (auto &var: allVars){
  18. if (extraVar == var) return true;
  19. if (extraVar == var+"_equal") return true;
  20. }
  21. return false;
  22. }
  23. string GetsWeightPlots(string year, bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, bool KshortDecaysInVelo, bool GetShapeFromMC, string SignalType, string BkgType, bool ConstrainParameters){
  24. string path = GetMassFitFile(year,false,UseOnlyJpsiEvents,UseOnlyMuMuEvents, KshortDecaysInVelo, GetShapeFromMC, SignalType,BkgType, ConstrainParameters,true,false);
  25. replace(path,"BplusMassModel","Sweight");
  26. return path;
  27. }
  28. double massFit(string year, string magnet, int Run,
  29. bool MC, bool Preselected, bool TM, bool PHSP, //input/output file selection
  30. bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, //signal/reference
  31. bool GetShapeFromMC, string SigType, string BkgType, bool ConstrainParameters, //shape
  32. bool KshortDecaysInVelo, bool UseLowQ2Range, //LL/DD? q2range?
  33. Double_t TMVAcut, int randomSubset, //TMVA options
  34. bool fixedMassRegion, bool yieldOverFullRange, //yield calculation region
  35. bool sWeight, //sWeight data?
  36. bool loopFit, bool IsEfficiency, //additional options
  37. string sExtraVar, int nExtraBin, //fit in bins of extra variable
  38. bool removeMultiple, //Remove multiple candidates?
  39. bool weighted, bool weightedFromPi0, string whichWeight, //use weight in the fit?
  40. bool nonTM, string customTMbranch, bool gammaTM, //TM options
  41. bool InclusiveSample){ //Fit inclusive sample?
  42. //bool notTM: if true and MC, fits the nonTM part of MC with a CB
  43. // To fit the CB as a background either in MC or Data, add "OneCB" to the BkgType string
  44. //randomSubset \in {-1,0,1}
  45. //loopFit means that MC fit is not performed, but parameters are fixed to previous fit, useful since one doesn't have to fit MC all the time in a loop
  46. //IsEfficiency: Just stored in a different folder
  47. //TODO: possibly add splittig in low/high Q2
  48. //Make ROOT quiet
  49. gStyle -> SetOptStat(0);
  50. LHCbStyle();
  51. gROOT->SetBatch(kTRUE);
  52. //Load all libraries for ROOT
  53. gSystem->Load("./BmassShape/SignalType_cpp.so");
  54. gSystem->Load("./BmassShape/BackgroundType_cpp.so");
  55. gSystem->Load("./BmassShape/ParamValues_cpp.so");
  56. gSystem->Load("./BmassShape/SignalPdf_cpp.so");
  57. gSystem->Load("./BmassShape/BackgroundPdf_cpp.so");
  58. int printLevel = 1;
  59. if (verboseLevel > 1){
  60. printLevel = -1;
  61. RooMsgService::instance().setGlobalKillBelow(RooFit::FATAL);
  62. }
  63. //sanity checks
  64. magnet = correct_magnet_string(magnet);
  65. checkMC(MC,false,PHSP,false);
  66. if (!checkTM(MC,TM,nonTM,Preselected)) return 0;
  67. checkKshort(KshortDecaysInVelo);
  68. if (!SplitInQ2 && UseLowQ2Range) {
  69. coutWarning("Cannot use low Q2 region if the data is not split in Q2! Setting UseLowQ2Range to false!");
  70. UseLowQ2Range = false;
  71. }
  72. if (!checkQ2Range(UseOnlyJpsiEvents,UseOnlyMuMuEvents)) return 0;
  73. if (TMVAcut > -1.0 && !Preselected){ //if TMVAcut == -1, no TMVA cut is applied
  74. coutWarning("TMVA cut can be only aplied on preselected data! Setting Preselected to true!");
  75. Preselected = true; //Cannot do BDT cut on stripped data
  76. }
  77. if(TM && MC && (GetShapeFromMC || ConstrainParameters)){
  78. coutWarning("Cannot fix MC fit to an MC fit! Setting GetShapeFromMC and ConstrainParameters to false.");
  79. GetShapeFromMC = false; //never run MC twice!
  80. ConstrainParameters = false; // never use constrains on MC samples
  81. }
  82. if (sWeight && MC){
  83. coutWarning("MC cannot be sWeighted! Setting sWeight to false!");
  84. sWeight = false;
  85. }
  86. if (sWeight && UseOnlyMuMuEvents){
  87. coutWarning("Data cannot be sWeighted only in the MuMu region! Setting UseOnlyMuMuEvents to false!");
  88. UseOnlyMuMuEvents = false;
  89. }
  90. if (customTMbranch =="") customTMbranch = TMbranch;
  91. if (customTMbranch =="TMedBKGCAT" && gammaTM == false) gammaTM = true;
  92. bool useExtraVar = useExtraVarBool(sExtraVar); //perform once so it doesn't have to run through all the ifs every time
  93. TMefficiencyClass extraVar = TMefficiencyClass(sExtraVar);
  94. //To make life easier, make a bool for using RefChannel MC
  95. bool UseRefMC = (MC && !PHSP && UseOnlyJpsiEvents);
  96. //Make a years vecotr based on Run and selected proper RunID based on a year
  97. std::vector<string> years;
  98. int RunID = 0;
  99. if (Run == 0){
  100. RunID = getRunID(year);
  101. if (MC && UseRefMC){
  102. //can't use yearVector since we can replace 2017 and 2018 MC by 2016
  103. if (!checkRefYear(year)) years.push_back("2016");
  104. else years.push_back(year);
  105. }
  106. else years.push_back(checkIf2015MC(year,MC,UseRefMC,PHSP));
  107. }
  108. else{
  109. RunID = Run;
  110. if (InclusiveSample) years = yearsBkgMC(UseOnlyJpsiEvents,false, false,true, Run);
  111. else if (MC) years = yearsMC(UseRefMC,PHSP,Run);
  112. else years = yearsData(Run);
  113. }
  114. coutInfo("Using year/s ");
  115. cout << "[INFO]\t"; printVector(years); cout << endl;
  116. coutInfo(" with RunID "+to_string(RunID));
  117. ///signal shape
  118. SignalPdf SigShape;
  119. SigShape.setSignalType(SigType,GetShapeFromMC,ConstrainParameters);
  120. ///background shape
  121. BackgroundPdf BkgShape;
  122. BkgShape.setBackgroundType(BkgType,TM,GetShapeFromMC,ConstrainParameters);
  123. ///----------------------------------------------------
  124. ///Get Fit parameters from fit to TMed MC if requested:
  125. ///----------------------------------------------------
  126. //Turn off MC fit in case of fitting in a loop, except for when TMVAcut == lowBDTcut
  127. //When performing scans, always fix the parameters to the MC value
  128. //however, the parameters are not calculated each iteration of the scan, because the MC shape does not change
  129. Float_t lowBDTcutCheck = (TMVAmethod == "MLP") ? 0.0 : -1.0; //check if at lower limit
  130. bool runMCforTMVAcut = (TMVAcut == lowBDTcutCheck || TMVAcut == 0.9); //if TMVA at lower limit/0.9 for fine scans, do the MC fit again
  131. coutDebug("Run MC for TMVA cut? " +to_string(runMCforTMVAcut));
  132. coutDebug("TMVA cut: " +to_string(TMVAcut));
  133. bool MC_UseOnlyJpsiEvents, MC_UseOnlyMuMuEvents;
  134. if(GetShapeFromMC && (runMCforTMVAcut || !loopFit)){
  135. //In case of CB in the background model, fit the nonTMed MC by oneCB
  136. if (sExtraVar == "q2_binned"){
  137. MC_UseOnlyJpsiEvents = false;
  138. MC_UseOnlyMuMuEvents = true;
  139. }
  140. else{
  141. MC_UseOnlyJpsiEvents = UseOnlyJpsiEvents;
  142. MC_UseOnlyMuMuEvents = UseOnlyMuMuEvents;
  143. }
  144. if (BkgShape.bkgOneCB){
  145. std::cout << std::endl;
  146. coutInfo("||==============================================||");
  147. coutInfo("|| Fitting the MC to obtain background shape! ||");
  148. coutInfo("||==============================================||");
  149. std::cout << std::endl;
  150. if(massFit(year,magnet,Run,
  151. true,true,false,PHSP,
  152. MC_UseOnlyJpsiEvents, MC_UseOnlyMuMuEvents,
  153. false,"NoSig","OneCB",false,
  154. KshortDecaysInVelo,UseLowQ2Range,
  155. TMVAcut, 0, fixedMassRegion, yieldOverFullRange,
  156. false, false, IsEfficiency, sExtraVar, nExtraBin,
  157. removeMultiple, weighted, weightedFromPi0, whichWeight,
  158. true, customTMbranch, gammaTMdefault, InclusiveSample) == 0){
  159. coutERROR("Fit to MC data did not work out!");
  160. return 0;
  161. }
  162. }
  163. //Now fit the TMed MC
  164. if (false){ //TODO: possibly switch to true
  165. std::cout << std::endl;
  166. coutInfo("||==================================================||");
  167. coutInfo("|| Fitting the MVAed data to obtain signal shape! ||");
  168. coutInfo("||==================================================||");
  169. std::cout << std::endl;
  170. if(massFit(year,magnet,Run,
  171. false, true, false,PHSP,
  172. true, false,
  173. false, SigType,BkgType, false,
  174. KshortDecaysInVelo, UseLowQ2Range,
  175. getTMVAcut(RunID), 0, fixedMassRegion, yieldOverFullRange,
  176. false, false, IsEfficiency, sExtraVar, nExtraBin,
  177. true, false, false, "",
  178. false, "", gammaTMdefault, false) == 0){
  179. coutERROR("Fit to MC data did not work out!");
  180. return 0;
  181. }
  182. }
  183. else{
  184. std::cout << std::endl;
  185. coutInfo("||===========================================||");
  186. coutInfo("|| Fitting the MC to obtain signal shape! ||");
  187. coutInfo("||===========================================||");
  188. std::cout << std::endl;
  189. if(massFit(year,magnet,Run,
  190. true,true, true,PHSP,
  191. MC_UseOnlyJpsiEvents, MC_UseOnlyMuMuEvents,
  192. false,SigType,"NoBckGnd",false,
  193. KshortDecaysInVelo, UseLowQ2Range,
  194. -1.0, 0, fixedMassRegion, yieldOverFullRange,
  195. false, false, IsEfficiency, sExtraVar, nExtraBin,
  196. removeMultiple, weighted, weightedFromPi0, whichWeight,
  197. false, customTMbranch, gammaTM, InclusiveSample) == 0){
  198. coutERROR("Fit to MC data did not work out!");
  199. return 0;
  200. }
  201. }
  202. std::cout << std::endl;
  203. coutInfo("||===========================================||");
  204. coutInfo("|| Apply signal shape and fit data with it! ||");
  205. coutInfo("||===========================================||");
  206. std::cout << std::endl;
  207. }
  208. //For now only MC can be weighted
  209. if (weighted && !MC){
  210. coutWarning("For now only weighted MC can be done! Setting weight to false!");
  211. weighted = false;
  212. }
  213. if (weighted) SumW2Error(kTRUE);
  214. //print info about signal and background shape
  215. coutInfo("Using a " + SigType + " for the Signal shape!");
  216. coutInfo("Using a " + BkgType + " for the Background shape!");
  217. ///------------------------------
  218. ///Load file
  219. ///------------------------------
  220. TChain* tree = new TChain(treeName(MC,Preselected).c_str());
  221. coutInfo("Reading data from TTree... ");
  222. if (TMVAcut != -1 || weightedFromPi0 || removeMultiple) tree = get_BDT_TChain(years, MC, MC && UseOnlyJpsiEvents, PHSP, KshortDecaysInVelo, weightedFromPi0);
  223. else if (weighted) tree = get_weighted_TChain(years, MC, UseOnlyJpsiEvents, PHSP, KshortDecaysInVelo);
  224. else tree = get_basic_TChain(magnet,years,Preselected,MC,UseOnlyJpsiEvents,PHSP,false, false, InclusiveSample);
  225. if(tree->GetEntries() == 0){
  226. coutERROR("No entries found in TTree. Exit program!");
  227. return 0;
  228. }
  229. else coutDebug("DONE!");
  230. ///------------------------------
  231. /// Set branches
  232. ///------------------------------
  233. string B_mass_branch = UseDTF ? (Preselected ? "B_plus_M_DTF" : "B_plus_DTF_M") : ("B_plus_M");
  234. coutDebug("Deactivating all not needed branches.. ");
  235. tree->SetBranchStatus("*",0);
  236. //activating all needed branches
  237. tree->SetBranchStatus("Q2", 1);
  238. tree->SetBranchStatus(B_mass_branch.c_str(),1);
  239. string weightBranch = weighted ? getWeightName(customTMbranch,gammaTM) : "";
  240. if (weighted) coutDebug("WeightBranch = " + weightBranch + ".");
  241. if (TMVAcut > -1.0) tree->SetBranchStatus(TMVAmethod+"response",1);
  242. if (TM || nonTM) tree->SetBranchStatus(customTMbranch.c_str(),1);
  243. if (TM || nonTM) tree->SetBranchStatus(gammaTMbranch.c_str(),1);
  244. if (TM || nonTM) tree->SetBranchStatus(customTMbranch.c_str(),1);
  245. if (randomSubset!=0) tree->SetBranchStatus("RandomSubSet",1);
  246. if (Kst2Kspiplus && SplitDDandLL) tree->SetBranchStatus("KshortDecayInVeLo",1);
  247. if (weighted) tree->SetBranchStatus(weightBranch.c_str(), 1);
  248. if (weightedFromPi0) tree->SetBranchStatus(Form("w_%s",whichWeight.c_str()),1);
  249. if (useExtraVar){
  250. for (auto var:extraVar.sBranchName)
  251. tree->SetBranchStatus(var.c_str(),1); //add last branch (or the only one)
  252. }
  253. if (removeMultiple) tree->SetBranchStatus(getAloneBranch(MC,TM,customTMbranch,gammaTM).c_str(),1);
  254. coutInfo("DONE!");
  255. ///------------------------------
  256. ///Fill all needed variables in RooDataSet
  257. ///------------------------------
  258. coutInfo("Loading the dataset...");
  259. RooRealVar *B_plus_M;
  260. B_plus_M = new RooRealVar(B_mass_branch.c_str(),
  261. (Kst2Kspiplus ? (UseDTF ? "m(K_{S}^{0}#pi^{+}#mu^{+}#mu^{-})" : "m(#pi^{+}#pi^{-}#pi^{+}#mu^{+}#mu^{-})") : (UseDTF ? "m(K^{+}#pi^{0}#mu^{+}#mu^{-})" : "m(K^{+}#gamma#gamma#mu^{+}#mu^{-})") ),
  262. get_cut_B_plus_M_low(year),
  263. cut_B_plus_M_high,
  264. " MeV/c^{2} ");
  265. //In case we want to change binning, this is really not ideal but oh well
  266. string finalCut = getFinalCut(MC,TM, nonTM, customTMbranch, gammaTM, UseOnlyMuMuEvents, UseOnlyJpsiEvents, SplitInQ2, UseLowQ2Range, useExtraVar, extraVar, nExtraBin, TMVAcut, removeMultiple);
  267. if (!Preselected) finalCut = "B_plus_DTF_M >0"; //Dummy
  268. coutDebug("Using cuts " + finalCut);
  269. RooRealVar Q2Bin ("Q2", " ", -0.1e6, 21.1e6," ");
  270. RooRealVar TMVAresponse (TMVAmethod+"response", " ", -1.0, 1.0, " ");
  271. RooRealVar TMvar (customTMbranch.c_str(), " ", -0.1, 1.1, " ");
  272. RooRealVar TMgammaVar (gammaTMbranch.c_str(), " ", -0.1, 6.1, " ");
  273. RooRealVar KshortDecayInVeLo("KshortDecayInVeLo", " ", KshortDecaysInVelo ? 0.9 : -0.1, KshortDecaysInVelo ? 1.1 : 0.1," ");
  274. RooRealVar RandomSubSet ("RandomSubSet", " ", randomSubset - 0.1, randomSubset + 0.1," ");
  275. const int nExtraVars = extraVar.sBranchName.size();
  276. RooRealVar *RooExtraVars[nExtraVars];
  277. for_indexed (auto var:extraVar.sBranchName){
  278. RooExtraVars[i] = new RooRealVar(var.c_str(), var.c_str(), extraVar.vVarRange.at(i).at(0), extraVar.vVarRange.at(i).at(1)," ");
  279. coutDebug("Var: " + string(var.c_str()));
  280. coutDebug("Range: " + to_string(extraVar.vVarRange.at(i).at(0)) + " to " + to_string(extraVar.vVarRange.at(i).at(1)));
  281. }
  282. RooRealVar IsAlone (getAloneBranch(MC,TM,customTMbranch,gammaTM).c_str(), " ", -1.0, 2.0, " ");
  283. RooRealVar *FinalWeight;
  284. if (weighted && weightedFromPi0){ //TODO: the question is if this works, test it at some point!
  285. FinalWeight = new RooRealVar("weight","weight",-10.0,10.0,"");
  286. double w;
  287. double w_pi0;
  288. tree->SetBranchAddress(weightBranch.c_str(),&w);
  289. tree->SetBranchAddress(Form("w_%s",whichWeight.c_str()),&w_pi0);
  290. for (int e = 0; e<tree->GetEntries();e++){
  291. tree->GetEntry(e);
  292. FinalWeight->setVal(w*w_pi0);
  293. }
  294. }
  295. else if (weighted){
  296. FinalWeight = new RooRealVar(weightBranch.c_str(), weightBranch.c_str(), -10.0, 10.0," ");
  297. }
  298. else if (weightedFromPi0){
  299. FinalWeight = new RooRealVar(Form("w_%s",whichWeight.c_str()), Form("w_%s",whichWeight.c_str()), 0.0, 10.0," ");
  300. }
  301. RooArgSet argSet = RooArgSet(*B_plus_M);
  302. argSet.add(Q2Bin);
  303. if (TM||nonTM) argSet.add(TMvar);
  304. if (TM||nonTM) argSet.add(TMgammaVar);
  305. if (useExtraVar)
  306. for(int i = 0; i < nExtraVars;i++) argSet.add(*RooExtraVars[i]);
  307. if (TMVAcut > -1.0) argSet.add(TMVAresponse);
  308. if (randomSubset) argSet.add(RandomSubSet);
  309. if (SplitDDandLL&&Kst2Kspiplus) argSet.add(KshortDecayInVeLo);
  310. if (removeMultiple) argSet.add(IsAlone);
  311. if (weighted||weightedFromPi0) argSet.add(*FinalWeight);
  312. RooDataSet* data= NULL;
  313. if (weighted||weightedFromPi0) data = new RooDataSet("data","data",argSet,Import(*tree),Cut(finalCut.c_str()), WeightVar(*FinalWeight));
  314. else data = new RooDataSet("data","data",argSet,Import(*tree),Cut(finalCut.c_str()));
  315. coutInfo(" DONE!");
  316. if (verboseLevel < 3) data->Print();
  317. coutDebug("Using weighted events? " + to_string (data->isWeighted()));
  318. coutDebug("The dataset contains " + to_string(data->numEntries()) + " events!");
  319. ///------------------------------
  320. ///Build the B+ mass signal shape
  321. ///------------------------------
  322. gROOT->ProcessLine(".L ./RooFit/RooDoubleCB/RooDoubleCB_cpp.so");
  323. gROOT->ProcessLine(".L ./GlobalFunctions.hh"); //This is very weird, but it works ¯\_(ツ)_/¯
  324. coutInfo("Setting signal fit parameters ... ");
  325. //set mean of B_plus mass peak
  326. RooRealVar* meanBplus = SigShape.getRooRealVar("mean",true);
  327. ///------------------------------
  328. ///Yields and Background + Signal Fit-Model
  329. ///------------------------------
  330. //yields
  331. coutDebug("The dataset has " + to_string(data->numEntries()) + " entries!");
  332. RooRealVar N_Bplus("N_Bplus", "#B^{+}", data->numEntries()/2., 0., 2*data->numEntries());
  333. RooRealVar N_comb("N_comb","N_comb", data->numEntries()/2., 0., 2*data->numEntries());
  334. //Create the signal PDF
  335. //Check if one selected any sigPdf and bkgPdf
  336. if (SigShape.NoSig && BkgShape.NoBackground){
  337. coutERROR("No fit model was selected. Abort.");
  338. return 0;
  339. }
  340. coutDebug("Creating BplusMassModel...");
  341. RooAddPdf *BplusMassModel = NULL;
  342. if (!SigShape.NoSig) BplusMassModel = SigShape.getBplusMassModel(B_plus_M,meanBplus, UseOnlyJpsiEvents);
  343. coutInfo("Signal PDF is created!");
  344. if (!SigShape.NoSig){
  345. coutInfo("Constraints PDF:");
  346. SigShape.ConsPDF->Print();
  347. }
  348. coutDebug("Creating BplusBckGndModel...");
  349. ///Build the B+ mass background model
  350. RooAddPdf * BplusBckGndModel = NULL;
  351. if (!BkgShape.NoBackground) BplusBckGndModel = BkgShape.getBplusBkgModel(B_plus_M);
  352. coutInfo("Background PDF is created!");
  353. //add all required pdfs
  354. RooAbsPdf* pdf = NULL;
  355. if (BkgShape.NoBackground){
  356. //Create the signal PDF
  357. pdf = new RooAddPdf("pdf", "pdf", RooArgList(*BplusMassModel), RooArgList(N_Bplus));
  358. }
  359. else{
  360. if (SigShape.NoSig) pdf = new RooAddPdf("pdf", "pdf", RooArgList(*BplusBckGndModel), RooArgList(N_comb));
  361. else pdf = new RooAddPdf("pdf", "pdf", RooArgList(*BplusMassModel, *BplusBckGndModel), RooArgList(N_Bplus, N_comb));
  362. }
  363. if (verboseLevel<2) pdf->Print();
  364. ///Gaussian Constraint to MC values
  365. if (!SigShape.AtLeastOneConstrainFound) coutDebug("No parameters in signal costrained.");
  366. if (!BkgShape.AtLeastOneConstrainFound) coutDebug("No parameters in background costrained.");
  367. ///------------------------------
  368. ///Fit
  369. ///------------------------------
  370. RooFitResult *result = new RooFitResult("FitResult","FitResult");
  371. //Add constrained PDFs
  372. if (SigShape.AtLeastOneConstrainFound || BkgShape.AtLeastOneConstrainFound){
  373. RooArgSet *constrPdfs;
  374. if (SigShape.AtLeastOneConstrainFound) constrPdfs = new RooArgSet(*SigShape.ConsPDF);
  375. if (BkgShape.AtLeastOneConstrainFound) constrPdfs = new RooArgSet(*BkgShape.BkgConsPDF);
  376. RooProdPdf *FitPDF_constraint = new RooProdPdf("FitPDF_constraint","FitPDF_constraint",RooArgSet(*pdf,*constrPdfs));
  377. if (!IsEfficiency){
  378. coutDebug("Constrained parameters are:" );
  379. SigShape.ConsParameter->Print();
  380. coutDebug("The following PDF is fitted to the data:" );
  381. FitPDF_constraint->Print();
  382. coutDebug("Start the fit with constrains! " );
  383. }
  384. result = FitPDF_constraint->fitTo(*data,Save(kTRUE),Extended(kTRUE),NumCPU(3),Constrain(*constrPdfs),PrintLevel(printLevel),SumW2Error(weighted ? kTRUE : kFALSE));
  385. delete FitPDF_constraint;
  386. }
  387. else{
  388. coutDebug("The following PDF is fitted to the data:" );
  389. if (verboseLevel<2) pdf->Print();
  390. coutDebug("Start the fit! " );
  391. result = pdf->fitTo(*data,Save(kTRUE),Extended(kTRUE),NumCPU(3),PrintLevel(printLevel),SumW2Error(weighted ? kTRUE : kFALSE));
  392. }
  393. coutDebug("The fit result is --------------- " );
  394. if (verboseLevel<2) result->Print();
  395. //Saving the results in case of constrianing to MC
  396. SigShape.setValuesAndErrors(true);
  397. BkgShape.setValuesAndErrors(false);
  398. ///------------------------------
  399. ///calculate # (signal)background events in signal region
  400. ///------------------------------
  401. coutDebug("The effective sigma is: " + to_string(SigShape.getEffSigmaFromResult()));
  402. if (fixedMassRegion) B_plus_M->setRange("SigRange",meanBplus->getVal() - B_plus_M_signal_window, meanBplus->getVal() + B_plus_M_signal_window );
  403. else B_plus_M->setRange("SigRange",meanBplus->getVal() - SignalRegionNsigma * SignalFitParameter.SigmaEff, meanBplus->getVal() + SignalRegionNsigma * SignalFitParameter.SigmaEff);
  404. coutInfo("Determining the signal and background yield");
  405. //Get signal yield
  406. RooAbsReal* S_fr = NULL;
  407. Double_t S = 0.0, S_error_test = 0.0, S_error = 0.0;
  408. if (!SigShape.NoSig){
  409. S_fr = BplusMassModel->createIntegral(*B_plus_M,NormSet(*B_plus_M),Range("SigRange"));
  410. S = S_fr->getVal() * N_Bplus.getVal();
  411. S_error_test = S_fr->getPropagatedError(*result) * N_Bplus.getVal();
  412. S_error = S_fr->getVal() *N_Bplus.getError();
  413. }
  414. //Get background yield
  415. RooAbsReal* B_fr = nullptr;
  416. Double_t B = 0.0, B_error = 0.0, B_error_test = 0.0;
  417. if(!BkgShape.NoBackground){
  418. B_fr = BplusBckGndModel->createIntegral(*B_plus_M,NormSet(*B_plus_M),Range("SigRange"));
  419. B = B_fr->getVal() * N_comb.getVal();
  420. B_error_test = B_fr->getPropagatedError(*result) * N_comb.getVal();
  421. B_error = B_fr->getVal() * N_comb.getError(); //B * (N_comb.getError()/N_comb.getVal());
  422. }
  423. coutInfo("S/sqrt(S+B)= " + to_string(S/sqrt(S+B)));
  424. if(B != 0.)coutInfo("S/B= " + to_string(S/B));
  425. coutInfo("S= " + to_string(S)+ "+-" + to_string(S_error));//+ "/+-" + to_string(S_error_test));
  426. coutInfo("B= " + to_string(B)+ "+-" + to_string(B_error));//+ "/+-" + to_string(B_error_test));
  427. cout << endl << endl;
  428. ///------------------------------
  429. ///Plot the models with indidivual components
  430. ///------------------------------
  431. //configurables for plotting
  432. Float_t pullHeight = 0.32;
  433. Int_t Bins = 100;
  434. if (UseOnlyMuMuEvents && Preselected && !MC) Bins = useExtraVar ? 30 : 50;
  435. //create two pads into one canvas
  436. TCanvas* c1= new TCanvas("");
  437. TPad *pad1 = new TPad("pad1", "plot",0.0,pullHeight,1.0,1.0,0);
  438. TPad *pad2 = new TPad("pad2", "pull",0.0,0.0,1.0,pullHeight,0);
  439. pad1->Draw();
  440. pad2->Draw();
  441. //modifiy pad for main plot
  442. pad1->SetBorderSize (0);
  443. pad1->SetBottomMargin(1e-6);
  444. pad1->SetTopMargin(pad1->GetTopMargin() / pullHeight * ( 1 - pullHeight) );
  445. pad1->cd();
  446. RooPlot* frame_m = B_plus_M->frame();
  447. //some axis-modifications on the main plot
  448. TGaxis::SetExponentOffset(1e+9,1e+9,"y");//offset = pad size * 1e+7
  449. //make the frame pretty
  450. designMassFitFrame(frame_m, pullHeight);
  451. data->plotOn(frame_m,Name("data"),MarkerSize(0.5),Binning(Bins),DataError(RooAbsData::SumW2));
  452. pdf->plotOn(frame_m,Name("pdf"),LineColor(kBlack),LineWidth(2));
  453. if (!SigShape.NoSig) pdf->plotOn(frame_m,Components("BplusMassModel"),LineColor(kBlue),LineStyle(kDashed),LineWidth(1));
  454. if (!BkgShape.NoBackground){pdf->plotOn(frame_m,Components("BplusBckGndModel"),LineColor(kRed),LineStyle(kDashed),LineWidth(1));
  455. //in case you want to plot ExpGaus
  456. //pdf->plotOn(frame_m,Components("bkg_exp1"),LineColor(kRed),LineStyle(kDashed),LineWidth(1));
  457. //pdf->plotOn(frame_m,Components("ExpG"),LineColor(kRed),LineStyle(kDashed),LineWidth(1));
  458. }
  459. //Plot the pdf and the box with fit results into the frame
  460. data->plotOn(frame_m,Name("data"),MarkerSize(0.5),Binning(Bins));
  461. //pdf->paramOn(frame_m, Format("NEU",AutoPrecision(1)));
  462. pdf->paramOn(frame_m, ShowConstants(kTRUE), Format("NEU",AutoPrecision(2)), Layout(0.65, 0.95, 0.88));
  463. frame_m->Draw();
  464. c1->Update();
  465. // TODO: Add a box with constrained parameters posibly
  466. //signal/background yield
  467. Float_t posX = MC ? 0.40 : 0.41, posY = 0.84;
  468. if(Kst2Kspiplus) posX = 0.34;
  469. TLatex* fitresult = new TLatex();
  470. fitresult->SetTextFont(132);
  471. fitresult->SetTextColor(1);
  472. fitresult->SetTextSize(0.04);
  473. fitresult->SetTextAlign(13);
  474. fitresult->SetNDC(1);
  475. //TODO
  476. if (!SigShape.NoSig) fitresult->DrawLatex(posX, posY - 0.08, Form("Signal: %.0f #pm %.0f", S, S_error)); //Signal defined by N sigma around peak mean value or in the mass window, depends on bool fixedMassRegion and B_plus_M_signal_window
  477. if(!BkgShape.NoBackground) fitresult->DrawLatex(posX, posY - 0.13, Form("Background: %.0f #pm %.0f", B, B_error));
  478. frame_m->addObject(fitresult) ;
  479. frame_m->Draw("SAME");
  480. if (MC) addLHCbtag(posX, 0.82, "simulation", 1./(1. - pullHeight));
  481. else addLHCbtag(posX, 0.82, "data", 1./(1. - pullHeight));
  482. //create pull histogram
  483. pad2->Clear();
  484. pad2->SetTopMargin(1e-6);
  485. pad2->SetBottomMargin(pad2->GetBottomMargin() / pullHeight );
  486. pad2->cd();
  487. //Design pull histogram
  488. RooPlot* pullFrame = B_plus_M->frame();
  489. designPullFrame(pullFrame,frame_m,pullHeight);
  490. //Add two 3-sigma lines:
  491. TLine * lUp = threeSigmaLine(true);
  492. TLine * lLow = threeSigmaLine(false);
  493. pullFrame->addObject(lUp);
  494. pullFrame->addObject(lLow);
  495. //Draw the pull
  496. pullFrame->Draw() ;
  497. //choose path to save files //TODO: check
  498. string filePath = "";
  499. if (IsEfficiency) filePath = GetEfficiencyMassFitFile(year, magnet, Run,
  500. Preselected, TM, PHSP, UseOnlyJpsiEvents, UseOnlyMuMuEvents,
  501. GetShapeFromMC, SigType, BkgType, ConstrainParameters,
  502. KshortDecaysInVelo, UseLowQ2Range,
  503. TMVAcut, fixedMassRegion,
  504. sExtraVar, nExtraBin,
  505. removeMultiple, weighted, weightedFromPi0,
  506. whichWeight, customTMbranch, gammaTM);
  507. else filePath = GetMassFitFile(year,magnet,Run,MC,Preselected,TM,PHSP,UseOnlyJpsiEvents,UseOnlyMuMuEvents,
  508. GetShapeFromMC, SigType, BkgType, ConstrainParameters,
  509. KshortDecaysInVelo, UseLowQ2Range, TMVAcut, randomSubset,
  510. fixedMassRegion, yieldOverFullRange, sExtraVar, nExtraBin,removeMultiple,
  511. weighted, weightedFromPi0, whichWeight, nonTM, customTMbranch, gammaTM, InclusiveSample);
  512. coutDebug("Saving into file "+ filePath);
  513. TFile *fitFile = new TFile(filePath.c_str(),"RECREATE");
  514. //save canvas to pdf and root format
  515. coutInfo("Writting signal and background pdfs into the file " + filePath + ".");
  516. fitFile->cd();
  517. result->Write();
  518. c1->Write();
  519. //Save Signal yield, background yield and it's error
  520. TVectorD yield(1);
  521. yield[0] = S;
  522. yield.Write("yield");
  523. TVectorD yield_err(1);
  524. yield_err[0] = S_error;
  525. yield_err.Write("yield_err");
  526. TVectorD B_vec(1);
  527. B_vec[0] = B;
  528. B_vec.Write("background");
  529. TVectorD B_vec_err(1);
  530. B_vec_err[0] = B_error;
  531. B_vec_err.Write("background_err");
  532. TVectorD sigma_eff(1);
  533. sigma_eff[0] = SignalFitParameter.SigmaEff;
  534. sigma_eff.Write("sigma_eff");
  535. fitFile->Close();
  536. coutDebug("File " + filePath + " closed." );
  537. //Plot the fit
  538. replace(filePath,".root",".eps");
  539. coutInfo("Plotting into " + filePath + ".");
  540. c1->Print(filePath.c_str());
  541. if(sWeight){
  542. if (BkgType == "NoBckGnd"){ //It crashes here if no background is selected
  543. coutERROR("No background selected! Splot needs SingleExponential, DoubleExponential or ExpGauss.");
  544. return 0;
  545. }
  546. meanBplus->setConstant();
  547. SigShape.setAllRooVarsConstant();
  548. BkgShape.setAllRooVarsConstant();
  549. SPlot* sData = new SPlot("sData","An SPlot",*data,pdf,RooArgList(N_Bplus, N_comb));
  550. ///Plot the sWeight distributions as a function of mass
  551. TCanvas* SwBplus = new TCanvas("Bplus sWeight","Bplus sWeight distribution");
  552. TH2 * SwBplusHist;
  553. SwBplusHist = (TH2*)data->createHistogram((UseDTF ? "B_plus_M_DTF,N_Bplus_sw" : "B_plus_M,N_Bplus_sw"));
  554. SwBplusHist->GetYaxis()->SetTitle("Signal sWeights");
  555. SwBplusHist->SetTitle("");
  556. //SwBplus->Write("",TObject::kWriteDelete);
  557. SwBplusHist->Draw();
  558. addLHCbtag(0.65, 0.85, "data", 1);
  559. filePath = GetsWeightPlots(year, UseOnlyJpsiEvents,UseOnlyMuMuEvents, KshortDecaysInVelo,GetShapeFromMC,SigType,BkgType,ConstrainParameters);
  560. SwBplus->SaveAs(filePath.c_str());
  561. replace(filePath,".root",".eps");
  562. SwBplus->Print(filePath.c_str());
  563. ///Create output file
  564. TFile* output = nullptr;
  565. output = new TFile(GetBDTinputFile(year,false,UseOnlyJpsiEvents,PHSP,KshortDecaysInVelo).c_str() ,"RECREATE");
  566. if(!output->IsOpen()){
  567. coutERROR("Could not create output file. Abort!");
  568. return 0;
  569. }
  570. output->cd();
  571. tree->SetBranchStatus("*",1);
  572. coutInfo("Copy Tree... " );
  573. TTree * new_tree = nullptr;
  574. string sVariable = (UseDTF ? "B_plus_M_DTF" : "B_plus_M");
  575. string q2Cut = "";
  576. if (UseOnlyJpsiEvents) //If for OnlyMuMu not needed so far //TODO
  577. q2Cut = "&& " + getJpsicut();
  578. if (SplitInQ2){
  579. if (UseLowQ2Range)
  580. q2Cut = "&& Q2 < 8.68e6";
  581. else
  582. q2Cut = "&& 10.09e6 < Q2";
  583. }
  584. //no use of saving only mumu data
  585. if(Kst2Kspiplus && SplitDDandLL){
  586. new_tree = tree->CopyTree(Form("%s >= %f && %s <= %f %s && KshortDecayInVeLo==%i", sVariable.c_str(), get_cut_B_plus_M_low(year), sVariable.c_str(), cut_B_plus_M_high, q2Cut.c_str(), KshortDecaysInVelo));
  587. }
  588. else{
  589. new_tree = tree->CopyTree(Form("%s >= %f && %s <= %f %s", sVariable.c_str(), get_cut_B_plus_M_low(year), sVariable.c_str(), cut_B_plus_M_high, q2Cut.c_str()));
  590. }
  591. coutDebug("Finished!" );
  592. double w;
  593. TBranch* Bra_sw = new_tree->Branch("N_Bplus_sw", &w, "N_Bplus_sw/D");
  594. ///loop over events
  595. int numEvents = new_tree->GetEntries();
  596. coutDebug("Entries in TTree:\t"+ to_string(numEvents) );
  597. coutDebug("Entries in RooDataSet:\t"+to_string(data->numEntries()));
  598. if(numEvents != data->numEntries()){
  599. coutERROR("Number of weights not equal to number of events");
  600. return 0;
  601. }
  602. coutDebug("Loop over data sample " + year + TheDecay + " to save sWeights from mass fit results!" );
  603. for(int i = 0; i < numEvents; i++){
  604. if ((0ul == (i % 10000ul) || i + 1 == numEvents) && i != 0) coutInfo("Read event " + to_string(i) + "/" + to_string(numEvents));
  605. tree->GetEntry(i);
  606. w = sData->GetSWeight(i,"N_Bplus_sw");
  607. Bra_sw->Fill();
  608. }
  609. coutInfo("Loop finished!!!");
  610. output->cd();
  611. new_tree->Write("",TObject::kWriteDelete);
  612. delete new_tree;
  613. output->Close();
  614. delete SwBplus;
  615. delete SwBplusHist;
  616. delete sData;
  617. }
  618. if (S < 0.1) S = 0.01; //protect zeroes from happening
  619. delete frame_m;
  620. delete tree;
  621. delete result;
  622. coutInfo("Mass fit is done.");
  623. return S;
  624. }
  625. int quickFit(string year, bool MC, bool sWeight, bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, bool KshortDecaysInVelo, bool GetShapeFromMC, string SigType, string BkgType, bool ConstrainParameters){
  626. return massFit(year,"both", 0,
  627. MC, true, MC, false,
  628. UseOnlyJpsiEvents, UseOnlyMuMuEvents,
  629. GetShapeFromMC,SigType,BkgType,ConstrainParameters,
  630. KshortDecaysInVelo,false,
  631. -1.0, 0,
  632. false, false,
  633. sWeight,
  634. false, false,
  635. "",-1,
  636. false,
  637. false, false, "",
  638. false, "", false,
  639. false);
  640. }
  641. int quickTest(bool gammaTM = false, string customTMbranch = "TMed"){
  642. setVerboseLevel(1);
  643. return massFit("2015","both", 0,
  644. false, true, true, false,
  645. false, false,
  646. true,"OneCB","SingleExponential",true,
  647. false,false,
  648. -1.0, 0,
  649. false, false,
  650. false,
  651. false, false,
  652. "",-1,false, true, false, "",false, customTMbranch, gammaTM,
  653. false);
  654. }
  655. int testOneCbBackground(bool MC = false, string SigType = "OneCB", string BkgType = "SingleExponentialOneCB", string customTMbranch = "", bool gammaTM = false){
  656. setVerboseLevel(1);
  657. return massFit("2016","both",0,
  658. false, true, true, false,
  659. !MC, false,
  660. true,SigType,BkgType,true,
  661. false, false,
  662. -1.0, 0,
  663. true, false,
  664. false, false, false,
  665. "",-1, false, false, false, "", false, customTMbranch, gammaTM, false);
  666. }
  667. int efficiencyFit(string year = "2011", string magnet = "down", int Run = 0,
  668. bool Preselected = true, bool TM = true, bool PHSP = false, //input/output file selection
  669. bool UseOnlyJpsiEvents = false, bool UseOnlyMuMuEvents = false, //signal/reference
  670. bool GetShapeFromMC = false, string SigType = "OneCB", string BkgType = "SingleExponential", bool ConstrainParameters = false, //shape
  671. bool KshortDecaysInVelo = Kst2Kspiplus, //LL/DD?
  672. Double_t TMVAcut = -1.0, //TMVA options
  673. bool fixedMassRegion = !Kst2Kspiplus, //yield calculation region
  674. bool UseLowQ2Range =false, //q2 ranges
  675. string sExtraVar = "", int nExtraBin = -1,bool removeMultiple = false, bool weighted = false,
  676. bool weightedFromPi0 = false, string whichWeight = "", //fit in bins of extra variable
  677. string customTMbranch = "", bool gammaTM = false
  678. ){
  679. return massFit(year,magnet,Run,
  680. true, Preselected, TM, PHSP,
  681. UseOnlyJpsiEvents, UseOnlyMuMuEvents,
  682. GetShapeFromMC,SigType,BkgType,ConstrainParameters,
  683. KshortDecaysInVelo, UseLowQ2Range,
  684. TMVAcut, 0,
  685. fixedMassRegion, false,
  686. false, false, true,
  687. sExtraVar, nExtraBin, removeMultiple,
  688. weighted, weightedFromPi0,whichWeight,
  689. false, customTMbranch, gammaTM, false
  690. );
  691. }
  692. int basicYieldFit(string year, int Run, bool MC, bool PHSP, //input/output file selection
  693. bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, //signal/reference
  694. bool GetShapeFromMC, string SigType, string BkgType, bool ConstrainParameters, //shape
  695. bool KshortDecaysInVelo, bool UseLowQ2Range, //LL/DD? q2range?
  696. Double_t TMVAcut, //TMVA options
  697. bool fixedMassRegion, bool loopFit,//yield calculation region
  698. bool removeMultiple //remove multiple candidates
  699. ){ //TODO: shape from MC if TMVA cut?
  700. return massFit(year,"both",Run,
  701. MC, true, MC, PHSP,//if MC then truthMatched
  702. UseOnlyJpsiEvents, UseOnlyMuMuEvents,
  703. GetShapeFromMC,SigType,BkgType,ConstrainParameters,
  704. KshortDecaysInVelo, UseLowQ2Range,
  705. TMVAcut, 0,
  706. fixedMassRegion, false,
  707. false, loopFit, false,
  708. "", -1, removeMultiple,
  709. true, false, "", //weighted=true only for MC, but also data then takes the shape from MC that is weighted
  710. false, "", gammaTMdefault, false);
  711. }
  712. int basicYieldFitAllYears(//Fits all years separately
  713. bool MC = true, bool PHSP = false, //input/output file selection
  714. bool UseOnlyJpsiEvents = false, bool UseOnlyMuMuEvents = false, //signal/reference
  715. bool GetShapeFromMC = false, string SigType = "OneCB", string BkgType = "SingleExponential", bool ConstrainParameters = false, //shape
  716. bool KshortDecaysInVelo = Kst2Kspiplus, bool UseLowQ2Range =false, //LL/DD? q2range?
  717. Double_t TMVAcut = -1.0, //TMVA options
  718. bool fixedMassRegion = !Kst2Kspiplus, bool loopFit = false, //yield calculation region
  719. bool removeMultiple = false //remove multiple candidates
  720. ){
  721. for(auto &y : yearsVector(MC,UseOnlyJpsiEvents,false, 12)){
  722. if (basicYieldFit(y,0, MC, PHSP, UseOnlyJpsiEvents,UseOnlyMuMuEvents,GetShapeFromMC, SigType, BkgType, ConstrainParameters,
  723. KshortDecaysInVelo,UseLowQ2Range,TMVAcut, fixedMassRegion,loopFit, removeMultiple) ==0) return 0;
  724. }
  725. return 1;
  726. }
  727. int basicFitAllYearsAndRegions(bool MC = true, bool PHSP = false, //input/output file selection
  728. bool GetShapeFromMC = false, string SigType = "OneCB", string BkgType = "SingleExponential", bool ConstrainParameters = false, //shape
  729. bool KshortDecaysInVelo = Kst2Kspiplus, bool UseLowQ2Range =false, //LL/DD? q2range?
  730. Double_t TMVAcut = -1.0, bool removeMultiple = false //TMVA options
  731. ){
  732. vector <bool> UseOnlyJpsiEvents = {true,false};
  733. vector <bool> UseOnlyMuMuEvents = {true,false};
  734. vector <bool> fixedMassRegion = {true,false};
  735. for(auto const&jpsi: UseOnlyJpsiEvents){
  736. for(auto const&mumu: UseOnlyMuMuEvents){
  737. for(auto const&fixedWindow: fixedMassRegion){
  738. if (basicYieldFitAllYears(MC,PHSP, jpsi,mumu,GetShapeFromMC, SigType, BkgType, ConstrainParameters,
  739. KshortDecaysInVelo,UseLowQ2Range,TMVAcut, fixedWindow,false,removeMultiple)==0) return 0;
  740. }
  741. }
  742. }
  743. return 1;
  744. }
  745. int getYieldBasicOptionsMC(bool TM, string year, int Run, bool ReferenceChannel, bool PHSP, bool removeMultiple){
  746. string bkg = TM ? "NoBckGnd" : "SingleExponential";
  747. bool useJpsiOnly = ReferenceChannel;
  748. bool useMuMuOnly = !PHSP && !ReferenceChannel;
  749. bool weighted = false;
  750. return massFit(year,"both",Run,
  751. true, true, TM, PHSP,
  752. useJpsiOnly, useMuMuOnly,
  753. false, "OneCB",bkg,false,
  754. false, false,
  755. -1.0, 0,
  756. true, false,
  757. false, false, false,
  758. "", -1, removeMultiple,
  759. weighted, false, "", //weighted=true only for MC, but also data then takes the shape from MC that is weighted
  760. false, "", gammaTMdefault, false);
  761. }
  762. int getYieldBasicOptionsMCAllYears(bool TM, bool ReferenceChannel, bool PHSP, bool removeMultiple){
  763. for (auto year: yearsMC(ReferenceChannel,PHSP,12)){
  764. if (getYieldBasicOptionsMC(TM, year, 0, ReferenceChannel, PHSP, removeMultiple)==0) return 0;
  765. }
  766. if (getYieldBasicOptionsMC(TM, "2011", 1, ReferenceChannel, PHSP, removeMultiple) == 0) return 0;
  767. if (getYieldBasicOptionsMC(TM, "2015", 2, ReferenceChannel, PHSP, removeMultiple) == 0) return 0;
  768. return 1;
  769. }
  770. int getYieldAllYearsBasicOptions(bool TM, bool removeMultiple){
  771. if (getYieldBasicOptionsMCAllYears(TM,false,false, removeMultiple)==0) return 0;
  772. if (getYieldBasicOptionsMCAllYears(TM,true ,false, removeMultiple)==0) return 0;
  773. if (getYieldBasicOptionsMCAllYears(TM,false,true, removeMultiple)==0) return 0;
  774. //if (basicYieldFitAllYears(false, false, true, false, true, "OneCB", "SingleExponential", true,
  775. // false, false, -1, true,false,true)==0) return 0;
  776. //if (basicYieldFitAllYears(false, false, false, true, true, "OneCB", "SingleExponential", true,
  777. // false, false, -1, true,false,true)==0) return 0;
  778. return 1;
  779. }
  780. int basicYieldFitAllRuns( //Fits data per year
  781. bool MC = true, bool PHSP = false, //input/output file selection
  782. bool UseOnlyJpsiEvents = false, bool UseOnlyMuMuEvents = false, //signal/reference
  783. bool GetShapeFromMC = false, string SigType = "OneCB", string BkgType = "SingleExponential", bool ConstrainParameters = false, //shape
  784. bool KshortDecaysInVelo = Kst2Kspiplus, bool UseLowQ2Range =false, //LL/DD? q2range?
  785. Double_t TMVAcut = -1.0, //TMVA options
  786. bool fixedMassRegion = !Kst2Kspiplus, bool loopFit = false,//yield calculation region
  787. bool removeMultiple = false //remove multiple candidates
  788. ){
  789. if ( basicYieldFit("2011",1, MC, PHSP, UseOnlyJpsiEvents,UseOnlyMuMuEvents,GetShapeFromMC, SigType, BkgType, ConstrainParameters,
  790. KshortDecaysInVelo,UseLowQ2Range,TMVAcut, fixedMassRegion,loopFit,removeMultiple)==0) return 0;
  791. if ( basicYieldFit("2015",2, MC, PHSP,UseOnlyJpsiEvents,UseOnlyMuMuEvents,GetShapeFromMC, SigType, BkgType, ConstrainParameters,
  792. KshortDecaysInVelo,UseLowQ2Range,TMVAcut, fixedMassRegion,loopFit,removeMultiple)==0) return 0;
  793. return 1;
  794. }
  795. int massFitTestAll(bool GetShapeFromMC = true,
  796. bool ConstrainParameters = false, int Run = 1){
  797. bool KshortDecaysInVelo= false;
  798. bool UseLowQ2Range = false;
  799. bool TM = false;
  800. bool MC = true;
  801. bool UseOnlyJpsiEvents = false;
  802. bool UseOnlyMuMuEvents = false;
  803. bool UseFixedMassRegion = false;
  804. bool yieldOverFullRange = false;
  805. std::vector<string> years = yearsData(Run);
  806. std::vector<string> signalShape = {//"SingleGaussian",
  807. "DoubleGaussian",
  808. //"CBLeft",
  809. //"CBRight",
  810. "CBDouble"
  811. };
  812. std::vector<string> backgroundShape = {//"SingleExponential",
  813. "DoubleExponential",
  814. "ExpGaus"
  815. };
  816. std::vector<string> polarity = { //"down",
  817. //"up",
  818. "both"
  819. };
  820. for (auto& y: years){
  821. for (auto& sig: signalShape){
  822. for (auto& bkg: backgroundShape){
  823. for (auto& magnet: polarity){
  824. if(massFit(y, magnet, 0, MC, true, TM, false,UseOnlyJpsiEvents, UseOnlyMuMuEvents, GetShapeFromMC, sig, bkg, ConstrainParameters,
  825. KshortDecaysInVelo, UseLowQ2Range, -1.0, false, UseFixedMassRegion,yieldOverFullRange,false, false, false, "", -1,false, false, false, "",false,"",false,false) == 0)return 0;
  826. }
  827. }
  828. }
  829. }
  830. return 1;
  831. }
  832. //check distributions in q2
  833. int massFitTestQ2All(int Run, bool PHSP, bool UseOnlyMuMuEvents, bool UseOnlyJpsiEvents){
  834. bool KshortDecaysInVelo= false;
  835. bool UseLowQ2Range = false;
  836. bool UseFixedMassRegion = false;
  837. bool yieldOverFullRange = false;
  838. bool removeMultiple = false;
  839. bool weighted = PHSP;
  840. string signalShape = "OneCB";
  841. string backgroundShape = "ExpGaus";
  842. for (int n = 4; n < 5; n++){
  843. if(massFit("2011", "both", Run,
  844. PHSP, true, PHSP, PHSP,
  845. UseOnlyJpsiEvents, UseOnlyMuMuEvents,
  846. true, signalShape, backgroundShape, true,
  847. KshortDecaysInVelo, UseLowQ2Range,
  848. -1.0, false, UseFixedMassRegion,yieldOverFullRange,
  849. false, false, false, "q2_binned", n, removeMultiple, weighted,
  850. false, "",false,
  851. "",gammaTMdefault,false) == 0)return 0;
  852. }
  853. return 1;
  854. }
  855. //Print efficiencies and fit parameters
  856. int PrintFitResults(RooFitResult* fitRes){
  857. RooArgSet fitargs = fitRes->floatParsFinal();
  858. if (fitargs.getSize() <=0){
  859. coutERROR("RooArgSet size is zero/nonDef!");
  860. return 0;
  861. }
  862. TIterator* iter(fitargs.createIterator());
  863. cout << " ======= results ====== " << endl;
  864. for (TObject *a = iter->Next(); a != 0; a = iter->Next()) {
  865. RooRealVar *rrv = dynamic_cast<RooRealVar *>(a);
  866. string name = rrv->GetName();
  867. cout<< name << ": " << rrv->getVal() <<" +/- "<<rrv->getError() << endl;
  868. }
  869. return 1;
  870. }
  871. int fitJpsi(string year, int Run, bool MC, double TMVAcut, bool RemoveMultiple){
  872. return massFit(year,"both", Run,
  873. MC, true, MC, false,
  874. true, false,
  875. !MC, "OneCB", "SingleExponential", true,
  876. false,false,
  877. TMVAcut, 0,
  878. false, false,
  879. false,
  880. false, false,
  881. "",-1,
  882. RemoveMultiple,
  883. false, false, "",
  884. false, "", gammaTMdefault,
  885. false);
  886. }