Commit 2cdfdc85 authored by Scott Snyder's avatar Scott Snyder Committed by Graeme Stewart
Browse files

Migrate AlgTool -> AthAlgTool. (AnalysisUtils-00-02-36)

parent 006270f9
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
#ifndef ANALYSISUTILS_AANTTREEMAP_H
#define ANALYSISUTILS_AANTTREEMAP_H
#include <map>
#include <string>
#include "TTree.h"
class AANTTreeMap
{
public:
static void setTree (const std::string &stream, TTree *tree) { m_treeMap[stream] = tree;}
static TTree * getTree (const std::string &stream) { return m_treeMap[stream]; }
private:
/// tree map
static std::map<std::string,TTree*> m_treeMap;
};
#endif
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
#ifndef ANALYSISUTILS_ANALYSISCOMBINATION_H
#define ANALYSISUTILS_ANALYSISCOMBINATION_H
/**
utility class to select combination of elements in a collection
@author Tadashi Maeno
*/
#include <vector>
namespace AnalysisUtils {
/** combination
*/
template <class COLL> class Combination {
public:
/** constructor
@param coll [in] collection
@param nElement [in] number of element to be selected
*/
Combination(COLL *coll, const unsigned int nElement);
/** destructor
*/
~Combination() {}
/** reset internal indices
*/
void reset();
/** get a combination. internal indices are incremented
@param comb [out] combination of elements
@retrun true:success false:end of selection
*/
template <class OUT>
bool get(OUT &comb)
{
// init returned combination
comb.clear();
if (m_first) {
if (m_index[m_nElement-1] >= m_coll->size()) return false;
m_first = false;
} else {
// increment indices
if (!setNewIndex(m_nElement-1)) return false;
}
// assign to returned combination
for (unsigned int i=0; i<m_nElement; ++i)
comb.push_back((*m_coll)[m_index[i]]);
return true;
}
/** get a combination which passes a selection criteria
@param caller
@param comb [out] combination of elements
@param criteria [in] a function pointer of selection criteria
@retrun true:success false:end of selection
*/
template <class CALLER, class OUT, class CRITERIA>
bool goodOnes(CALLER *caller, OUT &comb, CRITERIA criteria)
{
bool ret = get(comb);
if (!ret) return false;
// check if this passes the criteria
if (criteria(caller, comb)) return true;
// if not, look for next combination
return goodOnes(caller, comb, criteria);
}
/** get a combination and the remaining elements
*/
template <class OUT>
bool get(OUT &comb, OUT &remain)
{
// init returned vector
remain.clear();
bool ret = get(comb);
if (!ret) return false;
// assigin to remain
unsigned int sIndex = 0;
std::vector<unsigned int>::const_iterator it = m_index.begin();
std::vector<unsigned int>::const_iterator itE = m_index.end();
for (; ; ++it)
{
unsigned int eIndex;
if (it!=itE)
eIndex = *it;
else
eIndex = m_coll->size();
for (unsigned int i=sIndex; i<eIndex; ++i)
remain.push_back((*m_coll)[i]);
sIndex = eIndex+1;
if (it == itE) break;
}
return true;
}
/** get a combination and the remaining elements.
the combination passes a selection criteria
*/
template <class CALLER, class OUT, class CRITERIA>
bool goodOnes(CALLER *caller, OUT &comb, OUT &remain, CRITERIA criteria)
{
bool ret = get(comb, remain);
if (!ret) return false;
// check if this passes the criteria
if (criteria(caller, comb)) return true;
// if not, look for next combination
return goodOnes(caller, comb, remain, criteria);
}
private:
//! collection
COLL *m_coll;
//! number of elements to be selected
const unsigned int m_nElement;
//! indices of elements
std::vector<unsigned int> m_index;
//! flag to check if first
bool m_first;
//! set new index recursively
bool setNewIndex (int iElement);
};
////////////////////////////////////////////////////
// implementation
template <class COLL> inline Combination<COLL>::Combination(COLL *coll, const unsigned int nElement)
: m_coll(coll), m_nElement(nElement), m_first(true)
{
// init indices
// internal indices are [0,1,2...] at beginning
for (unsigned int i=0; i<nElement; ++i)
m_index.push_back(i);
}
template <class COLL> inline void Combination<COLL>::reset()
{
// reset indices
m_index.clear();
for (unsigned int i=0; i<m_nElement; ++i)
m_index.push_back(i);
// set first flag
m_first = true;
}
// iElement runs over 0..(m_nElement-1)
template <class COLL> inline bool Combination<COLL>::setNewIndex (int iElement)
{
if (iElement < 0) return false;
if (iElement+1 == static_cast<int>(m_nElement))
{
if ((m_index[iElement]+1) < m_coll->size())
{
++(m_index[iElement]);
return true;
}
}
else
{
if ((m_index[iElement]+1) < m_index[iElement+1])
{
++(m_index[iElement]);
return true;
}
}
if (setNewIndex (iElement-1))
{
m_index[iElement] = m_index[iElement-1]+1;
return true;
}
return false;
}
} // end of AnalysisUtils
#endif // END OF ANALYSISTOOLS_ANALYSISCOMBINATION_H
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
#ifndef ANALYSISUTILS_ANALYSISLOOPER_H
#define ANALYSISUTILS_ANALYSISLOOPER_H
/**
generalized looper
@author Tadashi Maeno
*/
#include <vector>
namespace AnalysisUtils {
namespace Private {
// Null type for list terminator
class NullType {};
// Bool to Type mapper
template <bool v> struct Bool2Type
{
enum {value = v};
};
// forward declaration
template <class PAR1, class PAR2> struct ParamChain;
// get length of the parameter chain
template <class CHAIN> struct Length;
template <class H, class T> struct Length< ParamChain<H,T> >
{
enum {value = 1+Length<T>::value};
};
template <> struct Length<NullType>
{
enum {value = 0};
};
// get type at index in the parameter chain
template <class CHAIN, unsigned int i> struct TypeAt;
template <class H, class T, unsigned int i> struct TypeAt< ParamChain<H,T>, i >
{
typedef typename TypeAt<T,i-1>::type type;
};
template <class H, class T> struct TypeAt< ParamChain<H,T>, 0 >
{
typedef H type;
};
// parameter chain
template <class PAR1, class PAR2> struct ParamChain
{
typedef PAR1 Head;
typedef PAR2 Tail;
typedef ParamChain<PAR1,PAR2> MyType;
// constructor
ParamChain(PAR2 *p2) : m_p1(0), m_p2(p2) {}
// assign
void assign(PAR1 p1) {m_p1 = p1;}
// get parameter stored at the index in the chain
template <unsigned int i> typename TypeAt<MyType,Length<MyType>::value-1-i>::type par()
{
return parHelper<i>(Bool2Type<i==Length<MyType>::value-1>());
}
private:
PAR1 m_p1;
PAR2 *m_p2;
// helper to get parameter stored at the index in the chain
template <unsigned int i> typename TypeAt<MyType,Length<MyType>::value-1-i>::type parHelper(Bool2Type<true>)
{
typedef typename TypeAt<MyType,Length<MyType>::value-1-i>::type return_t;
if (i==Length<MyType>::value-1) return reinterpret_cast<return_t>(m_p1);
}
template <unsigned int i> typename TypeAt<MyType,Length<MyType>::value-1-i>::type parHelper(Bool2Type<false>)
{
typedef typename TypeAt<MyType,Length<MyType>::value-1-i>::type return_t;
return reinterpret_cast<return_t>(m_p2->par<i>());
}
};
// specialized for the chain end
template <class PAR1> struct ParamChain<PAR1, NullType>
{
typedef PAR1 Head;
typedef NullType Tail;
typedef ParamChain<PAR1,NullType> MyType;
ParamChain() : m_p1(0) {}
// assign
void assign(PAR1 p1) {m_p1 = p1;}
template <unsigned int i> PAR1 par() {return m_p1;}
private:
PAR1 m_p1;
};
// base class to run all Looper at the same time
class LooperBase
{
public:
LooperBase () {}
virtual ~LooperBase() {}
// this method must be implemented in derived classes
virtual void execute() = 0;
// this method may be called from Daughter Looper
void addDaughter (LooperBase *d) {m_daughter.push_back(d);}
// execute all daughters
void executeDaughter ()
{
std::vector <LooperBase *>::iterator it = m_daughter.begin();
std::vector <LooperBase *>::iterator itE = m_daughter.end();
for (; it!=itE; ++it)
(*it)->execute();
}
private:
std::vector <LooperBase *> m_daughter;
};
}; // end of Private
/** Analysis Looper class
@param COLL : collection
@param ACTION : action policy must have a method "void action(...)"
@param PLOOPER : parent looper
*/
template <class COLL, class ACTION, class PLOOPER>
struct Looper : public ACTION, public Private::LooperBase
{
typedef Private::ParamChain<typename COLL::value_type, typename PLOOPER::chain_type >
chain_type;
// parameter chain
chain_type *m_chain;
// collection
COLL *m_coll;
// constructor
Looper (COLL *coll, PLOOPER *parent) : m_coll(coll) {
parent->addDaughter(this);
m_chain = new chain_type (parent->m_chain);
}
// destructor
~Looper() {delete m_chain;}
void execute ()
{
typename COLL::const_iterator it = m_coll->begin();
typename COLL::const_iterator itE = m_coll->end();
for (; it!=itE; ++it)
{
m_chain->assign(*it);
ACTION::action(m_chain);
executeDaughter ();
}
}
};
// specialized for Top Looper with Action
template <class COLL, class ACTION>
struct Looper<COLL, ACTION, Private::NullType>
: public ACTION, public Private::LooperBase
{
typedef Private::ParamChain<typename COLL::value_type, Private::NullType> chain_type;
chain_type *m_chain;
COLL *m_coll;
Looper (COLL *coll) : m_coll(coll) {
m_chain = new chain_type;
}
~Looper() {delete m_chain;}
void execute ()
{
typename COLL::const_iterator it = m_coll->begin();
typename COLL::const_iterator itE = m_coll->end();
for (; it!=itE; ++it)
{
m_chain->assign(*it);
ACTION::action(m_chain);
executeDaughter ();
}
}
};
// specialized for Top Looper without Action
template <class COLL>
struct Looper<COLL, Private::NullType, Private::NullType>
: public Private::NullType, public Private::LooperBase
{
typedef Private::ParamChain<typename COLL::value_type, Private::NullType> chain_type;
chain_type *m_chain;
COLL *m_coll;
Looper (COLL *coll) : m_coll(coll) {
m_chain = new chain_type;
}
~Looper() {delete m_chain;}
// execute only daughters
void execute ()
{
typename COLL::const_iterator it = m_coll->begin();
typename COLL::const_iterator itE = m_coll->end();
for (; it!=itE; ++it)
{
m_chain->assign(*it);
executeDaughter ();
}
}
};
} // end of AnalysisUtils namespace
#define PARLIST_1(P1) AnalysisUtils::Private::ParamChain<P1,AnalysisUtils::Private::NullType>
#define PARLIST_2(P1,P2) AnalysisUtils::Private::ParamChain<P2, PARLIST_1(P1) >
#define PARLIST_3(P1,P2,P3) AnalysisUtils::Private::ParamChain<P3, PARLIST_2(P1,P2) >
#define PARLIST_4(P1,P2,P3,P4) AnalysisUtils::Private::ParamChain<P4, PARLIST_3(P1,P2,P3) >
#define DEF_TopLooper(COLL,ACT) typedef AnalysisUtils::Looper<COLL,ACT,AnalysisUtils::Private::NullType>
#define DEF_TopLooperWoAct(COLL) typedef AnalysisUtils::Looper<COLL,AnalysisUtils::Private::NullType,AnalysisUtils::Private::NullType>
#define DEF_Looper(COLL,ACT,PAR) typedef AnalysisUtils::Looper<COLL,ACT,PAR>
#define DEF_LooperWoAct(COLL,PAR) typedef AnalysisUtils::Looper<COLL,AnalysisUtils::Private::NullType,PAR>
#endif // end of ANALYSISTOOLS_ANALYSISLOOPER_H
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
#ifndef ANALYSISUTILS_ANALYSISMISC_H
#define ANALYSISUTILS_ANALYSISMISC_H
/**
Tools collection
@author Tadashi Maeno
*/
#include <math.h>
#include <vector>
#include <algorithm>
#include "EventKernel/INavigable4Momentum.h"
#include "McParticleEvent/TruthParticleContainer.h"
#include "CxxUtils/fpcompare.h"
#include "CLHEP/Vector/LorentzVector.h"
#include "DataModel/DataVector.h"
#include "boost/type_traits/remove_pointer.hpp"
#include "boost/type_traits/is_convertible.hpp"
namespace AnalysisUtils {
/** compute \Delta
*/
namespace Delta {
/** \Delta\phi
*/
inline double phi (const INavigable4Momentum *p1, const INavigable4Momentum *p2) {
double phi1 = (p1->phi()>M_PI) ? p1->phi()-2*M_PI : p1->phi();
double phi2 = (p2->phi()>M_PI) ? p2->phi()-2*M_PI : p2->phi();
double dphi = fabs(phi1-phi2);
if(dphi>M_PI) dphi = 2*M_PI-dphi;
return dphi;
}
/** \Delta{R}
*/
inline double R (const INavigable4Momentum *p1, const double v_eta, const double v_phi) {
double phi1 = (p1->phi()>M_PI) ? p1->phi()-2*M_PI : p1->phi();
double phi2 = (v_phi>M_PI) ? v_phi-2*M_PI : v_phi;
double dphi = fabs(phi1-phi2);
if(dphi>M_PI) dphi = 2*M_PI-dphi;
double deta = p1->eta() - v_eta;
return sqrt(dphi*dphi+deta*deta);
}
/** \Delta{R}
*/
inline double R (const INavigable4Momentum *p1, const INavigable4Momentum *p2) {
return R (p1, p2->eta(), p2->phi());
}
} // end of Delta namespace
///////////////////////////////////////////////////////////////////////////
/** compute Invariant mass
*/
namespace Imass {
inline double two (const INavigable4Momentum *p1, const INavigable4Momentum *p2) {
return (p1->hlv()+p2->hlv()).m();
}
inline double four (const INavigable4Momentum *p1, const INavigable4Momentum *p2,
const INavigable4Momentum *p3, const INavigable4Momentum *p4) {
return (p1->hlv()+p2->hlv()+p3->hlv()+p4->hlv()).m();
}
} // end of Imass namespace
///////////////////////////////////////////////////////////////////////////
/** find the closest element in a collection to an INavigable4Momentum
*/
namespace Match {
/** find the closest element in R
@param index [out] index of the closest element
@param deltaR [out] \Delta{R}
@return true if found
*/
template <class COLL>
inline bool R (const double eta, const double phi, COLL *coll, int &index, double &deltaR, const int pdg)
{
deltaR = 10000.; // big value
bool l_return = false;
int l_idx = 0;
typename COLL::const_iterator it = coll->begin();
typename COLL::const_iterator itE = coll->end();
for (; it != itE; ++it)