//Constants and global options //David Gerick //Renata Kopecna //All the libraries are included here, I am way to lazy to clean up, so here we are #ifndef GLOBALFUNCTIONS #define GLOBALFUNCTIONS #include #include #include #include #include #include #include #include #include #include //ROOT Libraries #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "TRandom3.h" #include "TMath.h" #include "TString.h" #include "TSystem.h" #include "TStopwatch.h" #include #include "TGaxis.h" #include #include "TApplication.h" //RooFit Libraries #include #include #include "RooGaussModel.h" #include "RooExponential.h" #include "RooGenericPdf.h" #include "RooChebychev.h" #include "RooFitResult.h" #include "RooAddModel.h" #include "RooPolynomial.h" #include "RooTruthModel.h" #include "RooDecay.h" #include "RooPlot.h" #include "RooGaussian.h" #include "RooDstD0BG.h" #include "RooAddPdf.h" #include "RooExtendPdf.h" #include "RooDataHist.h" #include "RooCBShape.h" #include "RooCategory.h" #include "RooFormulaVar.h" #include "RooSimultaneous.h" #include "RooHist.h" #include "RooStats/SPlot.h" #include "RooTreeDataStore.h" #include "RooBifurGauss.h" #include "RooRealVar.h" #include "RooDataSet.h" #include "RooConstVar.h" #include "RooProdPdf.h" #include "RooNDKeysPdf.h" #include "RooKeysPdf.h" #include "RooGlobalFunc.h" #include "RooRealIntegral.h" #include "RooAbsReal.h" #include "RooMsgService.h" //Custom RooFit libraries #include "RooFit/RooExpAndGauss/RooExpAndGauss.hpp" #include "RooFit/RooDoubleCB/RooDoubleCB.h" #include "LHCbStyle.h" //indexed auto looping over vectors #define for_indexed(...) for_indexed_v(i, __VA_ARGS__) #define for_indexed_v(v, ...) for(bool _i_ = true, _break_ = false; _i_;) for(size_t v = 0; _i_; _i_ = false) for(__VA_ARGS__) if(_break_) break; else for(bool _j_ = true; _j_;) for(_break_ = true; _j_; _j_ = false) for(bool _k_ = true; _k_; v++, _k_ = false, _break_ = false) //////////////////////////////////// ///// ///// DECAY options ///// //////////////////////////////////// bool GetKSfromExePath(){ char cwd[256]; if (getcwd(cwd, sizeof(cwd)) != NULL) { //printf("Current working dir: %s\n", cwd); char * KS = NULL; KS = strstr(cwd, "dgerick"); if(KS){ std::cout << "Hello David! Now running KS0 pi+ mode!" << std::endl; return true; } } std::cout << "Hello Renata! Now running K+ pi0 mode!" << std::endl; return false; } const bool KshortChannel = GetKSfromExePath(); // false := pi0 channel const bool SplitDDandLL = KshortChannel ? true : false; //for pi0 SplitDDandLL is always false! std::string TheDecay = (KshortChannel ? "KshortPiplus" : "KplusPi0Resolved"); const bool Kst2Kpluspi0Resolved = !KshortChannel; //keep the old variables, but set global! const bool Kst2Kpluspi0Merged = false; const bool Kst2Kspiplus = KshortChannel; //////////////////////////////////// /// /// Basic options /// //////////////////////////////////// //use only small sample of data for testing purposes const bool smallSample = false; //folder with stored data const std::string path_to_data = "/auto/data/dgerick/B2Kstmumu"; const std::string path_to_output_KshortPiplus = "/auto/data/dgerick/B2Kstmumu"; const std::string path_to_output_KplusPizero = "/home/lhcb/kopecna/B2KstarMuMu_clean/Data"; const std::string thePath = Kst2Kspiplus ? path_to_output_KshortPiplus : path_to_output_KplusPizero; // Use DTF varialbes const bool UseDTF = KshortChannel ? true : true; //use mass and momenta of particles obtained by DTF? // Use PDG mass for LorentzVectors or PE from branch const bool UsePDGmIn4Dvectors = KshortChannel ? false : true; // Reweight MC to the ratio of sWeighted Jpsi Data to Jpsi MonteCarlo (both reference channel) const bool ReweightByRefChannel = KshortChannel ? true : true; // Always reweight MC to pure jpsi data? (also for years without jpsi MC) const bool AlwaysUseRefChannelData = KshortChannel ? true : true; // Include 2017 and 2018? const bool Use2017 = KshortChannel ? true : true; const bool Use2018 = KshortChannel ? true : true; // Use PIDgen for MC tuples const bool UsePIDgen = KshortChannel ? true : false; //////////////////////////////////// /// /// Weighting options /// //////////////////////////////////// /// const std::string firstMCweight = (KshortChannel ? "nLongTracks" : "nLongTracks"); const std::string seconMCweight = KshortChannel ? (UseDTF ? "B_plus_PT_DTF" : "B_plus_PT") : (UseDTF ? "B_plus_PT_DTF" : "B_plus_PT"); const UInt_t firstnBins = 75; const UInt_t secondnBins = 50; const double firstMCrange[2] = {-0.5, 149.5}; const double seconMCrange[2] = {TMath::Log(1500.), TMath::Log(50000.)}; const std::string firstMClatex = KshortChannel ? "N^{Long}_{Tracks}" : "N^{Long}_{Tracks}"; const std::string seconMClatex = KshortChannel ? "p_{T}(B^{+}) ( MeV/c )" : "p_{T}(B^{+}) ( MeV/c )"; //////////////////////////////////// /// /// TM options /// //////////////////////////////////// // TruthMatch MC only according to the BKGCAT const bool UseBKGCAT = KshortChannel ? true : false; //Truthmatching: set an option to TM particles const bool pi0TM = true; const std::string TMtag = UseBKGCAT ? "" : "_TM" + std::string(pi0TM ? "" : "_noPi0TM"); const std::string TMbranch = "TMed" + std::string(UseBKGCAT ? "BKGCAT" : "") + std::string(pi0TM ? "" : "_noPi0"); const std::string gammaTMbranch = "TM_gammas" + std::string(pi0TM ? "" : "_noPi0"); //Function bool isTM(std::string customTMbranch, bool TM, bool gammaTM, int gTM){ if(customTMbranch.find("BKGCAT") != std::string::npos){ return TM; } else{ if(gammaTM) return (TM && (gTM <4)); else return (TM && (gTM <6)); } } const bool gammaTMdefault = false; //////////////////////////////////// /// /// Cuts /// //////////////////////////////////// //DTF convergence cuts const double cut_DTF_status = 0.5; const double cut_DTF_chi2 = 200.0; //Mass cuts const double K_star_plus_mass_difference = 100.0; //MeV //difference between K* mass and PDG K* mass const double cut_B_plus_M_low_basic = 4900.; //MeV, to account for cut on non-DTF mass in stripping const double cut_B_plus_M_low = KshortChannel ? 5150. : 5150.; //MeV const double cut_B_plus_M_high = KshortChannel ? 6000. : 5800.; //MeV const double B_plus_M_signal_window = KshortChannel ? 50. : 100; //MeV -- as PDGmass +/- the window //kinematic cut <=> pseudorapidity (for each particle, except for gammas) const double cut_kin_Theta_low = 0.0; const double cut_kin_Theta_up = 0.4; //Kinematic cuts const double cut_K_star_plus_pT = 1350.0; //MeV const double cut_B_plus_pT = 2000.0; //MeV const double cut_pi_zero_PT = 800.0; //MeV const double cut_B_plus_DIRA = 0.99996; const double cut_muon_angle = 0.001; const double cut_B_plus_FDCHI2 = 121.0; const double cut_K_star_plus_FDCHI2 = 9.0; const double cut_B_plus_ConePTasym = -0.5; const double cut_DiMuon_M = 7100.0; //Primary vertex cuts const double cut_muon_IPCHI2_OWNPV_low = 9.0; const double cut_IPCHI2_OWNPV_low = 0.0; const double cut_IPCHI2_OWNPV_high = 12.0; //PID cuts const double cut_muon_ProbNNmu = 0.25; const double cut_K_plus_ProbNNk = 0.25; const double cut_gamma_CL = 0.15; const bool SplitInQ2 = KshortChannel ? false : false; //std::vector q2BinsUp = {0.98, 2.5, 4.0, 6.0, 8.0, 12.5, 17.0, 19.0}; //std::vector q2BinsLow = {0.1, 1.1, 2.5, 4.0, 6.0, 11.0, 15.0, 17.0}; //std::vector diMuonMassBinsUp = {}; ///TODO //std::vector diMuonMassBinsLow = {}; //TODO //const int nq2Bins = q2BinsUp.size(); //////////////////////////////////// /// /// Constants /// //////////////////////////////////// //TMVA meethod TString TMVAmethod = KshortChannel ? "BDTG" : "MLP"; //used TMVA method //define PDG masses: struct PDGMASS{ Double_t B_PLUS = 5279.29; const Double_t B_ZERO = 5279.61; const Double_t J_PSI = 3096.90; const Double_t PSI_2S = 3686.10; const Double_t K_STAR_PLUS = 891.66; const Double_t K_ONE_PLUS = 1272.0; const Double_t K_PLUS = 493.68; const Double_t K_SHORT = 497.61; const Double_t PI_PLUS = 139.57; const Double_t PI_ZERO = 134.98; const Double_t MU = 105.66; const Double_t GAMMA = 0; } PDGMASS; //define the TRUEIDs: struct TRUEIDS{ const Int_t B_PLUS = 521; const Int_t B_ZERO = 511; const Int_t K_STAR_PLUS = 323; const Int_t K_STAR_ZERO = 313; const Int_t K_ONE_PLUS = 10323; // K1(1270)+ const Int_t K_ONE_PLUS_1400 = 20323; // K1(1400)+ const Int_t K_ONE_PLUS_1410 = 100323; // K1(1410)+ const Int_t K_ONE_ZERO = 10313; // K0(1270)+ const Int_t K_PLUS = 321; const Int_t K_SHORT = 310; const Int_t PI_PLUS = 211; const Int_t PI_ZERO = 111; const Int_t RHO_ZERO = 113; const Int_t MU_MINUS = 13; const Int_t GAMMA = 22; const Int_t J_PSI = 443; const Int_t ELECTRON = 11; } TRUEID; //branching ratios //const double BR_sig = 9.6e-7; //PDG value for B+ -> K*+ mu mu //const double BR_sig = 6.09576e-7; //BR for B+ -> K*+ mu mu without resonances from LHCb-PAPER-2014-006 const double BR_sig = 8.668e-7; //BR for B+ -> K*+ mu mu without resonances from flavio (09-05-19) const double BR_ref = 1.43e-3 * 5.961e-2; //PDG value for B+ -> J/psi K*+ times J/psi -> mu mu const double BR_ref2 = 6.7e-4 * 8.0e-3; //PDG value for B+ -> psi(2s) K*+ times psi(2s) -> mu mu const float SignalRegionNsigma = 2.; //How many sigmas around the signal peak comprises the signal region double getTMVAcut(int Run){ if (Run == 1) return 0.9985; else if (Run == 2) return 0.996; else return 1; } #ifndef SIGNALPARAMETERS #define SIGNALPARAMETERS struct SignalFitParameters{ //TODO: possibly add the K1 to ParamValues at some point //signal fractions Double_t SigmaEff = 15.; //background parameter Double_t bkg_mean_K1 = 5158.6; Double_t bkg_sigma_K1 = 50.; //background fraction Double_t f_BplusBckGndK1 = 0.5; } SignalFitParameter; #endif //signalfitParams #ifndef SIGNALPARAMETERSFIXED #define SIGNALPARAMETERSFIXED struct FixedParameters{//TODO: possibly add the K1 to ParamValues at some point //background parameter bool bkg_mean_K1 = KshortChannel ? false : true; bool bkg_sigma_K1 = KshortChannel ? false : false; } FixParameter; #endif //sigparams //////////////////////////////////// /// /// Check if file exists /// //////////////////////////////////// inline bool exists_test (const std::string& name) { struct stat buffer; return (stat (name.c_str(), &buffer) == 0); } //////////////////////////////////// /// /// SetOutputLevel /// //////////////////////////////////// int verboseLevel = 2; //verboseLevel 0: cout Tests, Debugs, Infos, Warnings and Errors //verboseLevel 1: cout Debugs, Infos, Warnings and Errors //verboseLevel 2: cout Infos, Warnings and Errors //verboseLevel 3: cout Warnings and Errors //verboseLevel 4: cout Errors (always cout errors) void setVerboseLevel(int level){ verboseLevel = level; } bool set_gErrorIgnoreLevel(){ gStyle -> SetOptStat(0); LHCbStyle(); gROOT->SetBatch(kTRUE); if (verboseLevel == 3 || verboseLevel == 2) gErrorIgnoreLevel = kWarning; if (verboseLevel == 4) gErrorIgnoreLevel = kError; return true; } bool get_gErrorIgnoreLevel = set_gErrorIgnoreLevel(); //////////////////////////////////// /// /// Colors /// //////////////////////////////////// #define cBOLDWHITE "\033[1m\033[37m" /* Bold White */ #define cBOLDRED "\033[1m\033[31m" /* Bold Red */ #define cBOLDGREEN "\033[1m\033[32m" /* Bold Green */ #define cGREEN "\033[32m" /* Green */ #define cBOLDCYAN "\033[1m\033[36m" /* Bold Cyan */ #define cCYAN "\033[36m" /* Cyan */ #define cRED "\033[31m" /* Red */ #define cBOLDRED "\033[1m\033[31m" /* Bold red */ #define cYELLOW "\033[33m" /* Yellow */ #define cBOLDYELLOW "\033[1m\033[33m" /* Bold Yellow */ #define cRESET "\033[0m" //////////////////////////////////// /// /// Fancy couts /// //////////////////////////////////// void coutTest(string message){ if (verboseLevel==0) cout << "[TEST]\t\t" << message << endl; } void coutDebug(string message){ if (verboseLevel<2) cout << "[DEBUG]\t\t" << message << endl; } void coutInfo(string message){ if (verboseLevel<3) cout << "[INFO]\t\t" << message << endl; } void coutWarning(string message){ if (verboseLevel<4) cout << cBOLDYELLOW << "[WARN]\t\t" << cYELLOW << message << cRESET << endl; } void coutERROR(string message){ cout << cBOLDRED << "[ERROR]\t\t" << cRED << message << cRESET << endl; } //////////////////////////////////// /// /// FUNCTIONS /// /// bool IsDST(year,MC,ReferenceChannel,PHSP) /// checks whether the input file is MDST or DST /// Important for branch names in BDTSelection.cpp /// /// void addLHCbTag(x,y,suffix, color, Scaling) /// Draws TLatex "LHCb + suffix" with the size of 0.07*scaling /// /// string Float2Comma(f,d) /// Returns a comma-separated string of the input float up to the given precision. /// NO ROUNDING! /// /// bool replace(str,from,to) /// replaces string 'from' by 'to' /// replaces all occurences of 'from' /// /// void printVector(vector) /// couts members of a vector /// //////////////////////////////////// double get_cut_B_plus_M_low(int Run = 2){ //setting lower B mass cut for different run/years if (KshortChannel) return cut_B_plus_M_low; else{ if (Run==1) return 5150.0; else if (Run==2) return cut_B_plus_M_low; else{ std:: cout << "[WARN] Wrong year input! Choose either 1 or 2. Lower cut set to " << cut_B_plus_M_low << "MeV" << std::endl; return cut_B_plus_M_low; } } } double get_cut_B_plus_M_low( std::string year = "2015"){ if (KshortChannel) return cut_B_plus_M_low; else{ if (year == "2011" || year == "2012") return 5150.0; else if (year == "2015" || year == "2016" || year == "2017" || year =="2018" ) return cut_B_plus_M_low; else{ std:: cout << "[WARN] Wrong year input! Choose a year from 2011, 2012, 2015, 2016, 2017 or 2018. Lower cut set to " << cut_B_plus_M_low << "MeV" << std::endl; return cut_B_plus_M_low; } } } bool IsDST(std::string year, bool MC, bool ReferenceChannel, bool PHSP){ if (MC && (year == "2011" || year == "2012")) return true; if (MC && (year == "2018" && KshortChannel) && !PHSP) return true; if (MC && ReferenceChannel && (year == "2015" || year == "2016") && !KshortChannel) return true; return false; } void addLHCbtag(Float_t x = 0.6, Float_t y = 0.85, std::string suffix = "", Int_t color = 1, Float_t Scaling = 1.0){ TLatex* lhcbtext = new TLatex(); lhcbtext->SetTextFont(132); lhcbtext->SetTextColor(color); lhcbtext->SetTextSize(0.07*Scaling); lhcbtext->SetTextAlign(13); lhcbtext->SetNDC(1); lhcbtext->DrawLatex(x,y,("LHCb "+suffix).c_str()); } std::string Float2Comma(Float_t f, Int_t d){ if(d > 5){ std::cout << "[WARNING]\tPrecision larger '5' is not given by this function! Limit to 5." << std::endl; d = 5; } std::string out = Form("%i", static_cast(f + 1e-6)); /* just curious, why don't we use something like * tmp = f //just to be sure nothing happens to f itself * stringstream ss; * ss << fixed << setprecision(d) << tmp; * string out = ss.str() * out.replace(out.find("."),out.find(".")+1,",") * return out; * Seems a bit easier to me, or? * */ if(d <= 0)return out; Int_t N[d]; out.append(","); for(Int_t n = 0; n <= d; n++){ N[n] = static_cast((f + 1e-6) * TMath::Power(10., n)); //std::cout << "Iteration " << n << " : " << (f + 1e-6) * TMath::Power(10., n) << " and as INT: " << N[n] << std::endl; for(Int_t m = 0; m < n; m++)N[n] -= N[m] * TMath::Power(10., n - m); if(n != 0)out.append(Form("%i", N[n])); } return out; } bool replace(std::string& str, const std::string& from, const std::string& to) { size_t start_pos = str.find(from); if(start_pos == std::string::npos) return false; while ( (start_pos = str.find(from,start_pos)) != std::string::npos){ str.replace(start_pos, from.length(), to); start_pos += to.length(); // Handles case where 'to' is a substring of 'from' } return true; } void printVector (std::vector vector){ for (auto e: vector) cout << e << " "; } void printVector (std::vector vector){ for (auto e: vector) cout << e << " "; }/* void printVector (std::vector vector){ for (float e: vector) cout << e << " "; }*/ void printVector (std::vector vector){ for (auto e: vector) cout << e << " "; } std::vector yearsMC (bool Reference = false, bool PHSP = false, int Run = 1){ std::vector yearsTmp; if(Run != 1 && Run != 2 && Run !=12 ){ coutERROR("Invalid Run number given: " + to_string(Run) + ". Exit program!"); return yearsTmp; } if(Run == 1|| Run == 12) { yearsTmp.push_back("2011"); yearsTmp.push_back("2012"); } if(Run == 2|| Run == 12){ if (Kst2Kpluspi0Resolved){ if (Reference || PHSP) yearsTmp.push_back("2015"); //Buggy 2015 MC yearsTmp.push_back("2016"); if (!Reference){ //No reference channel for 2017 and 2018 if(Use2017) yearsTmp.push_back("2017"); if(Use2018) yearsTmp.push_back("2018"); } } else if (Kst2Kspiplus){ if (!Reference){ //no reference channel for Run II yearsTmp.push_back("2015"); yearsTmp.push_back("2016"); if(Use2017) yearsTmp.push_back("2017"); if(Use2018) yearsTmp.push_back("2018"); } if (Reference){ //@David TODO yearsTmp.push_back("2016"); } } } return yearsTmp; } std::vector yearsData (int Run = 1){ std::vector yearsTmp; if(Run != 1 && Run != 2 && Run !=12 ){ std::cout << "[ERROR]\t\tInvalid Run number given: " << Run << ". Exit program!" << std::endl; return yearsTmp; } if(Run == 1|| Run == 12) { yearsTmp.push_back("2011"); yearsTmp.push_back("2012"); } if(Run == 2|| Run == 12){ yearsTmp.push_back("2015"); yearsTmp.push_back("2016"); yearsTmp.push_back("2017"); yearsTmp.push_back("2018"); } return yearsTmp; } std::vector yearsVector (bool MC = false, bool Reference = false, bool PHSP = false, int Run = 1){ if (MC) return yearsMC(Reference,PHSP, Run); else return yearsData(Run); } std::vector yearsVectorInt(bool MC = false, bool Reference = false, bool PHSP = false, int Run = 1){ std::vector yearsTmp; for (auto yr: yearsVector(MC,Reference,PHSP,Run)) yearsTmp.push_back(stoi(yr)); return yearsTmp; } std::vector yearsInc(int Run){ std::vector yearsTmp; if(Run != 1 && Run != 2 && Run !=12 ){ std::cout << "[ERROR]\t\tInvalid Run number given: " << Run << ". Exit program!" << std::endl; return yearsTmp; } if(Run == 1|| Run == 12) { yearsTmp.push_back("2011"); yearsTmp.push_back("2012"); } if(Run == 2|| Run == 12){ yearsTmp.push_back("2016"); } return yearsTmp; } std::vector yearsBkgMC(bool Reference, bool B0, bool K1, bool Inc, int Run){ std::vector yearsTmp; if (B0){ if(Run == 1|| Run == 12) { yearsTmp.push_back("2011"); yearsTmp.push_back("2012"); } if(Run == 2|| Run == 12){ if (Kst2Kpluspi0Resolved){ yearsTmp.push_back("2015"); yearsTmp.push_back("2016"); } } } else if (K1){ if(Run == 1|| Run == 12) { if (!Reference) yearsTmp.push_back("2011"); yearsTmp.push_back("2012"); } if(Run == 2){ coutWarning("No Run II BtoK1Jpsi no BtoK1MuMu sample!"); coutERROR("Returning an empty vector."); } } else if (Inc){ if (!Reference){ coutWarning("No Run inclusive BtoXMuMu sample!"); coutERROR("Returning an empty vector."); } if(Run == 1|| Run == 12) { yearsTmp.push_back("2011"); yearsTmp.push_back("2012"); } if(Run == 2|| Run == 12){ if (Kst2Kpluspi0Resolved){ yearsTmp.push_back("2016"); } } } else{ coutERROR("No background sample selected! Choose between B0, K1 and inclusive samples!."); coutERROR("Returning an empty vector."); } return yearsTmp; } int getRunID(string year){ int RunID = -1; if (year == "2011" || year == "2012") RunID = 1; else if (year == "2015" || year == "2016"|| year == "2017"|| year == "2018") RunID = 2; else coutERROR("Wrong year input!"); return RunID; } #endif //GlobalFunctions