22   return StatusCode::SUCCESS;
 
   30   return StatusCode::SUCCESS;
 
   47 void createTruthMap(
const std::vector<const xAOD::TruthEventBaseContainer *> & truthEventContainers ) {
 
   51   for ( 
auto cit : truthEventContainers ) {
 
   55     for ( 
size_t i = 0; 
i < truthEvents.
size(); ++
i) {
 
   57       for ( 
auto & tkit : truthEvents[
i]->truthParticleLinks() ) { 
 
   61         if (elLink.
isValid() && tkit.isValid()) {
 
   62           backLinkDecor(**tkit) = elLink;
 
   73 void createTrackTruthMap(
const std::vector<const xAOD::TruthEventBaseContainer *> & truthEventContainers,
 
   78   createTruthMap(truthEventContainers);
 
   86   for (
auto trk : trackParticleContainer)
 
   89       if (trk_truthPartAcc.isAvailable(*trk) && trk_truthProbAcc.isAvailable(*trk)
 
   90           && trk_truthPartAcc(*trk).isValid() && trk_truthProbAcc(*trk) >= matchCut)
 
   92         const auto& truthParticle = trk_truthPartAcc(*trk);
 
   93         if (backLinkDecor.isAvailable(**truthParticle) && backLinkDecor(**truthParticle).isValid())
 
   95           trackLinkDecor(*trk) = backLinkDecor(**truthParticle);
 
  104   for ( 
size_t i = 0; 
i < matches.size(); ++
i ) {
 
  105     if ( link.
key() == std::get<0>(matches[
i]).key() && link.
index() == std::get<0>(matches[
i]).index() )
 
  109   matches.emplace_back( link, 0., 0. );
 
  110   return matches.size() - 1;
 
  123   for (
auto vtx : vxContainer)
 
  127       if (tpLink.isValid())
 
  129         return tpLink.getStorableObjectPointer();
 
  139   if (vxContainer.
empty() ||   
 
  142     return StatusCode::SUCCESS;
 
  146   if ( 
evtStore()->contains<xAOD::TruthEventBaseContainer>( 
"TruthEvents" ) )
 
  151   std::vector<const xAOD::TruthEventBaseContainer *> truthContainers;
 
  152   truthContainers.push_back( truthEvents );
 
  158   if ( 
evtStore()->contains<xAOD::TruthEventBaseContainer>( 
"TruthPileupEvents" ) )
 
  161     truthContainers.push_back( truthPileup );
 
  170     ATH_MSG_WARNING(
"Vertex container has no vertices with valid TrackParticle links");
 
  171     return StatusCode::SUCCESS;
 
  178   createTrackTruthMap( truthContainers, *tkContainer, 
m_trkMatchProb );
 
  212   unsigned int n_bad_links = 0;
 
  213   unsigned int n_links = 0;
 
  214   unsigned int n_vx_with_bad_links = 0;
 
  216   for ( 
auto vxit : vxContainer.
stdcont() ) {
 
  228     std::vector<VertexTruthMatchInfo> matchinfo;
 
  229     std::vector<VertexTruthMatchInfo> rawMatchinfo; 
 
  233       ATH_MSG_DEBUG(
"trackParticles or trackWeights not available, setting fake");
 
  236       matchInfoDecor( *vxit ) = matchinfo;
 
  238       rawMatchInfoDecor( *vxit ) = rawMatchinfo;
 
  239       nHSTrkDecor( *vxit ) = 0;
 
  245     ntracks = trkParts.size();
 
  246     const std::vector<float> & trkWeights = weightAcc( *vxit );
 
  249     if ( trkWeights.size() != ntracks ) {
 
  250       ATH_MSG_DEBUG(
"Vertex without same number of tracks and trackWeights, setting fake");
 
  252       matchInfoDecor( *vxit ) = matchinfo;
 
  254       rawMatchInfoDecor( *vxit ) = rawMatchinfo;
 
  255       nHSTrkDecor( *vxit ) = 0;
 
  259     ATH_MSG_DEBUG(
"Matching new vertex at (" << vxit->x() << 
", " << vxit->y() << 
", " << vxit->z() << 
")" << 
" with " << ntracks << 
" tracks, at index: " << vxit->index());
 
  261     float totalWeight = 0.;
 
  262     float totalFake = 0.;
 
  265     unsigned vx_n_bad_links = 0;
 
  267     for ( 
size_t t = 0; 
t < ntracks; ++
t ) {
 
  274       totalWeight += trkWeights[
t];
 
  276       trk_wtVtx(trk) = trkWeights[
t];
 
  279       float prob = trk_truthProbAcc( trk );
 
  281       if (!truthPartLink.
isValid()) 
continue;
 
  286         if ( 
pass( truthPart) ) {
 
  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];
 
  298             totalFake += trkWeights[
t];
 
  303           totalFake += trkWeights[
t];
 
  307         totalFake += trkWeights[
t];
 
  311     n_bad_links += vx_n_bad_links;
 
  312     if (vx_n_bad_links>0) {
 
  313        ++n_vx_with_bad_links;
 
  317     if ( totalWeight < 1
e-12 ) { 
 
  318       ATH_MSG_DEBUG(
"   Declaring vertex fully fake (no passing tracks included)");
 
  322     if ( totalFake > 0. )
 
  328     for ( 
auto & mit : matchinfo ) {
 
  329       std::get<1>(mit) /= totalWeight;
 
  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;
 
  347   std::vector<bool> assignedType( vxContainer.
size(), 
false );
 
  349   for ( 
size_t i = 0; 
i < vxContainer.
size(); ++
i ) {
 
  351     if ( assignedType[
i] ) 
continue; 
 
  353     std::vector<VertexTruthMatchInfo> & 
info = matchInfoDecor( *vxContainer[
i] );
 
  355       matchTypeDecor( *vxContainer[
i] ) = 
DUMMY;
 
  357       matchTypeDecor( *vxContainer[
i] ) = 
FAKE;
 
  359       matchTypeDecor( *vxContainer[
i] ) = 
MATCHED;
 
  361       matchTypeDecor( *vxContainer[
i] ) = 
MERGED;
 
  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] );
 
  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() ) {
 
  375           splitPartnerDecor( *vxContainer[
i] ).emplace_back( vxContainer, j );
 
  376           splitPartnerDecor( *vxContainer[j] ).emplace_back( vxContainer, 
i );
 
  378           for ( 
auto k : foundSplits ) { 
 
  379             splitPartnerDecor( *vxContainer[
k] ).emplace_back( vxContainer, j );
 
  380             splitPartnerDecor( *vxContainer[j] ).emplace_back( vxContainer, 
k );
 
  383           foundSplits.push_back(j);
 
  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] );
 
  395           matchTypeDecor( *vxContainer[
l] ) = 
SPLIT;
 
  396           assignedType[
l] = 
true;
 
  399       if ( indexOfMax!=
i ) matchTypeDecor( *vxContainer[
i] ) = 
SPLIT;
 
  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) );
 
  411           ATH_MSG_DEBUG(
"  Fakes with relative weight " << std::get<1>(vit) );
 
  414       if (matchTypeDecor(*vxit) == 
SPLIT) {
 
  416         for (
const auto &
split : splitPartnerDecor( *vxit ) ) {
 
  417           if ( 
split.isValid() )
 
  426   return StatusCode::SUCCESS;