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;
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;
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;
150 if( fabs( impactParameters.at(0)) > roughD0Cut || fabs( impactParameters.at(1) ) > roughZ0Cut ) {
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 );
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();
184 double dphi1 = TVector2::Phi_mpi_pi(vDist.phi() - (*itrk)->phi());
185 double dphi2 = TVector2::Phi_mpi_pi(vDist.phi() - (*jtrk)->phi());
187 const double dist_fromPV = vDist.norm();
188 if(
m_jp.FillHist )
m_hists[
"2trkVtxDistFromPV"]->Fill( dist_fromPV );
190 if(
m_jp.FillNtuple ) {
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. );
220 vertex->setPosition( wrkvrt.
vertex );
221 vertex->setFitQuality( wrkvrt.
Chi2, 1 );
229 pTAcc(*vertex) = wrkvrt.
vertexMom.Perp();
230 chargeAcc(*vertex) = wrkvrt.
Charge;
231 vPosAcc(*vertex) = vPos;
232 isFakeAcc(*vertex) =
true;
238 uint8_t trkiBLHit,trkjBLHit;
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 ) );
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() <<
")" );
265 Amg::Vector3D vTruth( truthVertex->x(), truthVertex->y(), truthVertex->z() );
268 const auto distance = vReco - vTruth;
271 cov.fillSymmetric( 0, 0, wrkvrt.
vertexCov.at(0) );
272 cov.fillSymmetric( 1, 0, wrkvrt.
vertexCov.at(1) );
273 cov.fillSymmetric( 1, 1, wrkvrt.
vertexCov.at(2) );
274 cov.fillSymmetric( 2, 0, wrkvrt.
vertexCov.at(3) );
275 cov.fillSymmetric( 2, 1, wrkvrt.
vertexCov.at(4) );
276 cov.fillSymmetric( 2, 2, wrkvrt.
vertexCov.at(5) );
278 const double s2 = distance.transpose() * cov.inverse() * distance;
280 if( distance.norm() < 2.0 || s2 < 100. ) {
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 ) {
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 ) {
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 );
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;
395 if(
m_jp.doDisappearingTrackVertexing){
397 return StatusCode::SUCCESS;
402 if(
m_jp.FillHist ) {
m_hists[
"2trkVerticesDist"]->Fill( compSize ); }
404 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": compatible track pair size = " << compSize );
408 if( not
m_jp.doFastMode ) {
410 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": incompatibility graph finder mode" );
413 workVerticesContainer->clear();
420 std::vector<long int> weit;
423 weit.emplace_back( pair.first + 1 );
424 weit.emplace_back( pair.second + 1 );
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++) {
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 );
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;
635 for(
auto& cluster: clusters ) {
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 );
651 clusters.emplace_back( c );
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();
663 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": found cluster size =" << clusters.size() );
665 std::unique_ptr<Trk::IVKalState> state =
m_fitSvc->makeState();
666 for(
auto& cluster : clusters ) {
676 for(
const auto&
index: cluster.tracks) {
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){
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;
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;
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; } );
816 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": size of good vertices = " << nGood );
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;
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 ) );
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;
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;
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;
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;
1173 [&] (
const auto* atrk) { return trk == atrk; } );
1181 if( trk->pt() <
m_jp.associatePtCut )
continue;
1184 if( trk->chiSquared() / trk->numberDoF() >
m_jp.associateChi2Cut )
continue;
1190 std::vector<double> impactParameters;
1191 std::vector<double> impactParErrors;
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) ) );
1203 candidates.emplace_back( trk );
1207 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": number of candidate tracks = " << candidates.size() );
1209 std::unique_ptr<Trk::IVKalState> state =
m_fitSvc->makeState();
1211 for(
const auto* trk : candidates ) {
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;
1223 wrkvrt.Chi2PerTrk.clear();
1225 for(
const auto&
index : wrkvrt.selectedTrackIndices ) {
1229 for(
const auto&
index : wrkvrt.associatedTrackIndices ) {
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) <<
")" );
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;
1524 ATH_CHECK(
evtStore()->retrieve( secondaryVertexContainer,
"VrtSecInclusive_" +
m_jp.secondaryVerticesContainerName +
m_jp.augVerString ) );
1529 enum { kPt, kEta, kPhi, kD0, kZ0, kErrP, kErrD0, kErrZ0, kChi2SV };
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 ) {
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 );
1586 return ( nPixelHits < 3 );
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 );
1595 return ( nPixelHits < 3 );
1597 wrkvrt.associatedTrackIndices.end() );
1600 if( statusCode.isFailure() ) {}
1605 if(
m_jp.doFinalImproveChi2 ) {
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();
1635 if(
sc.isFailure() ) {
1636 ATH_MSG_WARNING(
" > " << __FUNCTION__ <<
": detected vertex fitting failure!" );
1639 if( wrkvrt.fitQuality() > backup.
fitQuality() ) wrkvrt = backup;
1641 for(
auto&
index : indices ) {
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 );
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
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 );
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." );
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." );
1756 ATH_MSG_WARNING(
" > " << __FUNCTION__ <<
": > Track index " << trk->index() <<
": Failed in obtaining the SV perigee!" );
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 );
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;
1869 dphi_trk1 = TVector2::Phi_mpi_pi(vDist.phi() - track1->phi());
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;
1896 dphi_trk2 = TVector2::Phi_mpi_pi(vDist.phi() - track2->phi());
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();
1941 auto cos = p1 * p2 / p1.Mag() / p2.Mag();
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) {
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;
2112 vPosAcc(*vertex) = vPos;
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 ) {
2156 local_layerIndexAcc(*vertex) = mappedVtx.
layerIndex;
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;