136 {
137
139 if (vxContainer.
empty() ||
142 return StatusCode::SUCCESS;
143 }
144
148 else
150
151 std::vector<const xAOD::TruthEventBaseContainer *> truthContainers;
152 truthContainers.push_back( truthEvents );
153
155
156
160 if (truthPileup)
161 truthContainers.push_back( truthPileup );
162
164
165
166
168 if (!tkContainer)
169 {
170 ATH_MSG_WARNING(
"Vertex container has no vertices with valid TrackParticle links");
171 return StatusCode::SUCCESS;
172 }
173
175
176
177
178 createTrackTruthMap( truthContainers, *tkContainer,
m_trkMatchProb );
179
180
182
183
188 static const xAOD::Vertex::Decorator<int> nHSTrkDecor("nHSTrk");
189
190
191
194
196 xAOD::TrackParticle::ConstAccessor<float> trk_truthProbAcc("truthMatchProbability");
197
199 static const xAOD::TrackParticle::Decorator<float> trk_wtVtx("WeightVertex");
200
201
202 size_t ntracks;
204
206
207
208
209
210
211 size_t vxEntry = 0;
212 unsigned int n_bad_links = 0;
213 unsigned int n_links = 0;
214 unsigned int n_vx_with_bad_links = 0;
215
216 for (
auto vxit : vxContainer.
stdcont() ) {
217 vxEntry++;
220
221
223 continue;
224 }
225
226
227
228 std::vector<VertexTruthMatchInfo> matchinfo;
229 std::vector<VertexTruthMatchInfo> rawMatchinfo;
230
231
232 if (!trkAcc.isAvailable(*vxit) || !weightAcc.isAvailable(*vxit) ) {
233 ATH_MSG_DEBUG(
"trackParticles or trackWeights not available, setting fake");
234
235 matchinfo.emplace_back( ElementLink<xAOD::TruthEventBaseContainer>(), 1., 0. );
236 matchInfoDecor( *vxit ) = matchinfo;
237 rawMatchinfo.emplace_back( ElementLink<xAOD::TruthEventBaseContainer>(), 1., 0. );
238 rawMatchInfoDecor( *vxit ) = rawMatchinfo;
239 nHSTrkDecor( *vxit ) = 0;
240 continue;
241 }
242
243
245 ntracks = trkParts.size();
246 const std::vector<float> & trkWeights = weightAcc( *vxit );
247
248
249 if ( trkWeights.size() != ntracks ) {
250 ATH_MSG_DEBUG(
"Vertex without same number of tracks and trackWeights, setting fake");
251 matchinfo.emplace_back( ElementLink<xAOD::TruthEventBaseContainer>(), 1., 0. );
252 matchInfoDecor( *vxit ) = matchinfo;
253 rawMatchinfo.emplace_back( ElementLink<xAOD::TruthEventBaseContainer>(), 1., 0. );
254 rawMatchInfoDecor( *vxit ) = rawMatchinfo;
255 nHSTrkDecor( *vxit ) = 0;
256 continue;
257 }
258
259 ATH_MSG_DEBUG(
"Matching new vertex at (" << vxit->x() <<
", " << vxit->y() <<
", " << vxit->z() <<
")" <<
" with " << ntracks <<
" tracks, at index: " << vxit->index());
260
261 float totalWeight = 0.;
262 float totalFake = 0.;
263 int nHSTrk = 0;
264
265 unsigned vx_n_bad_links = 0;
266
267 for (
size_t t = 0;
t < ntracks; ++
t ) {
269 ++vx_n_bad_links;
270 continue;
271 }
273
274 totalWeight += trkWeights[
t];
275 trk_recoVtx(trk) = ElementLink<xAOD::VertexContainer>(vxContainer, vxEntry - 1);
276 trk_wtVtx(trk) = trkWeights[
t];
277
278 const ElementLink<xAOD::TruthParticleContainer> & truthPartLink = trk_truthPartAcc( trk );
279 float prob = trk_truthProbAcc( trk );
280
281 if (!truthPartLink.
isValid())
continue;
282
285
286 if (
pass( truthPart) ) {
287 ElementLink<xAOD::TruthEventBaseContainer>
match = backLinkDecor( truthPart );
288
289 if (
match.isValid() ) {
290 size_t matchIdx = indexOfMatchInfo( matchinfo,
match );
291 std::get<1>(matchinfo[matchIdx]) += trkWeights[
t];
292 std::get<2>(matchinfo[matchIdx]) += (trk.
pt()/1000.) * (trk.
pt()/1000.) * trkWeights[
t];
293 matchIdx = indexOfMatchInfo( rawMatchinfo,
match );
294 std::get<1>(rawMatchinfo[matchIdx]) += trkWeights[
t];
295 std::get<2>(rawMatchinfo[matchIdx]) += (trk.
pt()/1000.) * (trk.
pt()/1000.) * trkWeights[
t];
297 } else {
298 totalFake += trkWeights[
t];
299 }
300
301 } else {
302
303 totalFake += trkWeights[
t];
304 }
305 } else {
306
307 totalFake += trkWeights[
t];
308 }
309 }
310 n_links += ntracks;
311 n_bad_links += vx_n_bad_links;
312 if (vx_n_bad_links>0) {
313 ++n_vx_with_bad_links;
314 }
315
316
317 if ( totalWeight < 1e-12 ) {
318 ATH_MSG_DEBUG(
" Declaring vertex fully fake (no passing tracks included)");
319 totalWeight = 1.;
320 totalFake = 1.;
321 }
322 if ( totalFake > 0. )
323 {
324 matchinfo.emplace_back( ElementLink<xAOD::TruthEventBaseContainer>(), totalFake, 0. );
325 rawMatchinfo.emplace_back( ElementLink<xAOD::TruthEventBaseContainer>(), totalFake, 0. );
326 }
327
328 for ( auto & mit : matchinfo ) {
329 std::get<1>(mit) /= totalWeight;
330 }
331 std::sort( matchinfo.begin(), matchinfo.end(), compareMatchPair );
332 std::sort( rawMatchinfo.begin(), rawMatchinfo.end(), compareMatchPair );
333 matchInfoDecor( *vxit ) = matchinfo;
334 rawMatchInfoDecor( *vxit ) = rawMatchinfo;
335 nHSTrkDecor( *vxit ) = nHSTrk;
336 }
341
342
343
344
345
346
347 std::vector<bool> assignedType( vxContainer.
size(),
false );
348
349 for (
size_t i = 0;
i < vxContainer.
size(); ++
i ) {
350
351 if ( assignedType[i] ) continue;
352
353 std::vector<VertexTruthMatchInfo> &
info = matchInfoDecor( *vxContainer[i] );
355 matchTypeDecor( *vxContainer[i] ) =
DUMMY;
356 }
else if ( !std::get<0>(info[0]).
isValid() ) {
357 matchTypeDecor( *vxContainer[i] ) =
FAKE;
359 matchTypeDecor( *vxContainer[i] ) =
MATCHED;
360 } else {
361 matchTypeDecor( *vxContainer[i] ) =
MERGED;
362 }
363
364
365 if ( matchTypeDecor( *vxContainer[i] ) ==
MATCHED || matchTypeDecor( *vxContainer[i] ) ==
MERGED ) {
366 std::vector<size_t> foundSplits;
367 for (
size_t j = i + 1; j < vxContainer.
size(); ++j ) {
368 std::vector<VertexTruthMatchInfo> & info2 = matchInfoDecor( *vxContainer[j] );
369
370
371
372 if (matchTypeDecor( *vxContainer[j] ) ==
FAKE || matchTypeDecor( *vxContainer[j] ) ==
DUMMY)
continue;
373 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() ) {
374
375 splitPartnerDecor( *vxContainer[i] ).emplace_back( vxContainer, j );
376 splitPartnerDecor( *vxContainer[j] ).emplace_back( vxContainer, i );
377
378 for ( auto k : foundSplits ) {
379 splitPartnerDecor( *vxContainer[k] ).emplace_back( vxContainer, j );
380 splitPartnerDecor( *vxContainer[j] ).emplace_back( vxContainer, k );
381 }
382
383 foundSplits.push_back(j);
384 }
385 }
386
387
388 float maxSumpT2 = std::get<2>( matchInfoDecor( *vxContainer[i] )[0] );
389 size_t indexOfMax =
i;
390 for ( auto l : foundSplits ) {
391 if ( std::get<2>( matchInfoDecor( *vxContainer[l] )[0] ) > maxSumpT2 ){
392 maxSumpT2 = std::get<2>( matchInfoDecor( *vxContainer[l] )[0] );
394 } else {
395 matchTypeDecor( *vxContainer[l] ) =
SPLIT;
396 assignedType[
l] =
true;
397 }
398 }
399 if ( indexOfMax!=i ) matchTypeDecor( *vxContainer[i] ) =
SPLIT;
400 }
401 }
402
403
405 for (
const auto &vxit : vxContainer.
stdcont() ) {
406 ATH_MSG_DEBUG(
"Matched vertex (index " << (*vxit).index() <<
") to type " << matchTypeDecor(*vxit) <<
" with following info of size " << matchInfoDecor(*vxit).size() <<
":");
407 for (const auto &vit : matchInfoDecor(*vxit) ) {
408 if ( std::get<0>(vit).
isValid() ) {
409 ATH_MSG_DEBUG(
" GenEvent type " << (* std::get<0>(vit))->
type() <<
", index " << std::get<0>(vit).
index() <<
" with relative weight " << std::get<1>(vit) );
410 } else {
411 ATH_MSG_DEBUG(
" Fakes with relative weight " << std::get<1>(vit) );
412 }
413 }
414 if (matchTypeDecor(*vxit) ==
SPLIT) {
416 for (
const auto &
split : splitPartnerDecor( *vxit ) ) {
417 if (
split.isValid() )
419 else
421 }
422 }
423 }
424 }
425
426 return StatusCode::SUCCESS;
427
428}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
bool isValid(const T &p)
Av: we implement here an ATLAS-sepcific convention: all particles which are 99xxxxx are fine.
bool msgLvl(const MSG::Level lvl) const
const T * at(size_type n) const
Access an element, as an rvalue.
const PtrVector & stdcont() const
Return the underlying std::vector of the container.
size_type size() const noexcept
Returns the number of elements in the collection.
bool empty() const noexcept
Returns true if the collection is empty.
bool isValid() const
Test to see if the link can be dereferenced.
bool pass(const xAOD::TruthParticle &truthPart) const
static const xAOD::TrackParticleContainer * findTrackParticleContainer(const xAOD::VertexContainer &vxContainer)
SG::Decorator< T, ALLOC > Decorator
class to provide type-safe access to aux data.
SG::ConstAccessor< T, ALLOC > ConstAccessor
Helper 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.
VxType::VertexType vertexType() const
The type of the vertex.
bool contains(const std::string &s, const std::string ®x)
does a string contain the substring
std::vector< std::string > split(const std::string &s, const std::string &t=":")
bool match(std::string s1, std::string s2)
match the individual directories of two strings
l
Printing final latex table to .tex output file.
retrieve(aClass, aKey=None)
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
@ TruthEvent
The object is a truth event.
@ NoVtx
Dummy vertex. TrackParticle was not used in vertex fit.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
TruthEventBaseContainer_v1 TruthEventBaseContainer
Declare the latest version of the truth event container.
TruthParticle_v1 TruthParticle
Typedef to implementation.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".