36       bool is_pv_associated = 
false;
 
   40       for( 
const auto* vtx : *vertices ) {
 
   41         for( 
size_t iv = 0; iv < vtx->nTrackParticles(); iv++ ) {
 
   42           const auto* pvtrk = vtx->trackParticle( iv );
 
   43           if (pvtrk == 
nullptr) 
continue;
 
   45            if ( (trk_from_gsf == pvtrk) or (trk == pvtrk) ) {
 
   46             is_pv_associated = 
true;
 
   51       return is_pv_associated;
 
   56     return (v1-
v2).norm();
 
   61   double VrtSecInclusive::significanceBetweenVertices( 
const WrkVrt& v1, 
const WrkVrt& 
v2 )
 const {
 
   66       sumCov.fillSymmetric(0, 0, v1.
vertexCov.at(0) + 
v2.vertexCov.at(0));
 
   67       sumCov.fillSymmetric(1, 0, v1.
vertexCov.at(1) + 
v2.vertexCov.at(1));
 
   68       sumCov.fillSymmetric(1, 1, v1.
vertexCov.at(2) + 
v2.vertexCov.at(2));
 
   69       sumCov.fillSymmetric(2, 0, v1.
vertexCov.at(3) + 
v2.vertexCov.at(3));
 
   70       sumCov.fillSymmetric(2, 1, v1.
vertexCov.at(4) + 
v2.vertexCov.at(4));
 
   71       sumCov.fillSymmetric(2, 2, v1.
vertexCov.at(5) + 
v2.vertexCov.at(5));
 
   77       ATH_MSG_WARNING( 
" >>> " << __FUNCTION__ << 
": detected covariance matrix broken exception" );
 
   86                    xAOD::Muon::InnerDetectorTrackParticle,
 
   87                    xAOD::Muon::MuonSpectrometerTrackParticle,
 
   88                    xAOD::Muon::CombinedTrackParticle,
 
   89                    xAOD::Muon::ExtrapolatedMuonSpectrometerTrackParticle
 
   95     for( 
size_t i=0; 
i<
electron->nTrackParticles(); 
i++ ) trackTypes.emplace_back( 
i );
 
  102     return muon->trackParticle( 
static_cast<xAOD::Muon::TrackParticleType
>( trackType ) );
 
  107     return electron->trackParticle( trackType );
 
  112   double VrtSecInclusive::distanceBetweenVertices( 
const WrkVrt& v1, 
const WrkVrt& 
v2 )
 const {
 
  113     return (
v2.vertex - v1.
vertex).norm();
 
  118   StatusCode VrtSecInclusive::disassembleVertex(std::vector<WrkVrt> *workVerticesContainer, 
const unsigned& iv )
 
  121     auto& wrkvrt = workVerticesContainer->at(iv);
 
  123     ATH_MSG_VERBOSE(
" >> disassembleVertex(): begin: disassembling vertex[" << iv << 
"], workVerticesContainer.size() = " << workVerticesContainer->size() );
 
  124     ATH_MSG_VERBOSE(
" >> disassembleVertex(): Vertex: r = " << wrkvrt.vertex.perp() << 
", z = " << wrkvrt.vertex.z() );
 
  127     const auto& ntrk = wrkvrt.selectedTrackIndices.size();
 
  131     if( wrkvrt.selectedTrackIndices.size() <= 2 ) 
return StatusCode::SUCCESS;
 
  133     for( 
auto& 
index : wrkvrt.selectedTrackIndices ) {
 
  136       ATH_MSG_VERBOSE(
" >> disassembleVertex(): > track at vertex[" << iv << 
"]: " 
  137           << 
"index = " << trk->
index()
 
  138           << 
", pT = "  << trk->
pt()
 
  139           << 
", phi = " << trk->
phi()
 
  140           << 
", d0 = "  << trk->
d0()
 
  141           << 
", z0 = "  << trk->
z0());
 
  145     const auto& 
max = std::max_element( wrkvrt.Chi2PerTrk.begin(), wrkvrt.Chi2PerTrk.end() );
 
  147     if( 
max == wrkvrt.Chi2PerTrk.end() ) 
return StatusCode::SUCCESS;
 
  149     maxChi2TrackIndex = 
max - wrkvrt.Chi2PerTrk.begin();
 
  156     vector<const xAOD::NeutralParticle*>  dummyNeutrals;
 
  158     vector<WrkVrt> new_vertices;
 
  161     ATH_MSG_VERBOSE(
" >> disassembleVertex(): Loop over the tracks associated to the vertex other than the selected tracks.");
 
  162     for(
size_t itrk=0; itrk<ntrk; itrk++) {
 
  164       ATH_MSG_VERBOSE(
" >> disassembleVertex(): > Loop itrk = " << itrk << 
" / " << ntrk );
 
  167       if( itrk == maxChi2TrackIndex ) {
 
  172       const size_t this_trk_id     = wrkvrt.selectedTrackIndices[itrk];
 
  173       const size_t selected_trk_id = wrkvrt.selectedTrackIndices[maxChi2TrackIndex];
 
  175       ATH_MSG_VERBOSE(
" >> disassembleVertex(): > this_trk_id  = " << this_trk_id << 
", selected_trk_id = " << selected_trk_id << 
", alltrks_size = " << m_selectedTracks.size() );
 
  176       if( this_trk_id >= m_selectedTracks.size() ) {
 
  177   ATH_MSG_VERBOSE(
" >> disassembleVertex(): > this_trk_id is invalid. continue!" );
 
  180       if( selected_trk_id >= m_selectedTracks.size() ) {
 
  181   ATH_MSG_VERBOSE(
" >> disassembleVertex(): > selected_trk_id is invalid. continue!" );
 
  185       ATH_MSG_VERBOSE(
" >> disassembleVertex(): > Storing tracks to ListBaseTracks" );
 
  186       ATH_MSG_VERBOSE(
" >> disassembleVertex(): > m_selectedTracks.at( this_trk_id ) = " << m_selectedTracks.at( this_trk_id     )->index() );
 
  187       ATH_MSG_VERBOSE(
" >> disassembleVertex(): > m_selectedTracks.at( this_trk_id ) = " << m_selectedTracks.at( selected_trk_id )->index() );
 
  189       vector<const xAOD::TrackParticle*>    ListBaseTracks;
 
  190       ListBaseTracks.emplace_back( m_selectedTracks.at( this_trk_id     ) );
 
  191       ListBaseTracks.emplace_back( m_selectedTracks.at( selected_trk_id ) );
 
  193       ATH_MSG_VERBOSE(
" >> disassembleVertex(): > ListBaseTracks was stored." );
 
  202       std::unique_ptr<Trk::IVKalState> state = m_fitSvc->makeState();
 
  203       ATH_CHECK( m_fitSvc->VKalVrtFitFast( ListBaseTracks, newvrt.
vertex, *state ) );
 
  209           m_fitSvc->setApproximateVertex( wrkvrt.vertex[0], wrkvrt.vertex[1], wrkvrt.vertex[2], *state );
 
  213           m_fitSvc->setApproximateVertex( newvrt.
vertex[0], newvrt.
vertex[1], newvrt.
vertex[2], *state );
 
  228       if( 
sc.isFailure() ) 
continue;
 
  234       ATH_MSG_VERBOSE(
" >> disassembleVertex(): > register the new vertex to the vertex list" );
 
  235       new_vertices.emplace_back( newvrt );
 
  239     wrkvrt.selectedTrackIndices.erase( wrkvrt.selectedTrackIndices.begin() + maxChi2TrackIndex ); 
 
  240     ATH_MSG_VERBOSE(
" >> disassembleVertex(): removed the selected track from the original vertex. wrkvrt.selectedTrackIndices.size = " << wrkvrt.selectedTrackIndices.size() );
 
  243     ATH_MSG_VERBOSE(
" >> disassembleVertex(): refit the original vertex" );
 
  246     if( 
sc.isFailure() ) {
 
  249         return StatusCode::SUCCESS;
 
  253     for( 
const auto& 
vertex : new_vertices ) {
 
  254       ATH_MSG_VERBOSE(
" >> disassembleVertex(): > emplace_back new vertex" );
 
  255       workVerticesContainer->emplace_back( 
vertex );
 
  258     ATH_MSG_VERBOSE(
" >> disassembleVertex(): end. workVerticesContainer.size() = " << workVerticesContainer->size() );
 
  259     return StatusCode::SUCCESS;
 
  271     auto fitQuality_begin = 
vertex.fitQuality();
 
  273     auto removeCounter = 0;
 
  275     if( 
vertex.nTracksTotal() <= 2 ) 
return 0.;
 
  280       if( 
sc.isFailure() ) {
 
  286     double chi2Probability = TMath::Prob( 
vertex.Chi2, 
vertex.ndof() );
 
  288     while (chi2Probability < m_jp.improveChi2ProbThreshold ) {
 
  289       if( 
vertex.nTracksTotal() == 2 ) 
return chi2Probability;
 
  293       auto maxChi2 = std::max_element( 
vertex.Chi2PerTrk.begin(), 
vertex.Chi2PerTrk.end() );
 
  294       size_t index   = maxChi2 - 
vertex.Chi2PerTrk.begin();
 
  297       ATH_MSG_DEBUG( 
" >>> " << __FUNCTION__ << 
": worst chi2 trk index = " << 
index << 
", #trks = " << 
vertex.Chi2PerTrk.size() );
 
  300         vertex.selectedTrackIndices.erase( 
vertex.selectedTrackIndices.begin() + 
index ); 
 
  304         if( 
index >= 
vertex.associatedTrackIndices.size() ) {
 
  308         vertex.associatedTrackIndices.erase( 
vertex.associatedTrackIndices.begin() + 
index ); 
 
  320       chi2Probability = TMath::Prob( 
vertex.Chi2, 
vertex.ndof() );
 
  323     auto fitQuality_end = 
vertex.fitQuality();
 
  325     if( 0 == removeCounter ) {
 
  326       ATH_MSG_DEBUG( 
" >>> " << __FUNCTION__ << 
": no improvement was found." );
 
  328       ATH_MSG_DEBUG( 
" >>> " << __FUNCTION__ << 
": Removed " << removeCounter << 
" tracks; Fit quality improvement: " << fitQuality_begin << 
" ==> " << fitQuality_end );
 
  331     return chi2Probability;
 
  337   void VrtSecInclusive::removeTrackFromVertex(std::vector<WrkVrt> *workVerticesContainer,
 
  338                 std::vector< std::deque<long int> > *TrkInVrt,
 
  339                 const long int & trackIndexToRemove,
 
  340                 const long int & SelectedVertex)
 
  343     auto& wrkvrt = workVerticesContainer->at(SelectedVertex);
 
  344     auto& tracks = wrkvrt.selectedTrackIndices;
 
  347       auto end = 
std::remove_if( tracks.begin(), tracks.end(), [&](
long int index) { return index == trackIndexToRemove; } );
 
  348       tracks.erase( 
end, tracks.end() );
 
  352       for( 
auto& trks : *TrkInVrt ) {
 
  353         auto end = 
std::remove_if( trks.begin(), trks.end(), [&](
long int index) { return index == trackIndexToRemove; } );
 
  354         trks.erase( 
end, trks.end() );
 
  360     if( wrkvrt.selectedTrackIndices.size() == 1 ) {
 
  362       const auto& leftTrackIndex = *( tracks.begin() );
 
  363       auto& 
list = TrkInVrt->at(leftTrackIndex);
 
  380     for( 
auto& workVertex : *workVerticesContainer ) {
 
  382       workVertex.closestWrkVrtIndex = 0;
 
  387     for( 
auto iv = workVerticesContainer->begin(); iv != workVerticesContainer->end(); ++iv ) {
 
  388       if( (*iv).selectedTrackIndices.size()< 2) 
continue;   
 
  390       auto i_index = iv - workVerticesContainer->begin();
 
  392       for( 
auto jv = 
std::next(iv); jv != workVerticesContainer->end(); ++jv ) {
 
  393         if( (*jv).selectedTrackIndices.size()< 2) 
continue;   
 
  395         auto j_index = iv - workVerticesContainer->begin();
 
  401           indexPair.first  = i_index;
 
  402           indexPair.second = j_index;
 
  404         if( 
value < (*iv).closestWrkVrtValue ) {(*iv).closestWrkVrtValue = 
value; (*iv).closestWrkVrtIndex = j_index; }
 
  405         if( 
value < (*jv).closestWrkVrtValue ) {(*jv).closestWrkVrtValue = 
value; (*jv).closestWrkVrtIndex = i_index; }
 
  414   double VrtSecInclusive::findMinVerticesNextPair( std::vector<WrkVrt> *workVerticesContainer, std::pair<unsigned, unsigned>& indexPair )
 
  421     indexPair.second = 0;
 
  425     for(
unsigned iv=0; iv<workVerticesContainer->size()-1; iv++) {
 
  426       auto& 
vertex = workVerticesContainer->at(iv);
 
  428       if( 
vertex.selectedTrackIndices.size() < 2) 
continue;   
 
  429       if( 
vertex.closestWrkVrtIndex == 0 )        
continue;   
 
  433         unsigned jv = 
vertex.closestWrkVrtIndex;
 
  436         if( workVerticesContainer->at(jv).closestWrkVrtIndex == 0 ) 
continue;
 
  440         indexPair.first  = iv;
 
  441         indexPair.second = jv;
 
  471     v2.selectedTrackIndices.clear();             
 
  473     v2.closestWrkVrtIndex = 0;                   
 
  481     if( 
sc.isFailure() ) {
 
  485       ATH_MSG_DEBUG(
" >>> " << __FUNCTION__ << 
": failure in merging" );
 
  487       return StatusCode::FAILURE;
 
  490     return StatusCode::SUCCESS;
 
  498     std::unique_ptr<Trk::IVKalState> state = m_fitSvc->makeState();
 
  499     return refitVertex (workVertex, *state);
 
  510     vector<const xAOD::NeutralParticle*> dummyNeutrals;
 
  515       workVertex.
isGood = 
false;
 
  516       return StatusCode::SUCCESS;
 
  519     vector<const xAOD::TrackParticle*>  ListBaseTracks;
 
  524       ListBaseTracks.emplace_back( m_selectedTracks.at( 
index ) );
 
  529       ListBaseTracks.emplace_back( m_associatedTracks.at( 
index ) );
 
  533     auto& vertexPos = workVertex.
vertex;
 
  535     m_fitSvc->setApproximateVertex( vertexPos.x(), vertexPos.y(), vertexPos.z(), istate );
 
  537     ATH_MSG_VERBOSE( 
" >>> refitVertex: ListBaseTracks.size = " << ListBaseTracks.size()
 
  540     for( 
const auto *trk : ListBaseTracks ) {
 
  548     StatusCode sc = m_fitSvc->VKalVrtFitFast( ListBaseTracks, initVertex, istate );
 
  549     if(
sc.isFailure()) 
ATH_MSG_DEBUG(
" >>> refitVertex: fast crude estimation failed.");
 
  550     ATH_MSG_VERBOSE( 
" >>> refitVertex: Fast VKalVrtFit succeeded. vertex (r,z) = (" << initVertex.perp() << 
", " << initVertex.z() << 
", " << 
")" );
 
  554       m_fitSvc->setApproximateVertex( vertexPos.x(), vertexPos.y(), vertexPos.z(), istate );
 
  558       m_fitSvc->setApproximateVertex( initVertex.x(), initVertex.y(), initVertex.z(), istate );
 
  562     ATH_MSG_VERBOSE( 
" >>> refitVertex: approx vertex is set. Now going to perform fitting..." );
 
  564     StatusCode SC=m_fitSvc->VKalVrtFit(ListBaseTracks,dummyNeutrals,
 
  576     if(
SC.isFailure()) 
ATH_MSG_DEBUG(
" >>> refitVertex: SC in refitVertex returned failure ");
 
  578     ATH_MSG_VERBOSE( 
" >>> refitVertex: succeeded in fitting. New vertex pos (r,z) = (" << vertexPos.perp() << 
", " << vertexPos.z() << 
")" );
 
  579     ATH_MSG_VERBOSE( 
" >>> refitVertex: New vertex cov = (" << 
cov.at(0) << 
", " << 
cov.at(1) << 
", " << 
cov.at(2) << 
", " << 
cov.at(3) << 
", " << 
cov.at(4) << 
", " << 
cov.at(5) << 
")" );
 
  587     std::unique_ptr<Trk::IVKalState> state = m_fitSvc->makeState();
 
  588     return refitVertexWithSuggestion (workVertex, suggestedPosition, *state);
 
  599     vector<const xAOD::NeutralParticle*> dummyNeutrals;
 
  604       workVertex.
isGood = 
false;
 
  605       return StatusCode::SUCCESS;
 
  608     vector<const xAOD::TrackParticle*>  ListBaseTracks;
 
  613       ListBaseTracks.emplace_back( m_selectedTracks.at( 
index ) );
 
  618       ListBaseTracks.emplace_back( m_associatedTracks.at( 
index ) );
 
  622     auto& vertexPos = workVertex.
vertex;
 
  624     m_fitSvc->setApproximateVertex( suggestedPosition.x(), suggestedPosition.y(), suggestedPosition.z(), istate );
 
  626     ATH_MSG_VERBOSE( 
" >>> " << __FUNCTION__ <<
": ListBaseTracks.size = " << ListBaseTracks.size()
 
  629     for( 
const auto *trk : ListBaseTracks ) {
 
  630       ATH_MSG_VERBOSE( 
" >>> " << __FUNCTION__ << 
": track index = " << trk->index() );
 
  635     ATH_MSG_VERBOSE( 
" >>> " << __FUNCTION__ << 
": approx vertex is set. Now going to perform fitting..." );
 
  637     StatusCode SC=m_fitSvc->VKalVrtFit(ListBaseTracks,dummyNeutrals,
 
  649     if( 
SC.isFailure() ) 
ATH_MSG_VERBOSE(
" >>> " << __FUNCTION__ << 
": SC in refitVertex returned failure ");
 
  652     if( 
SC.isSuccess() ) {
 
  653       ATH_MSG_VERBOSE( 
" >>> " << __FUNCTION__ << 
": succeeded in fitting. New vertex pos = (" << vertexPos.x() << 
", " << vertexPos.y() << 
", " << vertexPos.z() << 
")" );
 
  654       ATH_MSG_VERBOSE( 
" >>> " << __FUNCTION__ << 
": New vertex cov = (" << 
cov.at(0) << 
", " << 
cov.at(1) << 
", " << 
cov.at(2) << 
", " << 
cov.at(3) << 
", " << 
cov.at(4) << 
", " << 
cov.at(5) << 
")" );
 
  662   size_t VrtSecInclusive::nTrkCommon( std::vector<WrkVrt> *workVerticesContainer, 
const std::pair<unsigned, unsigned>& pairIndex)
 
  668     auto& trackIndices1 = workVerticesContainer->at( pairIndex.first ).selectedTrackIndices;
 
  669     auto& trackIndices2 = workVerticesContainer->at( pairIndex.second ).selectedTrackIndices;
 
  671     if( trackIndices1.size() < 2 ) 
return 0;
 
  672     if( trackIndices2.size() < 2 ) 
return 0;
 
  676     for( 
auto& 
index : trackIndices1 ) {
 
  677   if( 
std::find(trackIndices2.begin(),trackIndices2.end(), 
index) != trackIndices2.end()) nTrkCom++;
 
  690     declareProperty(
"TrackLocation",                   m_jp.TrackLocation                   = 
"InDetTrackParticles"         );
 
  691     declareProperty(
"MuonLocation",                    m_jp.MuonLocation                    = 
"Muons"                       );
 
  692     declareProperty(
"ElectronLocation",                m_jp.ElectronLocation                = 
"Electrons"                   );
 
  693     declareProperty(
"PrimVrtLocation",                 m_jp.PrimVrtLocation                 = 
"PrimaryVertices"             );
 
  694     declareProperty(
"McParticleContainer",             m_jp.truthParticleContainerName      = 
"TruthParticles"              );
 
  695     declareProperty(
"MCEventContainer",                m_jp.mcEventContainerName            = 
"TruthEvents"                 );
 
  696     declareProperty(
"AugmentingVersionString",         m_jp.augVerString                    = 
"_VSI"                            );
 
  697     declareProperty(
"TruthParticleFilter",             m_jp.truthParticleFilter             = 
"Rhadron"                     ); 
 
  699     declareProperty(
"All2trkVerticesContainerName",    m_jp.all2trksVerticesContainerName   = 
"All2TrksVertices"            );
 
  700     declareProperty(
"SecondaryVerticesContainerName",  m_jp.secondaryVerticesContainerName  = 
"SecondaryVertices"           );
 
  702     declareProperty(
"FillHist",                        m_jp.FillHist                        = 
false                         );
 
  703     declareProperty(
"FillNtuple",                      m_jp.FillNtuple                      = 
false                         );
 
  704     declareProperty(
"FillIntermediateVertices",        m_jp.FillIntermediateVertices        = 
false                         );
 
  705     declareProperty(
"DoIntersectionPos",               m_jp.doIntersectionPos               = 
false                         );
 
  706     declareProperty(
"DoMapToLocal",                    m_jp.doMapToLocal                    = 
false                         );
 
  707     declareProperty(
"DoTruth",                         m_jp.doTruth                         = 
false                         );
 
  708     declareProperty(
"DoPVcompatibility",               m_jp.doPVcompatibilityCut            = 
true                          );
 
  709     declareProperty(
"DoTightPVcompatibility",          m_jp.doTightPVcompatibilityCut       = 
false                         );
 
  710     declareProperty(
"RemoveFake2TrkVrt",               m_jp.removeFakeVrt                   = 
true                          );
 
  711     declareProperty(
"DoDelayedFakeReject",             m_jp.removeFakeVrtLate               = 
false                         );
 
  712     declareProperty(
"CheckHitPatternStrategy",         m_checkPatternStrategy               = 
"Classical"                   ); 
 
  713     declareProperty(
"MCTrackResolution",               m_jp.mcTrkResolution                 = 0.06                          ); 
 
  714     declareProperty(
"TruthTrkLen",                     m_jp.TruthTrkLen                     = 1000                          ); 
 
  715     declareProperty(
"ExtrapPV",                        m_jp.extrapPV                        = 
false                         ); 
 
  716     declareProperty(
"PassThroughTrackSelection",       m_jp.passThroughTrackSelection       = 
false                         );
 
  717     declareProperty(
"DoFastMode",                      m_jp.doFastMode                      = 
false                         );
 
  720     declareProperty(
"DoTwoTrSoftBtag",                 m_jp.doTwoTrSoftBtag                 = 
false                         );
 
  721     declareProperty(
"TwoTrVrtAngleCut",                m_jp.twoTrVrtAngleCut                = -10                           );
 
  722     declareProperty(
"TwoTrVrtMinDistFromPVCut",        m_jp.twoTrVrtMinDistFromPV           = 0.                            );
 
  724     declareProperty(
"TruncateListOfWorkingVertices",   m_jp.truncateWrkVertices             = 
true                           );
 
  725     declareProperty(
"MaxNumberOfWorkingVertices",      m_jp.maxWrkVertices                  = 1500                           );
 
  728     declareProperty(
"do_PVvetoCut",                    m_jp.do_PVvetoCut                    = 
true                          );
 
  729     declareProperty(
"do_d0Cut",                        m_jp.do_d0Cut                        = 
true                          );
 
  730     declareProperty(
"do_z0Cut",                        m_jp.do_z0Cut                        = 
true                          );
 
  731     declareProperty(
"do_d0errCut",                     m_jp.do_d0errCut                     = 
false                         );
 
  732     declareProperty(
"do_z0errCut",                     m_jp.do_z0errCut                     = 
false                         );
 
  733     declareProperty(
"do_d0signifCut",                  m_jp.do_d0signifCut                  = 
false                         );
 
  734     declareProperty(
"do_z0signifCut",                  m_jp.do_z0signifCut                  = 
false                         );
 
  736     declareProperty(
"ImpactWrtBL",                     m_jp.ImpactWrtBL                     = 
true                          ); 
 
  737     declareProperty(
"a0TrkPVDstMinCut",                m_jp.d0TrkPVDstMinCut                = 0.                            ); 
 
  738     declareProperty(
"a0TrkPVDstMaxCut",                m_jp.d0TrkPVDstMaxCut                = 1000.                         ); 
 
  739     declareProperty(
"a0TrkPVSignifCut",                m_jp.d0TrkPVSignifCut                = 0.                            ); 
 
  740     declareProperty(
"twoTrkVtxFormingD0Cut",           m_jp.twoTrkVtxFormingD0Cut           = 1.                            ); 
 
  741     declareProperty(
"zTrkPVDstMinCut",                 m_jp.z0TrkPVDstMinCut                = 0.                            ); 
 
  742     declareProperty(
"zTrkPVDstMaxCut",                 m_jp.z0TrkPVDstMaxCut                = 1000.                         ); 
 
  743     declareProperty(
"zTrkPVSignifCut",                 m_jp.z0TrkPVSignifCut                = 0.                            ); 
 
  744     declareProperty(
"TrkA0ErrCut",                     m_jp.d0TrkErrorCut                   = 10000                         ); 
 
  745     declareProperty(
"TrkZErrCut",                      m_jp.z0TrkErrorCut                   = 20000                         ); 
 
  747     declareProperty(
"SelTrkMaxCutoff",                 m_jp.SelTrkMaxCutoff                 = 50                            ); 
 
  748     declareProperty(
"TrkPtCut",                        m_jp.TrkPtCut                        = 1000.                         ); 
 
  749     declareProperty(
"TrkChi2Cut",                      m_jp.TrkChi2Cut                      = 3.                            ); 
 
  750     declareProperty(
"PVcompatibilityCut",              m_jp.pvCompatibilityCut              = -20.                          ); 
 
  751     declareProperty(
"SelVrtChi2Cut",                   m_jp.SelVrtChi2Cut                   = 4.5                           ); 
 
  753     declareProperty(
"CutSctHits",                      m_jp.CutSctHits                      = 0                             );
 
  754     declareProperty(
"CutPixelHits",                    m_jp.CutPixelHits                    = 0                             );
 
  755     declareProperty(
"CutSiHits",                       m_jp.CutSiHits                       = 0                             );
 
  756     declareProperty(
"DoSAloneTRT",                     m_jp.SAloneTRT                       = 
false                         ); 
 
  757     declareProperty(
"CutBLayHits",                     m_jp.CutBLayHits                     = 0                             );
 
  758     declareProperty(
"CutSharedHits",                   m_jp.CutSharedHits                   = 0                             );
 
  759     declareProperty(
"doTRTPixCut",                     m_jp.doTRTPixCut                     = 
false                         ); 
 
  760     declareProperty(
"CutTRTHits",                      m_jp.CutTRTHits                      = 0                             );
 
  761     declareProperty(
"CutTightSCTHits",                 m_jp.CutTightSCTHits                 = 7                             );
 
  762     declareProperty(
"CutTightTRTHits",                 m_jp.CutTightTRTHits                 = 20                            );
 
  764     declareProperty(
"TrkExtrapolator",                 m_jp.trkExtrapolator                 = 2                             );
 
  766     declareProperty(
"doReassembleVertices",            m_jp.doReassembleVertices            = 
false                         );
 
  767     declareProperty(
"doMergeByShuffling",              m_jp.doMergeByShuffling              = 
false                         );
 
  768     declareProperty(
"doSuggestedRefitOnMerging",       m_jp.doSuggestedRefitOnMerging       = 
true                          ); 
 
  769     declareProperty(
"doMagnetMerging",                 m_jp.doMagnetMerging                 = 
true                          ); 
 
  770     declareProperty(
"doWildMerging",                   m_jp.doWildMerging                   = 
true                          ); 
 
  771     declareProperty(
"doMergeFinalVerticesDistance",    m_jp.doMergeFinalVerticesDistance    = 
false                         );
 
  772     declareProperty(
"doAssociateNonSelectedTracks",    m_jp.doAssociateNonSelectedTracks    = 
false                         );
 
  773     declareProperty(
"doFinalImproveChi2",              m_jp.doFinalImproveChi2              = 
false                         );
 
  775     declareProperty(
"VertexMergeCut",                  m_jp.VertexMergeCut                  = 3                             );
 
  776     declareProperty(
"TrackDetachCut",                  m_jp.TrackDetachCut                  = 6                             );
 
  777     declareProperty(
"associateMinDistanceToPV",        m_jp.associateMinDistanceToPV        = 0.5                           );
 
  778     declareProperty(
"associateMaxD0Signif",            m_jp.associateMaxD0Signif            = 5.                            ); 
 
  779     declareProperty(
"associateMaxZ0Signif",            m_jp.associateMaxZ0Signif            = 5.                            ); 
 
  780     declareProperty(
"associatePtCut",                  m_jp.associatePtCut                  = 0.                            ); 
 
  781     declareProperty(
"associateChi2Cut",                m_jp.associateChi2Cut                = 20.                           );
 
  782     declareProperty(
"reassembleMaxImpactParameterD0",  m_jp.reassembleMaxImpactParameterD0  = 1.                            ); 
 
  783     declareProperty(
"reassembleMaxImpactParameterZ0",  m_jp.reassembleMaxImpactParameterZ0  = 5.                            ); 
 
  784     declareProperty(
"mergeByShufflingMaxSignificance", m_jp.mergeByShufflingMaxSignificance = 100.                          ); 
 
  785     declareProperty(
"mergeByShufflingAllowance",       m_jp.mergeByShufflingAllowance       = 4.                            ); 
 
  786     declareProperty(
"VertexMergeFinalDistCut",         m_jp.VertexMergeFinalDistCut         = 1.                            ); 
 
  787     declareProperty(
"VertexMergeFinalDistScaling",     m_jp.VertexMergeFinalDistScaling     = 0.                            ); 
 
  788     declareProperty(
"improveChi2ProbThreshold",        m_jp.improveChi2ProbThreshold        = 1.e-4                         );
 
  791     declareProperty(
"doSelectTracksFromMuons",         m_jp.doSelectTracksFromMuons         = 
false                         );
 
  792     declareProperty(
"doRemoveCaloTaggedMuons",         m_jp.doRemoveCaloTaggedMuons         = 
false                         );
 
  793     declareProperty(
"doSelectTracksFromElectrons",     m_jp.doSelectTracksFromElectrons     = 
false                         );
 
  794     declareProperty(
"doSelectIDAndGSFTracks",          m_jp.doSelectIDAndGSFTracks          = 
false                         );
 
  795     declareProperty(
"doRemoveNonLeptonVertices",       m_jp.doRemoveNonLeptonVertices       = 
false                         );
 
  798     declareProperty(
"doDisappearingTrackVertexing",   m_jp.doDisappearingTrackVertexing     = 
false                           );
 
  799     declareProperty(
"twoTrVrtMaxPerigeeDist",         m_jp.twoTrVrtMaxPerigeeDist           = 50                            ); 
 
  800     declareProperty(
"twoTrVrtMinRadius",              m_jp.twoTrVrtMinRadius                = 50                            ); 
 
  805     declareProperty(
"doSelectTracksWithLRTCuts",     m_jp.doSelectTracksWithLRTCuts     = 
false                               );
 
  808     declareProperty(
"doAugmentDVimpactParametersToMuons",     m_jp.doAugmentDVimpactParametersToMuons     = 
false           );
 
  809     declareProperty(
"doAugmentDVimpactParametersToElectrons", m_jp.doAugmentDVimpactParametersToElectrons = 
false           );
 
  812     declareProperty(
"VertexFitterTool",                m_fitSvc, 
" Private TrkVKalVrtFitter"                                );
 
  813     declareProperty(
"Extrapolator",                    m_extrapolator                                                       );
 
  814     declareProperty(
"TrackToVertexTool",               m_trackToVertexTool                                                  );
 
  815     declareProperty(
"TrackToVertexIPEstimatorTool",    m_trackToVertexIPEstimatorTool                                       );
 
  816     declareProperty(
"VertexMapper",                    m_vertexMapper                                                       );
 
  817     declareProperty(
"TruthToTrack",                    m_truthToTrack                                                       );
 
  833     if( m_jp.FillNtuple ) m_ntupleVars->get<
unsigned int>( 
"NumPV" ) = 0;
 
  836     ATH_MSG_DEBUG( 
"processPrimaryVertices(): pv_size = " << m_primaryVertices->size() );
 
  840     for( 
const auto *
vertex : *m_primaryVertices ) {
 
  851       if( m_jp.FillNtuple ) {
 
  853         if( 0 == m_ntupleVars->get<
unsigned int>( 
"NumPV" ) ) {
 
  855           m_ntupleVars->get<
double>( 
"PVX" ) = 
vertex->x();
 
  856           m_ntupleVars->get<
double>( 
"PVY" ) = 
vertex->y();
 
  857           m_ntupleVars->get<
double>( 
"PVZ" ) = 
vertex->z();
 
  858           m_ntupleVars->get<
unsigned int>( 
"PVType" ) = 
vertex->vertexType();
 
  861           m_ntupleVars->get<
unsigned int>( 
"NTrksPV" ) = 
vertex->nTrackParticles();
 
  864         m_ntupleVars->get<
unsigned int>( 
"NumPV" )++;
 
  866         m_ntupleVars->get< vector<int> >   ( 
"NdofTrksPV" ) .emplace_back( 
vertex->numberDoF() );
 
  867         m_ntupleVars->get< vector<double> >( 
"PVZpile" )    .emplace_back( 
vertex->position().z() );
 
  880       ATH_MSG_DEBUG(
"No Reconstructed PV was found. Using the dummy PV instead.");
 
  881       for( 
const auto *
vertex : *m_primaryVertices ) {
 
  884         if( m_jp.FillNtuple ) {
 
  886           if( 0 == m_ntupleVars->get<
unsigned int>( 
"NumPV" ) ) {
 
  889             m_ntupleVars->get<
double>( 
"PVX" ) = 
vertex->x();
 
  890             m_ntupleVars->get<
double>( 
"PVY" ) = 
vertex->y();
 
  891             m_ntupleVars->get<
double>( 
"PVZ" ) = 
vertex->z();
 
  892             m_ntupleVars->get<
unsigned int>( 
"PVType" ) = 
vertex->vertexType();
 
  895             m_ntupleVars->get<
unsigned int>( 
"NTrksPV" ) = 
vertex->nTrackParticles();
 
  904       return StatusCode::FAILURE;
 
  907     ATH_MSG_DEBUG(
" Primary vertex successful. thePV = " << m_thePV );
 
  909     return StatusCode::SUCCESS;
 
  914   void VrtSecInclusive::trackClassification(std::vector<WrkVrt> *workVerticesContainer, std::map<
long int, std::vector<long int> >& trackToVertexMap )
 
  918     trackToVertexMap.clear();
 
  920     for( 
size_t iv = 0; iv<workVerticesContainer->size(); iv++ ) {
 
  924       auto& trackIndices = 
vertex.selectedTrackIndices;
 
  925       if( !
vertex.isGood ) 
continue;
 
  926       if( trackIndices.size() < 2 ) 
continue;
 
  928       for( 
auto& 
index : trackIndices ) {
 
  929   trackToVertexMap[
index].emplace_back( iv );
 
  933     for( 
auto& pair: trackToVertexMap ) {
 
  934       std::string 
msg = Form(
"track index [%ld]: vertices = (", pair.first);
 
  935       for( 
auto& 
v : pair.second ) {
 
  936         msg += Form(
"%ld, ", 
v);
 
  946   double VrtSecInclusive::findWorstChi2ofMaximallySharedTrack(std::vector<WrkVrt> *workVerticesContainer,
 
  947               std::map<
long int, std::vector<long int> >& trackToVertexMap,
 
  948               long int & maxSharedTrack,
 
  949               long int & worstMatchingVertex)
 
  955     auto maxSharedTrackToVertices = std::max_element( trackToVertexMap.begin(), trackToVertexMap.end(), []( 
auto& 
p1, 
auto& 
p2 ) { return p1.second.size() < p2.second.size(); } );
 
  957     if( maxSharedTrackToVertices == trackToVertexMap.end() ) 
return worstChi2;
 
  959     ATH_MSG_VERBOSE( 
" > " << __FUNCTION__ << 
": max-shared track index = " << maxSharedTrackToVertices->first << 
", number of shared vertices = " << maxSharedTrackToVertices->second.size() );
 
  961     if( maxSharedTrackToVertices->second.size() < 2 ) 
return worstChi2;
 
  964     std::map<long int, double> vrtChi2Map;
 
  967     for( 
auto& iv : maxSharedTrackToVertices->second ) {
 
  968       ATH_MSG_VERBOSE( 
" > " << __FUNCTION__ << 
": loop over vertices: vertex index " << iv );
 
  970       auto& wrkvrt = workVerticesContainer->at( iv );
 
  971       auto& trackIndices = wrkvrt.selectedTrackIndices;
 
  974       auto index = std::find_if( trackIndices.begin(), trackIndices.end(), [&]( 
auto& 
index ) { return index == maxSharedTrackToVertices->first; } );
 
  975       if( 
index == trackIndices.end() ) {
 
  976         ATH_MSG_WARNING(
" >> " << __FUNCTION__ << 
": index not found (algorithm inconsistent)" );
 
  980       auto& 
chi2 = wrkvrt.Chi2PerTrk.at( 
index - trackIndices.begin() );
 
  982       vrtChi2Map.emplace( std::pair<long int, double>(iv, 
chi2) );
 
  985     auto worstVrtChi2Pair = std::max_element( vrtChi2Map.begin(), vrtChi2Map.end(), []( 
auto& 
p1, 
auto& 
p2 ) { return p1.second < p2.second; } );
 
  987     if( worstVrtChi2Pair == vrtChi2Map.end() ) {
 
  988       ATH_MSG_WARNING(
" >> " << __FUNCTION__ << 
": max_element of vrtChi2Map not found" );
 
  992     maxSharedTrack      = maxSharedTrackToVertices->first;
 
  993     worstMatchingVertex = worstVrtChi2Pair->first;
 
  994     worstChi2           = worstVrtChi2Pair->second;
 
 1001   void VrtSecInclusive::printWrkSet(
const std::vector<WrkVrt> *workVerticesContainer, 
const std::string& 
name)
 
 1003     ATH_MSG_DEBUG( 
" >> " << __FUNCTION__ << 
": ===============================================================" );
 
 1004     ATH_MSG_DEBUG( 
" >> " << __FUNCTION__ << 
": " << 
name << 
": #vertices = " << workVerticesContainer->size() );
 
 1006     std::set<const xAOD::TrackParticle*> usedTracks;
 
 1008     auto concatenateIndicesToString = []( 
auto indices, 
auto& collection ) -> std::string {
 
 1009       if( 0 == 
indices.size() ) 
return "";
 
 1011                               [&collection]( 
const std::string& 
str, 
auto& 
index ) { return str + 
", " + std::to_string( collection.at(index)->index() ); } );
 
 1014     std::map<const xAOD::TruthVertex*, bool> 
previous;
 
 1016     for( 
auto& pair : m_matchMap ) { 
previous.emplace( pair.first, pair.second ); }
 
 1019     for( 
const auto* truthVertex : m_tracingTruthVertices ) { m_matchMap.emplace( truthVertex, 
false ); }
 
 1021     for(
size_t iv=0; iv<workVerticesContainer->size(); iv++) {
 
 1022       const auto& wrkvrt = workVerticesContainer->at(iv);
 
 1024       if( wrkvrt.nTracksTotal() < 2 ) 
continue;
 
 1026       std::string sels    = concatenateIndicesToString( wrkvrt.selectedTrackIndices,   m_selectedTracks   );
 
 1027       std::string assocs  = concatenateIndicesToString( wrkvrt.associatedTrackIndices, m_associatedTracks );
 
 1029       for( 
const auto& 
index : wrkvrt.selectedTrackIndices )   { usedTracks.insert( m_selectedTracks.at(
index) );   }
 
 1030       for( 
const auto& 
index : wrkvrt.associatedTrackIndices ) { usedTracks.insert( m_associatedTracks.at(
index) ); }
 
 1032       ATH_MSG_DEBUG( 
" >> " << __FUNCTION__ << 
": " << 
name << 
" vertex [" <<  iv << 
"]: " << &wrkvrt
 
 1033                      << 
", isGood  = "           << (wrkvrt.isGood? 
"true" : 
"false")
 
 1034                      << 
", #ntrks(tot, sel, assoc) = (" << wrkvrt.nTracksTotal() << 
", " << wrkvrt.selectedTrackIndices.size() << 
", " << wrkvrt.associatedTrackIndices.size() << 
"), " 
 1035                      << 
", chi2/ndof = "         << wrkvrt.fitQuality()
 
 1036                      << 
", (r, z) = ("           << wrkvrt.vertex.perp()
 
 1037                      << 
", "                     << wrkvrt.vertex.z() << 
")" 
 1038                      << 
", sels = { "            << sels << 
" }" 
 1039                      << 
", assocs = { "          << assocs << 
" }" );
 
 1042       for( 
const auto* truthVertex : m_tracingTruthVertices ) {
 
 1045         Amg::Vector3D vTruth( truthVertex->x(), truthVertex->y(), truthVertex->z() );
 
 1046         Amg::Vector3D vReco ( wrkvrt.vertex.x(), wrkvrt.vertex.y(), wrkvrt.vertex.z() );
 
 1048         const auto distance = vReco - vTruth;
 
 1051         cov.fillSymmetric( 0, 0, wrkvrt.vertexCov.at(0) );
 
 1052         cov.fillSymmetric( 1, 0, wrkvrt.vertexCov.at(1) );
 
 1053         cov.fillSymmetric( 1, 1, wrkvrt.vertexCov.at(2) );
 
 1054         cov.fillSymmetric( 2, 0, wrkvrt.vertexCov.at(3) );
 
 1055         cov.fillSymmetric( 2, 1, wrkvrt.vertexCov.at(4) );
 
 1056         cov.fillSymmetric( 2, 2, wrkvrt.vertexCov.at(5) );
 
 1060         if( 
distance.norm() < 2.0 || 
s2 < 100. ) m_matchMap.at( truthVertex ) = 
true;
 
 1066     ATH_MSG_DEBUG( 
" >> " << __FUNCTION__ << 
": number of used tracks = " << usedTracks.size() );
 
 1069       for( 
auto& pair : m_matchMap ) {
 
 1071         if( pair.second != 
previous.at( pair.first ) ) {
 
 1072           ATH_MSG_DEBUG( 
" >> " << __FUNCTION__ << 
": Match flag has changed: (r, z) = (" << pair.first->perp() << 
", " << pair.first->z() << 
")" );
 
 1077     if( m_jp.FillHist ) {
 
 1078       for( 
auto& pair : m_matchMap ) {
 
 1079         if( pair.second ) m_hists[
"nMatchedTruths"]->Fill( m_vertexingAlgorithmStep+2, pair.first->perp() );
 
 1084     for( 
const auto* trk : usedTracks ) { 
msg += Form(
"%ld, ", trk->index() ); }
 
 1087     ATH_MSG_DEBUG( 
" >> " << __FUNCTION__ << 
": ===============================================================" );
 
 1113     const EventContext& ctx = Gaudi::Hive::currentContext();
 
 1114     std::vector<std::unique_ptr<Trk::TrackParameters>> paramsVector =
 
 1121     for( 
auto& 
params : paramsVector ) {
 
 1123       const TVector3 position( 
params->position().x(), 
params->position().y(), 
params->position().z() );
 
 1125       if( prevPos == position ) {
 
 1131       const auto* detElement = 
params->associatedSurface().associatedDetectorElement();
 
 1137         const auto& 
id = detElement->identify();
 
 1140         if( m_atlasId->is_pixel(
id) ) {
 
 1142           auto idHash = m_pixelId->wafer_hash( 
id );
 
 1143           good = m_pixelCondSummaryTool->isGood( idHash, ctx );
 
 1145           pattern->emplace_back( std::make_tuple( position, 
Pixel, m_pixelId->barrel_ec(
id), m_pixelId->layer_disk(
id), 
good ) );
 
 1147         } 
else if( m_atlasId->is_sct(
id) ) {
 
 1149           auto idHash = m_sctId->wafer_hash( 
id );
 
 1150           good = m_sctCondSummaryTool->isGood( idHash, ctx );
 
 1152           pattern->emplace_back( std::make_tuple( position, 
SCT, m_sctId->barrel_ec(
id), m_sctId->layer_disk(
id), 
good ) );
 
 1158           ATH_MSG_VERBOSE(
" >> " << __FUNCTION__ << 
", track " << trk << 
": position = (" << position.Perp() << 
", " << position.z() << 
", " << position.Phi() << 
"), detElement ID = " << 
id << 
", good = " << 
good 
 1159                           << 
": (det, bec, layer) = (" << std::get<1>( 
pattern->back() ) << 
", " << std::get<2>( 
pattern->back() ) << 
", "  << std::get<3>( 
pattern->back() ) << 
")" );
 
 1161     if( !
good ) nDisabled++;
 
 1168     if( m_jp.FillHist ) {
 
 1169       m_hists[
"disabledCount"]->Fill( nDisabled );
 
 1181     if( m_extrapolatedPatternBank.find( trk ) == m_extrapolatedPatternBank.end() ) {
 
 1183       std::unique_ptr<ExtrapolatedPattern> exPattern_along( extrapolatedPattern( trk, 
Trk::alongMomentum ) );
 
 1184       std::unique_ptr<ExtrapolatedPattern> exPattern_oppos( extrapolatedPattern( trk, 
Trk::oppositeMomentum ) );
 
 1186       m_extrapolatedPatternBank.emplace( trk, std::make_pair( std::move(exPattern_along), std::move(exPattern_oppos) ) );
 
 1190     auto& exPattern = m_extrapolatedPatternBank.at( trk );
 
 1192     using LayerCombination = std::vector<int>;
 
 1194     std::map<LayerCombination, unsigned> layerMap;
 
 1195     if( layerMap.empty() ) {
 
 1238       const LayerCombination comb { std::get<detector>( point ), std::get<bec>( point ), std::get<layer>( point ) };
 
 1240       for( 
auto& pair : layerMap ) {
 
 1241         if( pair.first == comb ) {
 
 1249     enum { kShouldNotHaveHit, kShouldHaveHit, kMayHaveHit };
 
 1255     auto& exPattern_along = *( exPattern.first  );
 
 1257     for( 
auto itr = exPattern_along.begin(); itr != exPattern_along.end(); ++itr ) {
 
 1258       if( 
std::next( itr ) == exPattern_along.end() ) 
continue;
 
 1260       const auto& point      = *itr;
 
 1261       const auto& nextPoint  = *( 
std::next( itr ) );
 
 1263       ATH_MSG_VERBOSE( 
" > " <<  __FUNCTION__ << 
": isGood = " << std::get<isGood>( point ) );
 
 1265       const auto& thisPos = std::get<position>( point );
 
 1266       const auto& nextPos = std::get<position>( nextPoint );
 
 1268       auto sectionVector = nextPos - thisPos;
 
 1272       const auto& detectorType = getDetectorType( point );
 
 1274       ATH_MSG_VERBOSE( 
" > " <<  __FUNCTION__ << 
": detType = " << detectorType );
 
 1280       if( vertexVector.Mag() < 10. ) {
 
 1281         expectedHitPattern.at( detectorType ) = kMayHaveHit;
 
 1287       if( !
static_cast<bool>(std::get<isGood>( point )) ) {
 
 1288         expectedHitPattern.at( detectorType ) = kMayHaveHit;
 
 1297       if( sectionVector.Mag() == 0. ) 
continue;
 
 1300                        << 
": hitPos = (" << thisPos.Perp() << 
", " << thisPos.z() << 
", " << thisPos.Phi() << 
")" 
 1301                        << 
", sectionVec = (" << sectionVector.Perp() << 
", " << sectionVector.z() << 
", " << sectionVector.Phi() << 
")" 
 1302                        << 
", vertexVec = (" << vertexVector.Perp() << 
", " << vertexVector.z() << 
", " << vertexVector.Phi() << 
")" 
 1303                        << 
", cos(s,v)  = " << sectionVector * vertexVector / ( sectionVector.Mag() * vertexVector.Mag() + 
AlgConsts::infinitesimal ) );
 
 1305       if( sectionVector * vertexVector > 0. ) 
continue;
 
 1307       if( minExpectedRadius > thisPos.Perp() ) minExpectedRadius = thisPos.Perp();
 
 1311       expectedHitPattern.at( detectorType ) = kShouldHaveHit;
 
 1315     auto& exPattern_oppos = *( exPattern.second );
 
 1316     bool oppositeFlag = 
false;
 
 1318     for( 
auto itr = exPattern_oppos.begin(); itr != exPattern_oppos.end(); ++itr ) {
 
 1319       if( 
std::next( itr ) == exPattern_oppos.end() ) 
continue;
 
 1321       const auto& point      = *itr;
 
 1322       const auto& nextPoint  = *( 
std::next( itr ) );
 
 1324       const auto& thisPos = std::get<position>( point );
 
 1325       const auto& nextPos = std::get<position>( nextPoint );
 
 1327       auto sectionVector = nextPos - thisPos;
 
 1330       const auto& detectorType = getDetectorType( point );
 
 1332       ATH_MSG_VERBOSE( 
" > " <<  __FUNCTION__ << 
": detType = " << detectorType );
 
 1335                        << 
": hitPos = (" << thisPos.Perp() << 
", " << thisPos.z() << 
", " << thisPos.Phi() << 
")" 
 1336                        << 
", vertex = (" << 
vertex.perp() << 
", " << 
vertex.z() << 
", " << 
vertex.phi() << 
")" 
 1337                        << 
", cos(s,v)  = " << sectionVector * vertexVector / ( sectionVector.Mag() * vertexVector.Mag() + 
AlgConsts::infinitesimal ) );
 
 1342       if( sectionVector * vertexVector < 0. ) {
 
 1343         oppositeFlag = 
true;
 
 1352     std::string 
msg = 
"Expected hit pattern: ";
 
 1354       msg += Form(
"%s", expectedHitPattern.at(
i) < kMayHaveHit? Form(
"%u", expectedHitPattern.at(
i)) : 
"X" );
 
 1358     msg = 
"Recorded hit pattern: ";
 
 1364     std::vector<unsigned> matchedLayers;
 
 1367       const unsigned recordedPattern = ( (trk->
hitPattern()>>
i) & 1 );
 
 1369       if( expectedHitPattern.at(
i) == kMayHaveHit ) {
 
 1370         matchedLayers.emplace_back( 
i );
 
 1371       } 
else if( expectedHitPattern.at(
i) == kShouldHaveHit ) {
 
 1372         if( expectedHitPattern.at(
i) != recordedPattern ) {
 
 1375           matchedLayers.emplace_back( 
i );
 
 1378         if( expectedHitPattern.at(
i) != recordedPattern ) {
 
 1393     while( dphi >  TMath::Pi() ) dphi -= TMath::TwoPi();
 
 1394     while( dphi < -TMath::Pi() ) dphi += TMath::TwoPi();
 
 1396     ATH_MSG_DEBUG( 
" > " << __FUNCTION__ << 
": vtx phi = " << 
vertex.phi() << 
", track phi = " << trk->
phi() << 
", dphi = " << dphi
 
 1397                    << 
", oppositeFlag = " << oppositeFlag
 
 1398                    << 
", nPixelHits = " << 
static_cast<int>(PixelHits)
 
 1399                    << 
", nSCTHits = " << 
static_cast<int>(SctHits)
 
 1400                    << 
", nTRTHits = " << 
static_cast<int>(TRTHits)
 
 1401                    << 
", nMatchedLayers = " << matchedLayers.size() );
 
 1403     if( PixelHits == 0 && 
vertex.perp() > 300. ) {
 
 1404       ATH_MSG_DEBUG( 
" > " << __FUNCTION__ << 
": vertex r > 300 mm, w/o no pixel hits" );
 
 1409     if( matchedLayers.size() < 2 ) 
return false;
 
 1413       if( matchedLayers.size() < 4 ) 
return false;
 
 1419     if( oppositeFlag ) 
return false;
 
 1425       if( fabs( dphi ) > TMath::Pi()/2.0 ) 
return false;
 
 1428       TVector3 trkP; trkP.SetPtEtaPhi( trk->
pt(), trk->
eta(), trk->
phi() );
 
 1430       if( trkP.Dot( vtx ) < 0. ) 
return false;
 
 1450     const double absz = fabs( 
vertex.z() );
 
 1459       outsidePixelBarrel0_and_insidePixelBarrel1,
 
 1462       outsidePixelBarrel1_and_insidePixelBarrel2,
 
 1465       outsidePixelBarrel2_and_insidePixelBarrel3,
 
 1468       outsidePixelBarrel3_and_insideSctBarrel0,
 
 1471       outsideSctBarrel0_and_insideSctBarrel1,
 
 1476     int vertex_pattern = 0;
 
 1478       vertex_pattern = insideBeamPipe;
 
 1480     } 
else if( 
rad < 31.0 && absz < 331.5 ) {
 
 1481       vertex_pattern = insidePixelBarrel0;
 
 1483     } 
else if( 
rad < 38.4 && absz < 331.5 ) {
 
 1484       vertex_pattern = aroundPixelBarrel0;
 
 1486     } 
else if( 
rad < 47.7 && absz < 400.5 ) {
 
 1487       vertex_pattern = outsidePixelBarrel0_and_insidePixelBarrel1;
 
 1489     } 
else if( 
rad < 54.4 && absz < 400.5 ) {
 
 1490       vertex_pattern = aroundPixelBarrel1;
 
 1492     } 
else if( 
rad < 85.5 && absz < 400.5 ) {
 
 1493       vertex_pattern = outsidePixelBarrel1_and_insidePixelBarrel2;
 
 1495     } 
else if( 
rad < 92.2 && absz < 400.5 ) {
 
 1496       vertex_pattern = aroundPixelBarrel2;
 
 1498     } 
else if( 
rad < 119.3 && absz < 400.5 ) {
 
 1499       vertex_pattern = outsidePixelBarrel2_and_insidePixelBarrel3;
 
 1501     } 
else if( 
rad < 126.1 && absz < 400.5 ) {
 
 1502       vertex_pattern = aroundPixelBarrel3;
 
 1504     } 
else if( 
rad < 290 && absz < 749.0 ) {
 
 1505       vertex_pattern = outsidePixelBarrel3_and_insideSctBarrel0;
 
 1507     } 
else if( 
rad < 315 && absz < 749.0 ) {
 
 1508       vertex_pattern = aroundSctBarrel0;
 
 1510     } 
else if( 
rad < 360 && absz < 749.0 ) {
 
 1511       vertex_pattern = outsideSctBarrel0_and_insideSctBarrel1;
 
 1513     } 
else if( 
rad < 390 && absz < 749.0 ) {
 
 1514       vertex_pattern = aroundSctBarrel1;
 
 1519     unsigned nPixelLayers { 0 };
 
 1531     if( vertex_pattern == insideBeamPipe ) {
 
 1534       if( nPixelLayers < 3 )                     
return false;
 
 1537     } 
else if( vertex_pattern == insidePixelBarrel0 ) {
 
 1540       if( nPixelLayers < 3 )                     
return false;
 
 1544     else if( vertex_pattern == aroundPixelBarrel0 ) {
 
 1548       if( nPixelLayers < 2 )                     
return false;
 
 1552     else if( vertex_pattern == outsidePixelBarrel0_and_insidePixelBarrel1 ) {
 
 1556       if( nPixelLayers < 2 )                     
return false;
 
 1560     else if( vertex_pattern == aroundPixelBarrel1 ) {
 
 1565       if( nPixelLayers < 2 )                     
return false;
 
 1569     else if( vertex_pattern == outsidePixelBarrel1_and_insidePixelBarrel2 ) {
 
 1574       if( nPixelLayers < 2 )                     
return false;
 
 1578     else if( vertex_pattern == aroundPixelBarrel2 ) {
 
 1587     else if( vertex_pattern == outsidePixelBarrel2_and_insidePixelBarrel3 ) {
 
 1595     else if( vertex_pattern == aroundPixelBarrel3 ) {
 
 1605     else if( vertex_pattern == outsidePixelBarrel3_and_insideSctBarrel0 ) {
 
 1615     else if( vertex_pattern == aroundSctBarrel0 ) {
 
 1626     else if( vertex_pattern == outsideSctBarrel0_and_insideSctBarrel1 ) {
 
 1637     else if( vertex_pattern == aroundSctBarrel1 ) {
 
 1664     const double absz = fabs( 
vertex.z() );
 
 1673       outsidePixelBarrel0_and_insidePixelBarrel1,
 
 1676       outsidePixelBarrel1_and_insidePixelBarrel2,
 
 1679       outsidePixelBarrel2_and_insidePixelBarrel3,
 
 1682       outsidePixelBarrel3_and_insideSctBarrel0,
 
 1685       outsideSctBarrel0_and_insideSctBarrel1,
 
 1690     int vertex_pattern = 0;
 
 1692       vertex_pattern = insideBeamPipe;
 
 1694     } 
else if( 
rad < 31.0 && absz < 331.5 ) {
 
 1695       vertex_pattern = insidePixelBarrel0;
 
 1697     } 
else if( 
rad < 38.4 && absz < 331.5 ) {
 
 1698       vertex_pattern = aroundPixelBarrel0;
 
 1700     } 
else if( 
rad < 47.7 && absz < 400.5 ) {
 
 1701       vertex_pattern = outsidePixelBarrel0_and_insidePixelBarrel1;
 
 1703     } 
else if( 
rad < 54.4 && absz < 400.5 ) {
 
 1704       vertex_pattern = aroundPixelBarrel1;
 
 1706     } 
else if( 
rad < 85.5 && absz < 400.5 ) {
 
 1707       vertex_pattern = outsidePixelBarrel1_and_insidePixelBarrel2;
 
 1709     } 
else if( 
rad < 92.2 && absz < 400.5 ) {
 
 1710       vertex_pattern = aroundPixelBarrel2;
 
 1712     } 
else if( 
rad < 119.3 && absz < 400.5 ) {
 
 1713       vertex_pattern = outsidePixelBarrel2_and_insidePixelBarrel3;
 
 1715     } 
else if( 
rad < 126.1 && absz < 400.5 ) {
 
 1716       vertex_pattern = aroundPixelBarrel3;
 
 1718     } 
else if( 
rad < 290 && absz < 749.0 ) {
 
 1719       vertex_pattern = outsidePixelBarrel3_and_insideSctBarrel0;
 
 1721     } 
else if( 
rad < 315 && absz < 749.0 ) {
 
 1722       vertex_pattern = aroundSctBarrel0;
 
 1724     } 
else if( 
rad < 360 && absz < 749.0 ) {
 
 1725       vertex_pattern = outsideSctBarrel0_and_insideSctBarrel1;
 
 1727     } 
else if( 
rad < 390 && absz < 749.0 ) {
 
 1728       vertex_pattern = aroundSctBarrel1;
 
 1734     unsigned nPixelLayers { 0 };
 
 1746     if( vertex_pattern == insideBeamPipe ) {
 
 1750       if( nPixelLayers < 3                     ) 
return false;
 
 1752     } 
else if( vertex_pattern == insidePixelBarrel0 ) {
 
 1756       if( nPixelLayers < 3                     ) 
return false;
 
 1761     else if( vertex_pattern == aroundPixelBarrel0 ) {
 
 1766       if( nPixelLayers < 3                     ) 
return false;
 
 1770     else if( vertex_pattern == outsidePixelBarrel0_and_insidePixelBarrel1 ) {
 
 1774       if( nPixelLayers < 3                     ) 
return false;
 
 1778     else if( vertex_pattern == aroundPixelBarrel1 ) {
 
 1783       if( nPixelLayers < 2                     ) 
return false;
 
 1787     else if( vertex_pattern == outsidePixelBarrel1_and_insidePixelBarrel2 ) {
 
 1791       if( nPixelLayers < 2                     ) 
return false;
 
 1795     else if( vertex_pattern == aroundPixelBarrel2 ) {
 
 1802     else if( vertex_pattern == outsidePixelBarrel2_and_insidePixelBarrel3 ) {
 
 1807     else if( vertex_pattern == aroundPixelBarrel3 ) {
 
 1815     else if( vertex_pattern == outsidePixelBarrel3_and_insideSctBarrel0 ) {
 
 1822     else if( vertex_pattern == aroundSctBarrel0 ) {
 
 1830     else if( vertex_pattern == outsideSctBarrel0_and_insideSctBarrel1 ) {
 
 1837     else if( vertex_pattern == aroundSctBarrel1 ) {
 
 1858     const double absz = fabs( 
vertex.z() );
 
 1867       outsidePixelBarrel1_and_insidePixelBarrel2,
 
 1870       outsidePixelBarrel2_and_insidePixelBarrel3,
 
 1873       outsidePixelBarrel3_and_insideSctBarrel0,
 
 1876       outsideSctBarrel0_and_insideSctBarrel1,
 
 1881     Int_t vertex_pattern = 0;
 
 1883       vertex_pattern = insideBeamPipe;
 
 1885     } 
else if( 
rad < 47.7 && absz < 400.5 ) {
 
 1886       vertex_pattern = insidePixelBarrel1;
 
 1888     } 
else if( 
rad < 54.4 && absz < 400.5 ) {
 
 1889       vertex_pattern = aroundPixelBarrel1;
 
 1891     } 
else if( 
rad < 85.5 && absz < 400.5 ) {
 
 1892       vertex_pattern = outsidePixelBarrel1_and_insidePixelBarrel2;
 
 1894     } 
else if( 
rad < 92.2 && absz < 400.5 ) {
 
 1895       vertex_pattern = aroundPixelBarrel2;
 
 1897     } 
else if( 
rad < 119.3 && absz < 400.5 ) {
 
 1898       vertex_pattern = outsidePixelBarrel2_and_insidePixelBarrel3;
 
 1900     } 
else if( 
rad < 126.1 && absz < 400.5 ) {
 
 1901       vertex_pattern = aroundPixelBarrel3;
 
 1903     } 
else if( 
rad < 290 && absz < 749.0 ) {
 
 1904       vertex_pattern = outsidePixelBarrel3_and_insideSctBarrel0;
 
 1906     } 
else if( 
rad < 315 && absz < 749.0 ) {
 
 1907       vertex_pattern = aroundSctBarrel0;
 
 1909     } 
else if( 
rad < 360 && absz < 749.0 ) {
 
 1910       vertex_pattern = outsideSctBarrel0_and_insideSctBarrel1;
 
 1912     } 
else if( 
rad < 390 && absz < 749.0 ) {
 
 1913       vertex_pattern = aroundSctBarrel1;
 
 1920     if( vertex_pattern == insideBeamPipe ) {
 
 1927     else if( vertex_pattern == insidePixelBarrel1 ) {
 
 1933     else if( vertex_pattern == aroundPixelBarrel1 ) {
 
 1940     else if( vertex_pattern == outsidePixelBarrel1_and_insidePixelBarrel2 ) {
 
 1947     else if( vertex_pattern == aroundPixelBarrel2 ) {
 
 1955     else if( vertex_pattern == outsidePixelBarrel2_and_insidePixelBarrel3 ) {
 
 1962     else if( vertex_pattern == aroundPixelBarrel3 ) {
 
 1971     else if( vertex_pattern == outsidePixelBarrel3_and_insideSctBarrel0 ) {
 
 1980     else if( vertex_pattern == aroundSctBarrel0 ) {
 
 1990     else if( vertex_pattern == outsideSctBarrel0_and_insideSctBarrel1 ) {
 
 2000     else if( vertex_pattern == aroundSctBarrel1 ) {
 
 2023     const double absz = fabs( 
vertex.z() );
 
 2032       outsidePixelBarrel1_and_insidePixelBarrel2,
 
 2035       outsidePixelBarrel2_and_insidePixelBarrel3,
 
 2038       outsidePixelBarrel3_and_insideSctBarrel0,
 
 2041       outsideSctBarrel0_and_insideSctBarrel1,
 
 2046     Int_t vertex_pattern = 0;
 
 2048       vertex_pattern = insideBeamPipe;
 
 2050     } 
else if( 
rad < 47.7 && absz < 400.5 ) {
 
 2051       vertex_pattern = insidePixelBarrel1;
 
 2053     } 
else if( 
rad < 54.4 && absz < 400.5 ) {
 
 2054       vertex_pattern = aroundPixelBarrel1;
 
 2056     } 
else if( 
rad < 85.5 && absz < 400.5 ) {
 
 2057       vertex_pattern = outsidePixelBarrel1_and_insidePixelBarrel2;
 
 2059     } 
else if( 
rad < 92.2 && absz < 400.5 ) {
 
 2060       vertex_pattern = aroundPixelBarrel2;
 
 2062     } 
else if( 
rad < 119.3 && absz < 400.5 ) {
 
 2063       vertex_pattern = outsidePixelBarrel2_and_insidePixelBarrel3;
 
 2065     } 
else if( 
rad < 126.1 && absz < 400.5 ) {
 
 2066       vertex_pattern = aroundPixelBarrel3;
 
 2068     } 
else if( 
rad < 290 && absz < 749.0 ) {
 
 2069       vertex_pattern = outsidePixelBarrel3_and_insideSctBarrel0;
 
 2071     } 
else if( 
rad < 315 && absz < 749.0 ) {
 
 2072       vertex_pattern = aroundSctBarrel0;
 
 2074     } 
else if( 
rad < 360 && absz < 749.0 ) {
 
 2075       vertex_pattern = outsideSctBarrel0_and_insideSctBarrel1;
 
 2077     } 
else if( 
rad < 390 && absz < 749.0 ) {
 
 2078       vertex_pattern = aroundSctBarrel1;
 
 2085     if( vertex_pattern == insideBeamPipe ) {
 
 2092     else if( vertex_pattern == insidePixelBarrel1 ) {
 
 2098     else if( vertex_pattern == aroundPixelBarrel1 ) {
 
 2105     else if( vertex_pattern == outsidePixelBarrel1_and_insidePixelBarrel2 ) {
 
 2111     else if( vertex_pattern == aroundPixelBarrel2 ) {
 
 2118     else if( vertex_pattern == outsidePixelBarrel2_and_insidePixelBarrel3 ) {
 
 2123     else if( vertex_pattern == aroundPixelBarrel3 ) {
 
 2130     else if( vertex_pattern == outsidePixelBarrel3_and_insideSctBarrel0 ) {
 
 2136     else if( vertex_pattern == aroundSctBarrel0 ) {
 
 2143     else if( vertex_pattern == outsideSctBarrel0_and_insideSctBarrel1 ) {
 
 2149     else if( vertex_pattern == aroundSctBarrel1 ) {
 
 2210     if( m_extrapolatedPatternBank.find( trk ) == m_extrapolatedPatternBank.end() ) {
 
 2212       std::unique_ptr<ExtrapolatedPattern> exPattern_along( extrapolatedPattern( trk, 
Trk::alongMomentum ) );
 
 2214       m_extrapolatedPatternBank.emplace( trk, std::make_pair( std::move(exPattern_along), 
nullptr ) );
 
 2218     if( 
vertex.perp() < 31.0 ) {
 
 2219       double dphi = trk->
phi() - 
vertex.phi();
 
 2220       while( dphi >  TMath::Pi() ) { dphi -= TMath::TwoPi(); }
 
 2221       while( dphi < -TMath::Pi() ) { dphi += TMath::TwoPi(); }
 
 2222       if( 
cos(dphi) < -0.8 ) 
return false;
 
 2225     auto& exPattern = m_extrapolatedPatternBank.at( trk );
 
 2227     using LayerCombination = std::vector<int>;
 
 2229     std::map<LayerCombination, unsigned> layerMap;
 
 2230     if( layerMap.empty() ) {
 
 2273       const LayerCombination comb { std::get<detector>( point ), std::get<bec>( point ), std::get<layer>( point ) };
 
 2275       for( 
auto& pair : layerMap ) {
 
 2276         if( pair.first == comb ) {
 
 2287     auto& exPattern_along = *( exPattern.first  );
 
 2289     for( 
auto itr = exPattern_along.begin(); itr != exPattern_along.end(); ++itr ) {
 
 2290       if( 
std::next( itr ) == exPattern_along.end() ) 
continue;
 
 2292       const auto& point = *itr;
 
 2294       ATH_MSG_VERBOSE( 
" > " <<  __FUNCTION__ << 
": isGood = " << std::get<isGood>( point ) );
 
 2296       if( !std::get<isGood>( point ) ) {
 
 2297         const auto& detectorType = getDetectorType( point );
 
 2298         disabledPattern += (1 << detectorType);
 
 2303     uint32_t modifiedPattern = disabledPattern | hitPattern;
 
 2305     std::string 
msg = 
"Disabled hit pattern: ";
 
 2307       msg += Form(
"%u", ( disabledPattern >> 
i ) & 1 );
 
 2311     msg = 
"Recorded hit pattern: ";
 
 2313       msg += Form(
"%u", ( hitPattern >> 
i ) & 1 );
 
 2317     return patternCheck( modifiedPattern, 
vertex );
 
 2328     const bool& check_itrk = ( this->*m_patternStrategyFuncs[m_checkPatternStrategy] )( itrk, FitVertex );
 
 2329     const bool& check_jtrk = ( this->*m_patternStrategyFuncs[m_checkPatternStrategy] )( jtrk, FitVertex );
 
 2331     return ( check_itrk && check_jtrk );
 
 2337   void VrtSecInclusive::removeInconsistentTracks( 
WrkVrt& wrkvrt )
 
 2342     std::map< std::deque<long int>*, std::vector<const xAOD::TrackParticle*>& > indexMap
 
 2347     for( 
auto& pair : indexMap ) {
 
 2350       auto& tracks  = pair.second;
 
 2353                                     [&]( 
auto& 
index ) {
 
 2354                                       bool isConsistent = (this->*m_patternStrategyFuncs[m_checkPatternStrategy] )( tracks.at(index), vertex );
 
 2355                                       return !isConsistent;
 
 2366   void VrtSecInclusive::dumpTruthInformation() {
 
 2372     auto sc0 = evtStore()->retrieve( eventInfo, 
"EventInfo" );
 
 2373     if( sc0.isFailure() ) { 
return; }
 
 2379     auto sc1 = evtStore()->retrieve( truthParticles, 
"TruthParticles" );
 
 2380     if( sc1.isFailure() ) { 
return; }
 
 2382     auto sc2 = evtStore()->retrieve( truthVertices, 
"TruthVertices" );
 
 2383     if( sc2.isFailure() ) { 
return; }
 
 2385     if( !truthParticles ) { 
return; }
 
 2386     if( !truthVertices  ) { 
return; }
 
 2388     m_tracingTruthVertices.
clear();
 
 2390     std::vector<const xAOD::TruthParticle*> truthSvTracks;
 
 2397       if( truthVertex->nIncomingParticles() != 1 )                      
return false;
 
 2398       if( !truthVertex->incomingParticle(0) )                           
return false;
 
 2399       if( abs(truthVertex->incomingParticle(0)->pdgId()) < 1000000 )    
return false;
 
 2400       if( abs(truthVertex->incomingParticle(0)->pdgId()) > 1000000000 ) 
return false; 
 
 2402       bool hasNeutralino = 
false;
 
 2403       for( 
unsigned ip = 0; 
ip < truthVertex->nOutgoingParticles(); 
ip++ ) {
 
 2404         const auto* 
p = truthVertex->outgoingParticle(
ip);
 
 2405         if( abs( 
p->pdgId() ) == 1000022 ) {
 
 2406           hasNeutralino = 
true;
 
 2410       return hasNeutralino;
 
 2414       if( truthVertex->nIncomingParticles() != 1 )                      
return false;
 
 2415       if( !truthVertex->incomingParticle(0) )                           
return false;
 
 2416       if( abs(truthVertex->incomingParticle(0)->pdgId()) != 50 )        
return false;
 
 2421       if( truthVertex->nIncomingParticles() != 1 )                      
return false;
 
 2422       if( !truthVertex->incomingParticle(0) )                           
return false;
 
 2423       if( abs(truthVertex->incomingParticle(0)->pdgId()) != 36 )        
return false;
 
 2428       if( truthVertex->nIncomingParticles() != 1 )                      
return false;
 
 2429       if( !truthVertex->incomingParticle(0) )                           
return false;
 
 2430       if( abs(truthVertex->incomingParticle(0)->pdgId()) != 310 )       
return false;
 
 2435       if( truthVertex->nIncomingParticles() != 1 )                      
return false;
 
 2436       if( !truthVertex->incomingParticle(0) )                           
return false;
 
 2437       if( abs(truthVertex->incomingParticle(0)->pdgId()) <= 500 || abs(truthVertex->incomingParticle(0)->pdgId()) >= 600 ) 
return false;
 
 2442       if( truthVertex->nIncomingParticles() != 1 )                      
return false;
 
 2443       if( !truthVertex->incomingParticle(0) )                           
return false;
 
 2445       const auto* 
parent = truthVertex->incomingParticle(0);
 
 2446       if( 
parent->isLepton() )                                          
return false;
 
 2448       TLorentzVector p4sum_in;
 
 2449       TLorentzVector p4sum_out;
 
 2450       for( 
unsigned ip = 0; 
ip < truthVertex->nIncomingParticles(); 
ip++ ) {
 
 2451         const auto* 
particle = truthVertex->incomingParticle(
ip);
 
 2455       for( 
unsigned ip = 0; 
ip < truthVertex->nOutgoingParticles(); 
ip++ ) {
 
 2456         const auto* 
particle = truthVertex->outgoingParticle(
ip);
 
 2460       return p4sum_out.E() - p4sum_in.E() >= 100.;
 
 2466     std::map<std::string, ParticleSelectFunc> selectFuncs { { 
"",        selectNone    },
 
 2467                                                             { 
"Kshort",  selectKshort  },
 
 2468                                                             { 
"Bhadron", selectBhadron },
 
 2469                                                             { 
"Rhadron", selectRhadron },
 
 2470                                                             { 
"HNL",     selectHNL     },
 
 2471                                                             { 
"Higgs",   selectHiggs   },
 
 2472                                                             { 
"HadInt",  selectHadInt  }  };
 
 2475     if( selectFuncs.find( m_jp.truthParticleFilter ) == selectFuncs.end() ) {
 
 2476       ATH_MSG_WARNING( 
" > " << __FUNCTION__ << 
": invalid function specification: " << m_jp.truthParticleFilter );
 
 2480     auto selectFunc = selectFuncs.at( m_jp.truthParticleFilter );
 
 2483     for( 
const auto *truthVertex : *truthVertices ) {
 
 2484       if( selectFunc( truthVertex ) ) {
 
 2485         m_tracingTruthVertices.emplace_back( truthVertex );
 
 2487         msg += Form(
"pdgId = %d, (r, z) = (%.2f, %.2f), ", truthVertex->incomingParticle(0)->pdgId(), truthVertex->perp(), truthVertex->z());
 
 2488         msg += Form(
"nOutgoing = %lu, ", truthVertex->nOutgoingParticles() );
 
 2489         msg += Form(
"mass = %.3f GeV, pt = %.3f GeV", truthVertex->incomingParticle(0)->m()/1.e3, truthVertex->incomingParticle(0)->pt()/1.e3 );
 
 2494     if( m_jp.FillHist ) {
 
 2495       for( 
const auto* truthVertex : m_tracingTruthVertices ) {
 
 2496         m_hists[
"nMatchedTruths"]->Fill( 0., truthVertex->perp() );