52 {
53
55
65 return StatusCode::FAILURE;
66 }
67 } else {
69 return StatusCode::FAILURE;
70 }
71 }
72 }
73
74
76 static const xAOD::Vertex::Decorator<int> recoMatchTypeDecor("vertexMatchType");
78
79 static const xAOD::Vertex::Decorator<int> smOriginDecor("vertexMatchOriginType");
80
81 const xAOD::Vertex::Decorator<float> fakeScoreDecor("fakeScore");
82 const xAOD::Vertex::Decorator<float> otherScoreDecor("otherScore");
83
84
85
89 xAOD::TrackParticle::ConstAccessor<float> trk_truthProbAcc("truthMatchProbability");
90
92
93
94
95
96
98
99
100 std::vector<VertexTruthMatchInfo> matchinfo;
101
103 size_t ntracks = trackParticles.size();
104 const std::vector<float> & trkWeights = weightAcc( *vtx );
105
107
108
110
112
113
114
116
117 trkMuSATrkParts.reserve(ntracks);
118 for (const auto& trkLink : trackParticles) {
119 if (!trkLink.isValid()) continue;
121 if (acc_MSTPLink.isAvailable(trackParticle)) {
122 const ElementLink<xAOD::TrackParticleContainer>& trkMuSATrkLink = acc_MSTPLink(trackParticle);
123 if (trkMuSATrkLink.
isValid()) {
124 trkMuSATrkParts.push_back(trkMuSATrkLink);
125 } else {
127 }
128 } else {
129 ATH_MSG_WARNING(
"MuSATrk_MSTPLink decoration is not available on track particle");
130 }
131 }
132 }
133
134
135 if ((!trkAcc.isAvailable(*vtx) || !weightAcc.isAvailable(*vtx)) && !
m_doMuSA) {
136 ATH_MSG_WARNING(
"trackParticles or trackWeights not available, vertex is missing info");
137 continue;
138 }
139 if ( trkWeights.size() != ntracks ) {
140 ATH_MSG_WARNING(
"Vertex without same number of tracks and trackWeights, vertex is missing info");
141 continue;
142 }
143
144 ATH_MSG_DEBUG(
"Matching new vertex at (" << vtx->x() <<
", " << vtx->y() <<
", " << vtx->z() <<
")" <<
" with " << ntracks <<
" tracks, at index: " << vtx->index());
145
146 float totalWeight = 0.;
147 float totalPt = 0;
148 float otherPt = 0;
149 float fakePt = 0;
150
151
152 int combinedSMOrigin = 0;
153
154
155 for (
size_t t = 0;
t < ntracks; ++
t ) {
156
158
159
160 if (!trackParticles[t].
isValid()) {
162 continue;
163 }
164
165
166 if (t >= trkParts.size() || !trkParts[t].isValid()) {
167 ATH_MSG_DEBUG(
"Track " << t <<
" is invalid or out of bounds in trkParts!");
168 continue;
169 }
171
172
174 totalWeight += 1.0;
175 } else {
176 totalWeight += trkWeights[
t];
177 }
178
179
180 float trkPt = 0;
181 try {
183 totalPt += trkPt;
184 } catch (const std::exception& e) {
186 continue;
187 }
188
189
190 if (!trk_truthPartAcc.isAvailable(trk)) {
191 ATH_MSG_DEBUG(
"The truth particle link decoration isn't available.");
192 continue;
193 }
194 const ElementLink<xAOD::TruthParticleContainer> & truthPartLink = trk_truthPartAcc(trk);
197
200 } else {
201
202 prob = trk_truthProbAcc(trk);
204 }
205
206
209
210 const int ancestorVertexUniqueID =
checkProduction(truthPart, truthVerticesToMatch);
211
214 combinedSMOrigin |= smOrigin;
215
216
219 }
220 }
221
222
224
225
226 auto it = std::find_if(truthVerticesToMatch.begin(), truthVerticesToMatch.end(),
227 [&](const auto& ele){ return HepMC::uniqueID(ele) == ancestorVertexUniqueID;} );
228
229 if (it == truthVerticesToMatch.end()) {
230 ATH_MSG_WARNING(
"Truth vertex with unique ID " << ancestorVertexUniqueID <<
" not found!");
231 } else {
232 ElementLink<xAOD::TruthVertexContainer> elLink;
235 size_t matchIdx = indexOfMatchInfo(matchinfo, elLink);
236
238 std::get<1>(matchinfo[matchIdx]) += 1.0;
239 } else {
240 std::get<1>(matchinfo[matchIdx]) += trkWeights[
t];
241 }
242 std::get<2>(matchinfo[matchIdx]) += trk.
pt();
243 }
244 } else {
245
248 }
249 } else {
250
253
256 }
257 }
258 }
259
260
262 {
263 std::get<1>(link) /= totalWeight;
264 std::get<2>(link) /= totalPt;
265 });
266
267 float fakeScore = fakePt/totalPt;
268 float otherScore = otherPt/totalPt;
269
270 matchInfoDecor ( *vtx ) = matchinfo;
271 fakeScoreDecor ( *vtx ) = fakeScore;
272 otherScoreDecor( *vtx ) = otherScore;
273
274
276 smOriginDecor( *vtx ) = combinedSMOrigin;
277 }
278 }
279
280
281
282
283
284 std::vector<bool> assignedType( recoVerticesToMatch.size(), false );
285 static const xAOD::TruthVertex::Decorator<bool>
isMatched(
"matchedToRecoVertex");
286 static const xAOD::TruthVertex::Decorator<bool>
isSplit(
"vertexSplit");
287
288 for (
size_t i = 0;
i < recoVerticesToMatch.size(); ++
i ) {
289
290 int recoVertexMatchType = 0;
291
292 if ( assignedType[i] ) {
294 continue;
295 }
296
297 std::vector<VertexTruthMatchInfo> &
info = matchInfoDecor( *recoVerticesToMatch[i] );
298 float fakeScore = fakeScoreDecor( *recoVerticesToMatch[i] );
299
303 }
else if (
info.size() == 1) {
305 ATH_MSG_DEBUG(
"One true decay vertices matched with sufficient weight. Vertex is matched.");
307 isMatched(**std::get<0>(info[0])) =
true;
308 }
309 else {
310 ATH_MSG_DEBUG(
"One true decay vertices matched with insufficient weight. Vertex is other.");
312 }
313 }
else if (
info.size() >= 2 ) {
314 ATH_MSG_DEBUG(
"Multiple true decay vertices matched. Vertex is merged.");
317 {
318 isMatched(**std::get<0>(link)) = true;
319 });
320 } else {
321 ATH_MSG_DEBUG(
"Vertex is neither fake nor LLP. Marking as OTHER.");
323 }
324
325 recoMatchTypeDecor(*recoVerticesToMatch[i]) = recoVertexMatchType;
326
327
330 std::vector<size_t> foundSplits;
331 for (
size_t j = i + 1;
j < recoVerticesToMatch.size(); ++
j ) {
332 std::vector<VertexTruthMatchInfo> & info2 = matchInfoDecor( *recoVerticesToMatch[j] );
333
334
335
337 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() ) {
338
339 ElementLink<xAOD::VertexContainer> splitLink_ij;
340 splitLink_ij.
setElement( recoVerticesToMatch[j] );
342 splitPartnerDecor( *recoVerticesToMatch[i] ).emplace_back(splitLink_ij);
343
344 ElementLink<xAOD::VertexContainer> splitLink_ji;
345 splitLink_ji.
setElement( recoVerticesToMatch[i] );
347 splitPartnerDecor( *recoVerticesToMatch[j] ).emplace_back(splitLink_ji);
348
349
350 for ( auto k : foundSplits ) {
351 ElementLink<xAOD::VertexContainer> splitLink_kj;
352 splitLink_kj.
setElement( recoVerticesToMatch[j] );
354 splitPartnerDecor( *recoVerticesToMatch[k] ).emplace_back(splitLink_kj);
355
356 ElementLink<xAOD::VertexContainer> splitLink_jk;
357 splitLink_jk.
setElement( recoVerticesToMatch[k] );
359 splitPartnerDecor( *recoVerticesToMatch[j] ).emplace_back(splitLink_jk);
360 }
361
362 foundSplits.push_back(j);
365 isSplit(**std::get<0>(info[0])) =
true;
366 assignedType[
j] =
true;
367 }
368 }
369 }
370
371 }
372
373
374
376
377 static const xAOD::TruthVertex::Decorator<int> truthMatchTypeDecor("truthVertexMatchType");
378
380
381 std::vector<const xAOD::TruthParticle*> reconstructibleParticles;
384
385
386 std::vector<int> particleInfo = {0,0,0};
387 std::vector<int> vertexInfo = {0,0,0};
388
389 for(
size_t n = 0;
n < reconstructibleParticles.size();
n++){
392
393 if (trackParticles){
395
396 for(
size_t h = 0;
h < particleInfo.size();
h++){
397 vertexInfo.at(h) += particleInfo.at(h);
398 }
399 }
400 }
401
402 int truthMatchType = 0;
403 if( vertexInfo.at(0) > 1 &&
404 ((
m_doMuSA && (truthVtx->perp() < 8000 && std::abs(truthVtx->z()) < 10000)) ||
405 (!
m_doMuSA && truthVtx->perp() < 320 && std::abs(truthVtx->z()) < 1500))){
406 ATH_MSG_DEBUG(
"Vertex is reconstructable and in " << (
m_doMuSA ?
"Muon Spectrometer" :
"Inner Det") <<
" region");
408 }
412 }
414 ATH_MSG_DEBUG(
"Vertex is has at least two tracks passing track selection: " << vertexInfo.at(2));
416 }
418 ATH_MSG_DEBUG(
"Vertex is matched to a reconstructed secVtx");
420 }
424 }
425 truthMatchTypeDecor(*truthVtx) = truthMatchType;
426 }
428
429 return StatusCode::SUCCESS;
430
431}
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)
float j(const xAOD::IParticle &, const xAOD::TrackMeasurementValidation &hit, const Eigen::Matrix3d &jab_inv)
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.
MuonContainer_v1 MuonContainer
Definition of the current "Muon container version".