43 {
44
46
47
49 static const xAOD::Vertex::Decorator<int> recoMatchTypeDecor("vertexMatchType");
51
52 static const xAOD::Vertex::Decorator<int> smOriginDecor("vertexMatchOriginType");
53
54 const xAOD::Vertex::Decorator<float> fakeScoreDecor("fakeScore");
55 const xAOD::Vertex::Decorator<float> otherScoreDecor("otherScore");
56
57
58
62 xAOD::TrackParticle::ConstAccessor<float> trk_truthProbAcc("truthMatchProbability");
63
65
66
67
68
69
71
72
73 std::vector<VertexTruthMatchInfo> matchinfo;
74
76 size_t ntracks = trackParticles.size();
77 const std::vector<float> & trkWeights = weightAcc( *vtx );
78
80
81
83
85
86
87
89
90 trkMuSATrkParts.reserve(ntracks);
91 for (const auto& trkLink : trackParticles) {
92 if (!trkLink.isValid()) continue;
94 if (acc_MSTPLink.isAvailable(trackParticle)) {
95 const ElementLink<xAOD::TrackParticleContainer>& trkMuSATrkLink = acc_MSTPLink(trackParticle);
97 trkMuSATrkParts.push_back(trkMuSATrkLink);
98 } else {
100 }
101 } else {
102 ATH_MSG_WARNING(
"MuSATrk_MSTPLink decoration is not available on track particle");
103 }
104 }
105 }
106
107
108 if ((!trkAcc.isAvailable(*vtx) || !weightAcc.isAvailable(*vtx)) && !
m_doMuSA) {
109 ATH_MSG_WARNING(
"trackParticles or trackWeights not available, vertex is missing info");
110 continue;
111 }
112 if ( trkWeights.size() != ntracks ) {
113 ATH_MSG_WARNING(
"Vertex without same number of tracks and trackWeights, vertex is missing info");
114 continue;
115 }
116
117 ATH_MSG_DEBUG(
"Matching new vertex at (" << vtx->x() <<
", " << vtx->y() <<
", " << vtx->z() <<
")" <<
" with " << ntracks <<
" tracks, at index: " << vtx->index());
118
119 float totalWeight = 0.;
120 float totalPt = 0;
121 float otherPt = 0;
122 float fakePt = 0;
123
124
125 int combinedSMOrigin = 0;
126
127
128 for (
size_t t = 0;
t < ntracks; ++
t ) {
129
131
132
133 if (!trackParticles[t].
isValid()) {
135 continue;
136 }
137
138
139 if (t >= trkParts.size() || !trkParts[t].isValid()) {
140 ATH_MSG_DEBUG(
"Track " << t <<
" is invalid or out of bounds in trkParts!");
141 continue;
142 }
144
145
147 totalWeight += 1.0;
148 } else {
149 totalWeight += trkWeights[
t];
150 }
151
152
153 float trkPt = 0;
154 try {
156 totalPt += trkPt;
157 } catch (const std::exception& e) {
159 continue;
160 }
161
162
163 if (!trk_truthPartAcc.isAvailable(trk)) {
164 ATH_MSG_DEBUG(
"The truth particle link decoration isn't available.");
165 continue;
166 }
167 const ElementLink<xAOD::TruthParticleContainer> & truthPartLink = trk_truthPartAcc(trk);
170
173 } else {
174
175 prob = trk_truthProbAcc(trk);
177 }
178
179
182
183 const int ancestorVertexUniqueID =
checkProduction(truthPart, truthVerticesToMatch);
184
187 combinedSMOrigin |= smOrigin;
188
189
192 }
193 }
194
195
197
198
199 auto it = std::find_if(truthVerticesToMatch.begin(), truthVerticesToMatch.end(),
200 [&](const auto& ele){ return HepMC::uniqueID(ele) == ancestorVertexUniqueID;} );
201
202 if (it == truthVerticesToMatch.end()) {
203 ATH_MSG_WARNING(
"Truth vertex with unique ID " << ancestorVertexUniqueID <<
" not found!");
204 } else {
205 ElementLink<xAOD::TruthVertexContainer> elLink;
208 size_t matchIdx = indexOfMatchInfo(matchinfo, elLink);
209
211 std::get<1>(matchinfo[matchIdx]) += 1.0;
212 } else {
213 std::get<1>(matchinfo[matchIdx]) += trkWeights[
t];
214 }
215 std::get<2>(matchinfo[matchIdx]) += trk.
pt();
216 }
217 } else {
218
221 }
222 } else {
223
226
229 }
230 }
231 }
232
233
235 {
236 std::get<1>(link) /= totalWeight;
237 std::get<2>(link) /= totalPt;
238 });
239
240 float fakeScore = fakePt/totalPt;
241 float otherScore = otherPt/totalPt;
242
243 matchInfoDecor ( *vtx ) = matchinfo;
244 fakeScoreDecor ( *vtx ) = fakeScore;
245 otherScoreDecor( *vtx ) = otherScore;
246
247
249 smOriginDecor( *vtx ) = combinedSMOrigin;
250 }
251 }
252
253
254
255
256
257 std::vector<bool> assignedType( recoVerticesToMatch.size(), false );
258 static const xAOD::TruthVertex::Decorator<bool>
isMatched(
"matchedToRecoVertex");
259 static const xAOD::TruthVertex::Decorator<bool>
isSplit(
"vertexSplit");
260
261 for (
size_t i = 0;
i < recoVerticesToMatch.size(); ++
i ) {
262
263 int recoVertexMatchType = 0;
264
265 if ( assignedType[i] ) {
267 continue;
268 }
269
270 std::vector<VertexTruthMatchInfo> &
info = matchInfoDecor( *recoVerticesToMatch[i] );
271 float fakeScore = fakeScoreDecor( *recoVerticesToMatch[i] );
272
276 }
else if (
info.size() == 1) {
278 ATH_MSG_DEBUG(
"One true decay vertices matched with sufficient weight. Vertex is matched.");
280 isMatched(**std::get<0>(info[0])) =
true;
281 }
282 else {
283 ATH_MSG_DEBUG(
"One true decay vertices matched with insufficient weight. Vertex is other.");
285 }
286 }
else if (
info.size() >= 2 ) {
287 ATH_MSG_DEBUG(
"Multiple true decay vertices matched. Vertex is merged.");
290 {
291 isMatched(**std::get<0>(link)) = true;
292 });
293 } else {
294 ATH_MSG_DEBUG(
"Vertex is neither fake nor LLP. Marking as OTHER.");
296 }
297
298 recoMatchTypeDecor(*recoVerticesToMatch[i]) = recoVertexMatchType;
299
300
303 std::vector<size_t> foundSplits;
304 for ( size_t j = i + 1; j < recoVerticesToMatch.size(); ++j ) {
305 std::vector<VertexTruthMatchInfo> & info2 = matchInfoDecor( *recoVerticesToMatch[j] );
306
307
308
310 if (!info2.empty() && std::get<0>(info2[0]).isValid() && std::get<0>(info[0]).key() == std::get<0>(info2[0]).key() && std::get<0>(info[0]).index() == std::get<0>(info2[0]).index() ) {
311
312 ElementLink<xAOD::VertexContainer> splitLink_ij;
313 splitLink_ij.
setElement( recoVerticesToMatch[j] );
315 splitPartnerDecor( *recoVerticesToMatch[i] ).emplace_back(splitLink_ij);
316
317 ElementLink<xAOD::VertexContainer> splitLink_ji;
318 splitLink_ji.
setElement( recoVerticesToMatch[i] );
320 splitPartnerDecor( *recoVerticesToMatch[j] ).emplace_back(splitLink_ji);
321
322
323 for ( auto k : foundSplits ) {
324 ElementLink<xAOD::VertexContainer> splitLink_kj;
325 splitLink_kj.
setElement( recoVerticesToMatch[j] );
327 splitPartnerDecor( *recoVerticesToMatch[k] ).emplace_back(splitLink_kj);
328
329 ElementLink<xAOD::VertexContainer> splitLink_jk;
330 splitLink_jk.
setElement( recoVerticesToMatch[k] );
332 splitPartnerDecor( *recoVerticesToMatch[j] ).emplace_back(splitLink_jk);
333 }
334
335 foundSplits.push_back(j);
338 isSplit(**std::get<0>(info[0])) =
true;
339 assignedType[j] = true;
340 }
341 }
342 }
343
344 }
345
346
347
349
350 static const xAOD::TruthVertex::Decorator<int> truthMatchTypeDecor("truthVertexMatchType");
351
353
354 std::vector<const xAOD::TruthParticle*> reconstructibleParticles;
357
358
359 std::vector<int> particleInfo = {0,0,0};
360 std::vector<int> vertexInfo = {0,0,0};
361
362 for(
size_t n = 0;
n < reconstructibleParticles.size();
n++){
365
366 if (trackParticles){
368
369 for(
size_t h = 0;
h < particleInfo.size();
h++){
370 vertexInfo.at(h) += particleInfo.at(h);
371 }
372 }
373 }
374
375 int truthMatchType = 0;
376 if( vertexInfo.at(0) > 1 &&
377 ((
m_doMuSA && truthVtx->perp() < 8000 && std::abs(truthVtx->z()) < 10000) ||
378 (!
m_doMuSA && truthVtx->perp() < 320 && std::abs(truthVtx->z()) < 1500))){
379 ATH_MSG_DEBUG(
"Vertex is reconstructable and in " << (
m_doMuSA ?
"Muon Spectrometer" :
"Inner Det") <<
" region");
381 }
385 }
387 ATH_MSG_DEBUG(
"Vertex is has at least two tracks passing track selection: " << vertexInfo.at(2));
389 }
391 ATH_MSG_DEBUG(
"Vertex is matched to a reconstructed secVtx");
393 }
397 }
398 truthMatchTypeDecor(*truthVtx) = truthMatchType;
399 }
401
402 return StatusCode::SUCCESS;
403
404}
bool isValid(const T &p)
Av: we implement here an ATLAS-sepcific convention: all particles which are 99xxxxx are fine.
bool setElement(ElementType element)
Set to point to an element.
bool setStorableObject(BaseConstReference data, bool replace=false, IProxyDict *sg=0)
Set link to point to a new container (storable).
SG::Accessor< T, ALLOC > Accessor
SG::Decorator< T, ALLOC > Decorator
class to provide type-safe access to aux data.
virtual double pt() const override final
The transverse momentum ( ) of the particle.
std::vector< ElementLink< xAOD::TrackParticleContainer > > TrackParticleLinks_t
Type for the associated track particles.
bool isSeeded(int matchInfo)
bool isSplit(int matchInfo)
std::tuple< ElementLink< xAOD::TruthVertexContainer >, float, float > VertexTruthMatchInfo
bool isReconstructable(int matchInfo)
bool isMatched(int matchInfo)
bool isAccepted(int matchInfo)
bool isMerged(int matchInfo)
TruthVertexContainer_v1 TruthVertexContainer
Declare the latest version of the truth vertex container.
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
Vertex_v1 Vertex
Define the latest version of the vertex class.