|
|
//Libraries used for the B+ mass fit model
//Renata Kopecna
#ifndef MASSFIT_HPP
#define MASSFIT_HPP
#include "GlobalFunctions.hh"
#include "RooFit/RooDoubleCB/RooDoubleCB.h"
#include "BmassShape/SignalPdf.hpp"
using namespace std; using namespace RooFit; using namespace RooStats;
//////////////////////////////////////////////////////
/// \brief GetsWeightPlots()
//////////////////////////////////////////////////////
///
/// Returns path where the sWeighting control plots are stored
///
//////////////////////////////////////////////////////
/// \brief massFit()
//////////////////////////////////////////////////////
/// Based on quickFit in nTrackWeights.cc, but made into a seperate file
/// in on order to be able to be run as a standalone code
///
/// Main purpose is to fit the Bmass distribution and save the yield of the fit.
/// the fitted B+ mass spectrum may be saved in pdf and root files
///
///
/// FEATURES:
/// - choose your background and signal model:
/// signal: (double) Gaussian, left/right/double/two-tailed CrystalBall function
/// background: (double) Exponential, Exponential plus RooExpGaus or no background
/// - get signal shape from MC data if needed and restrict shape to these parameters
/// - choose if fit all data, Jpsi q^2 region or q^2 region without resonances
/// - choose if fit low/high q^2 region
/// - choose to fit LL/DD Kshort sample
/// - choose to fit up/down/both
/// - choose to fit per year or per run///
///
/// OPTIONAL:
/// - cut on TMVAresponse
/// - fit only randomly selected half of the data sample
/// - Calculate yield in a 2sigma/fixed window
/// - Calculate yield over the full region
/// - Turn off the fit of MC needed to get the shape parameters (usefull in loops)
/// - Save the mass plots in efficiency file
/// - Fit in bins of selected variable
///
/// - from the fit to the B+ mass distribution, a sPlot weight is calculated and saved to a new Branch in this merged file.
/// If only Jpsi is selected, Reference channel is used and if sWeight==true,
/// J/psi data only is saved
///
//////////////////////////////////////////////////////
/// \brief quickFit()
//////////////////////////////////////////////////////
///
/// massFit() with simplified options
/// suitable for reweighting MC and creating sPlots
///
/////////////////////////////////////////////////////////
/// efficiencyFit()
//////////////////////////////////////////////////////
///
/// \brief massFit() with simplified options
/// suitable for efficiency estimation fits
///
/////////////////////////////////////////////////////////
/// \brief basicYieldFit()
//////////////////////////////////////////////////////
///
/// massFit() with simplified options
/// suitable for getting yield information
///
/// Available also to be done for:
/// All years
/// All years and q2 regions
/// Both Runs
///
/////////////////////////////////////////////////////////
/// \brief massFitTestAll()
//////////////////////////////////////////////////////
///
/// Fits given data sample with different
/// signal and background shapes, useful
/// when deciding what shape describes
/// the data the best
///
//////////////////////////////////////////////////////
/// \brief PrintFitResults()
//////////////////////////////////////////////////////
/// Takes RooFitResult as an iput and prints its content
///
///
///
//////////////////////////////////////////////////////
/// TODO at some point
/// \param year
/// \param UseOnlyJpsiEvents
/// \param UseOnlyMuMuEvents
/// \param KshortDecaysInVelo
/// \param GetShapeFromMC
/// \param SigType
/// \param BckGndType
/// \param ConstrainParameters
///
///
///
class TMefficiencyClass{
public: string sVariable; std::vector<string> sBranchName; Int_t Bins; Float_t Range[2]; std::vector<std::array<double, 2>> vVarRange; std::vector<double> binEdges; std::vector<double> binEdgesEquidistant; bool isEquidistant; Float_t Step; string cut;
TMefficiencyClass(){ //default constructor
sVariable = ""; sBranchName = {}; Bins = 0; Range[0] = 0.; Range[1] = 0.; vVarRange = {}; binEdges = {}; binEdgesEquidistant = {}; cut = "";
}
void fillBinEdges(){ double step = (Range[1] - Range[0]) / Bins; for (int i = 0; i <= Bins; i++){ binEdgesEquidistant.push_back(Range[0]+i*step); } return; } void isEq(string &varName){ //'_equal' has to appear at the end of the variable!
//See if the '_equal' is present
size_t found = varName.find("_equal"); if (found != string::npos) isEquidistant = true; else isEquidistant = false; //Remove '_equal' from the string
replace(varName,"_equal",""); } bool check_vector_size(bool isEqui){ if (!isEqui){ if (int(binEdges.size()) != Bins+1){ coutDebug("Bins edges should be " + to_string(Bins+1) + " and are " + to_string(binEdges.size())); coutERROR("Wrong number of bin edges! Check " + sVariable); return false; } else return true; } else{ if (int(binEdgesEquidistant.size()) != Bins+1){ coutDebug("Bins edges should be " + to_string(Bins+1) + " and are " + to_string(binEdgesEquidistant.size())); coutERROR("Wrong number of bin edges! Check " + sVariable); return false; } else return true; } }
TMefficiencyClass(string varName){ // constructor
//first, replace the variable name
isEq(varName); coutDebug("Is equidistant? " + to_string(isEquidistant));
//q^2:
if (varName == "q2"){ sVariable = "q^{2} [MeV^{2}]"; sBranchName = {"Q2"}; Bins = 10; Range[0] = 0.; // in MeV^2
Range[1] = 20000000.; // in MeV^2
vVarRange = {{Range[0],Range[1]}}; fillBinEdges(); binEdges = {}; cut = sBranchName.at(0); } else if (varName == "q2_binned"){ //binned as in the analysis
sVariable = "q^{2} [GeV^{2}]"; sBranchName = {"Q2"}; Bins = 11; Range[0] = 0.1e6; // in MeV^2
Range[1] = 20e6; vVarRange = {{Range[0],Range[1]}}; fillBinEdges(); 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}; cut = sBranchName.at(0); } else if (varName == "q2_binned_fit"){ //binned as in the analysis
sVariable = "q^{2} [GeV^{2}]"; sBranchName = {"Q2"}; Bins = 6; Range[0] = 1.1e6; // in MeV^2
Range[1] = 20e6; vVarRange = {{Range[0],Range[1]}}; fillBinEdges(); binEdges = {0.1e6, 4.0e6, 8.0e6, 11.0e6, 12.5e6, 15.0e6, 20.0e6}; cut = sBranchName.at(0); }
//cos(Theta_k):
else if (varName == "thetak"){ sVariable = "cos(#theta_{k})"; sBranchName = {"B_plus_ThetaK"}; Bins = 10; Range[0] = -1.0; Range[1] = 1.0; //Range[0] = 0.;
//Range[1] = 3.142;
Step = (Range[1] - Range[0]) / Bins; fillBinEdges(); binEdges = {0.000, 1.053, 1.294, 1.488, 1.662, 1.827, 1.993, 2.163, 2.353, 2.585, 3.150}; vVarRange = {{0.,3.142}}; cut = "cos(B_plus_ThetaK)"; } //cos(Theta_l):
else if (varName == "thetal"){ sVariable = "cos(#theta_{l})"; sBranchName = {"B_plus_ThetaL"}; Bins = 10; Range[0] = -1.0; Range[1] = 1.0; //Range[0] = 0.;
//Range[1] = 3.142;
Step = (Range[1] - Range[0]) / Bins; fillBinEdges(); binEdges = {0.000, 0.630, 0.896, 1.110, 1.302, 1.486, 1.670, 1.866, 2.086, 2.368, 3.150}; vVarRange = {{0.,3.142}}; cut = "cos(B_plus_ThetaL)"; } //phi
else if (varName == "phi"){ sVariable = "#phi"; sBranchName = {"B_plus_Phi"}; Bins = 10; Range[0] = -3.15; Range[1] = 3.15; Step = (Range[1] - Range[0]) / Bins; fillBinEdges(); binEdges = {-3.150, -2.476, -1.832, -1.207, -0.593, 0.015, 0.624, 1.241, 1.870, 2.517, 3.150}; vVarRange = {{Range[0],Range[1]}}; cut = sBranchName.at(0); } else if (varName == "pi_zero_ETA"){ sVariable = "#eta(#pi^{0})"; sBranchName = {"pi_zero_resolved_ETA_DTF"}; Bins = 10; Range[0] = 1.5; Range[1] = 4.5; Step = (Range[1] - Range[0]) / Bins; fillBinEdges(); binEdges = {}; vVarRange = {{Range[0],Range[1]}}; cut = sBranchName.at(0); } else if (varName == "pi_zero_ETA-K_plus_ETA"){ sVariable = "|#eta(#pi^{0})-#eta(K^{+})|"; sBranchName = {"pi_zero_resolved_ETA_DTF","K_plus_ETA_DTF"}; Bins = 15; Range[0] = 0.0; Range[1] = 1.0; Step = (Range[1] - Range[0]) / Bins; fillBinEdges(); binEdges = {}; vVarRange = {{0.0,5.0},{0.0,5.0}}; cut = "TMath::Abs(pi_zero_resolved_ETA_DTF-K_plus_ETA_DTF)"; } else if (varName == "pi_zero_P"){ sVariable = "log(P(#pi^{0}))"; sBranchName = {"pi_zero_resolved_P"}; Bins = 10; Range[0] = 2980; //not log!
Range[1] = 100000;//not log!
Step = (Range[1] - Range[0]) / Bins; fillBinEdges(); binEdges = {8.0, 8.75367, 9.01297, 9.21333, 9.38583, 9.55554, 9.72447, 9.90965, 10.1241, 10.405, 11.5}; vVarRange = {{Range[0],Range[1]}}; cut = "log(pi_zero_resolved_P)";//TODO fix equidistant binning, now based on 2016 PHSP
} else if (varName == "pi_zero_P_DTF"){ sVariable = "log(P(#pi^{0}^{DTF}})"; sBranchName = {"pi_zero_resolved_P_DTF"}; Bins = 10; Range[0] = 2980; //not log!
Range[1] = 100000;//not log!
Step = (Range[1] - Range[0]) / Bins; fillBinEdges(); binEdges = {8.0, 8.7508, 9.01136, 9.20829, 9.38185, 9.55001, 9.723, 9.90559, 10.1195, 10.4024, 11.5}; vVarRange = {{Range[0],Range[1]}}; cut = "log(pi_zero_resolved_P_DTF)";//TODO fix equidistant binning, now based on 2016 PHSP
} else if (varName == "pi_zero_PT"){ sVariable = "log(P_{T}(#pi^{0}))"; sBranchName = {"pi_zero_resolved_PT"}; Bins = 10; Range[0] = 800; //not log!
Range[1] = 8000;//not log!
Step = (Range[1] - Range[0]) / Bins; fillBinEdges(); binEdges = {6.5, 6.81709, 6.91294, 7.01023, 7.11076, 7.21995, 7.34191, 7.48141, 7.64965, 7.88324, 9.0}; vVarRange = {{Range[0],Range[1]}}; cut = "log(pi_zero_resolved_PT)"; //TODO fix equidistant binning, now based on 2016 PHSP
} else if (varName == "pi_zero_PT_DTF"){ sVariable = "log(P_{T}(#pi^{0})^{DTF})"; sBranchName = {"pi_zero_resolved_PT_DTF"}; Bins = 10; Range[0] = 800; //not log!
Range[1] = 8000;//not log!
Step = (Range[1] - Range[0]) / Bins; fillBinEdges(); binEdges = {6.5, 6.8152, 6.91109, 7.00766, 7.10771, 7.21609, 7.33793, 7.47641, 7.64706, 7.88087, 9.0}; vVarRange = {{Range[0],Range[1]}}; cut = "log(pi_zero_resolved_PT_DTF)";//TODO fix equidistant binning, now based on 2016 PHSP
} else if (varName == "K_plus_PT"){ sVariable = "log(P_{T} (K^{+})) [MeV^{2}]"; sBranchName = {"K_plus_PT"}; Bins = 10; Range[0] = 270; //not log!
Range[1] = 16000;//not log!
Step = (Range[1] - Range[0]) / Bins; fillBinEdges(); binEdges = {5.6, 6.658, 6.91969, 7.12516, 7.30566, 7.47015, 7.64604, 7.8327, 8.04823, 8.35614, 9.7}; vVarRange = {{Range[0],Range[1]}}; cut = "log(K_plus_PT)"; } else{ sVariable = ""; sBranchName = {}; Bins = 1; Range[0] = 0.; Range[1] = 0.; vVarRange = {}; fillBinEdges(); binEdges={Range[0],Range[1]}; Step = 0; cut = ""; isEquidistant = false; } if (!check_vector_size(isEquidistant)){ sVariable = ""; sBranchName = {}; Bins = 0; Range[0] = 0.; Range[1] = 0.; vVarRange = {}; fillBinEdges(); Step = 0; cut = ""; }
} ~TMefficiencyClass(); //destuctor
};
TMefficiencyClass::~TMefficiencyClass(){}//destuctor
bool useExtraVarBool(string extraVar);
string GetsWeightPlots(string year, bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, bool KshortDecaysInVelo, bool GetShapeFromMC, string SignalType, string BkgType, bool ConstrainParameters);
double massFit(string year, string magnet, int Run, bool MC, bool Preselected, bool TM, bool PHSP, //input/output file selection
bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, //signal/reference
bool GetShapeFromMC, string SigType, string BkgType, bool ConstrainParameters, //shape
bool KshortDecaysInVelo, bool UseLowQ2Range, //LL/DD? q2range?
Double_t TMVAcut, int randomSubset, //TMVA options
bool fixedMassRegion, bool yieldOverFullRange, //yield calculation region
bool sWeight, //sWeight data?
bool loopFit, bool IsEfficiency, //additional options
string sExtraVar, int nExtraBin, //fit in bins of extra variable
bool removeMultiple, //Remove multiple candidates?
bool weighted, bool weightedFromPi0, string whichWeight, //use weight in the fit?
bool nonTM, string customTMbranch, bool gammaTM, //TM options
bool InclusiveSample);
int quickFit(string year, bool MC, bool sWeight, bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, bool KshortDecaysInVelo, bool GetShapeFromMC, string SigType, string BkgType, bool ConstrainParameters);
int efficiencyFit(std::string year, string magnet, int Run , bool Preselected, bool TM, bool PHSP, //input/output file selection
bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, //signal/reference
bool GetShapeFromMC, std::string SigType , std::string BckGndType , bool ConstrainParameters, //shape
bool KshortDecaysInVelo, //LL/DD?
Double_t TMVAcut, //TMVA options
bool fixedMassRegion, //yield calculation region
bool UseLowQ2Range, //q2 ranges
string sExtraVar, int nExtraBin, bool removeMultiple, bool weighted, bool weightedFromPi0, string whichWeight, string customTMbranch, bool gammaTM);
int basicYieldFit(std::string year, int Run , bool MC, bool PHSP, //input/output file selection
bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, //signal/reference
bool GetShapeFromMC, std::string SigType , std::string BckGndType , bool ConstrainParameters, //shape
bool KshortDecaysInVelo, bool UseLowQ2Range , //LL/DD? q2range?
Double_t TMVAcut, //TMVA options
bool fixedMassRegion, bool loopFit, bool removeMultiple);
int basicYieldFitAllYears(bool MC, bool PHSP, //input/output file selection
bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, //signal/reference
bool GetShapeFromMC, std::string SigType , std::string BckGndType , bool ConstrainParameters, //shape
bool KshortDecaysInVelo, bool UseLowQ2Range , //LL/DD? q2range?
Double_t TMVAcut, //TMVA options
bool fixedMassRegion, bool loopFit, bool removeMultiple);
int basicFitAllYearsAndRegions(bool MC, bool PHSP, //input/output file selection
bool GetShapeFromMC, std::string SigType , std::string BckGndType , bool ConstrainParameters, //shape
bool KshortDecaysInVelo, bool UseLowQ2Range , //LL/DD? q2range?
Double_t TMVAcut, bool removeMultiple //TMVA options, remove multiple
);
int basicYieldFitAllRuns( bool MC, //input/output file selection
bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, //signal/reference
bool GetShapeFromMC, std::string SigType , std::string BckGndType , bool ConstrainParameters, //shape
bool KshortDecaysInVelo, bool UseLowQ2Range , //LL/DD? q2range?
Double_t TMVAcut, //TMVA options
bool fixedMassRegion, bool loopFit,bool removeMultiple//yield calculation region
);
//Print efficiencies and fit parameters
int PrintFitResults(RooFitResult* fitRes);
int fitJpsi(string year, bool MC, double TMVAcut, bool RemoveMultiple);
#endif // MASSFIT_HPP
|