Program Listing for File HelperFunctions.h¶
↰ Return to documentation for file (xAODAnaHelpers/HelperFunctions.h
)
#ifndef xAODAnaHelpers_HELPERFUNCTIONS_H
#define xAODAnaHelpers_HELPERFUNCTIONS_H
// for typing in template
#include <typeinfo>
#include <cxxabi.h>
// Gaudi/Athena include(s):
#include "AthContainers/normalizedTypeinfoName.h"
// local includes
#include "AsgMessaging/StatusCode.h"
#include <AsgMessaging/MessageCheck.h>
#include <SampleHandler/SampleHandler.h>
// jet reclustering and trimming
#include <fastjet/JetDefinition.hh>
#include "xAODJet/JetContainer.h"
#include "xAODTracking/VertexContainer.h"
#include "AthContainers/ConstDataVector.h"
#include "xAODAnaHelpers/HelperClasses.h"
// CP interface includes
#include "PATInterfaces/SystematicRegistry.h"
#include "PATInterfaces/SystematicSet.h"
#include "PATInterfaces/SystematicsUtil.h"
#include "PATInterfaces/SystematicVariation.h"
#include "PATInterfaces/ISystematicsTool.h"
// ROOT includes
#include "TTree.h"
#include "TBranch.h"
#include "TFile.h"
#include "TH1D.h"
#include "TObjArray.h"
// messaging includes
#include <AsgMessaging/MsgStream.h>
// Functions that need to have a dictionary built. PyROOT does not
// seem to like the HelperFunctions namespace for some reason.
namespace xAH {
void addRucio(SH::SampleHandler& sh, const std::string& name, const std::string& dslist);
} // close namespace xAH
namespace HelperFunctions {
MsgStream& msg( MSG::Level lvl = MSG::INFO );
// primary vertex
bool passPrimaryVertexSelection(const xAOD::VertexContainer* vertexContainer, int Ntracks = 2);
int countPrimaryVertices(const xAOD::VertexContainer* vertexContainer, int Ntracks = 2);
const xAOD::Vertex* getPrimaryVertex(const xAOD::VertexContainer* vertexContainer, MsgStream& msg);
inline const xAOD::Vertex* getPrimaryVertex(const xAOD::VertexContainer* vertexContainer) { return getPrimaryVertex(vertexContainer, msg()); }
float getPrimaryVertexZ(const xAOD::Vertex* pvx);
int getPrimaryVertexLocation(const xAOD::VertexContainer* vertexContainer, MsgStream& msg);
inline int getPrimaryVertexLocation(const xAOD::VertexContainer* vertexContainer){ return getPrimaryVertexLocation(vertexContainer, msg()); }
bool applyPrimaryVertexSelection( const xAOD::JetContainer* jets, const xAOD::VertexContainer* vertices );
std::string replaceString(std::string subjet, const std::string& search, const std::string& replace);
std::vector<TString> SplitString(TString& orig, const char separator);
float dPhi(float phi1, float phi2);
bool has_exact(const std::string input, const std::string flag);
std::size_t string_pos( const std::string& haystack, const std::string& needle, unsigned int N );
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*\
| |
| Author : Marco Milesi |
| Email : marco.milesi@cern.ch |
| Logic copied from:
PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/trunk/Root/Tools.cxx |
Function to check if file is Full xAOD
\*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
StatusCode isAvailableMetaData(TTree* metaData);
bool isFilePrimaryxAOD(TFile* inputFile);
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*\
| |
| Author : Giordon Stark |
| Email : gstark@cern.ch |
| Thanks to Ben Nachman for inspiration |
| |
| jetReclustering(): |
| Takes a set of small-R jets and reclusters to large-R jets |
| |
| @jets |
| jet container to recluster and trim |
| @radius [1.0] |
| radius of large-R jet |
| @fcut [0.05] |
| trimming cut to apply |
| @rc_alg [fastjet::kt_algorithm] |
| clustering algorithm |
| |
| |
| jetTrimming(): |
| Takes a jet or a set of jets and applies an fcut on subjets |
| and reclusters into a TLorentzVector |
| |
| @jet(s) |
| jet (container to loop over and) to apply trimming |
| @radius [0.3] |
| radius of subjets to form |
| @fcut [0.05] |
| trimming cut to apply on subjets |
| @s_alg [fastjet::kt_algorithm] |
| algorithm for building subjets |
| |
\*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
std::vector<TLorentzVector> jetReclustering(
const xAOD::JetContainer* jets,
double radius = 1.0,
double fcut = 0.05,
fastjet::JetAlgorithm rc_alg = fastjet::antikt_algorithm);
/* http://www.lpthe.jussieu.fr/~salam/fastjet/repo/doxygen-3.0alpha2/classfastjet_1_1Filter.html#usage */
std::vector<TLorentzVector> jetTrimming(
const xAOD::JetContainer* jets,
double radius = 0.3,
double fcut = 0.05,
fastjet::JetAlgorithm s_alg = fastjet::kt_algorithm);
TLorentzVector jetTrimming(
const xAOD::Jet* jet,
double radius = 0.3,
double fcut = 0.05,
fastjet::JetAlgorithm s_alg = fastjet::kt_algorithm);
// miscellaneous
bool sort_pt(const xAOD::IParticle* partA, const xAOD::IParticle* partB);
std::vector< CP::SystematicSet > getListofSystematics( const CP::SystematicSet inSysts, std::string systNames, float systVal, MsgStream& msg );
void writeSystematicsListHist( const std::vector< CP::SystematicSet > &systs, std::string histName, TFile *file );
/* type_name<T>() The awesome type demangler!
- normally, typeid(T).name() is gibberish with gcc. This decodes it. Fucking magic man.
@ useXAOD [true] If set to false, will use the standard demangling
tool. Otherwise, use built-in StoreGate tool
Example Usage:
template <typename T>
void echoType(){
std::cout << "This is type " << HelperFunctions::type_name<T>() << std::endl;
}
*/
template <typename T>
std::string type_name(bool useXAOD=true) {
if(useXAOD) return SG::normalizedTypeinfoName( typeid(T) );
int status;
std::string tname = typeid(T).name();
char *demangled_name = abi::__cxa_demangle(tname.c_str(), NULL, NULL, &status);
if(status == 0) {
tname = demangled_name;
std::free(demangled_name);
}
return tname;
}
template< typename T1, typename T2 >
StatusCode makeSubsetCont( T1*& intCont, T2*& outCont, MsgStream& msg, const std::string& flagSelect = "", HelperClasses::ToolName tool_name = HelperClasses::ToolName::DEFAULT){
std::string funcName{"in makeSubsetCont<"+type_name<T1>()+","+type_name<T2>()+">(): "};
if ( tool_name == HelperClasses::ToolName::DEFAULT ) {
for ( auto in_itr : *(intCont) ) { outCont->push_back( in_itr ); }
return StatusCode::SUCCESS;
}
if ( flagSelect.empty() ) {
msg << MSG::ERROR << funcName << "flagSelect is an empty string, and passing a non-DEFAULT tool (presumably a SELECTOR). Please pass a non-empty flagSelect!" << endmsg;
return StatusCode::FAILURE;
}
SG::AuxElement::ConstAccessor<char> myAccessor(flagSelect);
for ( auto in_itr : *(intCont) ) {
if ( !myAccessor.isAvailable(*(in_itr)) ) {
std::stringstream ss; ss << in_itr->type();
msg << MSG::ERROR << funcName << "flag " << flagSelect << " is missing for object of type " << ss.str() << " ! Will not make a subset of its container" << endmsg;
return StatusCode::FAILURE;
}
if ( myAccessor(*(in_itr)) ) { outCont->push_back( in_itr ); }
}
return StatusCode::SUCCESS;
}
template< typename T1, typename T2 >
StatusCode makeSubsetCont( T1*& intCont, T2*& outCont, const std::string& flagSelect = "", HelperClasses::ToolName tool_name = HelperClasses::ToolName::DEFAULT) { return makeSubsetCont<T1, T2>(intCont, outCont, msg(), flagSelect, tool_name); }
template <typename T>
StatusCode retrieve(T*& cont, std::string name, xAOD::TEvent* event, xAOD::TStore* store, MsgStream& msg){
std::string funcName{"in retrieve<"+type_name<T>()+">(" + name + "): "};
if((event == NULL) && (store == NULL)){
msg << MSG::ERROR << funcName << "Both TEvent and TStore objects are null. Cannot retrieve anything." << endmsg;
return StatusCode::FAILURE;
}
msg << MSG::DEBUG << funcName << "\tAttempting to retrieve " << name << " of type " << type_name<T>() << endmsg;
if((event != NULL) && (store == NULL)) msg << MSG::DEBUG << funcName << "\t\tLooking inside: xAOD::TEvent" << endmsg;
if((event == NULL) && (store != NULL)) msg << MSG::DEBUG << funcName << "\t\tLooking inside: xAOD::TStore" << endmsg;
if((event != NULL) && (store != NULL)) msg << MSG::DEBUG << funcName << "\t\tLooking inside: xAOD::TStore, xAOD::TEvent" << endmsg;
if((store != NULL) && (store->contains<T>(name))){
msg << MSG::DEBUG << funcName << "\t\t\tFound inside xAOD::TStore" << endmsg;
if(!store->retrieve( cont, name ).isSuccess()) return StatusCode::FAILURE;
msg << MSG::DEBUG << funcName << "\t\t\tRetrieved from xAOD::TStore" << endmsg;
} else if((event != NULL) && (event->contains<T>(name))){
msg << MSG::DEBUG << funcName << "\t\t\tFound inside xAOD::TEvent" << endmsg;
if(!event->retrieve( cont, name ).isSuccess()) return StatusCode::FAILURE;
msg << MSG::DEBUG << funcName << "\t\t\tRetrieved from xAOD::TEvent" << endmsg;
} else {
msg << MSG::DEBUG << funcName << "\t\tNot found at all" << endmsg;
return StatusCode::FAILURE;
}
return StatusCode::SUCCESS;
}
/* retrieve() overload for no msgStream object passed in */
template <typename T>
StatusCode retrieve(T*& cont, std::string name, xAOD::TEvent* event, xAOD::TStore* store) { return retrieve<T>(cont, name, event, store, msg()); }
template <typename T>
StatusCode __attribute__((deprecated("retrieve<T>(..., bool) is deprecated. See https://github.com/UCATLAS/xAODAnaHelpers/pull/882"))) retrieve(T*& cont, std::string name, xAOD::TEvent* event, xAOD::TStore* store, bool debug) { return retrieve<T>(cont, name, event, store, msg()); }
template <typename T>
bool isAvailable(std::string name, xAOD::TEvent* event, xAOD::TStore* store, MsgStream& msg){
/* Checking Order:
- check if store contains 'xAOD::JetContainer' named 'name'
--- checkstore store
- check if event contains 'xAOD::JetContainer' named 'name'
--- checkstore event
*/
std::string funcName{"in isAvailable<"+type_name<T>()+">(" + name + "): "};
msg << MSG::DEBUG << funcName << "\tAttempting to retrieve " << name << " of type " << type_name<T>() << endmsg;
if(store == NULL) msg << MSG::DEBUG << funcName << "\t\tLooking inside: xAOD::TEvent" << endmsg;
if(event == NULL) msg << MSG::DEBUG << funcName << "\t\tLooking inside: xAOD::TStore" << endmsg;
if((event != NULL) && (store != NULL)) msg << MSG::DEBUG << funcName << "\t\tLooking inside: xAOD::TStore, xAOD::TEvent" << endmsg;
if((store != NULL) && (store->contains<T>(name))){
msg << MSG::DEBUG << funcName << "\t\t\tFound inside xAOD::TStore" << endmsg;;
return true;
} else if((event != NULL) && (event->contains<T>(name))){
msg << MSG::DEBUG << funcName << "\t\t\tFound inside xAOD::TEvent" << endmsg;
return true;
} else {
msg << MSG::DEBUG << funcName << "\t\tNot found at all" << endmsg;
return false;
}
return false;
}
/* isAvailable() overload for no msgStream object passed in */
template <typename T>
bool isAvailable(std::string name, xAOD::TEvent* event, xAOD::TStore* store) { return isAvailable<T>(name, event, store, msg()); }
// stolen from here
// https://svnweb.cern.ch/trac/atlasoff/browser/Event/xAOD/xAODEgamma/trunk/xAODEgamma/EgammaTruthxAODHelpers.h#L20
// util becomes a general xAOD tool
template<class T>
const T* getLink(const xAOD::IParticle* particle, std::string name){
if (!particle) return 0;
typedef ElementLink< DataVector<T> > Link_t;
if (!particle->isAvailable< Link_t >(name) ) {
return 0;
}
const Link_t link = particle->auxdata<Link_t>(name);
if (!link.isValid()) {
return 0;
}
return *link;
}
//
// For Sorting
//
struct pt_sort
{
inline bool operator() (const TLorentzVector& lhs, const TLorentzVector& rhs)
{
return (lhs.Pt() > rhs.Pt());
}
inline bool operator() (const TLorentzVector* lhs, const TLorentzVector* rhs)
{
return (lhs->Pt() > rhs->Pt());
}
inline bool operator() (const xAOD::IParticle& lhs, const xAOD::IParticle& rhs)
{
return (lhs.pt() > rhs.pt());
}
inline bool operator() (const xAOD::IParticle* lhs, const xAOD::IParticle* rhs)
{
return (lhs->pt() > rhs->pt());
}
};
template<typename T>
T sort_container_pt(T* inCont){
T sortedCont(SG::VIEW_ELEMENTS);
for(auto el : *inCont) sortedCont.push_back( el );
std::sort(sortedCont.begin(), sortedCont.end(), pt_sort());
return sortedCont;
}
template<typename T>
const T sort_container_pt(const T* inCont){
ConstDataVector<T> sortedCont(SG::VIEW_ELEMENTS);
for(auto el : *inCont) sortedCont.push_back( el );
std::sort(sortedCont.begin(), sortedCont.end(), pt_sort());
return *sortedCont.asDataVector();
}
/* return true if there's a least one non-empty string (i.e., syst name) in input list */
inline bool found_non_dummy_sys(std::vector<std::string>* sys_list) {
if ( sys_list ) {
for ( auto sys : *sys_list ) {
if ( !sys.empty() ) { return true; }
}
}
return false;
}
template <typename T1, typename T2, typename T3>
StatusCode makeDeepCopy(xAOD::TStore* m_store, std::string containerName, const T1* cont){
T1* cont_new = new T1;
T2* auxcont_new = new T2;
cont_new->setStore(auxcont_new);
if(!m_store->record(cont_new, containerName).isSuccess()){
std::cout << "can't record " << containerName << std::endl;
return StatusCode::FAILURE;
}
if(!m_store->record(auxcont_new, containerName+"Aux.").isSuccess()){
std::cout << "can't record aux" << containerName << std::endl;
return StatusCode::FAILURE;
}
for(const auto p: *cont){
T3* p_new = new T3;
cont_new->push_back(p_new);
*p_new = *p;
}
return StatusCode::SUCCESS;
}
template <typename T1, typename T2>
StatusCode recordOutput(xAOD::TEvent* m_event, xAOD::TStore* m_store, std::string containerName){
T1* cont(nullptr);
T2* auxcont(nullptr);
if(!m_store->retrieve(cont, containerName).isSuccess()) return StatusCode::FAILURE;
if(!m_store->retrieve(auxcont, containerName+"Aux.").isSuccess()) return StatusCode::FAILURE;
if(!m_event->record(cont, containerName).isSuccess()) return StatusCode::FAILURE;
if(!m_event->record(auxcont, containerName+"Aux.").isSuccess()) return StatusCode::FAILURE;
return StatusCode::SUCCESS;
}
template <typename T_BR> void connectBranch(std::string name, TTree *tree, const std::string& branch, std::vector<T_BR> **variable)
{
tree->SetBranchStatus ((name+"_"+branch).c_str() , 1);
tree->SetBranchAddress ((name+"_"+branch).c_str() , variable);
}
// function to remove duplicates from a vector. Thank you, oh internet!
// http://stackoverflow.com/questions/9237216/removing-duplicates-in-a-vector-of-strings
template <typename T>
void remove_duplicates(std::vector<T>& vec)
{
std::sort(vec.begin(), vec.end());
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
}
enum ShowerType {Unknown, Pythia8, Herwig7p1, Herwig7p2, Sherpa221, Sherpa2210, Sherpa2212, AmcPy8, AmcH7, Pythia8_517, Sherpa2214, Sherpa_Unknown};
ShowerType getMCShowerType(const std::string& sample_name, const std::string& m_taggerName);
} // close namespace HelperFunctions
# endif