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;
76 std::unique_ptr<Trk::IVKalState> state =
m_fitSvc->makeState();
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 StatusCode
sc =
m_fitSvc->VKalVrtFitFast( baseTracks, initVertex, *state );
130 if(
sc.isFailure() ) {
131 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": fast crude estimation fails ");
135 if( initVertex.perp() > maxR ) {
138 if(
m_jp.doDisappearingTrackVertexing && initVertex.perp() <
m_jp.twoTrVrtMinRadius){
141 if(
m_jp.FillHist )
m_hists[
"incompMonitor"]->Fill( kInitVtxPosition );
143 std::vector<double> impactParameters;
144 std::vector<double> impactParErrors;
149 if( fabs( impactParameters.at(0)) > roughD0Cut || fabs( impactParameters.at(1) ) > roughZ0Cut ) {
156 if( fabs( impactParameters.at(0) ) > roughD0Cut || fabs( impactParameters.at(1) ) > roughZ0Cut ) {
159 if(
m_jp.FillHist )
m_hists[
"incompMonitor"]->Fill( kImpactParamCheck );
161 m_fitSvc->setApproximateVertex( initVertex.x(), initVertex.y(), initVertex.z(), *state );
172 if(
sc.isFailure() ) {
175 if(
m_jp.FillHist )
m_hists[
"incompMonitor"]->Fill( kVKalVrtFit );
180 const double vPosMomAngT = ( vDist.x()*wrkvrt.
vertexMom.Px()+vDist.y()*wrkvrt.
vertexMom.Py() ) / vDist.perp() / wrkvrt.
vertexMom.Pt();
183 double dphi1 = TVector2::Phi_mpi_pi(vDist.phi() - (*itrk)->phi());
184 double dphi2 = TVector2::Phi_mpi_pi(vDist.phi() - (*jtrk)->phi());
186 const double dist_fromPV = vDist.norm();
187 if(
m_jp.FillHist )
m_hists[
"2trkVtxDistFromPV"]->Fill( dist_fromPV );
189 if(
m_jp.FillNtuple ) {
194 m_ntupleVars->get< std::vector<int> > (
"All2TrkVrtCharge" ) .emplace_back(wrkvrt.
Charge);
195 m_ntupleVars->get< std::vector<double> >(
"All2TrkVrtX" ) .emplace_back(wrkvrt.
vertex.x());
196 m_ntupleVars->get< std::vector<double> >(
"All2TrkVrtY" ) .emplace_back(wrkvrt.
vertex.y());
197 m_ntupleVars->get< std::vector<double> >(
"All2TrkVrtZ" ) .emplace_back(wrkvrt.
vertex.z());
198 m_ntupleVars->get< std::vector<double> >(
"All2TrkVrtChiSq" ) .emplace_back(wrkvrt.
Chi2);
205 if(
m_jp.FillIntermediateVertices ) {
209 for(
const auto *trk: baseTracks ) {
215 vertex->addTrackAtVertex( trackElementLink, 1. );
219 vertex->setPosition( wrkvrt.
vertex );
220 vertex->setFitQuality( wrkvrt.
Chi2, 1 );
228 pTAcc(*vertex) = wrkvrt.
vertexMom.Perp();
229 chargeAcc(*vertex) = wrkvrt.
Charge;
230 vPosAcc(*vertex) = vPos;
231 isFakeAcc(*vertex) =
true;
237 uint8_t trkiBLHit,trkjBLHit;
241 if(
m_jp.FillNtuple )
m_ntupleVars->get< std::vector<int> >(
"All2TrkSumBLHits" ).emplace_back( trkiBLHit + trkjBLHit );
244 if(
m_jp.FillHist )
m_hists[
"2trkChi2Dist"]->Fill( log10( wrkvrt.
Chi2 ) );
247 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": failed to pass chi2 threshold." );
250 if(
m_jp.FillHist )
m_hists[
"incompMonitor"]->Fill( kChi2 );
253 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": attempting form vertex from ( " << itrk_id <<
", " << jtrk_id <<
" )." );
254 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": candidate vertex: "
255 <<
" isGood = " << (wrkvrt.
isGood?
"true" :
"false")
260 <<
", (r, z) = (" << wrkvrt.
vertex.perp()
261 <<
", " << wrkvrt.
vertex.z() <<
")" );
264 Amg::Vector3D vTruth( truthVertex->x(), truthVertex->y(), truthVertex->z() );
267 const auto distance = vReco - vTruth;
270 cov.fillSymmetric( 0, 0, wrkvrt.
vertexCov.at(0) );
271 cov.fillSymmetric( 1, 0, wrkvrt.
vertexCov.at(1) );
272 cov.fillSymmetric( 1, 1, wrkvrt.
vertexCov.at(2) );
273 cov.fillSymmetric( 2, 0, wrkvrt.
vertexCov.at(3) );
274 cov.fillSymmetric( 2, 1, wrkvrt.
vertexCov.at(4) );
275 cov.fillSymmetric( 2, 2, wrkvrt.
vertexCov.at(5) );
277 const double s2 = distance.transpose() * cov.inverse() * distance;
279 if( distance.norm() < 2.0 || s2 < 100. ) {
280 ATH_MSG_DEBUG (
" > " << __FUNCTION__ <<
": truth-matched candidate! : signif^2 = " << s2 );
281 matchMap.emplace( truthVertex,
true );
285 if(
m_jp.FillHist ) {
286 dynamic_cast<TH2F*
>(
m_hists[
"vPosDist"] )->Fill( wrkvrt.
vertex.perp(), vPos );
287 dynamic_cast<TH2F*
>(
m_hists[
"vPosMomAngTDist"] )->Fill( wrkvrt.
vertex.perp(), vPosMomAngT );
288 m_hists[
"vPosMomAngT"] ->Fill( vPosMomAngT );
289 m_hists[
"vPosMomAng3D"] ->Fill( vPosMomAng3D );
292 if(
m_jp.doTwoTrSoftBtag ){
293 if(dist_fromPV <
m_jp.twoTrVrtMinDistFromPV ){
294 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": failed to pass the 2tr vertex min distance from PV cut." );
298 if( vPosMomAng3D <
m_jp.twoTrVrtAngleCut ){
299 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": failed to pass the vertex angle cut." );
304 if(
m_jp.doPVcompatibilityCut ) {
305 if( cos( dphi1 ) < -0.8 && cos( dphi2 ) < -0.8 ) {
306 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": failed to pass the vPos cut. (both tracks are opposite against the vertex pos)" );
309 if (
m_jp.doTightPVcompatibilityCut && (cos( dphi1 ) < -0.8 || cos( dphi2 ) < -0.8)){
310 ATH_MSG_DEBUG(
" > "<< __FUNCTION__ <<
": failed to pass the tightened vPos cut. (at least one track is opposite against the vertex pos)" );
313 if( vPosMomAngT < -0.8 ) {
314 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": failed to pass the vPos cut. (pos-mom directions are opposite)" );
317 if( vPos <
m_jp.pvCompatibilityCut ) {
318 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": failed to pass the vPos cut." );
322 if(
m_jp.FillHist )
m_hists[
"incompMonitor"]->Fill( kVposCut );
325 if(
m_jp.removeFakeVrt && !
m_jp.removeFakeVrtLate ) {
328 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": failed to pass fake rejection algorithm." );
332 if(
m_jp.FillHist )
m_hists[
"incompMonitor"]->Fill( kPatternMatch );
334 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": passed fake rejection." );
336 if(
m_jp.FillNtuple ) {
341 m_ntupleVars->get< std::vector<int> > (
"AfFakVrtCharge" ) .emplace_back(wrkvrt.
Charge);
342 m_ntupleVars->get< std::vector<double> >(
"AfFakVrtX" ) .emplace_back(wrkvrt.
vertex.x());
343 m_ntupleVars->get< std::vector<double> >(
"AfFakVrtY" ) .emplace_back(wrkvrt.
vertex.y());
344 m_ntupleVars->get< std::vector<double> >(
"AfFakVrtZ" ) .emplace_back(wrkvrt.
vertex.z());
345 m_ntupleVars->get< std::vector<double> >(
"AfFakVrtChiSq" ) .emplace_back(wrkvrt.
Chi2);
349 if(
m_jp.FillIntermediateVertices && vertex ) {
351 isFakeAcc(*vertex) =
false;
361 workVerticesContainer->emplace_back( wrkvrt );
363 msg += Form(
" (%d, %d), ", itrk_id, jtrk_id );
365 if(
m_jp.FillHist ) {
366 m_hists[
"initVertexDispD0"]->Fill( roughD0_itrk, initVertex.perp() );
367 m_hists[
"initVertexDispD0"]->Fill( roughD0_jtrk, initVertex.perp() );
368 m_hists[
"initVertexDispZ0"]->Fill( roughZ0_itrk, initVertex.z() );
369 m_hists[
"initVertexDispZ0"]->Fill( roughZ0_jtrk, initVertex.z() );
376 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": compatible track pairs = " <<
msg );
380 if(
m_jp.FillHist ) {
381 for(
auto& pair: matchMap ) {
382 if( pair.second )
m_hists[
"nMatchedTruths"]->Fill( 1, pair.first->perp() );
386 return StatusCode::SUCCESS;
394 if(
m_jp.doDisappearingTrackVertexing){
396 return StatusCode::SUCCESS;
401 if(
m_jp.FillHist ) {
m_hists[
"2trkVerticesDist"]->Fill( compSize ); }
403 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": compatible track pair size = " << compSize );
407 if( not
m_jp.doFastMode ) {
409 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": incompatibility graph finder mode" );
412 workVerticesContainer->clear();
419 std::vector<long int> weit;
422 weit.emplace_back( pair.first + 1 );
423 weit.emplace_back( pair.second + 1 );
442 long int solutionSize { 0 };
445 std::vector<const xAOD::TrackParticle*> baseTracks;
446 std::vector<const xAOD::NeutralParticle*> dummyNeutrals;
448 std::unique_ptr<Trk::IVKalState> state =
m_fitSvc->makeState();
449 auto pgraph = std::make_unique<Trk::PGraph>();
450 int iterationLimit(2000);
455 pgraph->pgraphm_( weit.data(), nEdges, nTracks, solution.data(), &solutionSize, nth);
457 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": Trk::pgraphm_() output: solutionSize = " << solutionSize );
458 if (0 == iterationLimit--){
459 ATH_MSG_WARNING(
"Iteration limit (2000) reached in VrtSecInclusive::findNtrackVertices, solution size = "<<solutionSize);
462 if(solutionSize <= 0)
break;
463 if(solutionSize == 1)
continue;
467 std::string
msg =
"solution = [ ";
468 for(
int i=0; i< solutionSize; i++) {
469 msg += Form(
"%ld, ", solution[i]-1 );
482 for(
long int i = 0; i<solutionSize; i++) {
490 StatusCode
sc =
m_fitSvc->VKalVrtFitFast( baseTracks, initVertex, *state );
491 if(
sc.isFailure())
ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": fast crude estimation fails ");
493 m_fitSvc->setApproximateVertex( initVertex.x(), initVertex.y(), initVertex.z(), *state );
495 sc =
m_fitSvc->VKalVrtFit(baseTracks, dummyNeutrals,
505 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": FoundAppVrt=" << solutionSize <<
", (r, z) = " << wrkvrt.
vertex.perp() <<
", " << wrkvrt.
vertex.z() <<
", chi2/ndof = " << wrkvrt.
fitQuality() );
507 if(
sc.isFailure() ) {
510 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": VKalVrtFit failed in 2-trk solution ==> give up.");
514 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": VKalVrtFit failed ==> retry...");
522 if( itrk == jtrk )
continue;
523 if( tmp.isGood )
continue;
525 tmp.selectedTrackIndices.clear();
526 tmp.selectedTrackIndices.emplace_back( itrk );
527 tmp.selectedTrackIndices.emplace_back( jtrk );
536 sc =
m_fitSvc->VKalVrtFitFast( baseTracks, initVertex, *state );
537 if(
sc.isFailure() )
ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": fast crude estimation fails ");
539 m_fitSvc->setApproximateVertex( initVertex.x(), initVertex.y(), initVertex.z(), *state );
541 sc =
m_fitSvc->VKalVrtFit(baseTracks, dummyNeutrals,
551 if(
sc.isFailure() )
continue;
559 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": Did not find any viable vertex in all 2-trk combinations. Give up.");
566 if( std::find( tmp.selectedTrackIndices.begin(), tmp.selectedTrackIndices.end(), itrk ) != tmp.selectedTrackIndices.end() )
continue;
570 tmp.selectedTrackIndices.emplace_back( itrk );
572 for(
auto& jtrk : tmp.selectedTrackIndices ) { baseTracks.emplace_back(
m_selectedTracks.at(jtrk) ); }
577 sc =
m_fitSvc->VKalVrtFitFast( baseTracks, initVertex, *state );
578 if(
sc.isFailure())
ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": fast crude estimation fails ");
580 m_fitSvc->setApproximateVertex( initVertex.x(), initVertex.y(), initVertex.z(), *state );
582 sc =
m_fitSvc->VKalVrtFit(baseTracks, dummyNeutrals,
592 if(
sc.isFailure() ) {
600 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": VKalVrtFit succeeded; register the vertex to the list.");
604 workVerticesContainer->emplace_back( wrkvrt );
608 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": VKalVrtFit succeeded; register the vertex to the list.");
612 workVerticesContainer->emplace_back( wrkvrt );
621 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": rapid finder mode" );
625 std::set<long int> tracks;
628 std::vector<struct Cluster> clusters;
630 for(
auto& wrkvrt : *workVerticesContainer ) {
632 bool foundCluster =
false;
634 for(
auto& cluster: clusters ) {
635 if( (wrkvrt.vertex - cluster.position).norm() < 1.0 ) {
636 for(
auto& itrk : wrkvrt.selectedTrackIndices ) {
637 cluster.tracks.insert( itrk );
644 if( !foundCluster ) {
646 c.position = wrkvrt.vertex;
647 for(
auto& itrk : wrkvrt.selectedTrackIndices ) {
648 c.tracks.insert( itrk );
650 clusters.emplace_back( c );
651 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": added a new cluster" );
657 std::vector<const xAOD::TrackParticle*> baseTracks;
658 std::vector<const xAOD::NeutralParticle*> dummyNeutrals;
660 workVerticesContainer->clear();
662 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": found cluster size =" << clusters.size() );
664 std::unique_ptr<Trk::IVKalState> state =
m_fitSvc->makeState();
665 for(
auto& cluster : clusters ) {
675 for(
const auto&
index: cluster.tracks) {
683 StatusCode
sc =
m_fitSvc->VKalVrtFitFast( baseTracks, initVertex, *state );
684 if(
sc.isFailure())
ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": fast crude estimation fails ");
686 m_fitSvc->setApproximateVertex( initVertex.x(), initVertex.y(), initVertex.z(), *state );
688 sc =
m_fitSvc->VKalVrtFit(baseTracks, dummyNeutrals,
698 if(
sc.isFailure() ) {
702 workVerticesContainer->emplace_back( wrkvrt );
707 if (
m_jp.truncateWrkVertices){
708 if (workVerticesContainer->size() >
m_jp.maxWrkVertices){
710 workVerticesContainer->resize(
m_jp.maxWrkVertices);
718 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": Remove vertices fully contained in other vertices .");
719 while( workVerticesContainer->size() > 1 ) {
720 size_t tmpN = workVerticesContainer->size();
723 for(; iv<tmpN-1; iv++) {
725 for(; jv<tmpN; jv++) {
726 const auto nTCom =
nTrkCommon( workVerticesContainer, {iv, jv} );
728 if( nTCom == workVerticesContainer->at(iv).selectedTrackIndices.size() ) { workVerticesContainer->erase(workVerticesContainer->begin()+iv);
break; }
729 else if( nTCom == workVerticesContainer->at(jv).selectedTrackIndices.size() ) { workVerticesContainer->erase(workVerticesContainer->begin()+jv);
break; }
734 if(iv==tmpN-1)
break;
738 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": Identify remaining 2-track vertices with very bad Chi2 and mass (b-tagging).");
739 for(
auto& wrkvrt : *workVerticesContainer ) {
741 if( TMath::Prob( wrkvrt.Chi2, wrkvrt.ndof() ) <
m_jp.improveChi2ProbThreshold ) wrkvrt.isGood =
false;
742 if( wrkvrt.selectedTrackIndices.size() != 2 )
continue;
743 if(
m_jp.FillHist )
m_hists[
"NtrkChi2Dist"]->Fill( log10( wrkvrt.fitQuality() ) );
746 if(
m_jp.FillNtuple)
m_ntupleVars->get<
unsigned int>(
"NumInitSecVrt" ) = workVerticesContainer->size();
748 return StatusCode::SUCCESS;
755 if(
m_jp.doDisappearingTrackVertexing){
757 return StatusCode::SUCCESS;
763 std::vector<long int> processedTracks;
765 unsigned mergeCounter { 0 };
766 unsigned brokenCounter { 0 };
767 unsigned removeTrackCounter { 0 };
772 long int maxSharedTrack;
773 long int worstMatchingVertex;
780 std::map<long int, std::vector<long int> > trackToVertexMap;
789 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": no shared tracks are found --> exit the while loop." );
793 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": vertex [" << worstMatchingVertex <<
"]: maximally shared track index = " << maxSharedTrack
794 <<
", multiplicity = " << trackToVertexMap.at( maxSharedTrack ).size()
795 <<
", worst chi2_trk = " << worstChi2 );
798 if( worstChi2 <
m_jp.TrackDetachCut ) {
803 std::vector< std::pair<unsigned, unsigned> > badPairs;
809 unsigned nShared { 0 };
812 auto& vrtList = trackToVertexMap.at( maxSharedTrack );
814 auto nGood = std::count_if( vrtList.begin(), vrtList.end(), [&](
auto& v ) { return workVerticesContainer->at(v).isGood; } );
815 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": size of good vertices = " << nGood );
817 std::vector< std::tuple< std::pair<unsigned, unsigned>, double,
unsigned> > significanceTuple;
818 enum { kIndexPair, kSignificance, kNshared };
820 for(
auto ivrt = vrtList.begin(); ivrt != vrtList.end(); ++ivrt ) {
821 for(
auto jvrt = std::next( ivrt ); jvrt != vrtList.end(); ++jvrt ) {
822 auto pair = std::pair<unsigned, unsigned>( *ivrt, *jvrt );
824 if( !( workVerticesContainer->at(*ivrt).isGood ) )
continue;
825 if( !( workVerticesContainer->at(*jvrt).isGood ) )
continue;
828 if( std::find( badPairs.begin(), badPairs.end(), pair ) != badPairs.end() )
continue;
832 auto& ivrtTrks = workVerticesContainer->at(*ivrt).selectedTrackIndices;
833 auto& jvrtTrks = workVerticesContainer->at(*jvrt).selectedTrackIndices;
835 auto nSharedTracks = std::count_if( ivrtTrks.begin(), ivrtTrks.end(),
837 return std::find( jvrtTrks.begin(), jvrtTrks.end(), index ) != jvrtTrks.end();
840 significanceTuple.emplace_back( pair, signif, nSharedTracks );
844 if( significanceTuple.empty() ) {
845 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": no vertex pairs are found --> exit the while loop." );
849 auto minSignificanceTuple = std::min_element( significanceTuple.begin(), significanceTuple.end(), [&](
auto& t1,
auto&t2 ) { return std::get<kSignificance>(t1) < std::get<kSignificance>(t2); } );
851 indexPair = std::get<kIndexPair> ( *minSignificanceTuple );
852 minSignificance = std::get<kSignificance> ( *minSignificanceTuple );
853 nShared = std::get<kNshared> ( *minSignificanceTuple );
856 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": minSignificance = " << minSignificance );
858 if( minSignificance < m_jp.VertexMergeCut || nShared >= 2 ) {
860 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": attempt to merge vertices " << indexPair.first <<
" and " << indexPair.second );
862 WrkVrt vertex_backup1 = workVerticesContainer->at( indexPair.first );
863 WrkVrt vertex_backup2 = workVerticesContainer->at( indexPair.second );
865 StatusCode
sc =
mergeVertices( workVerticesContainer->at( indexPair.first ), workVerticesContainer->at( indexPair.second ) );
869 if(
sc.isFailure() ) {
871 workVerticesContainer->at( indexPair.first ) = vertex_backup1;
872 workVerticesContainer->at( indexPair.second ) = vertex_backup2;
873 badPairs.emplace_back( indexPair );
878 workVerticesContainer->at( indexPair.second ).isGood =
false;
885 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": Merged vertices " << indexPair.first <<
" and " << indexPair.second <<
". merged vertex multiplicity = " << workVerticesContainer->at( indexPair.first ).selectedTrackIndices.size() );
893 auto& wrkvrt = workVerticesContainer->at( worstMatchingVertex );
895 auto end =
std::remove_if( wrkvrt.selectedTrackIndices.begin(), wrkvrt.selectedTrackIndices.end(), [&](
auto&
index ) { return index == maxSharedTrack; } );
896 wrkvrt.selectedTrackIndices.erase( end, wrkvrt.selectedTrackIndices.end() );
898 removeTrackCounter++;
900 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": removed track " << maxSharedTrack <<
" from vertex " << worstMatchingVertex );
902 if( wrkvrt.selectedTrackIndices.size() < 2 ) {
903 wrkvrt.isGood =
false;
909 if(
sc.isFailure() ) {
910 ATH_MSG_WARNING(
" > " << __FUNCTION__ <<
": detected vertex fitting failure!" );
923 auto& wrkvrt = workVerticesContainer->at( worstMatchingVertex );
925 auto end =
std::remove_if( wrkvrt.selectedTrackIndices.begin(), wrkvrt.selectedTrackIndices.end(), [&](
auto&
index ) { return index == maxSharedTrack; } );
926 wrkvrt.selectedTrackIndices.erase( end, wrkvrt.selectedTrackIndices.end() );
928 if( wrkvrt.nTracksTotal() >=2 ) {
930 auto wrkvrt_backup = wrkvrt;
932 if(
sc.isFailure() ) {
933 ATH_MSG_WARNING(
" > " << __FUNCTION__ <<
": detected vertex fitting failure!" );
934 wrkvrt = wrkvrt_backup;
938 wrkvrt.isGood =
false;
942 removeTrackCounter++;
944 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": removed track " << maxSharedTrack <<
" from vertex " << worstMatchingVertex );
952 for(
auto& wrkvrt : *workVerticesContainer ) {
954 if(!wrkvrt.isGood )
continue;
955 if( wrkvrt.selectedTrackIndices.size() < 3 )
continue;
959 if( wrkvrt.fitQuality() > backup.
fitQuality() ) wrkvrt = backup;
961 if( wrkvrt.nTracksTotal() < 2 ) wrkvrt.
isGood =
false;
965 if(
m_jp.FillNtuple ) {
966 m_ntupleVars->get<
unsigned int>(
"NumRearrSecVrt" )=workVerticesContainer->size();
967 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": Size of Solution Set: "<<
m_ntupleVars->get<
unsigned int>(
"NumRearrSecVrt" ));
970 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
"----------------------------------------------" );
971 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": Number of merges = " << mergeCounter <<
", Number of track removal = " << removeTrackCounter <<
", broken vertices = " << brokenCounter );
972 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
"----------------------------------------------" );
974 return StatusCode::SUCCESS;
1113 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": #verticess = " << workVerticesContainer->size() );
1115 unsigned associateCounter { 0 };
1118 for(
auto& wrkvrt : *workVerticesContainer ) {
1120 if( !wrkvrt.isGood )
continue;
1121 if( wrkvrt.selectedTrackIndices.size() <= 1 )
continue;
1125 wrkvrt.Chi2_core = wrkvrt.Chi2;
1127 auto& vertexPos = wrkvrt.vertex;
1129 std::vector<double> distanceToPVs;
1131 for(
const auto* pv : *pvs ) {
1134 const auto& minDistance = *( std::min_element( distanceToPVs.begin(), distanceToPVs.end() ) );
1136 if( minDistance <
m_jp.associateMinDistanceToPV )
continue;
1139 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": vertex pos = (" << vertexPos.x() <<
", " << vertexPos.y() <<
", " << vertexPos.z() <<
"), "
1140 "#selected = " << wrkvrt.selectedTrackIndices.size() <<
", #assoc = " << wrkvrt.associatedTrackIndices.size() );
1142 std::vector<const xAOD::TrackParticle*> candidates;
1145 for(
auto itr = allTracks->
begin(); itr != allTracks->
end(); ++itr ) {
1146 const auto* trk = *itr;
1150 auto result = std::find_if( workVerticesContainer->begin(), workVerticesContainer->end(),
1152 auto found = std::find_if( wrkvrt.selectedTrackIndices.begin(), wrkvrt.selectedTrackIndices.end(),
1153 [&]( long int index ) {
1155 if (m_jp.doSelectTracksFromElectrons || m_jp.doSelectIDAndGSFTracks) {
1156 const xAOD::TrackParticle *id_tr;
1157 id_tr = xAOD::EgammaHelpers::getOriginalTrackParticleFromGSF(m_selectedTracks.at(index));
1158 return trk == m_selectedTracks.at(index) or trk == id_tr;
1161 return trk == m_selectedTracks.at(index);
1166 if(
result != workVerticesContainer->end() )
continue;
1172 [&] (
const auto* atrk) { return trk == atrk; } );
1180 if( trk->pt() <
m_jp.associatePtCut )
continue;
1183 if( trk->chiSquared() / trk->numberDoF() >
m_jp.associateChi2Cut )
continue;
1189 std::vector<double> impactParameters;
1190 std::vector<double> impactParErrors;
1194 if( std::abs( impactParameters.at(0) ) / sqrt( impactParErrors.at(0) ) >
m_jp.associateMaxD0Signif )
continue;
1195 if( std::abs( impactParameters.at(1) ) / sqrt( impactParErrors.at(1) ) >
m_jp.associateMaxZ0Signif )
continue;
1198 <<
": d0 to vtx = " << impactParameters.at(
k_d0)
1199 <<
", z0 to vtx = " << impactParameters.at(
k_z0)
1200 <<
", distance to vtx = " << hypot( impactParameters.at(
k_d0), impactParameters.at(
k_z0) ) );
1202 candidates.emplace_back( trk );
1206 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": number of candidate tracks = " << candidates.size() );
1208 std::unique_ptr<Trk::IVKalState> state =
m_fitSvc->makeState();
1210 for(
const auto* trk : candidates ) {
1212 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": attempting to associate track = " << trk );
1215 WrkVrt wrkvrt_backup = wrkvrt;
1217 m_fitSvc->setApproximateVertex( vertexPos.x(), vertexPos.y(), vertexPos.z(), *state );
1219 std::vector<const xAOD::TrackParticle*> baseTracks;
1220 std::vector<const xAOD::NeutralParticle*> dummyNeutrals;
1222 wrkvrt.Chi2PerTrk.clear();
1224 for(
const auto&
index : wrkvrt.selectedTrackIndices ) {
1228 for(
const auto&
index : wrkvrt.associatedTrackIndices ) {
1233 baseTracks.emplace_back( trk );
1239 StatusCode
sc =
m_fitSvc->VKalVrtFitFast( baseTracks, initPos, *state );
1241 if(
sc.isFailure() )
ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": fast crude estimation failed.");
1243 const auto& diffPos = initPos - vertexPos;
1245 if( diffPos.norm() > 10. ) {
1247 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": approx vertex as original" );
1248 m_fitSvc->setApproximateVertex( vertexPos.x(), vertexPos.y(), vertexPos.z(), *state );
1252 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": approx vertex set to (" << initPos.x() <<
", " << initPos.y() <<
", " << initPos.z() <<
")" );
1253 m_fitSvc->setApproximateVertex( initPos.x(), initPos.y(), initPos.z(), *state );
1259 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": now vertex fitting..." );
1261 StatusCode
sc =
m_fitSvc->VKalVrtFit(baseTracks, dummyNeutrals,
1271 if(
sc.isFailure() ) {
1272 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": VKalVrtFit failure. Revert to backup");
1273 wrkvrt = wrkvrt_backup;
1275 if(
m_jp.FillHist )
m_hists[
"associateMonitor"]->Fill( 1 );
1281 if(
m_jp.FillHist )
m_hists[
"associateMonitor"]->Fill( 0 );
1283 auto& cov = wrkvrt.vertexCov;
1285 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": succeeded in associating. New vertex pos = (" << vertexPos.perp() <<
", " << vertexPos.z() <<
", " << vertexPos.perp()*vertexPos.phi() <<
")" );
1286 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) <<
")" );
1293 (*m_decor_isAssociated)( *trk ) =
true;
1299 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
"----------------------------------------------" );
1300 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": total associated number of tracks = " << associateCounter );
1301 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
"----------------------------------------------" );
1303 return StatusCode::SUCCESS;
1523 ATH_CHECK(
evtStore()->retrieve( secondaryVertexContainer,
"VrtSecInclusive_" +
m_jp.secondaryVerticesContainerName +
m_jp.augVerString ) );
1528 enum { kPt, kEta, kPhi, kD0, kZ0, kErrP, kErrD0, kErrZ0, kChi2SV };
1544 std::map<const WrkVrt*, const xAOD::Vertex*> wrkvrtLinkMap;
1547 const auto& ctx = Gaudi::Hive::currentContext();
1549 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": input #vertices = " << workVerticesContainer->size() );
1552 for(
auto& wrkvrt : *workVerticesContainer ) {
1554 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": candidate vertex: "
1555 <<
" isGood = " << (wrkvrt.isGood?
"true" :
"false")
1556 <<
", #ntrks = " << wrkvrt.nTracksTotal()
1557 <<
", #selectedTracks = " << wrkvrt.selectedTrackIndices.size()
1558 <<
", #associatedTracks = " << wrkvrt.associatedTrackIndices.size()
1560 <<
", (r, z) = (" << wrkvrt.vertex.perp()
1561 <<
", " << wrkvrt.vertex.z() <<
")" );
1563 if(
m_jp.FillHist )
m_hists[
"finalCutMonitor"]->Fill( 0 );
1565 if(
m_jp.removeFakeVrt &&
m_jp.removeFakeVrtLate ) {
1569 if( wrkvrt.nTracksTotal() < 2 ) {
1570 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": ntrk < 2 --> rejected." );
1574 if(
m_jp.FillHist )
m_hists[
"finalCutMonitor"]->Fill( 1 );
1578 if( wrkvrt.vertex.perp() < 31.0 ) {
1581 wrkvrt.selectedTrackIndices.erase(
std::remove_if( wrkvrt.selectedTrackIndices.begin(), wrkvrt.selectedTrackIndices.end(),
1582 [&](
auto&
index ) {
1583 auto* trk = m_selectedTracks.at( index );
1585 return ( nPixelHits < 3 );
1587 wrkvrt.selectedTrackIndices.end() );
1590 wrkvrt.associatedTrackIndices.erase(
std::remove_if( wrkvrt.associatedTrackIndices.begin(), wrkvrt.associatedTrackIndices.end(),
1591 [&](
auto&
index ) {
1592 auto* trk = m_associatedTracks.at( index );
1594 return ( nPixelHits < 3 );
1596 wrkvrt.associatedTrackIndices.end() );
1599 if( statusCode.isFailure() ) {}
1604 if(
m_jp.doFinalImproveChi2 ) {
1610 if( wrkvrt.fitQuality() > backup.
fitQuality() ) wrkvrt = backup;
1615 if( wrkvrt.nTracksTotal() < 2 )
continue;
1618 if( wrkvrt.selectedTrackIndices.size() < 2 )
continue;
1621 if(
m_jp.FillHist )
m_hists[
"finalCutMonitor"]->Fill( 2 );
1628 if(
sc.isFailure() ) {
1630 auto indices = wrkvrt.associatedTrackIndices;
1632 wrkvrt.associatedTrackIndices.clear();
1634 if(
sc.isFailure() ) {
1635 ATH_MSG_WARNING(
" > " << __FUNCTION__ <<
": detected vertex fitting failure!" );
1638 if( wrkvrt.fitQuality() > backup.
fitQuality() ) wrkvrt = backup;
1640 for(
auto&
index : indices ) {
1644 if(
sc.isFailure() || TMath::Prob( wrkvrt.Chi2, wrkvrt.ndof() ) <
m_jp.improveChi2ProbThreshold ) {
1645 ATH_MSG_WARNING(
" > " << __FUNCTION__ <<
": detected vertex fitting failure!" );
1652 if( wrkvrt.fitQuality() > backup.
fitQuality() ) wrkvrt = backup;
1656 if(
m_jp.FillHist )
m_hists[
"finalCutMonitor"]->Fill( 3 );
1663 TLorentzVector sumP4_pion;
1664 TLorentzVector sumP4_electron;
1665 TLorentzVector sumP4_proton;
1668 bool good_flag =
true;
1670 std::map<const std::deque<long int>*,
const std::vector<const xAOD::TrackParticle*>&> indicesSet
1676 for(
auto& pair : indicesSet ) {
1678 const auto* indices = pair.first;
1679 const auto& tracks = pair.second;
1681 for(
const auto& itrk : *indices ) {
1682 const auto* trk = tracks.at( itrk );
1685 ATH_MSG_INFO(
" > " << __FUNCTION__ <<
": > Track index " << trk->index() <<
": Failed in obtaining the SV perigee!" );
1693 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": sv perigee could not be obtained --> rejected" );
1697 if(
m_jp.FillHist )
m_hists[
"finalCutMonitor"]->Fill( 4 );
1700 std::vector<const xAOD::TrackParticle*> tracks;
1701 std::vector< std::pair<const xAOD::TrackParticle*, double> > trackChi2Pairs;
1705 for(
auto& pair : indicesSet ) {
1706 for(
const auto&
index : *pair.first ) tracks.emplace_back( pair.second.at(
index ) );
1709 auto trkitr = tracks.begin();
1710 auto chi2itr = wrkvrt.Chi2PerTrk.begin();
1712 for( ; ( trkitr!=tracks.end() && chi2itr!=wrkvrt.Chi2PerTrk.end() ); ++trkitr, ++chi2itr ) {
1713 trackChi2Pairs.emplace_back( *trkitr, *chi2itr );
1719 TLorentzVector sumP4_selected;
1721 bool badIPflag {
false };
1724 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": Track loop: size = " << tracks.size() );
1725 for(
auto& pair : trackChi2Pairs ) {
1727 const auto* trk = pair.first;
1728 const auto& chi2AtSV = pair.second;
1730 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": > Track index " << trk->index() <<
": start." );
1739 double trk_pt = trk->pt();
1740 double trk_eta = trk->eta();
1741 double trk_phi = trk->phi();
1743 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": > Track index " << trk->index() <<
": in vrt chg/pt/phi/eta = "
1744 << trk->charge() <<
","
1751 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": > Track index " << trk->index() <<
": Get the prigee of the track at the vertex." );
1755 ATH_MSG_WARNING(
" > " << __FUNCTION__ <<
": > Track index " << trk->index() <<
": Failed in obtaining the SV perigee!" );
1760 (*m_decor_is_svtrk_final)( *trk ) =
true;
1764 double qOverP_wrtSV = sv_perigee->parameters() [
Trk::qOverP];
1765 double theta_wrtSV = sv_perigee->parameters() [
Trk::theta];
1766 double p_wrtSV = 1.0 / std::abs( qOverP_wrtSV );
1767 double pt_wrtSV = p_wrtSV * sin( theta_wrtSV );
1768 double eta_wrtSV = -log( tan( theta_wrtSV/2. ) );
1769 double phi_wrtSV = sv_perigee->parameters() [
Trk::phi];
1770 double d0_wrtSV = sv_perigee->parameters() [
Trk::d0];
1771 double z0_wrtSV = sv_perigee->parameters() [
Trk::z0];
1772 double errd0_wrtSV = (*sv_perigee->covariance())(
Trk::d0,
Trk::d0 );
1773 double errz0_wrtSV = (*sv_perigee->covariance())(
Trk::z0,
Trk::z0 );
1787 (*m_decor_is_svtrk_final)( *trk ) =
true;
1789 TLorentzVector p4wrtSV_pion;
1790 TLorentzVector p4wrtSV_electron;
1791 TLorentzVector p4wrtSV_proton;
1799 if( !is_associatedAcc(*trk) ) {
1800 sumP4_selected += p4wrtSV_pion;
1803 sumP4_selected += p4wrtSV_pion;
1806 sumP4_pion += p4wrtSV_pion;
1807 sumP4_electron += p4wrtSV_electron;
1808 sumP4_proton += p4wrtSV_proton;
1810 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": > Track index " << trk->index() <<
": end." );
1815 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": Final Sec.Vertex=" << wrkvrt.nTracksTotal() <<
", "
1816 <<wrkvrt.vertex.perp() <<
", "<<wrkvrt.vertex.z() <<
", "
1817 <<wrkvrt.vertex.phi() <<
", mass = "<< sumP4_pion.M() <<
"," << sumP4_electron.M() );
1820 float perigee_x_trk1 = 0.0;
1821 float perigee_y_trk1 = 0.0;
1822 float perigee_z_trk1 = 0.0;
1823 float perigee_x_trk2 = 0.0;
1824 float perigee_y_trk2 = 0.0;
1825 float perigee_z_trk2 = 0.0;
1826 float perigee_px_trk1 = 0.0;
1827 float perigee_py_trk1 = 0.0;
1828 float perigee_pz_trk1 = 0.0;
1829 float perigee_px_trk2 = 0.0;
1830 float perigee_py_trk2 = 0.0;
1831 float perigee_pz_trk2 = 0.0;
1832 float perigee_cov_xx_trk1 = 0.0;
1833 float perigee_cov_xy_trk1 = 0.0;
1834 float perigee_cov_xz_trk1 = 0.0;
1835 float perigee_cov_yy_trk1 = 0.0;
1836 float perigee_cov_yz_trk1 = 0.0;
1837 float perigee_cov_zz_trk1 = 0.0;
1838 float perigee_cov_xx_trk2 = 0.0;
1839 float perigee_cov_xy_trk2 = 0.0;
1840 float perigee_cov_xz_trk2 = 0.0;
1841 float perigee_cov_yy_trk2 = 0.0;
1842 float perigee_cov_yz_trk2 = 0.0;
1843 float perigee_cov_zz_trk2 = 0.0;
1844 float perigee_d0_trk1 = 0.0;
1845 float perigee_d0_trk2 = 0.0;
1846 float perigee_z0_trk1 = 0.0;
1847 float perigee_z0_trk2 = 0.0;
1848 float perigee_qOverP_trk1 = 0.0;
1849 float perigee_qOverP_trk2 = 0.0;
1850 float perigee_theta_trk1 = 0.0;
1851 float perigee_theta_trk2 = 0.0;
1852 float perigee_phi_trk1 = 0.0;
1853 float perigee_phi_trk2 = 0.0;
1854 int perigee_charge_trk1 = 0;
1855 int perigee_charge_trk2 = 0;
1856 float perigee_distance = 9999.0;
1859 float vPos = (vDist.x() * wrkvrt.vertexMom.Px() + vDist.y() * wrkvrt.vertexMom.Py() + vDist.z() * wrkvrt.vertexMom.Pz()) / wrkvrt.vertexMom.Rho();
1860 float vPosMomAngT = (vDist.x() * wrkvrt.vertexMom.Px() + vDist.y() * wrkvrt.vertexMom.Py()) / vDist.perp() / wrkvrt.vertexMom.Pt();
1861 float vPosMomAng3D = (vDist.x() * wrkvrt.vertexMom.Px() + vDist.y() * wrkvrt.vertexMom.Py() + vDist.z() * wrkvrt.vertexMom.Pz()) / (vDist.norm() * wrkvrt.vertexMom.Rho());
1862 float dphi_trk1 = 0.0;
1863 float dphi_trk2 = 0.0;
1865 if (
m_jp.doDisappearingTrackVertexing){
1867 const auto* track1 = trackChi2Pairs[0].first;
1868 dphi_trk1 = TVector2::Phi_mpi_pi(vDist.phi() - track1->phi());
1871 perigee_x_trk1 = sv_perigee1->position().x();
1872 perigee_y_trk1 = sv_perigee1->position().y();
1873 perigee_z_trk1 = sv_perigee1->position().z();
1874 perigee_px_trk1 = sv_perigee1->momentum().x();
1875 perigee_py_trk1 = sv_perigee1->momentum().y();
1876 perigee_pz_trk1 = sv_perigee1->momentum().z();
1877 perigee_cov_xx_trk1 = (*sv_perigee1->covariance())(0, 0);
1878 perigee_cov_xy_trk1 = (*sv_perigee1->covariance())(0, 1);
1879 perigee_cov_xz_trk1 = (*sv_perigee1->covariance())(0, 2);
1880 perigee_cov_yy_trk1 = (*sv_perigee1->covariance())(1, 1);
1881 perigee_cov_yz_trk1 = (*sv_perigee1->covariance())(1, 2);
1882 perigee_cov_zz_trk1 = (*sv_perigee1->covariance())(2, 2);
1883 perigee_d0_trk1 = sv_perigee1->parameters()[
Trk::d0];
1884 perigee_z0_trk1 = sv_perigee1->parameters()[
Trk::z0];
1885 perigee_qOverP_trk1 = sv_perigee1->parameters()[
Trk::qOverP];
1886 perigee_theta_trk1 = sv_perigee1->parameters()[
Trk::theta];
1887 perigee_phi_trk1 = sv_perigee1->parameters()[
Trk::phi];
1888 perigee_charge_trk1 = sv_perigee1->parameters()[
Trk::qOverP] > 0 ? 1 : -1;
1890 ATH_MSG_DEBUG(
"Failed to obtain perigee for track1 at vertex.");
1894 const auto* track2 = trackChi2Pairs[1].first;
1895 dphi_trk2 = TVector2::Phi_mpi_pi(vDist.phi() - track2->phi());
1898 perigee_x_trk2 = sv_perigee2->position().x();
1899 perigee_y_trk2 = sv_perigee2->position().y();
1900 perigee_z_trk2 = sv_perigee2->position().z();
1901 perigee_px_trk2 = sv_perigee2->momentum().x();
1902 perigee_py_trk2 = sv_perigee2->momentum().y();
1903 perigee_pz_trk2 = sv_perigee2->momentum().z();
1904 perigee_cov_xx_trk2 = (*sv_perigee2->covariance())(0, 0);
1905 perigee_cov_xy_trk2 = (*sv_perigee2->covariance())(0, 1);
1906 perigee_cov_xz_trk2 = (*sv_perigee2->covariance())(0, 2);
1907 perigee_cov_yy_trk2 = (*sv_perigee2->covariance())(1, 1);
1908 perigee_cov_yz_trk2 = (*sv_perigee2->covariance())(1, 2);
1909 perigee_cov_zz_trk2 = (*sv_perigee2->covariance())(2, 2);
1910 perigee_d0_trk2 = sv_perigee2->parameters()[
Trk::d0];
1911 perigee_z0_trk2 = sv_perigee2->parameters()[
Trk::z0];
1912 perigee_qOverP_trk2 = sv_perigee2->parameters()[
Trk::qOverP];
1913 perigee_theta_trk2 = sv_perigee2->parameters()[
Trk::theta];
1914 perigee_phi_trk2 = sv_perigee2->parameters()[
Trk::phi];
1915 perigee_charge_trk2 = sv_perigee2->parameters()[
Trk::qOverP] > 0 ? 1 : -1;
1917 ATH_MSG_DEBUG(
"Failed to obtain perigee for track2 at vertex.");
1920 if(sv_perigee1 && sv_perigee2){
1921 perigee_distance = sqrt(
1922 (perigee_x_trk1 - perigee_x_trk2) * (perigee_x_trk1 - perigee_x_trk2) +
1923 (perigee_y_trk1 - perigee_y_trk2) * (perigee_y_trk1 - perigee_y_trk2) +
1924 (perigee_z_trk1 - perigee_z_trk2) * (perigee_z_trk1 - perigee_z_trk2)
1927 if(perigee_distance >
m_jp.twoTrVrtMaxPerigeeDist)
continue;
1934 std::vector<double> opAngles;
1936 for(
auto itr1 = tracks.begin(); itr1 != tracks.end(); ++itr1 ) {
1937 for(
auto itr2 = std::next( itr1 ); itr2 != tracks.end(); ++itr2 ) {
1938 const auto& p1 = (*itr1)->p4().Vect();
1939 const auto& p2 = (*itr2)->p4().Vect();
1940 auto cos = p1 * p2 / p1.Mag() / p2.Mag();
1941 opAngles.emplace_back( cos );
1944 minOpAng = *( std::max_element( opAngles.begin(), opAngles.end() ) );
1945 if(
m_jp.FillNtuple )
m_ntupleVars->get< vector<double> >(
"SecVtx_MinOpAng" ).emplace_back(minOpAng);
1948 if(
m_jp.FillHist )
m_hists[
"finalCutMonitor"]->Fill( 5 );
1951 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": Bad impact parameter signif wrt SV was flagged." );
1954 if (
m_jp.doRemoveNonLeptonVertices) {
1956 bool oneLepMatchTrack =
false;
1957 for (
const auto *trk: tracks) {
1959 oneLepMatchTrack =
true;
1965 if (!oneLepMatchTrack)
continue;
1971 wrkvrt.isGood =
true;
1976 secondaryVertexContainer->emplace_back( vertex );
1979 vertex->setPosition( wrkvrt.vertex );
1986 vertex->setFitQuality( wrkvrt.Chi2_core, wrkvrt.ndof_core() );
1989 std::vector<float> fCov(wrkvrt.vertexCov.cbegin(), wrkvrt.vertexCov.cend());
1990 vertex->setCovariance(fCov);
2011 vtx_pxAcc(*vertex) = wrkvrt.vertexMom.Px();
2012 vtx_pyAcc(*vertex) = wrkvrt.vertexMom.Py();
2013 vtx_pzAcc(*vertex) = wrkvrt.vertexMom.Pz();
2015 vtx_massAcc(*vertex) = wrkvrt.vertexMom.M();
2016 vtx_chargeAcc(*vertex) = wrkvrt.Charge;
2018 chi2_coreAcc(*vertex) = wrkvrt.Chi2_core;
2019 ndof_coreAcc(*vertex) = wrkvrt.ndof_core();
2020 chi2_assocAcc(*vertex) = wrkvrt.Chi2;
2021 ndof_assocAcc(*vertex) = wrkvrt.ndof();
2023 massAcc(*vertex) = sumP4_pion.M();
2024 mass_eAcc(*vertex) = sumP4_electron.M();
2025 mass_selectedTracksAcc(*vertex) = sumP4_selected.M();
2026 minOpAngAcc(*vertex) = minOpAng;
2027 num_trksAcc(*vertex) = wrkvrt.nTracksTotal();
2028 num_selectedTracksAcc(*vertex) = wrkvrt.selectedTrackIndices.size();
2029 num_associatedTracksAcc(*vertex) = wrkvrt.associatedTrackIndices.size();
2030 dCloseVrtAcc(*vertex) = wrkvrt.closestWrkVrtValue;
2033 if (
m_jp.doDisappearingTrackVertexing){
2075 perigee_x_trk1Acc(*vertex) = perigee_x_trk1;
2076 perigee_y_trk1Acc(*vertex) = perigee_y_trk1;
2077 perigee_z_trk1Acc(*vertex) = perigee_z_trk1;
2078 perigee_x_trk2Acc(*vertex) = perigee_x_trk2;
2079 perigee_y_trk2Acc(*vertex) = perigee_y_trk2;
2080 perigee_z_trk2Acc(*vertex) = perigee_z_trk2;
2081 perigee_px_trk1Acc(*vertex) = perigee_px_trk1;
2082 perigee_py_trk1Acc(*vertex) = perigee_py_trk1;
2083 perigee_pz_trk1Acc(*vertex) = perigee_pz_trk1;
2084 perigee_px_trk2Acc(*vertex) = perigee_px_trk2;
2085 perigee_py_trk2Acc(*vertex) = perigee_py_trk2;
2086 perigee_pz_trk2Acc(*vertex) = perigee_pz_trk2;
2087 perigee_cov_xx_trk1Acc(*vertex) = perigee_cov_xx_trk1;
2088 perigee_cov_xy_trk1Acc(*vertex) = perigee_cov_xy_trk1;
2089 perigee_cov_xz_trk1Acc(*vertex) = perigee_cov_xz_trk1;
2090 perigee_cov_yy_trk1Acc(*vertex) = perigee_cov_yy_trk1;
2091 perigee_cov_yz_trk1Acc(*vertex) = perigee_cov_yz_trk1;
2092 perigee_cov_zz_trk1Acc(*vertex) = perigee_cov_zz_trk1;
2093 perigee_cov_xx_trk2Acc(*vertex) = perigee_cov_xx_trk2;
2094 perigee_cov_xy_trk2Acc(*vertex) = perigee_cov_xy_trk2;
2095 perigee_cov_xz_trk2Acc(*vertex) = perigee_cov_xz_trk2;
2096 perigee_cov_yy_trk2Acc(*vertex) = perigee_cov_yy_trk2;
2097 perigee_cov_yz_trk2Acc(*vertex) = perigee_cov_yz_trk2;
2098 perigee_cov_zz_trk2Acc(*vertex) = perigee_cov_zz_trk2;
2099 perigee_d0_trk1Acc(*vertex) = perigee_d0_trk1;
2100 perigee_d0_trk2Acc(*vertex) = perigee_d0_trk2;
2101 perigee_z0_trk1Acc(*vertex) = perigee_z0_trk1;
2102 perigee_z0_trk2Acc(*vertex) = perigee_z0_trk2;
2103 perigee_qOverP_trk1Acc(*vertex) = perigee_qOverP_trk1;
2104 perigee_qOverP_trk2Acc(*vertex) = perigee_qOverP_trk2;
2105 perigee_theta_trk1Acc(*vertex) = perigee_theta_trk1;
2106 perigee_theta_trk2Acc(*vertex) = perigee_theta_trk2;
2107 perigee_phi_trk1Acc(*vertex) = perigee_phi_trk1;
2108 perigee_phi_trk2Acc(*vertex) = perigee_phi_trk2;
2109 perigee_charge_trk1Acc(*vertex) = perigee_charge_trk1;
2110 perigee_charge_trk2Acc(*vertex) = perigee_charge_trk2;
2111 vPosAcc(*vertex) = vPos;
2112 vPosMomAngTAcc(*vertex) = vPosMomAngT;
2113 vPosMomAng3DAcc(*vertex) = vPosMomAng3D;
2114 dphi_trk1Acc(*vertex) = dphi_trk1;
2115 dphi_trk2Acc(*vertex) = dphi_trk2;
2120 for(
auto trk_id : wrkvrt.selectedTrackIndices ) {
2128 vertex->addTrackAtVertex( link_trk, 1. );
2132 for(
auto trk_id : wrkvrt.associatedTrackIndices ) {
2140 vertex->addTrackAtVertex( link_trk, 1. );
2145 if(
m_jp.doMapToLocal ) {
2153 if( mappedVtx.
valid ) {
2155 local_layerIndexAcc(*vertex) = mappedVtx.
layerIndex;
2171 if(
m_jp.doTruth ) {
2176 wrkvrtLinkMap[&wrkvrt] = vertex;
2181 if( m_jp.FillNtuple ) {
2182 ATH_CHECK( fillAANT_SecondaryVertices( secondaryVertexContainer ) );
2187 if( m_jp.doAugmentDVimpactParametersToMuons ) {
ATH_CHECK( augmentDVimpactParametersToLeptons<xAOD::Muon> (
"Muons" ) ); }
2188 if( m_jp.doAugmentDVimpactParametersToElectrons ) {
ATH_CHECK( augmentDVimpactParametersToLeptons<xAOD::Electron>(
"Electrons" ) ); }
2190 }
catch (
const std::out_of_range& e) {
2192 ATH_MSG_WARNING(
" > " << __FUNCTION__ <<
": out of range error is detected: " <<
e.what() );
2194 return StatusCode::SUCCESS;
2198 ATH_MSG_WARNING(
" > " << __FUNCTION__ <<
": some other error is detected." );
2200 return StatusCode::SUCCESS;
2204 return StatusCode::SUCCESS;