ATLAS Offline Software
Loading...
Searching...
No Matches
PseudoJetGetter.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
15
16#ifndef PSEUDOJETGETTER_H
17#define PSEUDOJETGETTER_H
18
19#include "fastjet/PseudoJet.hh"
20#include "xAODBase/IParticle.h"
21
22#ifndef GENERATIONBASE
24#include "xAODPFlow/PFO.h"
27#include "xAODTracking/Vertex.h"
28#include "JetEDM/LabelIndex.h"
30#endif
31
32namespace PseudoJetGetter {
33
35 bool null{false};
36 bool negativeE{false};
37 bool skipNegativeEnergy{false};
38
41
42 bool operator()(const xAOD::IParticle* ip) {
43 null = (ip == 0);
44 negativeE = skipNegativeEnergy && ip->e() <= 0.0;
45 return (null || negativeE);
46 }
47 };
48
49
50 std::vector<fastjet::PseudoJet>
51 IParticlesToPJs(const xAOD::IParticleContainer& ips, bool skipNegativeEnergy) {
52
53 IParticleRejecter rejecter(skipNegativeEnergy);
54
55 std::vector<fastjet::PseudoJet> vpj;
56 int index = -1;
57
58 // loop over the input iparticles, select and convert to pseudojets
59 for(const xAOD::IParticle* ip: ips) {
60 ++index;
61 if(rejecter(ip)){continue;}
62
63 // Create a Pseudojet with the momentum of the selected IParticles.
64 fastjet::PseudoJet psj(ip->p4());
65
66 // user index is used to identify the xAOD object used for the PseudoJet
67 psj.set_user_index(index);
68 vpj.push_back(psj);
69
70 }
71 return vpj;
72 }
73
74 //**********************************************************************
75
76#ifndef GENERATIONBASE
77
80
81 bool operator()(const xAOD::IParticle* ip){
82 cluster = dynamic_cast<const xAOD::CaloCluster*>(ip);
83 return cluster == 0; // reject if not a cluster
84 }
85 };
86
87 std::vector<fastjet::PseudoJet>
88 EMToposToPJs(const xAOD::IParticleContainer& ips, bool skipNegativeEnergy) {
89
90 // helper objects for selecting iparticles to be converted to pseudojets
91 IParticleRejecter ipRejecter(skipNegativeEnergy);
92 EMTopoRejecter emRejecter;
93
94 std::vector<fastjet::PseudoJet> vpj;
95 int index = -1;
96
97 // loop over iparticles, select and convert to pseudojets
98
99 for(const xAOD::IParticle* ip: ips) {
100 ++index;
101 if(ipRejecter(ip) or emRejecter(ip)){continue;}
102
103 // Create a Pseudojet with the momentum of the cluster.
104 fastjet::PseudoJet
106
107 // user index is used to identify the xAOD object used for the PseudoJet
108 psj.set_user_index(index);
109 vpj.push_back(psj);
110 }
111 return vpj;
112 }
113
114 //**********************************************************************
115
117
119 bool useChargedPFOs{true};
120 bool useNeutralPFOs{true};
121 bool useChargedPV{true};
123 bool inputIsUFO{false};
124
125 PFlowRejecter(bool skip, bool useCharged, bool useNeutral, bool chargedPV, bool chargedPUsideband, bool isUFO):
127 useChargedPFOs(useCharged),
128 useNeutralPFOs(useNeutral),
129 useChargedPV(chargedPV),
130 useChargedPUsideband(chargedPUsideband),
131 inputIsUFO(isUFO){
132 }
133
135
136 bool reject = false;
137
138 // Reject PJs with invalid energy --- they will lead
139 // to crashes in fastjet. See ATLASRECTS-7137.
140 float e = ip->e();
141 if (std::isinf(e) || std::isnan(e)) return true;
142
143 if(ip->type() == xAOD::Type::FlowElement){
144 const xAOD::FlowElement* pfo = dynamic_cast<const xAOD::FlowElement*>(ip);
145
146 reject = (skipNegativeEnergy && e<FLT_MIN);
147
148 if(!inputIsUFO){
149 if( pfo->isCharged() ){
150 if(!useChargedPFOs) reject = true;
151 const static SG::AuxElement::ConstAccessor<char> PVMatchedAcc("matchedToPV");
152 if(useChargedPV && !PVMatchedAcc(*pfo)) reject = true;
153 const static SG::AuxElement::ConstAccessor<char> PUsidebandMatchedAcc("matchedToPUsideband");
154 if (useChargedPUsideband && !PUsidebandMatchedAcc(*pfo)) reject = true;
155 }
156 else{
157 if(!useNeutralPFOs) reject = true;
158 }
159 }
160 else{
163 }
164 return reject;
165 }
166
167 const xAOD::PFO* pfo = dynamic_cast<const xAOD::PFO*>(ip);
168
169 // keep charged PFOs with energy==0 because for MET TST with PFlow,
170 // there may be high pt
171 // charged PFOs that receive a weight of 0 due to being in dense
172 // showers, but need to be present for overlap removal, because they
173 // don't retain these weights when added to the TST
174
175 reject = (skipNegativeEnergy && e<FLT_MIN);
176
177 if( pfo->isCharged() ) {
178 if(!useChargedPFOs) reject = true;
179 const static SG::AuxElement::ConstAccessor<char> PVMatchedAcc("matchedToPV");
180 if(useChargedPV && !PVMatchedAcc(*pfo)) reject = true;
181 const static SG::AuxElement::ConstAccessor<char> PUsidebandMatchedAcc("matchedToPUsideband");
182 if (useChargedPUsideband && !PUsidebandMatchedAcc(*pfo)) reject = true;
183 }
184 else{
185 if(!useNeutralPFOs) reject = true;
186 }
187 return reject;
188 }
189 };
190
191
192 std::vector<fastjet::PseudoJet>
193 PFlowsToPJs(const xAOD::IParticleContainer& ips, bool skipNegativeEnergy, bool useChargedPFOs, bool useNeutralPFOs, bool useChargedPV, bool useChargedPUsideband, bool isUFO) {
194
195 PFlowRejecter rejecter(skipNegativeEnergy, useChargedPFOs, useNeutralPFOs, useChargedPV, useChargedPUsideband, isUFO);
196 std::vector<fastjet::PseudoJet> vpj;
197 int index = -1;
198
199 // loop over the input iparticles, select and convert to pseudojets
200
201 for(const xAOD::IParticle* ip: ips) {
202 ++index;
203 if(rejecter(ip)){continue;}
204
205 // Create a PSeudojet with the momentum of the selected IParticles.
206 fastjet::PseudoJet psj(ip->p4());
207
208 // user index is used to identify the xAOD object used for the PSeudoJet
209 psj.set_user_index(index);
210
211 vpj.push_back(psj);
212 }
213 return vpj;
214 }
215
216 std::vector<fastjet::PseudoJet>
217 ByVertexPFlowsToPJs(const xAOD::IParticleContainer& ips, const xAOD::VertexContainer* pvs, bool skipNegativeEnergy, bool useChargedPFOs, bool useNeutralPFOs, bool isUFO) {
218
219 const static SG::AuxElement::Accessor< unsigned > copyIndex("ConstituentCopyIndex"); // For neutral PFOs
220 const static SG::AuxElement::Accessor< std::vector<unsigned> > matchedPVs("MatchingPVs"); // For charged PFOs
221 const static SG::AuxElement::Accessor< std::vector<unsigned> > matchedPUSBs("MatchingPUsidebands"); // For charged PFOs
222 PFlowRejecter rejecter(skipNegativeEnergy, useChargedPFOs, useNeutralPFOs, false, false, isUFO);
223 std::vector<fastjet::PseudoJet> vpj;
224 int index = -1;
225
226 // loop over the input iparticles, select and convert to pseudojets
227 for(const xAOD::IParticle* ip: ips) {
228
229 const xAOD::FlowElement* pfo = dynamic_cast<const xAOD::FlowElement*>(ip);
230 ++index;
231 if(rejecter(ip)){
232 continue;
233 }
234
235 unsigned vertexIndex{0};
236 if (pfo->isCharged())
237 {
238 // Charged PFOs - use the vertex matched to the track
239 if (matchedPVs.isAvailable(*pfo) && matchedPVs(*pfo).size())
240 {
241 // A charged PFO can potentially match multiple vertices, depending on the matching criteria used
242 // For now, just use the first match, to be further optimised later -- TODO
243 // Also add the part for PU sidebands -- TODO
244 vertexIndex = matchedPVs(*pfo).at(0);
245 }
246 else{
247 continue;
248 }
249 }
250 else
251 {
252 // Neutral PFOs - there is one neutral PFO corrected to point to each vertex of interest
253 // As such, just get the vertex index that this neutral PFO corresponds to
254 if (copyIndex.isAvailable(*pfo)){
255 vertexIndex = copyIndex(*pfo);
256 }
257 else{
258 continue;
259 }
260 }
261
262 // Create a Pseudojet with the momentum of the selected IParticles.
263 fastjet::PseudoJet psj(ip->p4());
264
265
266 // Get the specified vertex and build the VertexIndexedConstituentUserInfo
267 for (const xAOD::Vertex* vertex : *pvs)
268 if (vertex->index() == vertexIndex){
269 // vertex indexed constituent info associated to the pseudojet
270 psj.set_user_info(new jet::VertexIndexedConstituentUserInfo(vertex));
271
272 // user index is used to identify the xAOD object used for the PSeudoJet
273 psj.set_user_index(index);
274
275 vpj.push_back(psj);
276 }
277 }
278 return vpj;
279 }
280
281#endif
282
283}
284
285#endif
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 FourMom_t p4() const
The full 4-momentum of the particle.
signal_t signalType() const
Class providing the definition of the 4-vector interface.
bool isCharged() const
is a charged PFO
Definition PFO_v1.cxx:251
Implementations of concrete input-to-PseudoJet conversions Separated from PseudoJetAlgorithm for read...
std::vector< fastjet::PseudoJet > EMToposToPJs(const xAOD::IParticleContainer &ips, bool skipNegativeEnergy)
std::vector< fastjet::PseudoJet > PFlowsToPJs(const xAOD::IParticleContainer &ips, bool skipNegativeEnergy, bool useChargedPFOs, bool useNeutralPFOs, bool useChargedPV, bool useChargedPUsideband, bool isUFO)
std::vector< fastjet::PseudoJet > IParticlesToPJs(const xAOD::IParticleContainer &ips, bool skipNegativeEnergy)
std::vector< fastjet::PseudoJet > ByVertexPFlowsToPJs(const xAOD::IParticleContainer &ips, const xAOD::VertexContainer *pvs, bool skipNegativeEnergy, bool useChargedPFOs, bool useNeutralPFOs, bool isUFO)
Definition index.py:1
@ FlowElement
The object is a track-calo-cluster.
Definition ObjectType.h:52
PFO_v1 PFO
Definition of the current "pfo version".
Definition PFO.h:17
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
FlowElement_v1 FlowElement
Definition of the current "pfo version".
Definition FlowElement.h:16
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
Vertex_v1 Vertex
Define the latest version of the vertex class.
DataVector< IParticle > IParticleContainer
Simple convenience declaration of IParticleContainer.
const xAOD::CaloCluster * cluster
bool operator()(const xAOD::IParticle *ip)
bool operator()(const xAOD::IParticle *ip)
PFlowRejecter(bool skip, bool useCharged, bool useNeutral, bool chargedPV, bool chargedPUsideband, bool isUFO)
bool operator()(const xAOD::IParticle *ip)