ATLAS Offline Software
Loading...
Searching...
No Matches
VertexDecoratorAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
13
14
16{
17 VertexDecoratorAlg ::VertexDecoratorAlg(const std::string &name,
18 ISvcLocator *pSvcLocator)
19 : AthHistogramAlgorithm (name, pSvcLocator)
20 {
21 }
22
23 StatusCode VertexDecoratorAlg ::initialize()
24 {
25 ATH_CHECK(m_vertexInKey.initialize());
26 ATH_CHECK(m_eventInKey.initialize());
27 ATH_CHECK(m_photonsInKey.initialize());
28 ATH_CHECK(m_electronsInKey.initialize());
29 ATH_CHECK(m_muonsInKey.initialize());
30 ATH_CHECK(m_jetsInKey.initialize());
31
32 const std::string baseName = m_vertexInKey.key();
33
34 // WriteHandleKeys
35 m_photonLinksKey = baseName + ".photonLinks";
36 m_jetLinksKey = baseName + ".jetLinks";
37 m_electronLinksKey = baseName + ".electronLinks";
38 m_muonLinksKey = baseName + ".muonLinks";
39 m_mDecor_ntrk = baseName + "." + m_mDecor_ntrk.key();
40 m_mDecor_sumPt = baseName + "." + m_mDecor_sumPt.key();
41 m_mDecor_chi2Over_ndf = baseName + "." + m_mDecor_chi2Over_ndf.key();
42 m_mDecor_z_asym = baseName + "." + m_mDecor_z_asym.key();
45 m_mDecor_z_skew = baseName + "." + m_mDecor_z_skew.key();
46 m_mDecor_photon_deltaz = baseName + "." + m_mDecor_photon_deltaz.key();
49
50 ATH_CHECK(m_photonLinksKey.initialize());
51 ATH_CHECK(m_jetLinksKey.initialize());
52 ATH_CHECK(m_electronLinksKey.initialize());
53 ATH_CHECK(m_muonLinksKey.initialize());
54 ATH_CHECK(m_mDecor_ntrk.initialize());
55 ATH_CHECK(m_mDecor_sumPt.initialize());
56 ATH_CHECK(m_mDecor_chi2Over_ndf.initialize());
57 ATH_CHECK(m_mDecor_z_asym.initialize());
60 ATH_CHECK(m_mDecor_z_skew.initialize());
64
65 // ReadHandleKeys
66 m_deltaZKey = baseName + ".deltaZ";
67 m_deltaPhiKey = baseName + ".deltaPhi";
68 ATH_CHECK(m_deltaZKey.initialize());
69 ATH_CHECK(m_deltaPhiKey.initialize());
70
71 // additional ReadHandleKeys to declare dependencies to the scheduler
72 std::string photonBaseName = m_photonsInKey.key();
73
74 m_caloPointingZKey = photonBaseName + ".caloPointingZ";
75 m_zCommonKey = photonBaseName + ".zCommon";
76 m_zCommonErrorKey = photonBaseName + ".zCommonError";
77
78 ATH_CHECK(m_caloPointingZKey.initialize());
79 ATH_CHECK(m_zCommonKey.initialize());
80 ATH_CHECK(m_zCommonErrorKey.initialize());
81
82 // Tools
83 ATH_CHECK(m_gnnTool.retrieve());
84 ATH_CHECK(m_trkVtxAssociationTool->setProperty("WorkingPoint","Prompt_MaxWeight"));
85 ATH_CHECK(m_trkVtxAssociationTool->setProperty("AMVFVerticesDeco","TTVA_AMVFVertices_forReco"));
86 ATH_CHECK(m_trkVtxAssociationTool->setProperty("AMVFWeightsDeco","TTVA_AMVFWeights_forReco"));
89
90 return StatusCode::SUCCESS;
91 }
92
93 StatusCode VertexDecoratorAlg ::execute()
94 {
95 const EventContext &ctx = Gaudi::Hive::currentContext();
97 ATH_CHECK(vertices.isValid());
98
100 ATH_CHECK(photonsIn.isValid());
102 ATH_CHECK(electronsIn.isValid());
104 ATH_CHECK(muonsIn.isValid());
106 ATH_CHECK(jetsIn.isValid());
108 ATH_CHECK(eventInfo.isValid());
109
114
117
118 // Decorations needed by the GNNTool
129
130 std::map< const xAOD::Vertex*, std::vector<ElementLink<xAOD::JetContainer>> > jetsInVertex;
131 std::map< const xAOD::Jet*, std::map< const xAOD::Vertex*, int> > jetVertexPt;
132
133 // initialize jet-vertex map
134 for(const xAOD::Vertex *vertex : *vertices){
135 jetsInVertex[vertex] = {};
136 for(const xAOD::Jet *jet : *jetsIn){
137 jetVertexPt[jet][vertex] = 0;
138 }
139 }
140
141 // pre-fill the jet-vertex map
142 for(const xAOD::Jet* jet : *jetsIn){
143
144 // for each jet, calculate the track pT associated to each vertex
145 std::vector<const xAOD::TrackParticle*> ghostTracks = jet->getAssociatedObjects<xAOD::TrackParticle >(xAOD::JetAttribute::GhostTrack);
146 for(const xAOD::TrackParticle* jtrk : ghostTracks){
147 if( !jtrk ) continue;
148 auto jetTrackVertex = m_trkVtxAssociationTool->getUniqueMatchVertexLink(*jtrk, *vertices);
149 if(jetTrackVertex) jetVertexPt[jet][*jetTrackVertex] += jtrk->pt();
150 }
151
152 // find vertex with the largest fraction of jet track pt
153 float maxPtFrac = -1;
154 const xAOD::Vertex* uniqueVertexAddress = nullptr;
155 for (const xAOD::Vertex *vertex : *vertices) {
156 if (vertex->vertexType() == xAOD::VxType::NoVtx) continue;
157 if(jetVertexPt[jet][vertex] > maxPtFrac){
158 maxPtFrac = jetVertexPt[jet][vertex];
159 uniqueVertexAddress = vertex;
160 }
161 }
162
163 // add jet to that vertex's vector of links
165 jetLink.setElement(jet);
166 jetLink.setStorableObject(*jetsIn.ptr(), true);
167 jetsInVertex[uniqueVertexAddress].push_back(jetLink);
168 }
169
170 for (const xAOD::Vertex *vertex : *vertices)
171 {
172 if (vertex->vertexType() == xAOD::VxType::NoVtx)
173 continue;
174
175 dec_actualInterPerXing(*vertex) = eventInfo->actualInteractionsPerCrossing();
176
177 // variables for calculation of delta Z asymmetry and delta d asymmetry
178 float z_asym = 0;
179 float sumDZ = 0;
180 float deltaZ = 0;
181 float modsumDZ = 0;
182 float weighted_sumDZ = 0;
183 float weighted_deltaZ = 0;
184 float weighted_modsumDZ = 0;
185 float weighted_z_asym = 0;
186
187 // make vector
188 std::vector<float> track_deltaZ;
189
190 for (size_t i = 0; i < vertex->nTrackParticles(); i++) {
191
192 const xAOD::TrackParticle *trackTmp = vertex->trackParticle(i);
193
194 if(!trackTmp) continue;
195
196 deltaZ = trackTmp->z0() + trackTmp->vz() - vertex->z();
197 track_deltaZ.push_back(deltaZ);
198 // get the track weight for each track to get the deltaZ/trk_weight
199 float trk_weight = vertex->trackWeight(i);
200 weighted_deltaZ = deltaZ * trk_weight;
201 // sum of delta z
202 sumDZ += deltaZ;
203 modsumDZ += std::abs(deltaZ);
204 weighted_sumDZ += weighted_deltaZ;
205 weighted_modsumDZ += std::abs(weighted_deltaZ);
206 } // end loop over tracks
207
208 if (modsumDZ > 0) {
209 z_asym = sumDZ / modsumDZ;
210 }
211 if (weighted_modsumDZ > 0) {
212 weighted_z_asym = weighted_sumDZ / weighted_modsumDZ;
213 }
214
215 float mean_Dz = sumDZ / track_deltaZ.size(); // calculate average
216 float number_tracks = track_deltaZ.size(); // get number of tracks
217
218 float z_skew = 0; // skewness of DeltaZ asymmetry
219 float z_kurt = 0; // Kurtosis of DeltaZ asymmetry
220 float z_var = 0; // variance of DeltaZ
221
222 for (auto i : track_deltaZ)
223 {
224 float z_zbar = (i - mean_Dz);
225 z_var += std::pow(z_zbar, 2);
226 z_skew += std::pow(z_zbar, 3);
227 z_kurt += std::pow(z_zbar, 4);
228 }
229 if (number_tracks > 1 && z_var > 0) {
230 z_var /= (number_tracks - 1);
231 float z_sd = std::sqrt(z_var);
232 z_skew /= (number_tracks - 1) * std::pow(z_sd, 3);
233 z_kurt /= (number_tracks - 1) * std::pow(z_sd, 4);
234 }
235 else
236 {
237 ATH_MSG_WARNING("z momenta are NaN: setting to zero");
238 z_skew = 0.;
239 z_kurt = 0.;
240 }
241
242 dec_ntrk(*vertex) = number_tracks;
243
244 if(!dec_sumPt.isAvailable()){
245 dec_sumPt(*vertex) = xAOD::PVHelpers::getVertexSumPt(vertex, 1, false);
246 }
247 dec_chi2Over_ndf(*vertex) = vertex->chiSquared() / vertex->numberDoF();
248 dec_z_asym(*vertex) = z_asym;
249 dec_weighted_z_asym(*vertex) = weighted_z_asym;
250 dec_z_kurt(*vertex) = z_kurt;
251 dec_z_skew(*vertex) = z_skew;
252
253 if (acc_deltaZ.isAvailable()) {
254 //protect against rare NaNs before assigning decorator: setting to 0 (-999 cause NaNs)
255 if (std::isnan(acc_deltaZ(*vertex))) {
256 ATH_MSG_WARNING("photon deltaPhi is NaN: setting to 0!");
257 dec_photon_deltaz(*vertex) = 0;
258 }
259 else{
260 dec_photon_deltaz(*vertex) = acc_deltaZ(*vertex);
261 }
262 }
263 else{
264 dec_photon_deltaz(*vertex) = 0;
265 }
266 if (acc_deltaPhi.isAvailable()) {
267 if (std::isnan(acc_deltaPhi(*vertex))) {
268 ATH_MSG_WARNING("photon deltaPhi is NaN: setting to 0!");
269 dec_photon_deltaPhi(*vertex) = 0;
270 }
271 else{
272 dec_photon_deltaPhi(*vertex) = acc_deltaPhi(*vertex);
273 }
274 }
275 else{
276 dec_photon_deltaPhi(*vertex) = 0;
277 }
278
279 // associate objects to vertices
280 std::vector<ElementLink<xAOD::ElectronContainer>> electronLinks;
281 for(const xAOD::Electron* electron : *electronsIn){
282 const auto *id_trk = xAOD::EgammaHelpers::getOriginalTrackParticle(electron);
283 if(!id_trk) continue;
284 auto eleVertex = m_trkVtxAssociationTool->getUniqueMatchVertexLink(*id_trk, *vertices);
285 if(!eleVertex) continue;
287 if(*eleVertex == vertex){
288 elLink.setElement(electron);
289 elLink.setStorableObject(*electronsIn.ptr(), true);
290 electronLinks.push_back(elLink);
291 }
292 }
293 dec_electronLinks(*vertex) = electronLinks;
294
295 std::vector<ElementLink<xAOD::PhotonContainer>> photonLinks;
296 for(const xAOD::Photon* photon : *photonsIn){
298 phLink.setElement(photon);
299 phLink.setStorableObject(*photonsIn.ptr(), true);
300 photonLinks.push_back(phLink);
301 }
302 dec_photonLinks(*vertex) = photonLinks;
303
304 // for jets, use prefilled map
305 dec_jetLinks(*vertex) = jetsInVertex[vertex];
306
307 std::vector<ElementLink<xAOD::MuonContainer>> muonLinks;
308 for(const xAOD::Muon* muon : *muonsIn){
309 const auto *tp = muon->trackParticle(xAOD::Muon::InnerDetectorTrackParticle);
310 if(!tp) continue;
311 try{
312 auto muonVertex = m_trkVtxAssociationTool->getUniqueMatchVertexLink(*tp, *vertices);
313 if(!muonVertex) continue;
315 if(*muonVertex == vertex){
316 muonLink.setElement(muon);
317 muonLink.setStorableObject(*muonsIn.ptr(), true);
318 muonLinks.push_back(muonLink);
319 }
320 }catch(...) {
321 ATH_MSG_DEBUG("Skipping muon as the track is not associated to any PV ");
322 ATH_MSG_DEBUG("Muon pT, eta = " << muon->pt() << " " << muon->eta());
323 }
324
325 }
326 dec_muonLinks(*vertex) = muonLinks;
327
328 // Finally, decorate the vertices with the GNN score
329 m_gnnTool->decorate(*vertex);
330 }
331
332 return StatusCode::SUCCESS;
333 }
334
335} // namespace InDetGNNHardScatterSelection
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Handle class for reading a decoration on an object.
Handle class for adding a decoration to an object.
DataVector adapter that acts like it holds const pointers.
AthHistogramAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
SG::WriteDecorHandleKey< xAOD::VertexContainer > m_mDecor_photon_deltaPhi
SG::WriteDecorHandleKey< xAOD::VertexContainer > m_mDecor_z_skew
SG::WriteDecorHandleKey< xAOD::VertexContainer > m_muonLinksKey
SG::WriteDecorHandleKey< xAOD::VertexContainer > m_mDecor_sumPt
SG::WriteDecorHandleKey< xAOD::VertexContainer > m_mDecor_chi2Over_ndf
SG::ReadDecorHandleKey< xAOD::VertexContainer > m_deltaZKey
SG::WriteDecorHandleKey< xAOD::VertexContainer > m_photonLinksKey
SG::ReadHandleKey< xAOD::MuonContainer > m_muonsInKey
SG::WriteDecorHandleKey< xAOD::VertexContainer > m_mDecor_weighted_z_asym
SG::ReadDecorHandleKey< xAOD::PhotonContainer > m_zCommonKey
SG::WriteDecorHandleKey< xAOD::VertexContainer > m_electronLinksKey
SG::ReadHandleKey< xAOD::EventInfo > m_eventInKey
SG::WriteDecorHandleKey< xAOD::VertexContainer > m_mDecor_ntrk
SG::WriteDecorHandleKey< xAOD::VertexContainer > m_mDecor_actualInterPerXing
ToolHandle< CP::TrackVertexAssociationTool > m_trkVtxAssociationTool
SG::ReadDecorHandleKey< xAOD::VertexContainer > m_deltaPhiKey
SG::WriteDecorHandleKey< xAOD::VertexContainer > m_mDecor_weighted_z_kurt
SG::ReadDecorHandleKey< xAOD::PhotonContainer > m_zCommonErrorKey
SG::WriteDecorHandleKey< xAOD::VertexContainer > m_mDecor_photon_deltaz
SG::ReadDecorHandleKey< xAOD::PhotonContainer > m_caloPointingZKey
SG::WriteDecorHandleKey< xAOD::VertexContainer > m_mDecor_z_asym
SG::ReadHandleKey< xAOD::VertexContainer > m_vertexInKey
SG::ReadHandleKey< xAOD::PhotonContainer > m_photonsInKey
SG::WriteDecorHandleKey< xAOD::VertexContainer > m_jetLinksKey
SG::ReadHandleKey< xAOD::ElectronContainer > m_electronsInKey
SG::ReadHandleKey< xAOD::JetContainer > m_jetsInKey
Handle class for reading a decoration on an object.
bool isAvailable()
Test to see if this variable exists in the store, for the referenced object.
const_pointer_type ptr()
Dereference the pointer.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Handle class for adding a decoration to an object.
bool isAvailable()
Test to see if this variable exists in the store, for the referenced object.
float z0() const
Returns the parameter.
float vz() const
The z origin for the parameters.
const xAOD::TrackParticle * getOriginalTrackParticle(const xAOD::Electron *el)
Helper function for getting the "Original" Track Particle (i.e before GSF) via the electron.
float getVertexSumPt(const xAOD::Vertex *vertex, int power=1, bool useAux=true)
Loop over track particles associated with vertex and return scalar sum of pT^power in GeV (from auxda...
@ NoVtx
Dummy vertex. TrackParticle was not used in vertex fit.
Jet_v1 Jet
Definition of the current "jet version".
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Vertex_v1 Vertex
Define the latest version of the vertex class.
Muon_v1 Muon
Reference the current persistent version:
Photon_v1 Photon
Definition of the current "egamma version".
Electron_v1 Electron
Definition of the current "egamma version".