simple/source/MainSimple.cpp
A simple TMVA based analysis
The analysis class
#pragma once
// include the Analysis base class
#include "boca/analysis/Analysis.hh"
namespace simple
{
// all Analyses inherit from the boca::Analysis base class
// the base class expects an Tagger class as template parameter
template<typename Tagger_>
{
public:
// override some functions of the base class
// Set Files used in the analysis
{
// add a signal file by passing its file and process name
break;
// add a background file by passing its file and process name
break;
}
}
// define how many events are supposed to beeing used
{
return 1000;
}
// define the analysis name
{
return "SimpleAnalysis";
}
};
}
The Tagger class
#pragma once
// include the Tagger base class
#include "boca/tagger/Tagger.hh"
// include the simple Observable definition
#include "simple/Observables.hh"
// include the simple Branch used by TMVA
#include "simple/Branch.hh"
namespace simple
{
// each Tagger class must inherit from the boca::Tagger base class
// the Base class expect a set of Observables and a root Branch definition as template paramter
{
public:
// The first phase during a multivariant analysis is called Training phase
// During the second Reading phase we retrieve objects of the Observable set
std::vector<Observables> Multiplets(boca::Event const &event, boca::PreCuts const &pre_cuts, TMVA::Reader const &reader) override;
// Name of the Tagger
};
}
The Tagger definition
#include "simple/Tagger.hh"
namespace simple
{
{
// Create one object of the the Observables and pass it the full event information
Observables observables(event);
// save also weather the Tag is signal or background
observables.SetTag(tag);
// Save the observables to the root file and return the number of saved objects (in this case always one)
}
std::vector<Observables> Tagger::Multiplets(boca::Event const &event, boca::PreCuts const &, TMVA::Reader const &reader)
{
// Create one object of the the Observables and pass it the full event information
Observables observables(event);
// save also the BDT response to this object
observables.SetBdt(Bdt(observables, reader));
// return all objects (in this case only one)
return {observables};
}
std::string Tagger::Name() const
{
return "Simple";
}
}
The Observable class
#pragma once
// include the Identification base class
#include "boca/fastjet/Particle.hh"
// include the Event class
#include "boca/event/Event.hh"
namespace simple
{
// use members of boca::units without prefix
using namespace boca::units;
// Each Observable is calculated by a function of this class
// Additionally the Tag and the BDT response has to be saved, which is done in the Identification base class
{
public:
// The constructor takes the complete event
Observables(boca::Event const &event);
// The number of leptons
int LeptonNumber() const;
// The number of jets
int JetNumber() const;
// The number of bottom jets
int BottomNumber() const;
// The sclar sum of the transvers momenta
Momentum ScalarHt() const;
// The transverse momentum of the n'th jet
// The transverse momentum of the n'th lepton
// The missing transvser energy
private:
// storage for the jets
std::vector<boca::Jet> jets_;
// storage for the leptons
std::vector<boca::Lepton> leptons_;
// storage for the scalar ht
Momentum scalar_ht_;
// storage for the missing et
Energy missing_et_;
};
}
The Observable definition
#include "boca/fastjet/Vector.hh"
#include "boca/fastjet/Sort.hh"
#include "simple/Observables.hh"
namespace simple
{
// Get the basic objects from the event
{
// store the jets sorted by pt
// store the leptons sorted by pt
// store the scalar ht
scalar_ht_ = event.ScalarHt();
// store the missing et
missing_et_ = event.MissingEt().Pt();
}
{
// return the number of leptons
return leptons_.size();
}
{
// return the number of jets
return jets_.size();
}
{
// return the number of jets with Delphes b-tag
}
{
// return scalar_ht
return scalar_ht_;
}
{
// return missing et
return missing_et_;
}
{
// return pt of jet at number
}
{
// return pt of lepton at number
return leptons_.size() > number ? leptons_.at(number).Pt() : at_rest;
}
}
The Branch class
#pragma once
// include the Units header
#include "boca/units/Units.hh"
// include Branch base
#include "boca/branch/Bdt.hh"
// include Observables
#include "boca/multivariant/Observables.hh"
namespace simple
{
// use the namespace for units
using namespace boca::units;
// define the branch for saving the root file
// inherits from the BDT branch base class
{
public:
// Constructor
Branch();
// All observables must be saved as floats
float jet_number;
float bottom_number;
float missing_et;
float scalar_ht;
float jet_1_pt;
float jet_2_pt;
float jet_3_pt;
float jet_4_pt;
// define how the branches are going to be filled from the Observables
template<typename Multiplet_>
void Fill(Multiplet_ const &multiplet)
{
// store the BDT value in the BDT member
boca::branch::Bdt::Fill(multiplet);
// store the other multiplet in their fields
jet_number = multiplet.JetNumber();
bottom_number = multiplet.BottomNumber();
// note that the Branch only takes plain numbers
missing_et = multiplet.MissingEt() / GeV;
scalar_ht = multiplet.ScalarHt() / GeV;
jet_1_pt = multiplet.JetPt(0) / GeV;
jet_2_pt = multiplet.JetPt(1) / GeV;
jet_3_pt = multiplet.JetPt(2) / GeV;
jet_4_pt = multiplet.JetPt(3) / GeV;
}
// return the Variables for TMVA
private:
ClassDef(Branch, 1)
};
}
The Branch definition
// include the Branch header
#include "simple/Branch.hh"
// include macros to create Observables
#include "boca/multivariant/OBSERVABLE_MACROS.hh"
namespace simple
{
// initiatialize all observables with an unphysical value
// note that only integer variables must be initiatialized as integer
{
}
{
// return a list of observables by passing all class members with their description to the OBSERVABLE macro
}
}
The root LinkDef necessary for the root file creation
#ifdef __MAKECINT__
#pragma link C++ defined_in "../../../../examples/simple/simple/Branch.hh";
#endif
The main file
#include "simple/Analysis.hh"
#include "simple/Tagger.hh"
{
// Create an object of the simple Analysis and pass it the simple Tagger
simple::Analysis<simple::Tagger> analysis;
// Run the simple analysis and create efficiency plots
}