.. _program_listing_file_xAODAnaHelpers_HelperFunctions.h: Program Listing for File HelperFunctions.h ========================================== |exhale_lsh| :ref:`Return to documentation for file ` (``xAODAnaHelpers/HelperFunctions.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #ifndef xAODAnaHelpers_HELPERFUNCTIONS_H #define xAODAnaHelpers_HELPERFUNCTIONS_H // for typing in template #include #include // Gaudi/Athena include(s): #include "AthContainers/normalizedTypeinfoName.h" // local includes #include "AsgMessaging/StatusCode.h" #include #include // jet reclustering and trimming #include #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 // 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 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 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 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() 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 void echoType(){ std::cout << "This is type " << HelperFunctions::type_name() << std::endl; } */ template 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()+","+type_name()+">(): "}; 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 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(intCont, outCont, msg(), flagSelect, tool_name); } template StatusCode retrieve(T*& cont, std::string name, xAOD::TEvent* event, xAOD::TStore* store, MsgStream& msg){ std::string funcName{"in retrieve<"+type_name()+">(" + 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() << 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(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(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 StatusCode retrieve(T*& cont, std::string name, xAOD::TEvent* event, xAOD::TStore* store) { return retrieve(cont, name, event, store, msg()); } template StatusCode __attribute__((deprecated("retrieve(..., 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(cont, name, event, store, msg()); } template 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()+">(" + name + "): "}; msg << MSG::DEBUG << funcName << "\tAttempting to retrieve " << name << " of type " << type_name() << 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(name))){ msg << MSG::DEBUG << funcName << "\t\t\tFound inside xAOD::TStore" << endmsg;; return true; } else if((event != NULL) && (event->contains(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 bool isAvailable(std::string name, xAOD::TEvent* event, xAOD::TStore* store) { return isAvailable(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 const T* getLink(const xAOD::IParticle* particle, std::string name){ if (!particle) return 0; typedef ElementLink< DataVector > Link_t; if (!particle->isAvailable< Link_t >(name) ) { return 0; } const Link_t link = particle->auxdata(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 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 const T sort_container_pt(const T* inCont){ ConstDataVector 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* sys_list) { if ( sys_list ) { for ( auto sys : *sys_list ) { if ( !sys.empty() ) { return true; } } } return false; } template 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 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 void connectBranch(std::string name, TTree *tree, const std::string& branch, std::vector **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 void remove_duplicates(std::vector& 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