348 lines
14 KiB
C++
Executable File
348 lines
14 KiB
C++
Executable File
//training and testing of BDT for B2Kstplusmumu
|
|
//different BDTs are created for the subdecays
|
|
//1) Kst -> Kplus pi0
|
|
//2) Kst -> Kshort pi+
|
|
//later one is further split into DD and LL tracks
|
|
//David Gerick
|
|
//Renata Kopecna
|
|
|
|
#include "GlobalFunctions.hh"
|
|
#include "Paths.hpp"
|
|
#include "MVAclass.hpp"
|
|
#include "PlotTMVA.cpp"
|
|
|
|
#include "TMVA/MethodBase.h"
|
|
#include "TMVA/MethodCategory.h"
|
|
//#include "../TMVA/TMVA-v4.2.0/TMVA/Data.h"
|
|
|
|
#include "TMVA/TMVAGui.h"
|
|
|
|
#if not defined(__CINT__) || defined(__MAKECINT__)
|
|
#include "TMVA/Factory.h"
|
|
#include "TMVA/Tools.h"
|
|
#endif
|
|
|
|
//////////////////////////////////////////////////////
|
|
/// MVA_b2kmm()
|
|
/// training and testing of the BDT for final signal selection
|
|
/// the variables used for the BDT are defined from line 142 on.
|
|
/// one can seperate the years 2011 & 2012 for individual
|
|
/// training and testing or use the combined data-set. The Kshort
|
|
/// channel may be split up into DD and LL tracks
|
|
/// One can include the B+ -> Jpsi K*+ MC (reference channel) into
|
|
/// the signal Factory. Don't know why... just to try it out.
|
|
/// The results of the BDT training are saved in an .XML file and
|
|
/// read-in by TMVAClassificationApplication_b2kmm.cc
|
|
///
|
|
///
|
|
/// RunMVA()
|
|
/// Function to perform the complete MVA training and testing
|
|
/// with the given configurations in the functions defined in the
|
|
/// lines above. Can choose between Kshort and PizeroResolved
|
|
/// subdecays.
|
|
///
|
|
|
|
Int_t MVA_b2kmm() {
|
|
|
|
//limit the number of signal events; default = 0 : no limit
|
|
Int_t nSignal = 0;
|
|
bool use2Dweight = true;
|
|
//use also the reference channel MC (B -> K*+ J/Psi)
|
|
bool IncludeRefMC = false;
|
|
|
|
//Should we cut away outliners in the training?
|
|
bool cutOutliners = false;
|
|
|
|
//Should we cut away multiple candidates?
|
|
bool cutMultipleCandidates = false;
|
|
|
|
//separate dataset if the kshort decays within the velo or not
|
|
//LL tracks: 1
|
|
//DD tracks: 0
|
|
|
|
//Check MVAcongif
|
|
if(MVAconfig.Run != 1 && MVAconfig.Run != 2 && MVAconfig.Run != 12){
|
|
coutERROR("Invaliad Run ID chosen: >> " + to_string(MVAconfig.Run) + " << . Exit!");
|
|
return 0;
|
|
}
|
|
if(MVAconfig.Run == 12)coutInfo("Evaluate both Run 1 & 2 in one GO (train together Run 1 and Run 2)!");
|
|
|
|
if(MVAconfig.years.size() == 0 && MVAconfig.SplitYears){
|
|
coutERROR("No year given for the MVA configuration! Please fix before executing the MVA_b2kmm() function.");
|
|
return 0;
|
|
}
|
|
if (MVAconfig.customTMbranch == "") MVAconfig.customTMbranch = TMbranch;
|
|
|
|
TMVA::Tools::Instance();
|
|
|
|
TString signalTree= "DecayTreeTruthMatched";
|
|
TString bkgTree="DecayTree";
|
|
TString targetFile = GetBDTConfigFile(MVAconfig.SplitYears,MVAconfig.years.at(0),MVAconfig.Run,MVAconfig.KShortDecaysInVelo,MVAconfig.nConfiguration,MVAconfig.UseLowQ2Range, MVAconfig.customTMbranch, MVAconfig.gammaTM);
|
|
|
|
TFile* outputFile = TFile::Open(targetFile,"RECREATE" );
|
|
TChain* signal = new TChain(signalTree);
|
|
TChain* background= new TChain(bkgTree);
|
|
|
|
// Factory
|
|
TString factoryOptions = "!V:!Silent:Color:Transformations=I;N:AnalysisType=Classification:DrawProgressBar";
|
|
TMVA::Factory *factory;
|
|
TString factoryName = (MVAconfig.SplitYears ? (to_string(MVAconfig.years.at(0)) + "_") : "") + "B2Kstmumu_" + TheDecay + (SplitDDandLL ? (MVAconfig.KShortDecaysInVelo ? "_LL" : "_DD") : "")
|
|
+ (!MVAconfig.SplitYears ? ("_Run" + to_string(MVAconfig.Run)) : "") + (MVAconfig.SplitInQ2Range ? (MVAconfig.UseLowQ2Range ? "_lowQ2" : "_highQ2") : "");
|
|
|
|
factory = new TMVA::Factory( factoryName, outputFile , factoryOptions);
|
|
|
|
//add variables used in training
|
|
string DL = "";
|
|
if(Kst2Kspiplus && SplitDDandLL) DL = MVAconfig.KShortDecaysInVelo ? "LL" : "DD";
|
|
|
|
//Read MVA variables from file
|
|
MVA_variables InputVariables(DL);
|
|
InputVariables.print();
|
|
|
|
//and feed them to the reader
|
|
for (vector<MVA_def>::iterator tracksIter1 = InputVariables.AllVariables.begin(); tracksIter1 !=InputVariables.AllVariables.end();++tracksIter1){
|
|
factory->AddVariable( (*tracksIter1).ReaderName,(*tracksIter1).LaTeXName,(*tracksIter1).Unit,(*tracksIter1).DataType);
|
|
}
|
|
|
|
//set MVAconfig.years accordingly to the chosen Run
|
|
if(!MVAconfig.SplitYears){
|
|
MVAconfig.years.clear();
|
|
MVAconfig.years = yearsVectorInt(false, false, false, MVAconfig.Run);
|
|
|
|
coutInfo("Load files for Run ");
|
|
std::cout << (MVAconfig.Run == 12 ? "1 & 2" : std::to_string(MVAconfig.Run).c_str()) << ": Years ";
|
|
for(UInt_t y = 0; y < MVAconfig.years.size(); y++){
|
|
if(y == MVAconfig.years.size() - 1) std::cout << "and " << MVAconfig.years.at(y) << "." << std::endl;
|
|
else std::cout << MVAconfig.years.at(y) << ", ";
|
|
}
|
|
}
|
|
|
|
if(MVAconfig.SplitYears && MVAconfig.years.size() > 1){
|
|
coutERROR("Vector with years cannot be larger 1 for the SplitYears configuration!");
|
|
return 0;
|
|
}
|
|
|
|
//load data to trees
|
|
for(UInt_t y = 0; y < MVAconfig.years.size(); y++){
|
|
|
|
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
|
|
if(IncludeRefMC) signal->Add(GetBDTinputFile(MVAconfig.years.at(y),true,true,false,MVAconfig.KShortDecaysInVelo).c_str());
|
|
background->Add(GetBDTinputFile(MVAconfig.years.at(y),false,false,false,MVAconfig.KShortDecaysInVelo).c_str());
|
|
}
|
|
// check the files
|
|
for(UInt_t y = 0; y < MVAconfig.years.size(); y++){
|
|
if (MVAconfig.years.at(y) != 2015 && Kst2Kpluspi0Resolved) coutDebug("Opening signal file " + GetBDTinputFile(MVAconfig.years.at(y),true,false,false,MVAconfig.KShortDecaysInVelo));
|
|
if(IncludeRefMC) coutDebug("Opening signal file " + GetBDTinputFile(MVAconfig.years.at(y),true,true,false,MVAconfig.KShortDecaysInVelo));
|
|
coutDebug("Opening background file " + GetBDTinputFile(MVAconfig.years.at(y),false,false,false,MVAconfig.KShortDecaysInVelo));
|
|
}
|
|
|
|
factory->AddSignalTree(signal,1.);
|
|
factory->AddBackgroundTree(background,1.);
|
|
|
|
string weightName = getWeightName(MVAconfig.customTMbranch,MVAconfig.gammaTM);
|
|
if (use2Dweight) factory->SetSignalWeightExpression(weightName.c_str()); //2D weights
|
|
else factory->SetSignalWeightExpression(weightName.c_str()); //1D weights
|
|
|
|
TCut cutsS;
|
|
TCut cutsB;
|
|
|
|
string sVariable = UseDTF ? "B_plus_M_DTF" : "B_plus_M";
|
|
|
|
if(Kst2Kspiplus){
|
|
//mass range:
|
|
cutsS = Form("%s < 5379 && %s > 5179", sVariable.c_str(), sVariable.c_str()); //cut +/- 100MeV on signal MC
|
|
cutsB = Form("%s > 5400", sVariable.c_str()); //upper mass sideband of data
|
|
|
|
//DD and LL split?
|
|
if(SplitDDandLL){
|
|
cutsS += Form("KshortDecayInVeLo == %i", MVAconfig.KShortDecaysInVelo);
|
|
cutsB += Form("KshortDecayInVeLo == %i", MVAconfig.KShortDecaysInVelo);
|
|
}
|
|
|
|
//Q2 range:
|
|
if(MVAconfig.SplitInQ2Range){
|
|
if(MVAconfig.UseLowQ2Range){
|
|
cutsS += "Q2 < 8.68e6";
|
|
cutsB += "Q2 < 8.68e6";
|
|
|
|
}
|
|
else{
|
|
cutsS += "(Q2 > 10.09e6 && Q2 < 12.9e6) || Q2 > 14.4e6)";
|
|
cutsB += "(Q2 > 10.09e6 && Q2 < 12.9e6) || Q2 > 14.4e6)";
|
|
}
|
|
}
|
|
else{
|
|
cutsS += "(Q2 < 8.68e6 || (Q2 > 10.09e6 && Q2 < 12.9e6) || Q2 > 14.4e6)";
|
|
cutsB += "(Q2 < 8.68e6 || (Q2 > 10.09e6 && Q2 < 12.9e6) || Q2 > 14.4e6)";
|
|
}
|
|
|
|
cutsS += TCut(getTMcut(true,false,MVAconfig.customTMbranch,MVAconfig.gammaTM).c_str());
|
|
}
|
|
else{ //pi0 channel
|
|
cutsS = Form("%s < 5379 && %s > 5179", sVariable.c_str(), sVariable.c_str()); // for signal use MC data from B mass window only (+-100MeV)
|
|
cutsB = Form("%s > 5700", sVariable.c_str()); // for background far upper sideband of data
|
|
|
|
//Q2 range: //TODO: check
|
|
if(MVAconfig.SplitInQ2Range){
|
|
if(MVAconfig.UseLowQ2Range){
|
|
cutsS += "Q2 < 8.68e6";
|
|
cutsB += "Q2 < 8.68e6";
|
|
}
|
|
else{
|
|
cutsS += "((Q2 > 10.09e6 && Q2 < 12.9e6) || Q2 > 14.4e6)";
|
|
cutsB += "((Q2 > 10.09e6 && Q2 < 12.9e6) || Q2 > 14.4e6)";
|
|
}
|
|
}
|
|
else{
|
|
//cutsS += "(Q2 < 8.68e6 || (Q2 > 10.09e6 && Q2 < 12.9e6) || Q2 > 14.4e6)";
|
|
//cutsB += "(Q2 < 8.68e6 || (Q2 > 10.09e6 && Q2 < 12.9e6) || Q2 > 14.4e6)";
|
|
cutsS += TCut(getMuMucut().c_str()); //TODO: check
|
|
cutsB += TCut(getMuMucut().c_str()); //TODO: check
|
|
}
|
|
//cut outliners
|
|
if (cutOutliners){
|
|
TCut outliners = "";
|
|
if (MVAconfig.Run == 1){
|
|
outliners += "B_plus_IP_OWNPV<0.1";
|
|
outliners += "TMath::Abs(pi_zero_resolved_ETA_DTF-K_plus_ETA_DTF)<1";
|
|
outliners += "TMath::Log(B_plus_PT_DTF)<10";
|
|
outliners += "TMath::Log(1.0-B_plus_DIRA_OWNPV)>-18";
|
|
outliners += "TMath::Log(K_plus_PT_DTF)<9.5";
|
|
outliners += "TMath::Log(mu_minus_IPCHI2_OWNPV)<11";
|
|
outliners += "gamma1_PT_DTF<3000";
|
|
outliners += "gamma2_PT_DTF<4000";
|
|
}
|
|
else if (MVAconfig.Run == 2){
|
|
outliners += "TMath::Max(TMath::Log(gamma1_PT_DTF),TMath::Log(gamma2_PT_DTF))<8.5";
|
|
outliners += "B_plus_IP_OWNPV<0.1";
|
|
outliners += "TMath::Abs(pi_zero_resolved_ETA_DTF-K_plus_ETA_DTF)<1";
|
|
outliners += "TMath::Log(B_plus_PT_DTF)<10.25";
|
|
outliners += "TMath::Log(K_plus_PT_DTF)<9.0";
|
|
outliners += "TMath::Log(K_plus_PT_DTF)>6.0";
|
|
outliners += "TMath::Log(1.0-B_plus_DIRA_OWNPV)>-18";
|
|
outliners += "TMath::Log(mu_minus_IPCHI2_OWNPV)<10";
|
|
outliners += "gamma1_PT_DTF<3000";
|
|
outliners += "gamma2_PT_DTF<4000";
|
|
}
|
|
cutsS+= outliners;
|
|
cutsB+= outliners;
|
|
}
|
|
if (cutMultipleCandidates){
|
|
cutsS += "totCandidates == 1";
|
|
cutsB += "totCandidates == 1";
|
|
}
|
|
cutsS += TCut(getTMcut(true,false,MVAconfig.customTMbranch,MVAconfig.gammaTM).c_str());
|
|
coutDebug("Using cut ");
|
|
if (verboseLevel < 3) cutsS.Print();
|
|
}
|
|
|
|
coutInfo("nEntries in signal tree: " + to_string(signal->GetEntries()));
|
|
coutInfo("nEntries in bckgnd tree: " + to_string(background->GetEntries()));
|
|
|
|
// Tell the factory how to use the training and testing events
|
|
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));
|
|
|
|
// MVA methods: book BDT as default
|
|
if (Kst2Kspiplus){
|
|
factory->BookMethod( TMVA::Types::kBDT, "BDT", "!H:!V:NTrees=300:MaxDepth=3:BoostType=AdaBoost:AdaBoostBeta=0.5:SeparationType=GiniIndex:nCuts=12:PruneMethod=NoPruning");
|
|
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" );
|
|
}
|
|
else if (Kst2Kpluspi0Resolved){
|
|
factory->BookMethod( TMVA::Types::kBDT, "BDT", "!H:!V:NTrees=300:MaxDepth=2:BoostType=AdaBoost:AdaBoostBeta=0.26:SeparationType=GiniIndex:nCuts=12:PruneMethod=NoPruning");
|
|
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" );
|
|
factory->BookMethod( TMVA::Types::kMLP, "MLP", "H:!V:VarTransform=N:NCycles=750:HiddenLayers=N+5:TestRate=10:!UseRegulator" );//IgnoreNegWeightsInTraining=True
|
|
}
|
|
|
|
// Train and test MVAs
|
|
factory->TrainAllMethods();
|
|
factory->TestAllMethods();
|
|
|
|
// Evaluate performances
|
|
factory->EvaluateAllMethods();
|
|
outputFile->Close();
|
|
|
|
delete factory;
|
|
|
|
// Launch the GUI for the root macros
|
|
//if (!gROOT->IsBatch()) TMVA::TMVAGui( targetFile );
|
|
|
|
//Plot everything TODO: fix year and add gammaTM
|
|
SaveAllFromOneFile(2011,MVAconfig.Run,MVAconfig.SplitYears,MVAconfig.KShortDecaysInVelo,MVAconfig.nConfiguration,MVAconfig.UseLowQ2Range, MVAconfig.customTMbranch, MVAconfig.gammaTM);
|
|
|
|
coutInfo("MVA training done!");
|
|
return 1;
|
|
|
|
}
|
|
|
|
//Ks only
|
|
Int_t RunMore(Int_t Run = 1){
|
|
|
|
MVAconfig.Run = Run;
|
|
MVAconfig.SplitYears = false;
|
|
MVAconfig.SplitInQ2Range = false;
|
|
MVAconfig.nConfiguration = 1;
|
|
MVAconfig.KShortDecaysInVelo = 1;
|
|
if (MVA_b2kmm() == 0) return 0;
|
|
|
|
MVAconfig.KShortDecaysInVelo = 0;
|
|
if (MVA_b2kmm() == 0) return 0;
|
|
|
|
MVAconfig.SplitInQ2Range = true;
|
|
MVAconfig.UseLowQ2Range = true;
|
|
MVAconfig.nConfiguration = 2;
|
|
MVAconfig.KShortDecaysInVelo = 1;
|
|
if (MVA_b2kmm() == 0) return 0;
|
|
|
|
MVAconfig.KShortDecaysInVelo = 0;
|
|
if (MVA_b2kmm() == 0) return 0;
|
|
|
|
MVAconfig.UseLowQ2Range = false;
|
|
MVAconfig.nConfiguration = 3;
|
|
MVAconfig.KShortDecaysInVelo = 1;
|
|
if (MVA_b2kmm() == 0) return 0;
|
|
|
|
MVAconfig.KShortDecaysInVelo = 0;
|
|
if (MVA_b2kmm() == 0) return 0;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
Int_t RunDDandLLKshort(Int_t Run = 1){
|
|
MVAconfig.Run = Run;
|
|
MVAconfig.SplitYears = false;
|
|
MVAconfig.SplitInQ2Range = false;
|
|
MVAconfig.nConfiguration = 1;
|
|
MVAconfig.KShortDecaysInVelo = 1;
|
|
if (MVA_b2kmm() == 0) return 0;
|
|
MVAconfig.KShortDecaysInVelo = 0;
|
|
if (MVA_b2kmm() == 0) return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
Int_t RunKplusPizeroResolved(Int_t Run = 1, int config=0, string customTMbranch ="", bool gammaTM = false){
|
|
MVAconfig.Run = Run;
|
|
MVAconfig.nConfiguration = config;
|
|
MVAconfig.KShortDecaysInVelo = false;
|
|
MVAconfig.SplitYears = false;
|
|
MVAconfig.SplitInQ2Range = false;
|
|
MVAconfig.UseLowQ2Range = false;
|
|
MVAconfig.customTMbranch = customTMbranch;
|
|
MVAconfig.gammaTM = gammaTM;
|
|
if (MVA_b2kmm() == 0) return 0;
|
|
return 1;
|
|
}
|
|
|
|
Int_t RunMVA(Int_t Run = 1){
|
|
if(Kst2Kspiplus)return RunDDandLLKshort(Run);
|
|
if(Kst2Kpluspi0Resolved){
|
|
//RunKplusPizeroResolved(Run,1,"TMedBKGCAT",false);
|
|
RunKplusPizeroResolved(Run,0,"TMed",false);
|
|
//RunKplusPizeroResolved(Run,2,"TMed",true);
|
|
|
|
}
|
|
return 0;
|
|
}
|
|
|