22 #include "TLorentzVector.h"
39 StatusCode VrtSecInclusive::extractIncompatibleTrackPairs( std::vector<WrkVrt>* workVerticesContainer )
49 if( m_jp.FillIntermediateVertices ) {
50 ATH_CHECK( evtStore()->
retrieve( twoTrksVertexContainer,
"VrtSecInclusive_" + m_jp.all2trksVerticesContainerName + m_jp.augVerString ) );
56 std::vector<const xAOD::TrackParticle*> baseTracks;
57 std::vector<const xAOD::NeutralParticle*> dummyNeutrals;
59 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": Selected Tracks = "<< m_selectedTracks.size());
60 if( m_jp.FillHist ) { m_hists[
"selTracksDist"]->Fill( m_selectedTracks.size() ); }
64 enum recoStep { kStart, kInitVtxPosition, kImpactParamCheck, kVKalVrtFit, kChi2, kVposCut, kPatternMatch };
66 const double maxR { 563. };
67 double roughD0Cut = 100.;
68 double roughZ0Cut = 50.;
69 if(m_jp.doDisappearingTrackVertexing){
75 std::map<const xAOD::TruthVertex*, bool> matchMap;
78 for(
auto itrk = m_selectedTracks.begin(); itrk != m_selectedTracks.end(); ++itrk ) {
79 for(
auto jtrk =
std::next(itrk); jtrk != m_selectedTracks.end(); ++jtrk ) {
83 const int itrk_id = itrk - m_selectedTracks.begin();
84 const int jtrk_id = jtrk - m_selectedTracks.begin();
91 m_incomp.emplace_back( itrk_id, jtrk_id );
93 if(m_jp.doDisappearingTrackVertexing) {
98 if ( !cont_i || !cont_j ) {
108 ATH_MSG_DEBUG(
" link itrk (" << (*itrk)->index() <<
") or jtrk (" << (*jtrk)->index() <<
") is not valid");
118 if( std::abs( (*itrk)->d0() ) < m_jp.twoTrkVtxFormingD0Cut && std::abs( (*jtrk)->d0() ) < m_jp.twoTrkVtxFormingD0Cut )
continue;
121 baseTracks.emplace_back( *itrk );
122 baseTracks.emplace_back( *jtrk );
124 if( m_jp.FillHist ) m_hists[
"incompMonitor"]->Fill( kStart );
129 std::unique_ptr<Trk::IVKalState> state = m_fitSvc->makeState();
130 StatusCode sc = m_fitSvc->VKalVrtFitFast( baseTracks, initVertex, *state );
131 if(
sc.isFailure() ) {
132 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": fast crude estimation fails ");
136 if( initVertex.perp() > maxR ) {
139 if( m_jp.doDisappearingTrackVertexing && initVertex.perp() <m_jp.twoTrVrtMinRadius){
142 if( m_jp.FillHist ) m_hists[
"incompMonitor"]->Fill( kInitVtxPosition );
144 std::vector<double> impactParameters;
145 std::vector<double> impactParErrors;
147 if( !getSVImpactParameters( *itrk, initVertex, impactParameters, impactParErrors) )
continue;
148 const auto roughD0_itrk = impactParameters.at(TrkParameter::k_d0);
149 const auto roughZ0_itrk = impactParameters.at(TrkParameter::k_z0);
150 if( fabs( impactParameters.at(0)) > roughD0Cut || fabs( impactParameters.at(1) ) > roughZ0Cut ) {
154 if( !getSVImpactParameters( *jtrk, initVertex, impactParameters, impactParErrors) )
continue;
155 const auto roughD0_jtrk = impactParameters.at(TrkParameter::k_d0);
156 const auto roughZ0_jtrk = impactParameters.at(TrkParameter::k_z0);
157 if( fabs( impactParameters.at(0) ) > roughD0Cut || fabs( impactParameters.at(1) ) > roughZ0Cut ) {
160 if( m_jp.FillHist ) m_hists[
"incompMonitor"]->Fill( kImpactParamCheck );
162 m_fitSvc->setApproximateVertex( initVertex.x(), initVertex.y(), initVertex.z(), *state );
167 sc = m_fitSvc->VKalVrtFit( baseTracks,
173 if(
sc.isFailure() ) {
176 if( m_jp.FillHist ) m_hists[
"incompMonitor"]->Fill( kVKalVrtFit );
181 const double vPosMomAngT = ( vDist.x()*wrkvrt.
vertexMom.Px()+vDist.y()*wrkvrt.
vertexMom.Py() ) / vDist.perp() / wrkvrt.
vertexMom.Pt();
187 const double dist_fromPV = vDist.norm();
188 if( m_jp.FillHist ) m_hists[
"2trkVtxDistFromPV"]->Fill( dist_fromPV );
190 if( m_jp.FillNtuple ) {
192 m_ntupleVars->get<
unsigned int>(
"All2TrkVrtNum" )++;
193 m_ntupleVars->get< std::vector<double> >(
"All2TrkVrtMass" ) .emplace_back(wrkvrt.
vertexMom.M());
194 m_ntupleVars->get< std::vector<double> >(
"All2TrkVrtPt" ) .emplace_back(wrkvrt.
vertexMom.Perp());
195 m_ntupleVars->get< std::vector<int> > (
"All2TrkVrtCharge" ) .emplace_back(wrkvrt.
Charge);
196 m_ntupleVars->get< std::vector<double> >(
"All2TrkVrtX" ) .emplace_back(wrkvrt.
vertex.x());
197 m_ntupleVars->get< std::vector<double> >(
"All2TrkVrtY" ) .emplace_back(wrkvrt.
vertex.y());
198 m_ntupleVars->get< std::vector<double> >(
"All2TrkVrtZ" ) .emplace_back(wrkvrt.
vertex.z());
199 m_ntupleVars->get< std::vector<double> >(
"All2TrkVrtChiSq" ) .emplace_back(wrkvrt.
Chi2);
206 if( m_jp.FillIntermediateVertices ) {
210 for(
const auto *trk: baseTracks ) {
216 vertex->addTrackAtVertex( trackElementLink, 1. );
232 isFakeAcc(*
vertex) =
true;
242 if( m_jp.FillNtuple ) m_ntupleVars->get< std::vector<int> >(
"All2TrkSumBLHits" ).emplace_back( trkiBLHit + trkjBLHit );
245 if( m_jp.FillHist ) m_hists[
"2trkChi2Dist"]->Fill( log10( wrkvrt.
Chi2 ) );
247 if( wrkvrt.
fitQuality() > m_jp.SelVrtChi2Cut) {
248 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": failed to pass chi2 threshold." );
251 if( m_jp.FillHist ) m_hists[
"incompMonitor"]->Fill( kChi2 );
254 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": attempting form vertex from ( " << itrk_id <<
", " << jtrk_id <<
" )." );
255 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": candidate vertex: "
256 <<
" isGood = " << (wrkvrt.
isGood?
"true" :
"false")
261 <<
", (r, z) = (" << wrkvrt.
vertex.perp()
262 <<
", " << wrkvrt.
vertex.z() <<
")" );
264 for(
const auto* truthVertex : m_tracingTruthVertices ) {
265 Amg::Vector3D vTruth( truthVertex->x(), truthVertex->y(), truthVertex->z() );
268 const auto distance = vReco - vTruth;
281 ATH_MSG_DEBUG (
" > " << __FUNCTION__ <<
": truth-matched candidate! : signif^2 = " <<
s2 );
282 matchMap.emplace( truthVertex,
true );
286 if( m_jp.FillHist ) {
287 dynamic_cast<TH2F*
>( m_hists[
"vPosDist"] )->Fill( wrkvrt.
vertex.perp(), vPos );
288 dynamic_cast<TH2F*
>( m_hists[
"vPosMomAngTDist"] )->Fill( wrkvrt.
vertex.perp(), vPosMomAngT );
289 m_hists[
"vPosMomAngT"] ->Fill( vPosMomAngT );
290 m_hists[
"vPosMomAng3D"] ->Fill( vPosMomAng3D );
293 if( m_jp.doTwoTrSoftBtag ){
294 if(dist_fromPV < m_jp.twoTrVrtMinDistFromPV ){
295 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": failed to pass the 2tr vertex min distance from PV cut." );
299 if( vPosMomAng3D < m_jp.twoTrVrtAngleCut ){
300 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": failed to pass the vertex angle cut." );
305 if( m_jp.doPVcompatibilityCut ) {
306 if(
cos( dphi1 ) < -0.8 &&
cos( dphi2 ) < -0.8 ) {
307 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": failed to pass the vPos cut. (both tracks are opposite against the vertex pos)" );
310 if (m_jp.doTightPVcompatibilityCut && (
cos( dphi1 ) < -0.8 ||
cos( dphi2 ) < -0.8)){
311 ATH_MSG_DEBUG(
" > "<< __FUNCTION__ <<
": failed to pass the tightened vPos cut. (at least one track is opposite against the vertex pos)" );
314 if( vPosMomAngT < -0.8 ) {
315 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": failed to pass the vPos cut. (pos-mom directions are opposite)" );
318 if( vPos < m_jp.pvCompatibilityCut ) {
319 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": failed to pass the vPos cut." );
323 if( m_jp.FillHist ) m_hists[
"incompMonitor"]->Fill( kVposCut );
326 if( m_jp.removeFakeVrt && !m_jp.removeFakeVrtLate ) {
327 if( !this->passedFakeReject( wrkvrt.
vertex, (*itrk), (*jtrk) ) ) {
329 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": failed to pass fake rejection algorithm." );
333 if( m_jp.FillHist ) m_hists[
"incompMonitor"]->Fill( kPatternMatch );
335 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": passed fake rejection." );
337 if( m_jp.FillNtuple ) {
339 m_ntupleVars->get<
unsigned int >(
"AfFakVrtNum" )++;
340 m_ntupleVars->get< std::vector<double> >(
"AfFakVrtMass" ) .emplace_back(wrkvrt.
vertexMom.M());
341 m_ntupleVars->get< std::vector<double> >(
"AfFakVrtPt" ) .emplace_back(wrkvrt.
vertexMom.Perp());
342 m_ntupleVars->get< std::vector<int> > (
"AfFakVrtCharge" ) .emplace_back(wrkvrt.
Charge);
343 m_ntupleVars->get< std::vector<double> >(
"AfFakVrtX" ) .emplace_back(wrkvrt.
vertex.x());
344 m_ntupleVars->get< std::vector<double> >(
"AfFakVrtY" ) .emplace_back(wrkvrt.
vertex.y());
345 m_ntupleVars->get< std::vector<double> >(
"AfFakVrtZ" ) .emplace_back(wrkvrt.
vertex.z());
346 m_ntupleVars->get< std::vector<double> >(
"AfFakVrtChiSq" ) .emplace_back(wrkvrt.
Chi2);
350 if( m_jp.FillIntermediateVertices &&
vertex ) {
352 isFakeAcc(*
vertex) =
false;
362 workVerticesContainer->emplace_back( wrkvrt );
364 msg += Form(
" (%d, %d), ", itrk_id, jtrk_id );
366 if( m_jp.FillHist ) {
367 m_hists[
"initVertexDispD0"]->Fill( roughD0_itrk, initVertex.perp() );
368 m_hists[
"initVertexDispD0"]->Fill( roughD0_jtrk, initVertex.perp() );
369 m_hists[
"initVertexDispZ0"]->Fill( roughZ0_itrk, initVertex.z() );
370 m_hists[
"initVertexDispZ0"]->Fill( roughZ0_jtrk, initVertex.z() );
377 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": compatible track pairs = " <<
msg );
379 if( m_jp.FillNtuple ) m_ntupleVars->get<
unsigned int>(
"SizeIncomp" ) = m_incomp.size();
381 if( m_jp.FillHist ) {
382 for(
auto& pair: matchMap ) {
383 if( pair.second ) m_hists[
"nMatchedTruths"]->Fill( 1, pair.first->perp() );
387 return StatusCode::SUCCESS;
392 StatusCode VrtSecInclusive::findNtrackVertices( std::vector<WrkVrt> *workVerticesContainer )
395 if(m_jp.doDisappearingTrackVertexing){
397 return StatusCode::SUCCESS;
401 const auto compSize = m_selectedTracks.size()*(m_selectedTracks.size() - 1)/2 - m_incomp.size();
402 if( m_jp.FillHist ) { m_hists[
"2trkVerticesDist"]->Fill( compSize ); }
404 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": compatible track pair size = " << compSize );
405 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": incompatible track pair size = " << m_incomp.size() );
408 if( not m_jp.doFastMode ) {
410 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": incompatibility graph finder mode" );
413 workVerticesContainer->clear();
420 std::vector<long int> weit;
422 for(
auto& pair : m_incomp ) {
423 weit.emplace_back( pair.first + 1 );
424 weit.emplace_back( pair.second + 1 );
429 std::vector<long int> solution( m_selectedTracks.size() );
432 long int nEdges = m_incomp.size();
435 long int nTracks =
static_cast<long int>( m_selectedTracks.size() );
443 long int solutionSize { 0 };
446 std::vector<const xAOD::TrackParticle*> baseTracks;
447 std::vector<const xAOD::NeutralParticle*> dummyNeutrals;
449 std::unique_ptr<Trk::IVKalState> state = m_fitSvc->makeState();
450 auto pgraph = std::make_unique<Trk::PGraph>();
451 int iterationLimit(2000);
456 pgraph->pgraphm_( weit.data(), nEdges, nTracks, solution.data(), &solutionSize, nth);
458 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": Trk::pgraphm_() output: solutionSize = " << solutionSize );
459 if (0 == iterationLimit--){
460 ATH_MSG_WARNING(
"Iteration limit (2000) reached in VrtSecInclusive::findNtrackVertices, solution size = "<<solutionSize);
463 if(solutionSize <= 0)
break;
464 if(solutionSize == 1)
continue;
468 std::string
msg =
"solution = [ ";
469 for(
int i=0;
i< solutionSize;
i++) {
470 msg += Form(
"%ld, ", solution[
i]-1 );
483 for(
long int i = 0;
i<solutionSize;
i++) {
485 baseTracks.emplace_back( m_selectedTracks.at(solution[
i]-1) );
491 StatusCode sc = m_fitSvc->VKalVrtFitFast( baseTracks, initVertex, *state );
492 if(
sc.isFailure())
ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": fast crude estimation fails ");
494 m_fitSvc->setApproximateVertex( initVertex.x(), initVertex.y(), initVertex.z(), *state );
496 sc = m_fitSvc->VKalVrtFit(baseTracks, dummyNeutrals,
506 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": FoundAppVrt=" << solutionSize <<
", (r, z) = " << wrkvrt.
vertex.perp() <<
", " << wrkvrt.
vertex.z() <<
", chi2/ndof = " << wrkvrt.
fitQuality() );
508 if(
sc.isFailure() ) {
511 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": VKalVrtFit failed in 2-trk solution ==> give up.");
515 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": VKalVrtFit failed ==> retry...");
523 if( itrk == jtrk )
continue;
524 if(
tmp.isGood )
continue;
526 tmp.selectedTrackIndices.clear();
527 tmp.selectedTrackIndices.emplace_back( itrk );
528 tmp.selectedTrackIndices.emplace_back( jtrk );
531 baseTracks.emplace_back( m_selectedTracks.at( itrk ) );
532 baseTracks.emplace_back( m_selectedTracks.at( jtrk ) );
537 sc = m_fitSvc->VKalVrtFitFast( baseTracks, initVertex, *state );
538 if(
sc.isFailure() )
ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": fast crude estimation fails ");
540 m_fitSvc->setApproximateVertex( initVertex.x(), initVertex.y(), initVertex.z(), *state );
542 sc = m_fitSvc->VKalVrtFit(baseTracks, dummyNeutrals,
552 if(
sc.isFailure() )
continue;
560 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": Did not find any viable vertex in all 2-trk combinations. Give up.");
567 if(
std::find(
tmp.selectedTrackIndices.begin(),
tmp.selectedTrackIndices.end(), itrk ) !=
tmp.selectedTrackIndices.end() )
continue;
571 tmp.selectedTrackIndices.emplace_back( itrk );
573 for(
auto& jtrk :
tmp.selectedTrackIndices ) { baseTracks.emplace_back( m_selectedTracks.at(jtrk) ); }
578 sc = m_fitSvc->VKalVrtFitFast( baseTracks, initVertex, *state );
579 if(
sc.isFailure())
ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": fast crude estimation fails ");
581 m_fitSvc->setApproximateVertex( initVertex.x(), initVertex.y(), initVertex.z(), *state );
583 sc = m_fitSvc->VKalVrtFit(baseTracks, dummyNeutrals,
593 if(
sc.isFailure() ) {
601 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": VKalVrtFit succeeded; register the vertex to the list.");
605 workVerticesContainer->emplace_back( wrkvrt );
609 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": VKalVrtFit succeeded; register the vertex to the list.");
613 workVerticesContainer->emplace_back( wrkvrt );
622 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": rapid finder mode" );
626 std::set<long int> tracks;
629 std::vector<struct Cluster>
clusters;
631 for(
auto& wrkvrt : *workVerticesContainer ) {
633 bool foundCluster =
false;
636 if( (wrkvrt.vertex - cluster.position).norm() < 1.0 ) {
637 for(
auto& itrk : wrkvrt.selectedTrackIndices ) {
638 cluster.tracks.insert( itrk );
645 if( !foundCluster ) {
647 c.position = wrkvrt.vertex;
648 for(
auto& itrk : wrkvrt.selectedTrackIndices ) {
649 c.tracks.insert( itrk );
652 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": added a new cluster" );
658 std::vector<const xAOD::TrackParticle*> baseTracks;
659 std::vector<const xAOD::NeutralParticle*> dummyNeutrals;
661 workVerticesContainer->clear();
665 std::unique_ptr<Trk::IVKalState> state = m_fitSvc->makeState();
676 for(
const auto&
index: cluster.tracks) {
678 baseTracks.emplace_back( m_selectedTracks.at(
index ) );
684 StatusCode sc = m_fitSvc->VKalVrtFitFast( baseTracks, initVertex, *state );
685 if(
sc.isFailure())
ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": fast crude estimation fails ");
687 m_fitSvc->setApproximateVertex( initVertex.x(), initVertex.y(), initVertex.z(), *state );
689 sc = m_fitSvc->VKalVrtFit(baseTracks, dummyNeutrals,
699 if(
sc.isFailure() ) {
703 workVerticesContainer->emplace_back( wrkvrt );
708 if (m_jp.truncateWrkVertices){
709 if (workVerticesContainer->size() > m_jp.maxWrkVertices){
710 m_vertexingStatus = 3;
711 workVerticesContainer->resize(m_jp.maxWrkVertices);
719 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": Remove vertices fully contained in other vertices .");
720 while( workVerticesContainer->size() > 1 ) {
721 size_t tmpN = workVerticesContainer->size();
724 for(; iv<tmpN-1; iv++) {
726 for(; jv<tmpN; jv++) {
727 const auto nTCom = nTrkCommon( workVerticesContainer, {iv, jv} );
729 if( nTCom == workVerticesContainer->at(iv).selectedTrackIndices.size() ) { workVerticesContainer->erase(workVerticesContainer->begin()+iv);
break; }
730 else if( nTCom == workVerticesContainer->at(jv).selectedTrackIndices.size() ) { workVerticesContainer->erase(workVerticesContainer->begin()+jv);
break; }
735 if(iv==tmpN-1)
break;
739 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": Identify remaining 2-track vertices with very bad Chi2 and mass (b-tagging).");
740 for(
auto& wrkvrt : *workVerticesContainer ) {
742 if( TMath::Prob( wrkvrt.Chi2, wrkvrt.ndof() ) < m_jp.improveChi2ProbThreshold ) wrkvrt.isGood =
false;
743 if( wrkvrt.selectedTrackIndices.size() != 2 )
continue;
744 if( m_jp.FillHist ) m_hists[
"NtrkChi2Dist"]->Fill( log10( wrkvrt.fitQuality() ) );
747 if( m_jp.FillNtuple) m_ntupleVars->get<
unsigned int>(
"NumInitSecVrt" ) = workVerticesContainer->size();
749 return StatusCode::SUCCESS;
754 StatusCode VrtSecInclusive::rearrangeTracks( std::vector<WrkVrt> *workVerticesContainer )
756 if(m_jp.doDisappearingTrackVertexing){
758 return StatusCode::SUCCESS;
764 std::vector<long int> processedTracks;
766 unsigned mergeCounter { 0 };
767 unsigned brokenCounter { 0 };
768 unsigned removeTrackCounter { 0 };
773 long int maxSharedTrack;
774 long int worstMatchingVertex;
781 std::map<long int, std::vector<long int> > trackToVertexMap;
784 trackClassification( workVerticesContainer, trackToVertexMap );
787 auto worstChi2 = findWorstChi2ofMaximallySharedTrack( workVerticesContainer, trackToVertexMap, maxSharedTrack, worstMatchingVertex );
790 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": no shared tracks are found --> exit the while loop." );
794 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": vertex [" << worstMatchingVertex <<
"]: maximally shared track index = " << maxSharedTrack
795 <<
", multiplicity = " << trackToVertexMap.at( maxSharedTrack ).size()
796 <<
", worst chi2_trk = " << worstChi2 );
799 if( worstChi2 < m_jp.TrackDetachCut ) {
804 std::vector< std::pair<unsigned, unsigned> > badPairs;
810 unsigned nShared { 0 };
813 auto& vrtList = trackToVertexMap.at( maxSharedTrack );
815 auto nGood = std::count_if( vrtList.begin(), vrtList.end(), [&](
auto&
v ) { return workVerticesContainer->at(v).isGood; } );
818 std::vector< std::tuple< std::pair<unsigned, unsigned>,
double,
unsigned> > significanceTuple;
819 enum { kIndexPair, kSignificance, kNshared };
821 for(
auto ivrt = vrtList.begin(); ivrt != vrtList.end(); ++ivrt ) {
822 for(
auto jvrt =
std::next( ivrt ); jvrt != vrtList.end(); ++jvrt ) {
823 auto pair = std::pair<unsigned, unsigned>( *ivrt, *jvrt );
825 if( !( workVerticesContainer->at(*ivrt).isGood ) )
continue;
826 if( !( workVerticesContainer->at(*jvrt).isGood ) )
continue;
829 if(
std::find( badPairs.begin(), badPairs.end(), pair ) != badPairs.end() )
continue;
831 auto signif = significanceBetweenVertices( workVerticesContainer->at( *ivrt ), workVerticesContainer->at( *jvrt ) );
833 auto& ivrtTrks = workVerticesContainer->at(*ivrt).selectedTrackIndices;
834 auto& jvrtTrks = workVerticesContainer->at(*jvrt).selectedTrackIndices;
836 auto nSharedTracks = std::count_if( ivrtTrks.begin(), ivrtTrks.end(),
838 return std::find( jvrtTrks.begin(), jvrtTrks.end(), index ) != jvrtTrks.end();
841 significanceTuple.emplace_back( pair, signif, nSharedTracks );
845 if( significanceTuple.empty() ) {
846 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": no vertex pairs are found --> exit the while loop." );
850 auto minSignificanceTuple = std::min_element( significanceTuple.begin(), significanceTuple.end(), [&](
auto&
t1,
auto&
t2 ) { return std::get<kSignificance>(t1) < std::get<kSignificance>(t2); } );
852 indexPair = std::get<kIndexPair> ( *minSignificanceTuple );
853 minSignificance = std::get<kSignificance> ( *minSignificanceTuple );
854 nShared = std::get<kNshared> ( *minSignificanceTuple );
857 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": minSignificance = " << minSignificance );
859 if( minSignificance < m_jp.VertexMergeCut || nShared >= 2 ) {
861 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": attempt to merge vertices " << indexPair.first <<
" and " << indexPair.second );
863 WrkVrt vertex_backup1 = workVerticesContainer->at( indexPair.first );
864 WrkVrt vertex_backup2 = workVerticesContainer->at( indexPair.second );
866 StatusCode sc = mergeVertices( workVerticesContainer->at( indexPair.first ), workVerticesContainer->at( indexPair.second ) );
868 if( m_jp.FillHist ) { m_hists[
"mergeType"]->Fill( RECONSTRUCT_NTRK ); }
870 if(
sc.isFailure() ) {
872 workVerticesContainer->at( indexPair.first ) = vertex_backup1;
873 workVerticesContainer->at( indexPair.second ) = vertex_backup2;
874 badPairs.emplace_back( indexPair );
879 workVerticesContainer->at( indexPair.second ).isGood =
false;
886 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": Merged vertices " << indexPair.first <<
" and " << indexPair.second <<
". merged vertex multiplicity = " << workVerticesContainer->at( indexPair.first ).selectedTrackIndices.size() );
894 auto& wrkvrt = workVerticesContainer->at( worstMatchingVertex );
896 auto end =
std::remove_if( wrkvrt.selectedTrackIndices.begin(), wrkvrt.selectedTrackIndices.end(), [&](
auto&
index ) { return index == maxSharedTrack; } );
897 wrkvrt.selectedTrackIndices.erase(
end, wrkvrt.selectedTrackIndices.end() );
899 removeTrackCounter++;
901 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": removed track " << maxSharedTrack <<
" from vertex " << worstMatchingVertex );
903 if( wrkvrt.selectedTrackIndices.size() < 2 ) {
904 wrkvrt.isGood =
false;
910 if(
sc.isFailure() ) {
911 ATH_MSG_WARNING(
" > " << __FUNCTION__ <<
": detected vertex fitting failure!" );
924 auto& wrkvrt = workVerticesContainer->at( worstMatchingVertex );
926 auto end =
std::remove_if( wrkvrt.selectedTrackIndices.begin(), wrkvrt.selectedTrackIndices.end(), [&](
auto&
index ) { return index == maxSharedTrack; } );
927 wrkvrt.selectedTrackIndices.erase(
end, wrkvrt.selectedTrackIndices.end() );
929 if( wrkvrt.nTracksTotal() >=2 ) {
931 auto wrkvrt_backup = wrkvrt;
933 if(
sc.isFailure() ) {
934 ATH_MSG_WARNING(
" > " << __FUNCTION__ <<
": detected vertex fitting failure!" );
935 wrkvrt = wrkvrt_backup;
939 wrkvrt.isGood =
false;
943 removeTrackCounter++;
945 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": removed track " << maxSharedTrack <<
" from vertex " << worstMatchingVertex );
953 for(
auto& wrkvrt : *workVerticesContainer ) {
955 if(!wrkvrt.isGood )
continue;
956 if( wrkvrt.selectedTrackIndices.size() < 3 )
continue;
959 improveVertexChi2( wrkvrt );
960 if( wrkvrt.fitQuality() > backup.
fitQuality() ) wrkvrt = backup;
962 if( wrkvrt.nTracksTotal() < 2 ) wrkvrt.
isGood =
false;
966 if( m_jp.FillNtuple ) {
967 m_ntupleVars->get<
unsigned int>(
"NumRearrSecVrt" )=workVerticesContainer->size();
968 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": Size of Solution Set: "<< m_ntupleVars->get<
unsigned int>(
"NumRearrSecVrt" ));
971 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
"----------------------------------------------" );
972 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": Number of merges = " << mergeCounter <<
", Number of track removal = " << removeTrackCounter <<
", broken vertices = " << brokenCounter );
973 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
"----------------------------------------------" );
975 return StatusCode::SUCCESS;
980 StatusCode VrtSecInclusive::reassembleVertices( std::vector<WrkVrt>* workVerticesContainer )
989 unsigned reassembleCounter { 0 };
992 std::sort( workVerticesContainer->begin(), workVerticesContainer->end(), [](
WrkVrt& v1,
WrkVrt&
v2) { return v1.selectedTrackIndices.size() < v2.selectedTrackIndices.size(); } );
994 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": #vertices = " << workVerticesContainer->size() );
996 for(
auto& wrkvrt : *workVerticesContainer ) {
997 if( !wrkvrt.isGood )
continue;
998 if( wrkvrt.selectedTrackIndices.size() <= 1 )
continue;
1000 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": vertex " << &wrkvrt <<
" #tracks = " << wrkvrt.selectedTrackIndices.size() );
1001 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": candidate vertex: "
1002 <<
" isGood = " << (wrkvrt.isGood?
"true" :
"false")
1003 <<
", #ntrks = " << wrkvrt.nTracksTotal()
1004 <<
", #selectedTracks = " << wrkvrt.selectedTrackIndices.size()
1005 <<
", #associatedTracks = " << wrkvrt.associatedTrackIndices.size()
1006 <<
", chi2/ndof = " << wrkvrt.fitQuality()
1007 <<
", (r, z) = (" << wrkvrt.vertex.perp()
1008 <<
", " << wrkvrt.vertex.z() <<
")" );
1010 std::map<unsigned, std::vector<WrkVrt>::reverse_iterator> mergiableVertex;
1011 std::set<std::vector<WrkVrt>::reverse_iterator> mergiableVerticesSet;
1013 for(
auto&
index : wrkvrt.selectedTrackIndices ) {
1017 mergiableVertex[
index] = workVerticesContainer->rend();
1019 std::vector<double> distances;
1022 for(
auto ritr = workVerticesContainer->rbegin(); ritr != workVerticesContainer->rend(); ++ritr ) {
1023 auto& targetVertex = *ritr;
1025 if( &wrkvrt == &targetVertex )
continue;
1026 if( wrkvrt.selectedTrackIndices.size() >= targetVertex.selectedTrackIndices.size() )
continue;
1029 std::vector<double> impactParameters;
1030 std::vector<double> impactParErrors;
1032 if( !getSVImpactParameters(trk,targetVertex.vertex,impactParameters,impactParErrors) )
continue;
1034 const auto&
distance = hypot( impactParameters.at(0), impactParameters.at(1) );
1035 distances.emplace_back(
distance );
1037 if( std::abs( impactParameters.at(0) ) > m_jp.reassembleMaxImpactParameterD0 )
continue;
1038 if( std::abs( impactParameters.at(1) ) > m_jp.reassembleMaxImpactParameterZ0 )
continue;
1040 mergiableVertex[
index] = ritr;
1041 mergiableVerticesSet.emplace( ritr );
1045 auto min_distance = !distances.empty() ? *(std::min_element( distances.begin(), distances.end() )) :
AlgConsts::invalidFloat;
1047 if( mergiableVertex[
index] == workVerticesContainer->rend() ) {
1048 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": track " << trk <<
" --> none : min distance = " << min_distance );
1050 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": track " << trk <<
" --> " << &( *(mergiableVertex[
index]) ) <<
" --> size = " << mergiableVertex[
index]->selectedTrackIndices.size() <<
": min distance = " << min_distance );
1055 size_t count_mergiable = std::count_if( mergiableVertex.begin(), mergiableVertex.end(),
1056 [&](
const std::pair<
unsigned, std::vector<WrkVrt>::reverse_iterator>&
p ) {
1057 return p.second != workVerticesContainer->rend(); } );
1059 if( mergiableVerticesSet.size() == 1 && count_mergiable == wrkvrt.selectedTrackIndices.size() ) {
1061 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": identified a unique association destination vertex" );
1063 WrkVrt& destination = *( mergiableVertex.begin()->second );
1067 if(
sc.isFailure() ) {
1068 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": failure in vertex merging" );
1071 improveVertexChi2( destination );
1073 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": merged destination vertex: "
1074 <<
" isGood = " << (destination.
isGood?
"true" :
"false")
1078 <<
", chi2/ndof = " << destination.
fitQuality()
1079 <<
", (r, z) = (" << destination.
vertex.perp()
1080 <<
", " << destination.
vertex.z() <<
")" );
1082 if( m_jp.FillHist ) { m_hists[
"mergeType"]->Fill( REASSEMBLE ); }
1086 reassembleCounter++;
1092 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
"----------------------------------------------" );
1093 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": reassembled vertices = " << reassembleCounter );
1094 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
"----------------------------------------------" );
1096 return StatusCode::SUCCESS;
1101 StatusCode VrtSecInclusive::associateNonSelectedTracks( std::vector<WrkVrt>* workVerticesContainer )
1110 if( !m_decor_isAssociated ) {
1111 m_decor_isAssociated.emplace (
"is_associated" + m_jp.augVerString );
1114 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": #verticess = " << workVerticesContainer->size() );
1116 unsigned associateCounter { 0 };
1119 for(
auto& wrkvrt : *workVerticesContainer ) {
1121 if( !wrkvrt.isGood )
continue;
1122 if( wrkvrt.selectedTrackIndices.size() <= 1 )
continue;
1124 improveVertexChi2( wrkvrt );
1126 wrkvrt.Chi2_core = wrkvrt.Chi2;
1128 auto& vertexPos = wrkvrt.vertex;
1130 std::vector<double> distanceToPVs;
1132 for(
const auto*
pv : *pvs ) {
1135 const auto& minDistance = *( std::min_element( distanceToPVs.begin(), distanceToPVs.end() ) );
1137 if( minDistance < m_jp.associateMinDistanceToPV )
continue;
1140 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": vertex pos = (" << vertexPos.x() <<
", " << vertexPos.y() <<
", " << vertexPos.z() <<
"), "
1141 "#selected = " << wrkvrt.selectedTrackIndices.size() <<
", #assoc = " << wrkvrt.associatedTrackIndices.size() );
1143 std::vector<const xAOD::TrackParticle*>
candidates;
1146 for(
auto itr = allTracks->
begin(); itr != allTracks->
end(); ++itr ) {
1147 const auto* trk = *itr;
1151 auto result = std::find_if( workVerticesContainer->begin(), workVerticesContainer->end(),
1153 auto found = std::find_if( wrkvrt.selectedTrackIndices.begin(), wrkvrt.selectedTrackIndices.end(),
1154 [&]( long int index ) {
1156 if (m_jp.doSelectTracksFromElectrons || m_jp.doSelectIDAndGSFTracks) {
1157 const xAOD::TrackParticle *id_tr;
1158 id_tr = xAOD::EgammaHelpers::getOriginalTrackParticleFromGSF(m_selectedTracks.at(index));
1159 return trk == m_selectedTracks.at(index) or trk == id_tr;
1162 return trk == m_selectedTracks.at(index);
1167 if(
result != workVerticesContainer->end() )
continue;
1172 auto result = std::find_if( m_associatedTracks.begin(), m_associatedTracks.end(),
1173 [&] (
const auto* atrk) { return trk == atrk; } );
1174 if(
result != m_associatedTracks.end() )
continue;
1181 if( trk->pt() < m_jp.associatePtCut )
continue;
1184 if( trk->chiSquared() / trk->numberDoF() > m_jp.associateChi2Cut )
continue;
1187 if( !checkTrackHitPatternToVertexOuterOnly( trk, vertexPos ) )
continue;
1190 std::vector<double> impactParameters;
1191 std::vector<double> impactParErrors;
1193 if( !getSVImpactParameters( trk, vertexPos, impactParameters, impactParErrors) )
continue;
1195 if( std::abs( impactParameters.at(0) ) / sqrt( impactParErrors.at(0) ) > m_jp.associateMaxD0Signif )
continue;
1196 if( std::abs( impactParameters.at(1) ) / sqrt( impactParErrors.at(1) ) > m_jp.associateMaxZ0Signif )
continue;
1199 <<
": d0 to vtx = " << impactParameters.at(k_d0)
1200 <<
", z0 to vtx = " << impactParameters.at(k_z0)
1201 <<
", distance to vtx = " << hypot( impactParameters.at(k_d0), impactParameters.at(k_z0) ) );
1209 std::unique_ptr<Trk::IVKalState> state = m_fitSvc->makeState();
1213 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": attempting to associate track = " << trk );
1216 WrkVrt wrkvrt_backup = wrkvrt;
1218 m_fitSvc->setApproximateVertex( vertexPos.x(), vertexPos.y(), vertexPos.z(), *state );
1220 std::vector<const xAOD::TrackParticle*> baseTracks;
1221 std::vector<const xAOD::NeutralParticle*> dummyNeutrals;
1225 for(
const auto&
index : wrkvrt.selectedTrackIndices ) {
1226 baseTracks.emplace_back( m_selectedTracks.at(
index ) );
1229 for(
const auto&
index : wrkvrt.associatedTrackIndices ) {
1230 baseTracks.emplace_back( m_associatedTracks.at(
index ) );
1234 baseTracks.emplace_back( trk );
1240 StatusCode sc = m_fitSvc->VKalVrtFitFast( baseTracks, initPos, *state );
1242 if(
sc.isFailure() )
ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": fast crude estimation failed.");
1244 const auto& diffPos = initPos - vertexPos;
1246 if( diffPos.norm() > 10. ) {
1248 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": approx vertex as original" );
1249 m_fitSvc->setApproximateVertex( vertexPos.x(), vertexPos.y(), vertexPos.z(), *state );
1253 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": approx vertex set to (" << initPos.x() <<
", " << initPos.y() <<
", " << initPos.z() <<
")" );
1254 m_fitSvc->setApproximateVertex( initPos.x(), initPos.y(), initPos.z(), *state );
1260 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": now vertex fitting..." );
1262 StatusCode sc = m_fitSvc->VKalVrtFit(baseTracks, dummyNeutrals,
1272 if(
sc.isFailure() ) {
1273 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": VKalVrtFit failure. Revert to backup");
1274 wrkvrt = wrkvrt_backup;
1276 if( m_jp.FillHist ) m_hists[
"associateMonitor"]->Fill( 1 );
1282 if( m_jp.FillHist ) m_hists[
"associateMonitor"]->Fill( 0 );
1284 auto&
cov = wrkvrt.vertexCov;
1286 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": succeeded in associating. New vertex pos = (" << vertexPos.perp() <<
", " << vertexPos.z() <<
", " << vertexPos.perp()*vertexPos.phi() <<
")" );
1287 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) <<
")" );
1291 wrkvrt.associatedTrackIndices.emplace_back( m_associatedTracks.size() );
1293 m_associatedTracks.emplace_back( trk );
1294 (*m_decor_isAssociated)( *trk ) =
true;
1300 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
"----------------------------------------------" );
1301 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": total associated number of tracks = " << associateCounter );
1302 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
"----------------------------------------------" );
1304 return StatusCode::SUCCESS;
1309 StatusCode VrtSecInclusive::mergeByShuffling( std::vector<WrkVrt> *workVerticesContainer )
1312 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": #verticess = " << workVerticesContainer->size() );
1314 unsigned mergeCounter { 0 };
1317 std::sort( workVerticesContainer->begin(), workVerticesContainer->end(), [](
WrkVrt& v1,
WrkVrt&
v2) { return v1.selectedTrackIndices.size() < v2.selectedTrackIndices.size(); } );
1320 for(
auto& wrkvrt : *workVerticesContainer ) {
1321 if( !wrkvrt.isGood )
continue;
1322 if( wrkvrt.selectedTrackIndices.size() <= 1 )
continue;
1325 for(
auto ritr = workVerticesContainer->rbegin(); ritr != workVerticesContainer->rend(); ++ritr ) {
1326 auto& vertexToMerge = *ritr;
1328 if( !vertexToMerge.isGood )
continue;
1329 if( vertexToMerge.selectedTrackIndices.size() <= 1 )
continue;
1330 if( &wrkvrt == &vertexToMerge )
continue;
1331 if( vertexToMerge.selectedTrackIndices.size() < wrkvrt.selectedTrackIndices.size() )
continue;
1333 const double& significance = significanceBetweenVertices( wrkvrt, vertexToMerge );
1335 if( significance > m_jp.mergeByShufflingMaxSignificance )
continue;
1337 bool mergeFlag {
false };
1340 <<
": vertex " << &wrkvrt <<
" #tracks = " << wrkvrt.selectedTrackIndices.size()
1341 <<
" --> to Merge : " << &vertexToMerge <<
", #tracks = " << vertexToMerge.selectedTrackIndices.size()
1342 <<
" significance = " << significance );
1347 if( m_jp.doSuggestedRefitOnMerging && !mergeFlag ) {
1348 WrkVrt testVertex = wrkvrt;
1350 if(
sc.isFailure() ) {
1354 const auto signif = significanceBetweenVertices( testVertex, vertexToMerge );
1355 if( signif < min_signif ) min_signif = signif;
1357 if( signif < m_jp.mergeByShufflingAllowance ) {
1358 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": method1: vertexToMerge " << &vertexToMerge <<
": test signif = " << signif );
1363 if( m_jp.FillHist && min_signif > 0. ) m_hists[
"shuffleMinSignif1"]->Fill( log10( min_signif ) );
1364 if( m_jp.FillHist && mergeFlag ) { m_hists[
"mergeType"]->Fill( SHUFFLE1 ); }
1369 if( m_jp.doMagnetMerging && !mergeFlag ) {
1372 for(
auto&
index : vertexToMerge.selectedTrackIndices ) {
1374 WrkVrt testVertex = wrkvrt;
1378 if(
sc.isFailure() ) {
1382 const auto signif = significanceBetweenVertices( testVertex, vertexToMerge );
1383 if( signif < min_signif ) min_signif = signif;
1385 if( signif < m_jp.mergeByShufflingAllowance ) {
1386 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": method2: vertexToMerge " << &vertexToMerge <<
" track index " <<
index <<
": test signif = " << signif );
1393 if( m_jp.FillHist && min_signif > 0. ) m_hists[
"shuffleMinSignif2"]->Fill( log10( min_signif ) );
1395 if( m_jp.FillHist && mergeFlag ) { m_hists[
"mergeType"]->Fill( SHUFFLE2 ); }
1399 if( m_jp.doWildMerging && !mergeFlag ) {
1401 WrkVrt testVertex = wrkvrt;
1403 for(
auto&
index : vertexToMerge.selectedTrackIndices ) {
1408 if(
sc.isFailure() ) {
1412 const auto signif = significanceBetweenVertices( testVertex, vertexToMerge );
1413 if( signif < min_signif ) min_signif = signif;
1415 if( signif < m_jp.mergeByShufflingAllowance ) {
1416 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": method3: vertexToMerge " << &vertexToMerge <<
": test signif = " << signif );
1420 if( m_jp.FillHist && min_signif > 0. ) m_hists[
"shuffleMinSignif3"]->Fill( log10( min_signif ) );
1421 if( m_jp.FillHist && mergeFlag ) { m_hists[
"mergeType"]->Fill( SHUFFLE3 ); }
1428 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": vertexToMerge " << &vertexToMerge <<
" ==> min signif = " << min_signif <<
" judged to merge" );
1430 auto vertexToMerge_backup = vertexToMerge;
1431 auto wrkvrt_backup = wrkvrt;
1433 StatusCode sc = mergeVertices( vertexToMerge, wrkvrt );
1434 if(
sc.isFailure() ) {
1435 vertexToMerge = vertexToMerge_backup;
1436 wrkvrt = wrkvrt_backup;
1440 improveVertexChi2( wrkvrt );
1449 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
"----------------------------------------------" );
1450 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": Number of merges = " << mergeCounter );
1451 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
"----------------------------------------------" );
1453 return StatusCode::SUCCESS;
1458 StatusCode VrtSecInclusive::mergeFinalVertices( std::vector<WrkVrt> *workVerticesContainer )
1461 unsigned mergeCounter { 0 };
1467 for(
auto& wrkvrt : *workVerticesContainer) {
1473 auto minDistance = findMinVerticesPair( workVerticesContainer, indexPair, &VrtSecInclusive::distanceBetweenVertices );
1479 auto& v1 = workVerticesContainer->at(indexPair.first);
1480 auto&
v2 = workVerticesContainer->at(indexPair.second);
1482 const double averageRadius = ( v1.vertex.perp() +
v2.vertex.perp() ) / 2.0;
1484 if( minDistance > m_jp.VertexMergeFinalDistCut + m_jp.VertexMergeFinalDistScaling * averageRadius ) {
1485 ATH_MSG_DEBUG(
"Vertices " << indexPair.first <<
" and " << indexPair.second
1486 <<
" are separated by distance " << minDistance );
1490 ATH_MSG_DEBUG(
"Merging FINAL vertices " << indexPair.first <<
" and " << indexPair.second
1491 <<
" which are separated by distance "<< minDistance );
1494 if(
sc.isFailure() ) {}
1495 if( m_jp.FillHist ) { m_hists[
"mergeType"]->Fill(
FINAL ); }
1497 improveVertexChi2( v1 );
1503 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
"----------------------------------------------" );
1504 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": Number of merges = " << mergeCounter );
1505 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
"----------------------------------------------" );
1507 return StatusCode::SUCCESS;
1514 StatusCode VrtSecInclusive::refitAndSelectGoodQualityVertices( std::vector<WrkVrt> *workVerticesContainer )
1524 ATH_CHECK( evtStore()->
retrieve( secondaryVertexContainer,
"VrtSecInclusive_" + m_jp.secondaryVerticesContainerName + m_jp.augVerString ) );
1529 enum { kPt,
kEta,
kPhi, kD0, kZ0, kErrP, kErrD0, kErrZ0, kChi2SV };
1530 if( m_trkDecors.empty() ) {
1541 if( !m_decor_is_svtrk_final ) {
1542 m_decor_is_svtrk_final.emplace (
"is_svtrk_final" + m_jp.augVerString );
1545 std::map<const WrkVrt*, const xAOD::Vertex*> wrkvrtLinkMap;
1548 const auto& ctx = Gaudi::Hive::currentContext();
1550 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": input #vertices = " << workVerticesContainer->size() );
1553 for(
auto& wrkvrt : *workVerticesContainer ) {
1555 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": candidate vertex: "
1556 <<
" isGood = " << (wrkvrt.isGood?
"true" :
"false")
1557 <<
", #ntrks = " << wrkvrt.nTracksTotal()
1558 <<
", #selectedTracks = " << wrkvrt.selectedTrackIndices.size()
1559 <<
", #associatedTracks = " << wrkvrt.associatedTrackIndices.size()
1561 <<
", (r, z) = (" << wrkvrt.vertex.perp()
1562 <<
", " << wrkvrt.vertex.z() <<
")" );
1564 if( m_jp.FillHist ) m_hists[
"finalCutMonitor"]->Fill( 0 );
1566 if( m_jp.removeFakeVrt && m_jp.removeFakeVrtLate ) {
1567 removeInconsistentTracks( wrkvrt );
1570 if( wrkvrt.nTracksTotal() < 2 ) {
1571 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": ntrk < 2 --> rejected." );
1575 if( m_jp.FillHist ) m_hists[
"finalCutMonitor"]->Fill( 1 );
1579 if( wrkvrt.vertex.perp() < 31.0 ) {
1582 wrkvrt.selectedTrackIndices.erase(
std::remove_if( wrkvrt.selectedTrackIndices.begin(), wrkvrt.selectedTrackIndices.end(),
1583 [&](
auto&
index ) {
1584 auto* trk = m_selectedTracks.at( index );
1588 wrkvrt.selectedTrackIndices.end() );
1591 wrkvrt.associatedTrackIndices.erase(
std::remove_if( wrkvrt.associatedTrackIndices.begin(), wrkvrt.associatedTrackIndices.end(),
1592 [&](
auto&
index ) {
1593 auto* trk = m_associatedTracks.at( index );
1597 wrkvrt.associatedTrackIndices.end() );
1605 if( m_jp.doFinalImproveChi2 ) {
1609 improveVertexChi2( wrkvrt );
1611 if( wrkvrt.fitQuality() > backup.
fitQuality() ) wrkvrt = backup;
1616 if( wrkvrt.nTracksTotal() < 2 )
continue;
1619 if( wrkvrt.selectedTrackIndices.size() < 2 )
continue;
1622 if( m_jp.FillHist ) m_hists[
"finalCutMonitor"]->Fill( 2 );
1629 if(
sc.isFailure() ) {
1631 auto indices = wrkvrt.associatedTrackIndices;
1633 wrkvrt.associatedTrackIndices.clear();
1634 sc = refitVertex( wrkvrt );
1635 if(
sc.isFailure() ) {
1636 ATH_MSG_WARNING(
" > " << __FUNCTION__ <<
": detected vertex fitting failure!" );
1639 if( wrkvrt.fitQuality() > backup.
fitQuality() ) wrkvrt = backup;
1644 sc = refitVertex( wrkvrt );
1645 if(
sc.isFailure() || TMath::Prob( wrkvrt.Chi2, wrkvrt.ndof() ) < m_jp.improveChi2ProbThreshold ) {
1646 ATH_MSG_WARNING(
" > " << __FUNCTION__ <<
": detected vertex fitting failure!" );
1653 if( wrkvrt.fitQuality() > backup.
fitQuality() ) wrkvrt = backup;
1657 if( m_jp.FillHist ) m_hists[
"finalCutMonitor"]->Fill( 3 );
1662 if( m_jp.FillNtuple ) m_ntupleVars->get<
unsigned int>(
"NumSecVrt" )++;
1664 TLorentzVector sumP4_pion;
1665 TLorentzVector sumP4_electron;
1666 TLorentzVector sumP4_proton;
1669 bool good_flag =
true;
1671 std::map<const std::deque<long int>*,
const std::vector<const xAOD::TrackParticle*>&> indicesSet
1673 { &(wrkvrt.selectedTrackIndices), m_selectedTracks },
1674 { &(wrkvrt.associatedTrackIndices), m_associatedTracks }
1677 for(
auto& pair : indicesSet ) {
1679 const auto*
indices = pair.first;
1680 const auto& tracks = pair.second;
1682 for(
const auto& itrk : *
indices ) {
1683 const auto* trk = tracks.at( itrk );
1684 auto sv_perigee = m_trackToVertexTool->perigeeAtVertex(ctx, *trk, wrkvrt.vertex );
1686 ATH_MSG_INFO(
" > " << __FUNCTION__ <<
": > Track index " << trk->index() <<
": Failed in obtaining the SV perigee!" );
1694 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": sv perigee could not be obtained --> rejected" );
1698 if( m_jp.FillHist ) m_hists[
"finalCutMonitor"]->Fill( 4 );
1701 std::vector<const xAOD::TrackParticle*> tracks;
1702 std::vector< std::pair<const xAOD::TrackParticle*, double> > trackChi2Pairs;
1706 for(
auto& pair : indicesSet ) {
1707 for(
const auto&
index : *pair.first ) tracks.emplace_back( pair.second.at(
index ) );
1710 auto trkitr = tracks.begin();
1711 auto chi2itr = wrkvrt.Chi2PerTrk.begin();
1713 for( ; ( trkitr!=tracks.end() && chi2itr!=wrkvrt.Chi2PerTrk.end() ); ++trkitr, ++chi2itr ) {
1714 trackChi2Pairs.emplace_back( *trkitr, *chi2itr );
1720 TLorentzVector sumP4_selected;
1722 bool badIPflag {
false };
1725 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": Track loop: size = " << tracks.size() );
1726 for(
auto& pair : trackChi2Pairs ) {
1728 const auto* trk = pair.first;
1729 const auto& chi2AtSV = pair.second;
1731 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": > Track index " << trk->index() <<
": start." );
1734 fillTrackSummary( trk_summary, trk );
1740 double trk_pt = trk->pt();
1741 double trk_eta = trk->eta();
1742 double trk_phi = trk->phi();
1744 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": > Track index " << trk->index() <<
": in vrt chg/pt/phi/eta = "
1745 << trk->charge() <<
","
1752 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": > Track index " << trk->index() <<
": Get the prigee of the track at the vertex." );
1754 auto sv_perigee = m_trackToVertexTool->perigeeAtVertex(ctx, *trk, wrkvrt.vertex );
1756 ATH_MSG_WARNING(
" > " << __FUNCTION__ <<
": > Track index " << trk->index() <<
": Failed in obtaining the SV perigee!" );
1758 for(
auto& pair : m_trkDecors ) {
1761 (*m_decor_is_svtrk_final)( *trk ) =
true;
1765 double qOverP_wrtSV = sv_perigee->parameters() [
Trk::qOverP];
1766 double theta_wrtSV = sv_perigee->parameters() [
Trk::theta];
1767 double p_wrtSV = 1.0 / std::abs( qOverP_wrtSV );
1768 double pt_wrtSV = p_wrtSV *
sin( theta_wrtSV );
1769 double eta_wrtSV = -
log(
tan( theta_wrtSV/2. ) );
1770 double phi_wrtSV = sv_perigee->parameters() [
Trk::phi];
1771 double d0_wrtSV = sv_perigee->parameters() [
Trk::d0];
1772 double z0_wrtSV = sv_perigee->parameters() [
Trk::z0];
1773 double errd0_wrtSV = (*sv_perigee->covariance())(
Trk::d0,
Trk::d0 );
1774 double errz0_wrtSV = (*sv_perigee->covariance())(
Trk::z0,
Trk::z0 );
1778 ( m_trkDecors.at(kPt) )( *trk ) = pt_wrtSV;
1779 ( m_trkDecors.at(
kEta) )( *trk ) = eta_wrtSV;
1780 ( m_trkDecors.at(
kPhi) )( *trk ) = phi_wrtSV;
1781 ( m_trkDecors.at(kD0) )( *trk ) = d0_wrtSV;
1782 ( m_trkDecors.at(kZ0) )( *trk ) = z0_wrtSV;
1783 ( m_trkDecors.at(kErrP) )( *trk ) = errP_wrtSV;
1784 ( m_trkDecors.at(kErrD0) )( *trk ) = errd0_wrtSV;
1785 ( m_trkDecors.at(kErrZ0) )( *trk ) = errz0_wrtSV;
1786 ( m_trkDecors.at(kChi2SV))( *trk ) = chi2AtSV;
1788 (*m_decor_is_svtrk_final)( *trk ) =
true;
1790 TLorentzVector p4wrtSV_pion;
1791 TLorentzVector p4wrtSV_electron;
1792 TLorentzVector p4wrtSV_proton;
1800 if( !is_associatedAcc(*trk) ) {
1801 sumP4_selected += p4wrtSV_pion;
1804 sumP4_selected += p4wrtSV_pion;
1807 sumP4_pion += p4wrtSV_pion;
1808 sumP4_electron += p4wrtSV_electron;
1809 sumP4_proton += p4wrtSV_proton;
1811 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": > Track index " << trk->index() <<
": end." );
1816 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": Final Sec.Vertex=" << wrkvrt.nTracksTotal() <<
", "
1817 <<wrkvrt.vertex.perp() <<
", "<<wrkvrt.vertex.z() <<
", "
1818 <<wrkvrt.vertex.phi() <<
", mass = "<< sumP4_pion.M() <<
"," << sumP4_electron.M() );
1821 float perigee_x_trk1 = 0.0;
1822 float perigee_y_trk1 = 0.0;
1823 float perigee_z_trk1 = 0.0;
1824 float perigee_x_trk2 = 0.0;
1825 float perigee_y_trk2 = 0.0;
1826 float perigee_z_trk2 = 0.0;
1827 float perigee_px_trk1 = 0.0;
1828 float perigee_py_trk1 = 0.0;
1829 float perigee_pz_trk1 = 0.0;
1830 float perigee_px_trk2 = 0.0;
1831 float perigee_py_trk2 = 0.0;
1832 float perigee_pz_trk2 = 0.0;
1833 float perigee_cov_xx_trk1 = 0.0;
1834 float perigee_cov_xy_trk1 = 0.0;
1835 float perigee_cov_xz_trk1 = 0.0;
1836 float perigee_cov_yy_trk1 = 0.0;
1837 float perigee_cov_yz_trk1 = 0.0;
1838 float perigee_cov_zz_trk1 = 0.0;
1839 float perigee_cov_xx_trk2 = 0.0;
1840 float perigee_cov_xy_trk2 = 0.0;
1841 float perigee_cov_xz_trk2 = 0.0;
1842 float perigee_cov_yy_trk2 = 0.0;
1843 float perigee_cov_yz_trk2 = 0.0;
1844 float perigee_cov_zz_trk2 = 0.0;
1845 float perigee_d0_trk1 = 0.0;
1846 float perigee_d0_trk2 = 0.0;
1847 float perigee_z0_trk1 = 0.0;
1848 float perigee_z0_trk2 = 0.0;
1849 float perigee_qOverP_trk1 = 0.0;
1850 float perigee_qOverP_trk2 = 0.0;
1851 float perigee_theta_trk1 = 0.0;
1852 float perigee_theta_trk2 = 0.0;
1853 float perigee_phi_trk1 = 0.0;
1854 float perigee_phi_trk2 = 0.0;
1855 int perigee_charge_trk1 = 0;
1856 int perigee_charge_trk2 = 0;
1857 float perigee_distance = 9999.0;
1860 float vPos = (vDist.x() * wrkvrt.vertexMom.Px() + vDist.y() * wrkvrt.vertexMom.Py() + vDist.z() * wrkvrt.vertexMom.Pz()) / wrkvrt.vertexMom.Rho();
1861 float vPosMomAngT = (vDist.x() * wrkvrt.vertexMom.Px() + vDist.y() * wrkvrt.vertexMom.Py()) / vDist.perp() / wrkvrt.vertexMom.Pt();
1862 float vPosMomAng3D = (vDist.x() * wrkvrt.vertexMom.Px() + vDist.y() * wrkvrt.vertexMom.Py() + vDist.z() * wrkvrt.vertexMom.Pz()) / (vDist.norm() * wrkvrt.vertexMom.Rho());
1863 float dphi_trk1 = 0.0;
1864 float dphi_trk2 = 0.0;
1866 if (m_jp.doDisappearingTrackVertexing){
1868 const auto* track1 = trackChi2Pairs[0].first;
1870 auto sv_perigee1 = m_trackToVertexTool->perigeeAtVertex(ctx, *track1, wrkvrt.vertex);
1872 perigee_x_trk1 = sv_perigee1->position().x();
1873 perigee_y_trk1 = sv_perigee1->position().y();
1874 perigee_z_trk1 = sv_perigee1->position().z();
1875 perigee_px_trk1 = sv_perigee1->momentum().x();
1876 perigee_py_trk1 = sv_perigee1->momentum().y();
1877 perigee_pz_trk1 = sv_perigee1->momentum().z();
1878 perigee_cov_xx_trk1 = (*sv_perigee1->covariance())(0, 0);
1879 perigee_cov_xy_trk1 = (*sv_perigee1->covariance())(0, 1);
1880 perigee_cov_xz_trk1 = (*sv_perigee1->covariance())(0, 2);
1881 perigee_cov_yy_trk1 = (*sv_perigee1->covariance())(1, 1);
1882 perigee_cov_yz_trk1 = (*sv_perigee1->covariance())(1, 2);
1883 perigee_cov_zz_trk1 = (*sv_perigee1->covariance())(2, 2);
1884 perigee_d0_trk1 = sv_perigee1->parameters()[
Trk::d0];
1885 perigee_z0_trk1 = sv_perigee1->parameters()[
Trk::z0];
1886 perigee_qOverP_trk1 = sv_perigee1->parameters()[
Trk::qOverP];
1887 perigee_theta_trk1 = sv_perigee1->parameters()[
Trk::theta];
1888 perigee_phi_trk1 = sv_perigee1->parameters()[
Trk::phi];
1889 perigee_charge_trk1 = sv_perigee1->parameters()[
Trk::qOverP] > 0 ? 1 : -1;
1891 ATH_MSG_DEBUG(
"Failed to obtain perigee for track1 at vertex.");
1895 const auto* track2 = trackChi2Pairs[1].first;
1897 auto sv_perigee2 = m_trackToVertexTool->perigeeAtVertex(ctx, *track2, wrkvrt.vertex);
1899 perigee_x_trk2 = sv_perigee2->position().x();
1900 perigee_y_trk2 = sv_perigee2->position().y();
1901 perigee_z_trk2 = sv_perigee2->position().z();
1902 perigee_px_trk2 = sv_perigee2->momentum().x();
1903 perigee_py_trk2 = sv_perigee2->momentum().y();
1904 perigee_pz_trk2 = sv_perigee2->momentum().z();
1905 perigee_cov_xx_trk2 = (*sv_perigee2->covariance())(0, 0);
1906 perigee_cov_xy_trk2 = (*sv_perigee2->covariance())(0, 1);
1907 perigee_cov_xz_trk2 = (*sv_perigee2->covariance())(0, 2);
1908 perigee_cov_yy_trk2 = (*sv_perigee2->covariance())(1, 1);
1909 perigee_cov_yz_trk2 = (*sv_perigee2->covariance())(1, 2);
1910 perigee_cov_zz_trk2 = (*sv_perigee2->covariance())(2, 2);
1911 perigee_d0_trk2 = sv_perigee2->parameters()[
Trk::d0];
1912 perigee_z0_trk2 = sv_perigee2->parameters()[
Trk::z0];
1913 perigee_qOverP_trk2 = sv_perigee2->parameters()[
Trk::qOverP];
1914 perigee_theta_trk2 = sv_perigee2->parameters()[
Trk::theta];
1915 perigee_phi_trk2 = sv_perigee2->parameters()[
Trk::phi];
1916 perigee_charge_trk2 = sv_perigee2->parameters()[
Trk::qOverP] > 0 ? 1 : -1;
1918 ATH_MSG_DEBUG(
"Failed to obtain perigee for track2 at vertex.");
1921 if(sv_perigee1 && sv_perigee2){
1922 perigee_distance = sqrt(
1923 (perigee_x_trk1 - perigee_x_trk2) * (perigee_x_trk1 - perigee_x_trk2) +
1924 (perigee_y_trk1 - perigee_y_trk2) * (perigee_y_trk1 - perigee_y_trk2) +
1925 (perigee_z_trk1 - perigee_z_trk2) * (perigee_z_trk1 - perigee_z_trk2)
1928 if(perigee_distance > m_jp.twoTrVrtMaxPerigeeDist)
continue;
1935 std::vector<double> opAngles;
1937 for(
auto itr1 = tracks.begin(); itr1 != tracks.end(); ++itr1 ) {
1938 for(
auto itr2 =
std::next( itr1 ); itr2 != tracks.end(); ++itr2 ) {
1939 const auto&
p1 = (*itr1)->p4().Vect();
1940 const auto&
p2 = (*itr2)->p4().Vect();
1942 opAngles.emplace_back(
cos );
1945 minOpAng = *( std::max_element( opAngles.begin(), opAngles.end() ) );
1946 if( m_jp.FillNtuple ) m_ntupleVars->get< vector<double> >(
"SecVtx_MinOpAng" ).emplace_back(minOpAng);
1949 if( m_jp.FillHist ) m_hists[
"finalCutMonitor"]->Fill( 5 );
1952 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": Bad impact parameter signif wrt SV was flagged." );
1955 if (m_jp.doRemoveNonLeptonVertices) {
1957 bool oneLepMatchTrack =
false;
1958 for (
const auto *trk: tracks) {
1959 if (
std::find(m_leptonicTracks.begin(), m_leptonicTracks.end(), trk) != m_leptonicTracks.end() ) {
1960 oneLepMatchTrack =
true;
1966 if (!oneLepMatchTrack)
continue;
1972 wrkvrt.isGood =
true;
1977 secondaryVertexContainer->emplace_back(
vertex );
1980 vertex->setPosition( wrkvrt.vertex );
1987 vertex->setFitQuality( wrkvrt.Chi2_core, wrkvrt.ndof_core() );
1990 std::vector<float> fCov(wrkvrt.vertexCov.cbegin(), wrkvrt.vertexCov.cend());
1991 vertex->setCovariance(fCov);
2012 vtx_pxAcc(*
vertex) = wrkvrt.vertexMom.Px();
2013 vtx_pyAcc(*
vertex) = wrkvrt.vertexMom.Py();
2014 vtx_pzAcc(*
vertex) = wrkvrt.vertexMom.Pz();
2016 vtx_massAcc(*
vertex) = wrkvrt.vertexMom.M();
2017 vtx_chargeAcc(*
vertex) = wrkvrt.Charge;
2019 chi2_coreAcc(*
vertex) = wrkvrt.Chi2_core;
2020 ndof_coreAcc(*
vertex) = wrkvrt.ndof_core();
2021 chi2_assocAcc(*
vertex) = wrkvrt.Chi2;
2022 ndof_assocAcc(*
vertex) = wrkvrt.ndof();
2024 massAcc(*
vertex) = sumP4_pion.M();
2025 mass_eAcc(*
vertex) = sumP4_electron.M();
2026 mass_selectedTracksAcc(*
vertex) = sumP4_selected.M();
2027 minOpAngAcc(*
vertex) = minOpAng;
2028 num_trksAcc(*
vertex) = wrkvrt.nTracksTotal();
2029 num_selectedTracksAcc(*
vertex) = wrkvrt.selectedTrackIndices.size();
2030 num_associatedTracksAcc(*
vertex) = wrkvrt.associatedTrackIndices.size();
2031 dCloseVrtAcc(*
vertex) = wrkvrt.closestWrkVrtValue;
2034 if (m_jp.doDisappearingTrackVertexing){
2076 perigee_x_trk1Acc(*
vertex) = perigee_x_trk1;
2077 perigee_y_trk1Acc(*
vertex) = perigee_y_trk1;
2078 perigee_z_trk1Acc(*
vertex) = perigee_z_trk1;
2079 perigee_x_trk2Acc(*
vertex) = perigee_x_trk2;
2080 perigee_y_trk2Acc(*
vertex) = perigee_y_trk2;
2081 perigee_z_trk2Acc(*
vertex) = perigee_z_trk2;
2082 perigee_px_trk1Acc(*
vertex) = perigee_px_trk1;
2083 perigee_py_trk1Acc(*
vertex) = perigee_py_trk1;
2084 perigee_pz_trk1Acc(*
vertex) = perigee_pz_trk1;
2085 perigee_px_trk2Acc(*
vertex) = perigee_px_trk2;
2086 perigee_py_trk2Acc(*
vertex) = perigee_py_trk2;
2087 perigee_pz_trk2Acc(*
vertex) = perigee_pz_trk2;
2088 perigee_cov_xx_trk1Acc(*
vertex) = perigee_cov_xx_trk1;
2089 perigee_cov_xy_trk1Acc(*
vertex) = perigee_cov_xy_trk1;
2090 perigee_cov_xz_trk1Acc(*
vertex) = perigee_cov_xz_trk1;
2091 perigee_cov_yy_trk1Acc(*
vertex) = perigee_cov_yy_trk1;
2092 perigee_cov_yz_trk1Acc(*
vertex) = perigee_cov_yz_trk1;
2093 perigee_cov_zz_trk1Acc(*
vertex) = perigee_cov_zz_trk1;
2094 perigee_cov_xx_trk2Acc(*
vertex) = perigee_cov_xx_trk2;
2095 perigee_cov_xy_trk2Acc(*
vertex) = perigee_cov_xy_trk2;
2096 perigee_cov_xz_trk2Acc(*
vertex) = perigee_cov_xz_trk2;
2097 perigee_cov_yy_trk2Acc(*
vertex) = perigee_cov_yy_trk2;
2098 perigee_cov_yz_trk2Acc(*
vertex) = perigee_cov_yz_trk2;
2099 perigee_cov_zz_trk2Acc(*
vertex) = perigee_cov_zz_trk2;
2100 perigee_d0_trk1Acc(*
vertex) = perigee_d0_trk1;
2101 perigee_d0_trk2Acc(*
vertex) = perigee_d0_trk2;
2102 perigee_z0_trk1Acc(*
vertex) = perigee_z0_trk1;
2103 perigee_z0_trk2Acc(*
vertex) = perigee_z0_trk2;
2104 perigee_qOverP_trk1Acc(*
vertex) = perigee_qOverP_trk1;
2105 perigee_qOverP_trk2Acc(*
vertex) = perigee_qOverP_trk2;
2106 perigee_theta_trk1Acc(*
vertex) = perigee_theta_trk1;
2107 perigee_theta_trk2Acc(*
vertex) = perigee_theta_trk2;
2108 perigee_phi_trk1Acc(*
vertex) = perigee_phi_trk1;
2109 perigee_phi_trk2Acc(*
vertex) = perigee_phi_trk2;
2110 perigee_charge_trk1Acc(*
vertex) = perigee_charge_trk1;
2111 perigee_charge_trk2Acc(*
vertex) = perigee_charge_trk2;
2113 vPosMomAngTAcc(*
vertex) = vPosMomAngT;
2114 vPosMomAng3DAcc(*
vertex) = vPosMomAng3D;
2115 dphi_trk1Acc(*
vertex) = dphi_trk1;
2116 dphi_trk2Acc(*
vertex) = dphi_trk2;
2121 for(
auto trk_id : wrkvrt.selectedTrackIndices ) {
2129 vertex->addTrackAtVertex( link_trk, 1. );
2133 for(
auto trk_id : wrkvrt.associatedTrackIndices ) {
2141 vertex->addTrackAtVertex( link_trk, 1. );
2146 if( m_jp.doMapToLocal ) {
2154 if( mappedVtx.
valid ) {
2172 if( m_jp.doTruth ) {
2177 wrkvrtLinkMap[&wrkvrt] =
vertex;
2182 if( m_jp.FillNtuple ) {
2183 ATH_CHECK( fillAANT_SecondaryVertices( secondaryVertexContainer ) );
2188 if( m_jp.doAugmentDVimpactParametersToMuons ) {
ATH_CHECK( augmentDVimpactParametersToLeptons<xAOD::Muon> (
"Muons" ) ); }
2189 if( m_jp.doAugmentDVimpactParametersToElectrons ) {
ATH_CHECK( augmentDVimpactParametersToLeptons<xAOD::Electron>(
"Electrons" ) ); }
2191 }
catch (
const std::out_of_range&
e) {
2193 ATH_MSG_WARNING(
" > " << __FUNCTION__ <<
": out of range error is detected: " <<
e.what() );
2195 return StatusCode::SUCCESS;
2199 ATH_MSG_WARNING(
" > " << __FUNCTION__ <<
": some other error is detected." );
2201 return StatusCode::SUCCESS;
2205 return StatusCode::SUCCESS;
2210 StatusCode VrtSecInclusive::monitorVertexingAlgorithmStep( std::vector<WrkVrt>* workVerticesContainer,
const std::string&
name,
bool final ) {
2212 if( m_jp.FillIntermediateVertices ) {
2219 ATH_CHECK( evtStore()->
retrieve( intermediateVertexContainer,
"VrtSecInclusive_IntermediateVertices_" +
name + m_jp.augVerString ) );
2221 for(
auto& wrkvrt : *workVerticesContainer ) {
2224 intermediateVertexContainer->emplace_back(
vertex );
2227 vertex->setPosition( wrkvrt.vertex );
2233 int ndof = wrkvrt.ndof();
2237 std::vector<float> fCov(wrkvrt.vertexCov.cbegin(), wrkvrt.vertexCov.cend());
2238 vertex->setCovariance(fCov);
2242 for(
auto trk_id : wrkvrt.selectedTrackIndices ) {
2250 vertex->addTrackAtVertex( link_trk, 1. );
2254 for(
auto trk_id : wrkvrt.associatedTrackIndices ) {
2262 vertex->addTrackAtVertex( link_trk, 1. );
2271 if( !m_jp.FillHist )
return StatusCode::SUCCESS;
2273 printWrkSet( workVerticesContainer, Form(
"%s (step %u)",
name.c_str(), m_vertexingAlgorithmStep) );
2275 unsigned count = std::count_if( workVerticesContainer->begin(), workVerticesContainer->end(),
2276 [](
WrkVrt&
v ) { return ( v.selectedTrackIndices.size() + v.associatedTrackIndices.size() ) >= 2; } );
2278 if( m_vertexingAlgorithmStep == 0 ) {
2280 const auto compSize = m_selectedTracks.size()*(m_selectedTracks.size() - 1)/2 - m_incomp.size();
2281 m_hists[
"vertexYield"]->Fill( m_vertexingAlgorithmStep, compSize );
2285 m_hists[
"vertexYield"]->Fill( m_vertexingAlgorithmStep,
count );
2289 m_hists[
"vertexYield"]->GetXaxis()->SetBinLabel( m_vertexingAlgorithmStep+1,
name.c_str() );
2291 for(
auto&
vertex : *workVerticesContainer ) {
2292 auto ntrk =
vertex.selectedTrackIndices.size() +
vertex.associatedTrackIndices.size();
2293 if(
vertex.isGood && ntrk >= 2 ) {
2294 dynamic_cast<TH2F*
>( m_hists[
"vertexYieldNtrk"] )->Fill( ntrk, m_vertexingAlgorithmStep );
2298 m_hists[
"vertexYieldNtrk"]->GetYaxis()->SetBinLabel( m_vertexingAlgorithmStep+1,
name.c_str() );
2299 m_hists[
"vertexYieldChi2"]->GetYaxis()->SetBinLabel( m_vertexingAlgorithmStep+1,
name.c_str() );
2302 if( !
final )
return StatusCode::SUCCESS;
2304 for(
auto&
vertex : *workVerticesContainer ) {
2305 auto ntrk =
vertex.selectedTrackIndices.size() +
vertex.associatedTrackIndices.size();
2306 if(
vertex.isGood && ntrk >= 2 ) {
2307 m_hists[
"finalVtxNtrk"] ->Fill( ntrk );
2308 m_hists[
"finalVtxR"] ->Fill(
vertex.vertex.perp() );
2309 dynamic_cast<TH2F*
>( m_hists[
"finalVtxNtrkR"] )->Fill( ntrk,
vertex.vertex.perp() );
2313 return StatusCode::SUCCESS;
2318 std::vector<double>& impactParameters,
2319 std::vector<double>& impactParErrors){
2321 impactParameters.clear();
2322 impactParErrors.clear();
2324 if( m_jp.trkExtrapolator==1 ){
2325 m_fitSvc->VKalGetImpact(trk,
vertex,
static_cast<int>( trk->
charge() ), impactParameters, impactParErrors);
2327 else if( m_jp.trkExtrapolator==2 ){
2328 auto sv_perigee = m_trackToVertexTool->perigeeAtVertex(Gaudi::Hive::currentContext(), *trk,
vertex );
2329 if( !sv_perigee )
return false;
2330 impactParameters.push_back(sv_perigee->parameters() [
Trk::d0]);
2331 impactParameters.push_back(sv_perigee->parameters() [
Trk::z0]);
2332 impactParErrors.push_back((*sv_perigee->covariance())(
Trk::d0,
Trk::d0 ));
2333 impactParErrors.push_back((*sv_perigee->covariance())(
Trk::z0,
Trk::z0 ));
2336 ATH_MSG_WARNING(
" > " << __FUNCTION__ <<
": Unknown track extrapolator " << m_jp.trkExtrapolator );