diff --git a/CommonTools/RecoAlgos/plugins/JetConstituentSelector.cc b/CommonTools/RecoAlgos/plugins/JetConstituentSelector.cc index 514eb017632be..26f03a47bbf65 100644 --- a/CommonTools/RecoAlgos/plugins/JetConstituentSelector.cc +++ b/CommonTools/RecoAlgos/plugins/JetConstituentSelector.cc @@ -41,8 +41,7 @@ class JetConstituentSelector : public edm::stream::EDProducer<> { JetConstituentSelector(edm::ParameterSet const& params) : srcToken_{consumes>(params.getParameter("src"))}, - selector_{params.getParameter("cut")}, - unpackAK8_{params.getParameter("unpackAK8")} + selector_{params.getParameter("cut")} { produces(); produces("constituents"); @@ -54,7 +53,6 @@ class JetConstituentSelector : public edm::stream::EDProducer<> { desc.add("src")->setComment("InputTag used for retrieving jets in event."); desc.add("cut")->setComment("Cut used by which to select jets. For example:\n" " \"pt > 100.0 && abs(rapidity()) < 2.4\"."); - desc.add("unpackAK8", false)->setComment("Assume the jets are AK8 jets from miniAOD and need to be unpacked."); // addDefault must be used here instead of add unless this function is specialized // for different sets of template parameter types. Each specialization would need @@ -84,25 +82,8 @@ class JetConstituentSelector : public edm::stream::EDProducer<> { // Add the jets that pass to the output collection jets->push_back(jet); - if ( !unpackAK8_) { - for (unsigned int ida {}; ida < jet.numberOfDaughters(); ++ida) { + for (unsigned int ida {}; ida < jet.numberOfDaughters(); ++ida) { candsOut->emplace_back( initptr(jet.daughterPtr(ida)) ); - } - } - else { - // Special case for AK8 pat::Jets from miniAOD, which store the subjets in the first two - // daughter links, and then the rest of the daughters that do not satisfy the jet groomer. - for (unsigned int ida {}; ida < jet.numberOfDaughters(); ++ida) { - auto const & dau = jet.daughterPtr(ida); - if ( dau->numberOfDaughters() == 0 ) { - candsOut->emplace_back( initptr(dau) ); - } else { - auto const * dauJet = dynamic_cast(dau.get()); - for ( unsigned int jda {}; jda < dauJet->numberOfDaughters(); ++jda ) { - candsOut->emplace_back( initptr(dauJet->daughterPtr(jda)) ); - } - } - } } } } @@ -114,7 +95,6 @@ class JetConstituentSelector : public edm::stream::EDProducer<> { private: edm::EDGetTokenT> const srcToken_; StringCutObjectSelector const selector_; - bool unpackAK8_; }; template<> diff --git a/DataFormats/Candidate/interface/CompositePtrCandidate.h b/DataFormats/Candidate/interface/CompositePtrCandidate.h index 6e44866f5b7ba..ba84830a61c51 100755 --- a/DataFormats/Candidate/interface/CompositePtrCandidate.h +++ b/DataFormats/Candidate/interface/CompositePtrCandidate.h @@ -50,9 +50,9 @@ namespace reco { /// clear daughter references void clearDaughters() { dau.clear(); } /// reference to daughter at given position - CandidatePtr daughterPtr( size_type i ) const { return dau[ i ]; } + virtual CandidatePtr daughterPtr( size_type i ) const { return dau[ i ]; } /// references to daughtes - const daughters & daughterPtrVector() const { return dau; } + virtual const daughters & daughterPtrVector() const { return dau; } /// return pointer to mother const Candidate * mother( size_t i = 0 ) const override; /// number of source candidates diff --git a/DataFormats/PatCandidates/interface/Jet.h b/DataFormats/PatCandidates/interface/Jet.h index 88a8eed200691..fdaa76e1465ec 100644 --- a/DataFormats/PatCandidates/interface/Jet.h +++ b/DataFormats/PatCandidates/interface/Jet.h @@ -441,6 +441,9 @@ namespace pat { /// Else return the reco Jet number of constituents const reco::Candidate * daughter(size_t i) const override; + reco::CandidatePtr daughterPtr( size_t i ) const override; + const reco::CompositePtrCandidate::daughters & daughterPtrVector() const override; + using reco::LeafCandidate::daughter; // avoid hiding the base implementation /// Return number of daughters: @@ -550,7 +553,8 @@ namespace pat { // ---- Jet Substructure ---- std::vector< pat::JetPtrCollection> subjetCollections_; - std::vector< std::string> subjetLabels_; + std::vector< std::string> subjetLabels_; + edm::AtomicPtrCache > daughtersTemp_; // ---- MC info ---- @@ -637,6 +641,7 @@ namespace pat { /// cache calo towers void cacheCaloTowers() const; void cachePFCandidates() const; + void cacheDaughters() const; }; } diff --git a/DataFormats/PatCandidates/src/Jet.cc b/DataFormats/PatCandidates/src/Jet.cc index 592ef17fe5528..50e84f8ec7de7 100644 --- a/DataFormats/PatCandidates/src/Jet.cc +++ b/DataFormats/PatCandidates/src/Jet.cc @@ -203,9 +203,29 @@ const reco::Candidate * Jet::daughter(size_t i) const { else return reco::Jet::daughter(i); } } + if ( !subjetCollections_.empty() ) { + if ( !daughtersTemp_.isSet() ) cacheDaughters(); + return daughtersTemp_->at(i).get(); + } return reco::Jet::daughter(i); } +reco::CandidatePtr Jet::daughterPtr( size_t i ) const { + if ( !subjetCollections_.empty() ) { + if ( !daughtersTemp_.isSet() ) cacheDaughters(); + return daughtersTemp_->at(i); + } + return reco::Jet::daughterPtr(i); +} + +const reco::CompositePtrCandidate::daughters & Jet::daughterPtrVector() const { + if ( !subjetCollections_.empty() ) { + if ( !daughtersTemp_.isSet() ) cacheDaughters(); + return *daughtersTemp_; + } + return reco::Jet::daughterPtrVector(); +} + size_t Jet::numberOfDaughters() const { if (isCaloJet() || isJPTJet()) { if ( embeddedCaloTowers_ ) { @@ -221,6 +241,10 @@ size_t Jet::numberOfDaughters() const { else return reco::Jet::numberOfDaughters(); } } + if ( !subjetCollections_.empty() ) { + if ( !daughtersTemp_.isSet() ) cacheDaughters(); + return daughtersTemp_->size(); + } return reco::Jet::numberOfDaughters(); } @@ -584,8 +608,24 @@ void Jet::cachePFCandidates() const { // Set the cache pfCandidatesTemp_.set(std::move(pfCandidatesTemp)); } - - + +/// method to cache the daughters to allow "user-friendly" access +void Jet::cacheDaughters() const { + // Jets in MiniAOD produced via JetSubstructurePacker contain a mixture of subjets and particles as daughters + std::unique_ptr> daughtersTemp{ new std::vector{}}; + const std::vector & jdaus = reco::Jet::daughterPtrVector(); + for (const reco::CandidatePtr & dau : jdaus) { + if (dau->isJet()) { + const reco::Jet *subjet = dynamic_cast(&*dau); + if (subjet) { + const std::vector & sjdaus = subjet->daughterPtrVector(); + daughtersTemp->insert(daughtersTemp->end(), sjdaus.begin(), sjdaus.end()); + } + } else + daughtersTemp->push_back( dau ); + } + daughtersTemp_.set(std::move(daughtersTemp)); +} /// Access to subjet list diff --git a/DataFormats/PatCandidates/src/classes_def_objects.xml b/DataFormats/PatCandidates/src/classes_def_objects.xml index 34442568459c0..1b269200a6712 100644 --- a/DataFormats/PatCandidates/src/classes_def_objects.xml +++ b/DataFormats/PatCandidates/src/classes_def_objects.xml @@ -236,6 +236,7 @@ + @@ -249,6 +250,15 @@ + + + + + + + + + diff --git a/PhysicsTools/NanoAOD/python/jets_cff.py b/PhysicsTools/NanoAOD/python/jets_cff.py index fb7e550a0de3c..0a13267eb0a78 100644 --- a/PhysicsTools/NanoAOD/python/jets_cff.py +++ b/PhysicsTools/NanoAOD/python/jets_cff.py @@ -256,9 +256,9 @@ btagDeepB = Var("bDiscriminator('pfDeepCSVJetTags:probb')+bDiscriminator('pfDeepCSVJetTags:probbb')",float,doc="DeepCSV b+bb tag discriminator",precision=10), btagCSVV2 = Var("bDiscriminator('pfCombinedInclusiveSecondaryVertexV2BJetTags')",float,doc=" pfCombinedInclusiveSecondaryVertexV2 b-tag discriminator (aka CSVV2)",precision=10), btagHbb = Var("bDiscriminator('pfBoostedDoubleSecondaryVertexAK8BJetTags')",float,doc="Higgs to BB tagger discriminator",precision=10), - subJetIdx1 = Var("?numberOfSourceCandidatePtrs()>0 && sourceCandidatePtr(0).numberOfSourceCandidatePtrs()>0?sourceCandidatePtr(0).key():-1", int, + subJetIdx1 = Var("?nSubjetCollections()>0 && subjets().size()>0?subjets()[0].key():-1", int, doc="index of first subjet"), - subJetIdx2 = Var("?numberOfSourceCandidatePtrs()>1 && sourceCandidatePtr(1).numberOfSourceCandidatePtrs()>0?sourceCandidatePtr(1).key():-1", int, + subJetIdx2 = Var("?nSubjetCollections()>0 && subjets().size()>1?subjets()[1].key():-1", int, doc="index of second subjet"), # btagDeepC = Var("bDiscriminator('pfDeepCSVJetTags:probc')",float,doc="CMVA V2 btag discriminator",precision=10),