ATLAS Offline Software
Loading...
Searching...
No Matches
JetConstituentFiller.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// JetConstituentFiller.cxx
6
8#include <map>
11#include "JetEDM/LabelIndex.h"
13#include "fastjet/PseudoJet.hh"
15#include <iostream>
16
17using PseudoJetVector = std::vector<fastjet::PseudoJet>;
18using xAOD::IParticle;
21using ParticleVector = std::vector<const IParticle *>;
22using ParticleMap = std::vector<ParticleVector>;
23using PtMap = std::vector<double>;
27using MuonSegmentVector = std::vector<const MuonSegment *>;
29using MuonSegmentMap = std::vector<MuonSegmentVector>;
30
31//**********************************************************************
32
33namespace {
34 enum ParType { UNDEF, IPART, MUSEG };
35}
36using ParTypeVector = std::vector<ParType>;
37
38//**********************************************************************
39
41extractConstituents(xAOD::Jet& jet, const NameList* pghostlabs,
42 const fastjet::PseudoJet* ppj2) {
43
44 static const SG::AuxElement::Accessor<const fastjet::PseudoJet*> pjAccessor("PseudoJet");
45 const fastjet::PseudoJet* ppseudojet = nullptr;
46 if(pjAccessor.isAvailable(jet)) ppseudojet = pjAccessor(jet);
47
48 if ( ppseudojet == nullptr ) {
49 ppseudojet = ppj2;
50 }
51 if ( ppseudojet == nullptr ) return -1;
52 int nbad = 0;
53 const PseudoJetVector& cons = ppseudojet->constituents();
54 ParticleMap out;
55 MuonSegmentMap outms;
56 PtMap ptout;
57 ParTypeVector partypes;
58 const LabelIndex* pli = nullptr;
59 for ( PseudoJetVector::const_iterator icon=cons.begin(); icon!=cons.end(); ++icon ) {
60 if ( icon->has_user_info<IConstituentUserInfo>() ) {
61 const IConstituentUserInfo& cui = icon->user_info<IConstituentUserInfo>();
62 // Initialize with the first constituent.
63 if ( pli == nullptr ) {
64 pli = cui.labelMap();
65 if ( pli == nullptr ) return -2;
66 unsigned int maxli = pli->size() + 1; // +1 because LabelIndex starts at 1;
67 out.resize(maxli); // +1 because LabelIndex starts at 1
68 outms.resize(maxli);
69 for ( unsigned int ili=0; ili<maxli; ++ili ) {
70 ptout.push_back(0.0);
71 }
72 for ( ParType& partype : partypes ) partype = UNDEF;
73 for ( unsigned int idx=0; idx<maxli; ++idx ) {
74 std::string lab = pli->label(idx);
75 if ( lab.empty() ) {
76 partypes.push_back(UNDEF);
77 if ( idx ) return -3;
78 } else if ( lab.find("MuonSegment") != std::string::npos ) {
79 partypes.push_back(MUSEG);
80 } else {
81 partypes.push_back(IPART);
82 }
83 }
84 }
85 if ( pli != cui.labelMap() ) return -4;
86 const IParticle* ppar = cui.particle();
87 const MuonSegment* pms = nullptr;
88 // If this is not an IParticle, find the full type.
89 unsigned int icui = cui.index();
90 ParType partype = partypes[icui];
91 if ( ppar == nullptr ) {
92 const MuonSegmentCUI* pmscui = dynamic_cast<const MuonSegmentCUI*>(&cui);
93 if ( pmscui == nullptr ) return -5;
94 pms = pmscui->object();
95 if ( partype != MUSEG ) return -6;
96 } else {
97 if ( partype != IPART ) return -7;
98 }
99 Label lab = cui.label();
100 // Add to constituent list or associated object list.
101 if ( ! cui.isGhost() ) {
102 if (!ppar) {
103 ++nbad;
104 }
105 else {
106 jet.addConstituent(ppar);
107 jet.setConstituentsSignalState( cui.constitScale() );
108 }
109 } else {
110 if ( partype == MUSEG ) {
111 outms[icui].push_back(pms);
112 } else if ( partype == IPART ) {
113 out[icui].push_back(ppar);
114 }
115 }
116 } else {
117 ++nbad;
118 }
119 }
120
121 // Set ghost associated particles:
122 if (pli){
123 for ( size_t i=1; i<out.size(); ++i ) {
124 if ( pghostlabs) {
125 const NameList& ghostlabs = *pghostlabs;
126 if ( find(ghostlabs.begin(), ghostlabs.end(), pli->label(i)) == ghostlabs.end() ) {
127 nbad += out[i].size();
128 continue;
129 }
130 }
131 ParType& partype = partypes[i];
132 std::string cname = pli->label(i) + "Count";
133 std::string ptname = pli->label(i) + "Pt";
134 // Check if this is in the parent jet
135 int count_test; // dummy var to retrieve into -- we don't care about the value
136 const static SG::AuxElement::ConstAccessor<ElementLink<xAOD::JetContainer> > cacc_parent("Parent");
137 if(!m_isTrigger) {
138 if(cacc_parent.isAvailable(jet) && cacc_parent(jet).isValid()) {
139 if(!(*cacc_parent(jet))->getAttribute(cname,count_test)) {
140 nbad += out[i].size(); // Skip if the parent does not have this
141 continue;
142 }
143 }
144 }
145 if ( partype == MUSEG ) {
146 // Record associated muons.
147 jet.setAssociatedObjects(pli->label(i) , outms[i]);
148 jet.setAttribute<int>(cname, outms[i].size());
149 } else if ( partype == IPART ) {
150 // Record associated particles.
151 jet.setAssociatedObjects(pli->label(i), out[i]);
152 jet.setAttribute<int>(cname, out[i].size());
153 jet.setAttribute<float>(ptname, ptout[i]);
154 if ( ! outms[i].empty() ) return -9;
155 } else {
156 return -10;
157 }
158 }
159 }
160 return nbad;
161}
162
163int JetConstituentFiller::extractConstituents(xAOD::Jet& jet, const fastjet::PseudoJet* ppj2) {
164 return extractConstituents(jet, nullptr, ppj2);
165}
166
167//**********************************************************************
168
169PseudoJetVector JetConstituentFiller::constituentPseudoJets(const xAOD::Jet& jet, bool ignoreGhosts, bool requireJetStructure){
170
171 static const SG::AuxElement::Accessor<const fastjet::PseudoJet*> pjAccessor("PseudoJet");
172 const fastjet::PseudoJet* jet_pj = nullptr;
173 if(pjAccessor.isAvailable(jet)) jet_pj = pjAccessor(jet);
174
175 PseudoJetVector constituents;
176
177 if(jet_pj && !ignoreGhosts ){ // Retrieve constituents from the PseudoJet
178 constituents = jet_pj->constituents(); // all constituents, including ghosts
179 // Removed block for (existing jet_pt and ignoreGhosts), because
180 // in the PseudoJetContainer model, the constituent user info is
181 // not attached, and hence it's not possible to know if a pj is
182 // ghost or constituent.
183 } else { // no PseudoJet in jet or need to reject ghosts. Build them from constituents.
184
185 // For SoftDrop variables like zg, rg, the structure of the jet is needed and
186 // constituents have to be retrieved from the Pseudojet
187 if(jet_pj && requireJetStructure){
188 PseudoJetVector constituents_all = jet_pj->constituents(); // all constituents, including ghosts
189 //Filter out ghosts before calculating variables (comparison to constituents)
190 xAOD::JetConstituentVector constituents_tmp = jet.getConstituents();
191 constituents.reserve( jet.numConstituents() );
192 for(size_t i = 0; i < constituents_all.size(); i++){
193 for(size_t j = 0; j < constituents_tmp.size(); j++){
194 if(std::abs((constituents_all[i].px()-constituents_tmp[j].Px())/constituents_tmp[j].Px()) < 0.0001 &&
195 std::abs((constituents_all[i].py()-constituents_tmp[j].Py())/constituents_tmp[j].Py()) < 0.0001 &&
196 std::abs((constituents_all[i].pz()-constituents_tmp[j].Pz())/constituents_tmp[j].Pz()) < 0.0001){
197 constituents.push_back(constituents_all[i]);
198 break;
199 }
200 }
201 }
202 }
203 else{
204 xAOD::JetConstituentVector constituents_tmp = jet.getConstituents();
205 constituents.reserve( jet.numConstituents() );
206 for(size_t i = 0; i < constituents_tmp.size(); i++){
207 constituents.emplace_back( constituents_tmp[i].Px(), constituents_tmp[i].Py(), constituents_tmp[i].Pz(), constituents_tmp[i].E() );
208 }
209 }
210 }
211 return constituents;
212}
213//**********************************************************************
214
bool isValid(const T &p)
Av: we implement here an ATLAS-sepcific convention: all particles which are 99xxxxx are fine.
Definition AtlasPID.h:878
IndexedConstituentUserInfo::Label Label
IndexedTConstituentUserInfo< MuonSegment > MuonSegmentCUI
std::vector< ParType > ParTypeVector
std::vector< const MuonSegment * > MuonSegmentVector
std::vector< ParticleVector > ParticleMap
std::vector< fastjet::PseudoJet > PseudoJetVector
std::vector< const IParticle * > ParticleVector
std::vector< double > PtMap
std::vector< MuonSegmentVector > MuonSegmentMap
static const Attributes_t empty
int extractConstituents(xAOD::Jet &jet, const NameList *pghostlabs, const fastjet::PseudoJet *ppj=0)
Build and fill constituents of jet from its PseudoJet (or from ppj) Returns the number of pseudojet c...
SG::ConstAccessor< T, ALLOC > ConstAccessor
Definition AuxElement.h:569
SG::Accessor< T, ALLOC > Accessor
Definition AuxElement.h:572
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
virtual const LabelIndex * labelMap() const
virtual xAOD::JetConstitScale constitScale() const
Return the constituent scale used to build the PseudoJet.
virtual Label label() const =0
virtual bool isGhost() const
Returns true if this constituent is a ghost.
virtual const xAOD::IParticle * particle() const =0
int extractConstituents(xAOD::Jet &jet, const NameList *pghostlabs, const fastjet::PseudoJet *ppj=0)
Build and fill constituents of jet from its PseudoJet (or from ppj) Returns the number of pseudojet c...
std::vector< std::string > NameList
static PseudoJetVector constituentPseudoJets(const xAOD::Jet &jet, bool ignoreGhosts=true, bool requireJetStructure=false)
Returns the jet's constituents as a vector of PseudoJet if ignoreGhosts==true, ghost constituents are...
Index size() const
Number of label stored in this map. WARNING the index starts at 1, so range is [1....
Label label(Index idx) const
Fetch the label for an index.
Class providing the definition of the 4-vector interface.
A vector of jet constituents at the scale used during jet finding.
size_t size() const
number of constituents
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:138
std::vector< fastjet::PseudoJet > PseudoJetVector
Jet_v1 Jet
Definition of the current "jet version".
MuonSegment_v1 MuonSegment
Reference the current persistent version: