Program Listing for File ParticleContainer.h¶
↰ Return to documentation for file (xAODAnaHelpers/ParticleContainer.h
)
#ifndef xAODAnaHelpers_ParticleContainer_H
#define xAODAnaHelpers_ParticleContainer_H
#include <TTree.h>
#include <TLorentzVector.h>
#include <vector>
#include <string>
#include <xAODAnaHelpers/HelperClasses.h>
#include <xAODAnaHelpers/HelperFunctions.h>
#include <xAODAnaHelpers/Particle.h>
#include <xAODBase/IParticle.h>
namespace xAH
{
template <class T_PARTICLE, class T_INFOSWITCH>
class ParticleContainer
{
public:
ParticleContainer(const std::string& name,
const std::string& detailStr="",
float units = 1e3,
bool mc = false,
bool useMass=false,
bool storeSystSFs = true,
const std::string& suffix="")
: m_name(name),
m_infoSwitch(detailStr),
m_mc(mc),
m_debug(false),
m_units(units),
m_storeSystSFs(storeSystSFs),
m_useMass(useMass),
m_suffix(suffix)
{
m_n = 0;
// kinematic
m_pt =new std::vector<float>();
m_eta =new std::vector<float>();
m_phi =new std::vector<float>();
m_E =new std::vector<float>();
m_M =new std::vector<float>();
}
virtual ~ParticleContainer()
{
// kinematic
if(m_infoSwitch.m_kinematic){
delete m_pt;
delete m_eta;
delete m_phi;
delete m_E;
delete m_M;
}
}
virtual void setTree(TTree *tree)
{
std::string counterName = "n"+m_name;
if (!m_suffix.empty()) counterName += "_" + m_suffix;
if (m_infoSwitch.m_useTheS) { counterName += "s";
std::cerr << "WARNING! The useTheS option is depricated in ParticleContainer." << std::endl;
}
tree->SetBranchStatus (counterName.c_str() , 1);
if(!m_infoSwitch.m_noMultiplicity) tree->SetBranchAddress (counterName.c_str() , &m_n);
if(m_infoSwitch.m_kinematic)
{
// Determine whether mass or energy is saved
std::string mname = branchName("m");
m_useMass=tree->GetBranch(mname.c_str())!=0;
connectBranch<float>(tree,"pt" ,&m_pt);
connectBranch<float>(tree,"eta",&m_eta);
connectBranch<float>(tree,"phi",&m_phi);
if(m_useMass) connectBranch<float>(tree,"m" ,&m_M);
else connectBranch<float>(tree,"E" ,&m_E);
}
}
virtual void setBranches(TTree *tree)
{
std::string counterName = "n"+m_name;
if (!m_suffix.empty()) { counterName += "_" + m_suffix; }
if(!m_infoSwitch.m_noMultiplicity) tree->Branch(counterName.c_str(), &m_n, (counterName+"/I").c_str());
if(m_infoSwitch.m_kinematic) {
if(m_useMass) setBranch<float>(tree,"m", m_M );
else setBranch<float>(tree,"E", m_E );
setBranch<float>(tree,"pt", m_pt );
setBranch<float>(tree,"phi", m_phi );
setBranch<float>(tree,"eta", m_eta );
}
}
virtual void clear()
{
m_n = 0;
if(m_infoSwitch.m_kinematic) {
if(m_useMass) m_M->clear();
else m_E->clear();
m_pt ->clear();
m_phi ->clear();
m_eta ->clear();
}
}
virtual void FillParticle(const xAOD::IParticle* particle)
{
m_n++;
if( m_infoSwitch.m_kinematic ){
m_pt -> push_back( particle->pt() / m_units );
m_eta -> push_back( particle->eta() );
m_phi -> push_back( particle->phi() );
if(m_useMass) m_M->push_back ( particle->m() / m_units );
else m_E->push_back ( particle->e() / m_units );
}
}
void updateEntry()
{
m_particles.resize(m_n);
for(int i=0;i<m_n;i++)
updateParticle(i,m_particles[i]);
}
std::vector<T_PARTICLE>& particles()
{ return m_particles; }
T_PARTICLE& at_nonConst(uint idx)
{ return m_particles[idx]; }
const T_PARTICLE& at(uint idx) const
{ return m_particles[idx]; }
const T_PARTICLE& operator[](uint idx) const
{ return m_particles[idx]; }
uint size() const
{ return m_particles.size(); }
protected:
std::string branchName(const std::string& varName)
{
std::string name = m_name + "_" + varName;
if (! m_suffix.empty()) { name += "_" + m_suffix; }
return name;
}
template <typename T_BR> void connectBranch(TTree *tree, const std::string& branch, std::vector<T_BR> **variable)
{
std::string name = branchName(branch);
if(*variable) { delete (*variable); (*variable)=0; }
if(tree->GetBranch(name.c_str()))
{
(*variable)=new std::vector<T_BR>();
tree->SetBranchStatus (name.c_str() , 1);
tree->SetBranchAddress (name.c_str() , variable);
}
}
template<typename T> void setBranch(TTree* tree, std::string varName, std::vector<T>* localVectorPtr){
std::string name = branchName(varName);
tree->Branch(name.c_str(), localVectorPtr);
}
template<typename T, typename U, typename V> void safeFill(const V* xAODObj, SG::AuxElement::ConstAccessor<T>& accessor, std::vector<U>* destination, U defaultValue, int units = 1){
if ( accessor.isAvailable( *xAODObj ) ) {
destination->push_back( accessor( *xAODObj ) / units );
} else {
destination->push_back( defaultValue );
}
}
template<typename T, typename U, typename V> void safeVecFill(const V* xAODObj, SG::AuxElement::ConstAccessor<std::vector<T> >& accessor, std::vector<std::vector<U> >* destination, int units = 1){
destination->push_back( std::vector<U>() );
if ( accessor.isAvailable( *xAODObj ) ) {
for(U itemInVec : accessor(*xAODObj)) destination->back().push_back(itemInVec / units);
}
return;
}
template<typename T, typename V> void safeSFVecFill(const V* xAODObj, SG::AuxElement::ConstAccessor<std::vector<T> >& accessor, std::vector<std::vector<T> >* destination, const std::vector<T> &defaultValue) {
if ( accessor.isAvailable( *xAODObj ) ) {
if ( m_storeSystSFs ) {
destination->push_back( accessor(*xAODObj) );
} else {
destination->push_back( std::vector< float > ({accessor(*xAODObj)[0]}) );
//std::cout << "NUMBER: " << std::vector< float > ({accessor(*xAODObj)[0]}) << std::endl;
}
} else {
destination->push_back( defaultValue );
}
}
virtual void updateParticle(uint idx, T_PARTICLE& particle)
{
if(m_infoSwitch.m_kinematic)
{
if(m_useMass){
particle.p4.SetPtEtaPhiM(m_pt ->at(idx),
m_eta->at(idx),
m_phi->at(idx),
m_M ->at(idx));
} else{
particle.p4.SetPtEtaPhiE(m_pt ->at(idx),
m_eta->at(idx),
m_phi->at(idx),
m_E ->at(idx));
}
}
}
std::string m_name;
std::vector<T_PARTICLE> m_particles;
public:
T_INFOSWITCH m_infoSwitch;
bool m_mc;
bool m_debug;
float m_units;
bool m_storeSystSFs;
int m_n;
private:
bool m_useMass;
std::string m_suffix;
//
// Vector branches
// kinematic
std::vector<float> *m_pt;
std::vector<float> *m_eta;
std::vector<float> *m_phi;
std::vector<float> *m_E;
std::vector<float> *m_M;
};
}//xAH
#endif // xAODAnaHelpers_ParticleContainer_H