diff --git a/Reconstruction/Jet/JetRec/CMakeLists.txt b/Reconstruction/Jet/JetRec/CMakeLists.txt index aff27b01f08c92d2fa64308d2d0e8b7a5cb7b698..cb6a36c663ac74f18a216297ebdc9a0d627d2fda 100644 --- a/Reconstruction/Jet/JetRec/CMakeLists.txt +++ b/Reconstruction/Jet/JetRec/CMakeLists.txt @@ -16,6 +16,7 @@ endif() atlas_depends_on_subdirs( PUBLIC Control/AthLinks + Control/AthContainers Control/AthToolSupport/AsgTools Event/xAOD/xAODCaloEvent Event/xAOD/xAODJet @@ -44,7 +45,7 @@ atlas_add_library( JetRecLib PUBLIC_HEADERS JetRec INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${FASTJET_INCLUDE_DIRS} PRIVATE_INCLUDE_DIRS ${FASTJETCONTRIB_INCLUDE_DIRS} - LINK_LIBRARIES ${ROOT_LIBRARIES} ${FASTJET_LIBRARIES} AthLinks AsgTools + LINK_LIBRARIES ${ROOT_LIBRARIES} ${FASTJET_LIBRARIES} AthLinks AthContainers AsgTools xAODCaloEvent xAODJet xAODMuon EventShapeInterface JetEDM JetInterface PRIVATE_LINK_LIBRARIES ${FASTJETCONTRIB_LIBRARIES} CxxUtils xAODBase xAODCore diff --git a/Reconstruction/Jet/JetRec/Root/JetRecTool.cxx b/Reconstruction/Jet/JetRec/Root/JetRecTool.cxx index 91d0d6f03b9abab91e630e06c890c364495bda1f..71f76f3034dac0e642553266c1692f7f00072028 100644 --- a/Reconstruction/Jet/JetRec/Root/JetRecTool.cxx +++ b/Reconstruction/Jet/JetRec/Root/JetRecTool.cxx @@ -186,10 +186,6 @@ StatusCode JetRecTool::initialize() { ATH_MSG_INFO(prefix << "Extracting input type from primary label."); ATH_MSG_INFO(prefix << "Input label: " << label); m_inputtype = xAOD::JetInput::inputType(label); - if ( m_inputtype == xAOD::JetInput::Uncategorized ) { - ATH_MSG_ERROR("Invalid label for first pseudojet getter: " << label); - rstat = StatusCode::FAILURE; - } } else { m_ghostlabs.push_back(label); } diff --git a/Reconstruction/Jet/JetRec/src/JetViewAlg.cxx b/Reconstruction/Jet/JetRec/src/JetViewAlg.cxx new file mode 100644 index 0000000000000000000000000000000000000000..067e5f15d60a42bd5775703bdca4baa42e296b5c --- /dev/null +++ b/Reconstruction/Jet/JetRec/src/JetViewAlg.cxx @@ -0,0 +1,75 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +// JetViewAlg.cxx + +#include <memory> +#include "JetViewAlg.h" + +//********************************************************************** + +// Called before event loop +StatusCode JetViewAlg::initialize() { + + // Initialise DataHandleKeys so that the scheduler is aware of + // data dependencies & products + if(m_input.key().empty() || m_output.key().empty()) { + ATH_MSG_ERROR("Input/output key(s) is/are blank!"); + return StatusCode::FAILURE; + } + + ATH_CHECK(m_input.initialize()); + ATH_CHECK(m_output.initialize()); + + ATH_MSG_DEBUG("Will select jets from " << m_input.key() + << " and write them to " << m_output.key()); + ATH_MSG_DEBUG("Selection criteria are: \n" + << " pT > " << m_ptmin << " MeV" + << " |eta| < " << m_absetamax + ); + + return StatusCode::SUCCESS; +} + +//********************************************************************** + +bool JetViewAlg::selected(const xAOD::Jet& jet) const { + + if(jet.pt() < m_ptmin) {return false;} + if(std::abs(jet.eta()) > m_absetamax) {return false;} + + return true; +} + +//********************************************************************** + +StatusCode JetViewAlg::execute(const EventContext& ctx) const { + + SG::ReadHandle<xAOD::JetContainer> inputHandle(m_input,ctx); + + // Need to place jets into a CDV because we can't put const objects in a DataVector + auto selected_jets = std::make_unique<ConstDataVector<xAOD::JetContainer> >( SG::VIEW_ELEMENTS ); + for(const xAOD::Jet* jet : *inputHandle) { + ATH_MSG_VERBOSE("Jet " << jet->index() << std::setprecision(3) + << " with pt " << jet->pt() + << " eta " << jet->eta() + ); + if( selected(*jet) ) { + selected_jets->push_back(jet); + ATH_MSG_VERBOSE(" Passed selection"); + } else { + ATH_MSG_VERBOSE(" Failed selection"); + } + } + ATH_MSG_DEBUG("Selected " << selected_jets->size() << " from input container of size " << inputHandle->size() ); + + // Write out JetContainer and JetAuxContainer + SG::WriteHandle<ConstDataVector<xAOD::JetContainer> > jetContHandle(m_output,ctx); + ATH_CHECK( jetContHandle.record( std::move(selected_jets) ) ); + + return StatusCode::SUCCESS; +} + +//********************************************************************** + diff --git a/Reconstruction/Jet/JetRec/src/JetViewAlg.h b/Reconstruction/Jet/JetRec/src/JetViewAlg.h new file mode 100644 index 0000000000000000000000000000000000000000..9968704e7c48eda83ec595b8860354a4345a4879 --- /dev/null +++ b/Reconstruction/Jet/JetRec/src/JetViewAlg.h @@ -0,0 +1,56 @@ +// this is a -*- C++ -*- file +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + + +//////////////////////////////////////////////////// +/// \class JetViewAlg +/// +/// Algorithm that selects a subset of jets from +/// the input container, places them in a view +/// JetContainer +/// (i.e. one that does not own its contents) +/// and then writes this container to StoreGate. +/// +/// + +#ifndef JetViewAlg_H +#define JetViewAlg_H + +#include "AthenaBaseComps/AthReentrantAlgorithm.h" +#include "StoreGate/ReadHandleKey.h" +#include "StoreGate/WriteHandleKey.h" +#include "xAODJet/Jet.h" +#include "xAODJet/JetContainer.h" +#include "AthContainers/ConstDataVector.h" + +class JetViewAlg : public AthReentrantAlgorithm { + +public: + + //Delegate to base-class constructor + using AthReentrantAlgorithm::AthReentrantAlgorithm; + + /// Athena algorithm's Hooks + StatusCode initialize() override; + StatusCode execute(const EventContext&) const override; + StatusCode finalize() override {return StatusCode::SUCCESS;}; + +private: + + /// Method to select jets + bool selected( const xAOD::Jet& ) const; + +private: + + Gaudi::Property<float> m_ptmin {this, "PtMin", 0.0, "Min pT in MeV"}; + Gaudi::Property<float> m_absetamax {this, "AbsEtaMax", 10.0, "Max absolute eta"}; + + SG::ReadHandleKey<xAOD::JetContainer> m_input = {this, "InputContainer", "", "The input jet container name"}; + SG::WriteHandleKey<ConstDataVector<xAOD::JetContainer> > m_output = {this, "OutputContainer", "", "The output jet container name"}; + +}; + +#endif + diff --git a/Reconstruction/Jet/JetRec/src/components/JetRec_entries.cxx b/Reconstruction/Jet/JetRec/src/components/JetRec_entries.cxx index ee75cb7e4434e0b18ba54578696015ff2534818a..7f851f41d76cc2722abf509d7deb5240bdc50e46 100644 --- a/Reconstruction/Jet/JetRec/src/components/JetRec_entries.cxx +++ b/Reconstruction/Jet/JetRec/src/components/JetRec_entries.cxx @@ -1,5 +1,6 @@ #include "../JetAlgorithm.h" #include "../JetRecAlg.h" +#include "../JetViewAlg.h" #include "../PseudoJetAlgorithm.h" #include "JetRec/JetToolRunner.h" #include "JetRec/JetRecTool.h" @@ -50,5 +51,6 @@ DECLARE_COMPONENT( PseudoJetMerger ) DECLARE_COMPONENT( JetAlgorithm ) DECLARE_COMPONENT( JetRecAlg ) +DECLARE_COMPONENT( JetViewAlg ) DECLARE_COMPONENT( PseudoJetAlgorithm ) diff --git a/Reconstruction/Jet/JetRecConfig/python/JetRecConfig.py b/Reconstruction/Jet/JetRecConfig/python/JetRecConfig.py index 08e126ccae6104fddc0ae9d257311f7e9c9a6792..593555356b890434a3c0e7497031d36986393b83 100644 --- a/Reconstruction/Jet/JetRecConfig/python/JetRecConfig.py +++ b/Reconstruction/Jet/JetRecConfig/python/JetRecConfig.py @@ -362,10 +362,13 @@ def getGhostPrereqs(ghostdef): def getConstitPJGAlg(basedef): jetlog.debug("Getting PseudoJetAlg for label {0} from {1}".format(basedef.label,basedef.inputname)) # - getter = JetRecConf.PseudoJetGetter("pjg_"+basedef.label, + full_label = basedef.label + if basedef.basetype == xAODType.Jet: + full_label += "_"+basedef.inputname + getter = JetRecConf.PseudoJetGetter("pjg_"+full_label, InputContainer = basedef.inputname, - OutputContainer = "PseudoJet"+basedef.label, - Label = basedef.label, + OutputContainer = "PseudoJet"+full_label, + Label = full_label, SkipNegativeEnergy=True, GhostScale=0. ) diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetRecoSequences.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetRecoSequences.py index bc87e39e8084c38251fedebd4ce8133128e49822..c290444174516ac69ac899bac8fc36d192ec5502 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetRecoSequences.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetRecoSequences.py @@ -53,8 +53,16 @@ def jetRecoSequence( dummyFlags, dataSource, RoIs = 'FSJETRoI', **jetRecoDict): (basicJetRecoSequence,basicJetsName) = RecoFragmentsPool.retrieve(jetRecoSequence,None,dataSource=dataSource, **basicJetRecoDict) recoSeq += basicJetRecoSequence + rcJetPtMin = 20e3 # 20 GeV minimum pt for jets to be reclustered + from JetRec.JetRecConf import JetViewAlg + filteredJetsName = basicJetsName+"_pt20" + recoSeq += JetViewAlg("jetview_"+filteredJetsName, + InputContainer=basicJetsName, + OutputContainer=filteredJetsName, + PtMin=rcJetPtMin, OutputLevel=1) + rcJetDef = JetRecoConfiguration.defineReclusteredJets(jetRecoDict) - rcJetDef.inputdef.inputname = basicJetsName + rcJetDef.inputdef.inputname = filteredJetsName rcJetsFullName = jetNamePrefix+rcJetDef.basename+"RCJets_"+jetRecoDict["jetCalib"] rcModList = [] # Could set substructure mods rcJetDef.modifiers = rcModList @@ -73,8 +81,6 @@ def jetRecoSequence( dummyFlags, dataSource, RoIs = 'FSJETRoI', **jetRecoDict): elif doGrooming: # Grooming needs to be set up similarly to reclustering # --> build ungroomed jets, then add a grooming alg - # Reclustering -- recursively call the basic jet reco and add this to the sequence, - # then add another jet algorithm to run the reclustering step ungroomedJetRecoDict = dict(jetRecoDict) ungroomedJetRecoDict["recoAlg"] = ungroomedJetRecoDict["recoAlg"].rstrip("t") # Drop grooming spec ungroomedJetRecoDict["jetCalib"] = "nojcalib" # No need to calibrate @@ -82,6 +88,8 @@ def jetRecoSequence( dummyFlags, dataSource, RoIs = 'FSJETRoI', **jetRecoDict): recoSeq += ungroomedJetRecoSequence ungroomedDef = JetRecoConfiguration.defineJets(ungroomedJetRecoDict) + # Cluster large-R jets only down to 50 GeV + # Trigger thresholds are in the 100s of GeV ungroomedDef.ptmin = 50e3 groomDef = JetRecoConfiguration.defineGroomedJets(jetRecoDict,ungroomedDef,ungroomedJetsName)