31      m_materialMapInnerFileName(
"MaterialMap_v3.2_Inner.root"),
 
   32      m_materialMapInnerHistName(
"FinalMap_inner"),
 
   33      m_materialMapInnerMatrixName(
"FoldingInfo"),
 
   34      m_materialMapOuterFileName(
"MaterialMap_v3_Outer.root"),
 
   35      m_materialMapOuterHistName(
"matmap_outer")
 
   46         return StatusCode::FAILURE;
 
   48      std::unique_ptr<TFile> materialMapInnerFile = std::make_unique<TFile>(
inFileName.c_str(), 
"READ");
 
   49      if(materialMapInnerFile->IsOpen()){
 
   54      materialMapInnerFile->Close();
 
   59         return StatusCode::FAILURE;
 
   61      std::unique_ptr<TFile> materialMapOuterFile = std::make_unique<TFile>(
outFileName.c_str(), 
"READ");
 
   62      if(materialMapOuterFile->IsOpen()){
 
   66      materialMapOuterFile->Close();
 
   87    return StatusCode::SUCCESS;
 
   95    std::unique_ptr<xAOD::VertexContainer>     theXAODContainer    = std::make_unique<xAOD::VertexContainer>();
 
   96    std::unique_ptr<xAOD::VertexAuxContainer>  theXAODAuxContainer = std::make_unique<xAOD::VertexAuxContainer>();
 
   97    theXAODContainer->setStore( theXAODAuxContainer.get() );
 
   98    xAODContainers theXAODContainers = std::make_pair( std::move(theXAODContainer), std::move(theXAODAuxContainer) );
 
  103    std::unique_ptr<xAOD::VertexContainer>     theXAODTrkPairContainer    = std::make_unique<xAOD::VertexContainer>();
 
  104    std::unique_ptr<xAOD::VertexAuxContainer>  theXAODTrkPairAuxContainer = std::make_unique<xAOD::VertexAuxContainer>();
 
  105    theXAODTrkPairContainer->setStore( theXAODTrkPairAuxContainer.get() );
 
  106    xAODContainers theXAODTrkPairContainers = std::make_pair( std::move(theXAODTrkPairContainer), std::move(theXAODTrkPairAuxContainer) );
 
  114       privtx = vertex_container->
at(0);
 
  124       ATH_MSG_WARNING( 
"couldn't retrieve primary vertex, keeping null privtx" );
 
  131    bool isFirstTrackValid  = firstPassTrackParticleCollection.
isValid();
 
  132    bool isSecondTrackValid = secondPassTrackParticleCollection.
isValid();
 
  147    auto monTime = 
Monitored::Group(
m_monTool, timerTrackSel, timerTwoTrackVertex, timerMapClustering, timerNTrackVertex, timerNTrackVtxOffVSI, timerCleanUp, timerWriteVertices, timerOverall);
 
  149    timerOverall.start();
 
  153    std::vector<std::pair<size_t,size_t>>    v_incomp;
 
  154    std::vector<const xAOD::TrackParticle*>  v_selectedTracks;
 
  158    timerTrackSel.start();
 
  160    if( isFirstTrackValid ) {
 
  161      if( isSecondTrackValid ) {
 
  168    timerTrackSel.stop();
 
  177    v_diwrkvrt.reserve(5000);
 
  181      timerTwoTrackVertex.start();
 
  183      timerTwoTrackVertex.stop();
 
  186      timerTwoTrackVertex.start();
 
  188      timerTwoTrackVertex.stop();
 
  198    TrigVSI::VtxMap<WrkVrt, TrigVSI::Coordinate::Pseudo> vtxmap( std::make_unique<TH3D>(
"TrigVrtSecInclusive_VtxMap", 
"TrigVrtSecInclusive_VtxMap", 
vsic::binNumR, 
vsic::IDrInner, 
vsic::IDrInner+
vsic::mapBinWid*
vsic::binNumR, 
vsic::nEta, -
vsic::maxEta, 
vsic::maxEta, 
vsic::nPhi, -TMath::Pi(), TMath::Pi()) );
 
  202    v_wrkvrt.reserve(1000);
 
  209      timerMapClustering.start();
 
  210      for (
auto wrkvrt_iter = v_diTrkVertices.begin(); wrkvrt_iter != v_diTrkVertices.end(); ++wrkvrt_iter ) {
 
  211        if ( wrkvrt_iter->isGood && wrkvrt_iter->cuts.isFullPass() ) {
 
  212          vtxmap.
Fill( &(*wrkvrt_iter) );
 
  217      ATH_MSG_DEBUG( 
"filled vertex map with " << trkpair_cnt << 
" pairs" );
 
  219      timerMapClustering.stop();
 
  223      timerNTrackVertex.start();
 
  225      timerNTrackVertex.stop();
 
  228      timerCleanUp.start();
 
  229      size_t n_pre_clean   = v_wrkvrt.size();
 
  231      size_t n_post_clean  = v_wrkvrt.size();
 
  233      ATH_MSG_DEBUG( 
"cleaned up " << n_pre_clean - n_post_clean << 
" out of " << n_pre_clean );
 
  237      timerNTrackVtxOffVSI.start();
 
  239      timerNTrackVtxOffVSI.stop();
 
  244    timerWriteVertices.start();
 
  253    ATH_CHECK(outputVertices.
record(std::move(theXAODContainers.first), std::move(theXAODContainers.second)));
 
  254    ATH_CHECK(outputTrkPairs.
record(std::move(theXAODTrkPairContainers.first), std::move(theXAODTrkPairContainers.second)));
 
  257    timerWriteVertices.stop();
 
  262    return StatusCode::SUCCESS;
 
  269   std::vector<const xAOD::TrackParticleContainer*> v_containers;
 
  270   if( firstPassTrackParticles  != 
nullptr ) v_containers.push_back(firstPassTrackParticles);
 
  271   if( secondPassTrackParticles != 
nullptr ) v_containers.push_back(secondPassTrackParticles);
 
  275   for(
unsigned int i=0; 
i<v_containers.size(); 
i++) {
 
  278      for (TrackParticleDataVecIter itr  = trackParticles->
begin(); itr != trackParticles->
end(); ++itr) {
 
  279   if( 
selectTrack(*itr) ) { selectedTracks.push_back(*itr); n_trk++; }
 
  281      ATH_MSG_DEBUG(
"Of " << trackParticles->
size() << 
" tracks " << n_trk << 
" survived the preselection.");
 
  283   ATH_MSG_DEBUG(selectedTracks.size() << 
" tracks in total passed the selection.");
 
  284   return StatusCode::SUCCESS;
 
  292   for (
const auto& wrkvrt : workVerticesContainer) {
 
  294     if ( !wrkvrt.isGood && !wrkvrt.isPair ) 
continue;
 
  296     std::vector<const xAOD::TrackParticle*> baseTracks;
 
  297     for ( 
auto i : wrkvrt.selectedTrackIndices() ) {
 
  298       baseTracks.emplace_back( selectedTracks.at(
i) );
 
  303     vertex->makePrivateStore();
 
  306     for( 
auto *trk: baseTracks ) {
 
  310              vertex->addTrackAtVertex( trackElementLink, 1. );
 
  314     vertex->setPosition( wrkvrt.vertex );
 
  315     vertex->setFitQuality( wrkvrt.chi2, 1 ); 
 
  321     vsi_massAcc(*
vertex)   = wrkvrt.vertexMom.M();
 
  322     vsi_pTAcc(*
vertex)     = wrkvrt.vertexMom.Perp();
 
  323     vsi_chargeAcc(*
vertex) = wrkvrt.charge;
 
  324     vsi_isFakeAcc(*
vertex)  = 0;
 
  341     vsi_twoCirc_drAcc(*
vertex)                      = wrkvrt.param.twoCirc_dr;
 
  342     vsi_twoCirc_dphiAcc(*
vertex)                    = wrkvrt.param.twoCirc_dphi;
 
  343     vsi_twoCirc_int_rAcc(*
vertex)                   = wrkvrt.param.twoCirc_int_r;
 
  344     vsi_vrtFast_rAcc(*
vertex)                       = wrkvrt.param.vrtFast_r;
 
  345     vsi_vrtFast_etaAcc(*
vertex)                     = wrkvrt.param.vrtFast_eta;
 
  346     vsi_vrtFast_phiAcc(*
vertex)                     = wrkvrt.param.vrtFast_phi;
 
  347     vsi_vrtFast_trkd0Acc(*
vertex)    = wrkvrt.param.vrtFast_trkd0;
 
  348     vsi_vrtFast_trkz0Acc(*
vertex)    = wrkvrt.param.vrtFast_trkz0;
 
  349     vsi_vrtFit_rAcc(*
vertex)                        = wrkvrt.vertex.perp();
 
  350     vsi_vrtFit_chi2Acc(*
vertex)                     = wrkvrt.chi2;
 
  351     vsi_vPosAcc(*
vertex)                            = wrkvrt.param.vPos;
 
  352     vsi_vPosMomAngTAcc(*
vertex)                     = wrkvrt.param.vPosMomAngT;
 
  353     vsi_dphi1Acc(*
vertex)                           = wrkvrt.param.dphi1;
 
  354     vsi_dphi2Acc(*
vertex)                           = wrkvrt.param.dphi2;
 
  355     vsi_isPassMMVAcc(*
vertex)                        = wrkvrt.param.isPassMMV ? 1 : 0;
 
  364     vsi_trkd0cutAcc(*
vertex)                         = wrkvrt.cuts.trkd0cut ?      1 : 0;
 
  365     vsi_twoCircErrcutAcc(*
vertex)                    = wrkvrt.cuts.twoCircErrcut ? 1 : 0;
 
  366     vsi_twoCircRcutAcc(*
vertex)                      = wrkvrt.cuts.twoCircRcut ?   1 : 0;
 
  367     vsi_fastErrcutAcc(*
vertex)                       = wrkvrt.cuts.fastErrcut ?    1 : 0;
 
  368     vsi_fastRcutAcc(*
vertex)                         = wrkvrt.cuts.fastRcut ?      1 : 0;
 
  369     vsi_fitErrcutAcc(*
vertex)                        = wrkvrt.cuts.fitErrcut ?     1 : 0;
 
  370     vsi_chi2cutAcc(*
vertex)                          = wrkvrt.cuts.chi2cut ?       1 : 0;
 
  374   return StatusCode::SUCCESS;
 
  379 ( 
WrkVrtContainer& workVerticesContainer, std::vector<std::pair<size_t,size_t>>& incomp, std::vector<const xAOD::TrackParticle*>& selectedTracks, 
const EventContext& ctx, 
const xAOD::Vertex *primVertex )
 const 
  386    std::vector<float> mnt_pair_dphi;
 
  387    std::vector<float> mnt_pair_dr;
 
  388    std::vector<float> mnt_intersect_r;
 
  389    std::vector<float> mnt_init_r;
 
  390    std::vector<float> mnt_init_trkd0;
 
  391    std::vector<float> mnt_init_trkz0;
 
  392    std::vector<float> mnt_vtxfit_chi2;
 
  393    std::vector<float> mnt_vtxfit_r;
 
  394    std::vector<float> mnt_vtx_chi2;
 
  395    std::vector<float> mnt_vtx_mass;
 
  396    std::vector<float> mnt_vtx_mass_high;
 
  397    std::vector<float> mnt_vtx_pt;
 
  398    std::vector<float> mnt_vtx_charge;
 
  399    std::vector<float> mnt_vtx_r;
 
  414    auto monVertex  = 
Monitored::Group(
m_monTool, mon_pair_dphi, mon_pair_dr, mon_intersect_r, mon_init_r, mon_init_trkd0, mon_init_trkz0, mon_vtxfit_chi2, mon_vtxfit_r,
 
  415                       mon_vtx_chi2,mon_vtx_mass,mon_vtx_mass_high,mon_vtx_pt,mon_vtx_charge,mon_vtx_r);
 
  418    unsigned int nPairsAll           = 0;
 
  419    unsigned int nPairsTrkd0         = 0;
 
  420    unsigned int nPairsIntersect     = 0;
 
  421    unsigned int nPairsIntersectPos = 0;
 
  422    unsigned int nPairsInitPos      = 0;
 
  423    unsigned int nPairsInitTrkd0z0  = 0;
 
  424    unsigned int nPairsVtxFit       = 0;
 
  425    unsigned int nPairsVtxChi2      = 0;
 
  426    unsigned int nPairsVtxComp      = 0;
 
  427    unsigned int nPairsVtxMatveto   = 0;
 
  429    for( 
auto itrkIter = selectedTracks.begin(); itrkIter != selectedTracks.end(); ++itrkIter ) {
 
  431       for( 
auto jtrkIter = 
std::next(itrkIter); jtrkIter != selectedTracks.end(); ++jtrkIter ) {  
 
  438          const int itrk_id = 
std::distance(selectedTracks.begin(), itrkIter);
 
  439          const int jtrk_id = 
std::distance(selectedTracks.begin(), jtrkIter);
 
  455          incomp.emplace_back( std::pair<size_t, size_t>(itrk_id, jtrk_id) );
 
  463          timerTwoCircIntsect.start();
 
  465          timerTwoCircIntsect.stop();
 
  466          if (errorcode != 0) {
 
  469             wrkvrt.
param            = wrkprm;
 
  470             wrkvrt.
cuts             = wrkcuts;
 
  473             workVerticesContainer.push_back( std::move(wrkvrt) );
 
  476          float dphi = std::abs(decors[
"deltaPhiTracks"]);
 
  477          float dr   = std::abs(decors[
"DR1R2"]);
 
  478          float intersect_r = circIntersect.perp();
 
  479          mnt_pair_dphi.push_back(dphi);
 
  480          mnt_pair_dr.push_back(
dr);
 
  481          mnt_intersect_r.push_back(intersect_r);
 
  490          nPairsIntersectPos++;
 
  493          std::vector<const xAOD::TrackParticle*> baseTracks;
 
  494          baseTracks.emplace_back( itrk );
 
  495          baseTracks.emplace_back( jtrk );
 
  498          timerVrtFitFast.start();
 
  499          auto fitterState = 
m_fitSvc->makeState(ctx);
 
  500          m_fitSvc->setApproximateVertex( circIntersect.x(), circIntersect.y(), circIntersect.z(), *fitterState );
 
  503          timerVrtFitFast.stop();
 
  504          if( 
sc.isFailure() ) {
 
  507             wrkvrt.
param        = wrkprm;
 
  508             wrkvrt.
cuts         = wrkcuts;
 
  511             workVerticesContainer.push_back( std::move(wrkvrt) );
 
  516          mnt_init_r.push_back(initVertex.perp());
 
  526          std::vector<double> impactParameters;
 
  527          std::vector<double> impactParErrors;
 
  528          if( ! 
m_fitSvc->VKalGetImpact(itrk, initVertex, 
static_cast<int>( itrk->
charge() ), impactParameters, impactParErrors) ) 
continue;
 
  529          const auto roughD0_itrk = impactParameters.at(TrkParameter::k_d0);
 
  530          const auto roughZ0_itrk = impactParameters.at(TrkParameter::k_z0);
 
  531          mnt_init_trkd0.push_back(std::abs(roughD0_itrk));
 
  532          mnt_init_trkz0.push_back(std::abs(roughZ0_itrk));
 
  536          if( ! 
m_fitSvc->VKalGetImpact(jtrk, initVertex, 
static_cast<int>( jtrk->
charge() ), impactParameters, impactParErrors) ) 
continue;
 
  537          const auto roughD0_jtrk = impactParameters.at(TrkParameter::k_d0);
 
  538          const auto roughZ0_jtrk = impactParameters.at(TrkParameter::k_z0);
 
  539          mnt_init_trkd0.push_back(std::abs(roughD0_jtrk));
 
  540          mnt_init_trkz0.push_back(std::abs(roughZ0_jtrk));
 
  550          std::vector<const xAOD::NeutralParticle*>  dummyNeutrals;
 
  552          m_fitSvc->setApproximateVertex( initVertex.x(), initVertex.y(), initVertex.z(), *fitterState );
 
  559          if( 
sc.isFailure() ) {
 
  561             wrkvrt.
param       = wrkprm;
 
  562             wrkvrt.
cuts        = wrkcuts;
 
  565             workVerticesContainer.push_back( std::move(wrkvrt) );
 
  571          mnt_vtxfit_chi2.push_back(wrkvrt.
chi2);
 
  575             wrkvrt.
param    = wrkprm;
 
  576             wrkvrt.
cuts     = wrkcuts;
 
  579             workVerticesContainer.push_back( std::move(wrkvrt) );
 
  583          mnt_vtxfit_r.push_back(wrkvrt.
vertex.perp());
 
  588          const double vPosMomAngT = ( vDist.x()*wrkvrt.
vertexMom.Px()+vDist.y()*wrkvrt.
vertexMom.Py() ) / vDist.perp() / wrkvrt.
vertexMom.Pt();
 
  590          double dphi1 = vDist.phi() - itrk->
phi(); 
while( dphi1 > TMath::Pi() ) { dphi1 -= TMath::TwoPi(); } 
while( dphi1 < -TMath::Pi() ) { dphi1 += TMath::TwoPi(); }
 
  591          double dphi2 = vDist.phi() - jtrk->
phi(); 
while( dphi2 > TMath::Pi() ) { dphi2 -= TMath::TwoPi(); } 
while( dphi2 < -TMath::Pi() ) { dphi2 += TMath::TwoPi(); }
 
  595          wrkprm.
dphi1       = dphi1;
 
  596          wrkprm.
dphi2       = dphi2;
 
  601                ATH_MSG_DEBUG( 
": failed to pass the vPos cut. (both tracks are opposite against the vertex pos)" );
 
  605                ATH_MSG_DEBUG( 
": failed to pass the vPos cut. (pos-mom directions are opposite)" );
 
  620             if (wrkvrt.
vertex.perp() > 150) {
 
  625                for (
int i=0;
i<5;
i++){
 
  626                   if (wrkvrt.
vertex.perp() < mmm[
i][0]) {
 
  627                      float test_x = wrkvrt.
vertex.x() + mmm[
i][1];
 
  628                      float test_y = wrkvrt.
vertex.y() + mmm[
i][2];
 
  629                      double calc_phi = std::fmod( 
TMath::ATan2(test_y,test_x),TMath::Pi()/mmm[
i][3] );
 
  630                      if (calc_phi <0) calc_phi = calc_phi + TMath::Pi()/mmm[
i][3];
 
  643          wrkvrt.
param = wrkprm;
 
  644          wrkvrt.
cuts  = wrkcuts;
 
  648          workVerticesContainer.push_back( std::move(wrkvrt) );
 
  651    ATH_MSG_DEBUG(
"Of " << nPairsAll  << 
" pairs : trkd0" << 
" / "  <<  
"intersect"       << 
" / "  <<  
"intersectPos"        <<  
" / " <<  
"initPos"       <<  
" / " <<  
"initD0Z0"          <<  
" / " <<  
"vtxFit"        <<  
" / " <<  
"vtxChi2"       <<  
" / " <<  
"vtxComp"       <<  
" / " <<  
"matVeto = " 
  652                                                 << nPairsTrkd0     << 
" / "  <<  nPairsIntersect  << 
" / "  <<  nPairsIntersectPos  <<  
" / " <<  nPairsInitPos <<  
" / " <<  nPairsInitTrkd0z0 <<  
" / " <<  nPairsVtxFit  <<  
" / " <<  nPairsVtxChi2 <<  
" / " <<  nPairsVtxComp <<  
" / " <<  nPairsVtxMatveto);
 
  654    return StatusCode::SUCCESS;
 
  659 ( 
WrkVrtContainer& workVerticesContainer, std::vector<std::pair<size_t,size_t>>& incomp, std::vector<const xAOD::TrackParticle*>& selectedTracks, 
const EventContext& ctx, 
const xAOD::Vertex *primVertex )
 const 
  666    std::vector<float> mnt_pair_dphi;
 
  667    std::vector<float> mnt_pair_dr;
 
  668    std::vector<float> mnt_intersect_r;
 
  669    std::vector<float> mnt_init_r;
 
  670    std::vector<float> mnt_init_trkd0;
 
  671    std::vector<float> mnt_init_trkz0;
 
  672    std::vector<float> mnt_vtxfit_chi2;
 
  673    std::vector<float> mnt_vtxfit_r;
 
  674    std::vector<float> mnt_vtx_chi2;
 
  675    std::vector<float> mnt_vtx_mass;
 
  676    std::vector<float> mnt_vtx_mass_high;
 
  677    std::vector<float> mnt_vtx_pt;
 
  678    std::vector<float> mnt_vtx_charge;
 
  679    std::vector<float> mnt_vtx_r;
 
  694    auto monVertex  = 
Monitored::Group(
m_monTool, mon_pair_dphi, mon_pair_dr, mon_intersect_r, mon_init_r, mon_init_trkd0, mon_init_trkz0, mon_vtxfit_chi2, mon_vtxfit_r,
 
  695         mon_vtx_chi2,mon_vtx_mass,mon_vtx_mass_high,mon_vtx_pt,mon_vtx_charge,mon_vtx_r);
 
  698    const double roughD0Cut{ 100. };
 
  699    const double roughZ0Cut{  50. };
 
  701    unsigned int nPairsAll           = 0;
 
  702    unsigned int nPairsTrkd0         = 0;
 
  703    unsigned int nPairsIntersect     = 0;
 
  704    unsigned int nPairsIntersectPos  = 0;
 
  705    unsigned int nPairsInitPos       = 0;
 
  706    unsigned int nPairsInitTrkd0z0   = 0;
 
  707    unsigned int nPairsVtxFit        = 0;
 
  708    unsigned int nPairsVtxChi2       = 0;
 
  709    unsigned int nPairsVtxComp       = 0;
 
  711    for( 
auto itrkIter = selectedTracks.begin(); itrkIter != selectedTracks.end(); ++itrkIter ) {
 
  713       for( 
auto jtrkIter = 
std::next(itrkIter); jtrkIter != selectedTracks.end(); ++jtrkIter ) {  
 
  720          const int itrk_id = 
std::distance(selectedTracks.begin(), itrkIter);
 
  721          const int jtrk_id = 
std::distance(selectedTracks.begin(), jtrkIter);
 
  737          incomp.emplace_back( std::pair<size_t, size_t>(itrk_id, jtrk_id) );
 
  745          timerTwoCircIntsect.start();
 
  747          timerTwoCircIntsect.stop();
 
  748          if (errorcode != 0) {
 
  751             wrkvrt.
param            = wrkprm;
 
  752             wrkvrt.
cuts             = wrkcuts;
 
  755             workVerticesContainer.push_back( std::move(wrkvrt) );
 
  758          float dphi = std::abs(decors[
"deltaPhiTracks"]);
 
  759          float dr   = std::abs(decors[
"DR1R2"]);
 
  760          float intersect_r = circIntersect.perp();
 
  761          mnt_pair_dphi.push_back(dphi);
 
  762          mnt_pair_dr.push_back(
dr);
 
  763          mnt_intersect_r.push_back(intersect_r);
 
  771          nPairsIntersectPos++;
 
  774          std::vector<const xAOD::TrackParticle*> baseTracks;
 
  775          baseTracks.emplace_back( itrk );
 
  776          baseTracks.emplace_back( jtrk );
 
  778          timerVrtFitFast.start();
 
  779          auto fitterState = 
m_fitSvc->makeState(ctx);
 
  780          m_fitSvc->setApproximateVertex( 0., 0., 0., *fitterState );
 
  782          timerVrtFitFast.stop();
 
  783          if( 
sc.isFailure() ) {
 
  786             wrkvrt.
param        = wrkprm;
 
  787             wrkvrt.
cuts         = wrkcuts;
 
  790             workVerticesContainer.push_back( std::move(wrkvrt) );
 
  795          mnt_init_r.push_back(initVertex.perp());
 
  804          std::vector<double> impactParameters;
 
  805          std::vector<double> impactParErrors;
 
  806          if( ! 
m_fitSvc->VKalGetImpact(itrk, initVertex, 
static_cast<int>( itrk->
charge() ), impactParameters, impactParErrors) ) 
continue;
 
  807          const auto roughD0_itrk = impactParameters.at(TrkParameter::k_d0);
 
  808          const auto roughZ0_itrk = impactParameters.at(TrkParameter::k_z0);
 
  809          mnt_init_trkd0.push_back(std::abs(roughD0_itrk));
 
  810          mnt_init_trkz0.push_back(std::abs(roughZ0_itrk));
 
  813          if( std::abs(roughD0_itrk) > roughD0Cut || std::abs(roughZ0_itrk) > roughZ0Cut ) 
continue;
 
  815          if( ! 
m_fitSvc->VKalGetImpact(jtrk, initVertex, 
static_cast<int>( jtrk->
charge() ), impactParameters, impactParErrors) ) 
continue;
 
  816          const auto roughD0_jtrk = impactParameters.at(TrkParameter::k_d0);
 
  817          const auto roughZ0_jtrk = impactParameters.at(TrkParameter::k_z0);
 
  818          mnt_init_trkd0.push_back(std::abs(roughD0_jtrk));
 
  819          mnt_init_trkz0.push_back(std::abs(roughZ0_jtrk));
 
  822          if( std::abs(roughD0_jtrk) > roughD0Cut || std::abs(roughZ0_jtrk) > roughZ0Cut ) 
continue;
 
  827          std::vector<const xAOD::NeutralParticle*>  dummyNeutrals;
 
  829          m_fitSvc->setApproximateVertex( initVertex.x(), initVertex.y(), initVertex.z(), *fitterState );
 
  836          if( 
sc.isFailure() ) {
 
  838            wrkvrt.
param = wrkprm;
 
  839            wrkvrt.
cuts  = wrkcuts;
 
  842            workVerticesContainer.push_back( std::move(wrkvrt) );
 
  849          mnt_vtxfit_chi2.push_back(wrkvrt.
chi2);
 
  853             wrkvrt.
param    = wrkprm;
 
  854             wrkvrt.
cuts     = wrkcuts;
 
  857             workVerticesContainer.push_back( std::move(wrkvrt) );
 
  861          mnt_vtxfit_r.push_back(wrkvrt.
vertex.perp());
 
  866          const double vPosMomAngT = ( vDist.x()*wrkvrt.
vertexMom.Px()+vDist.y()*wrkvrt.
vertexMom.Py() ) / vDist.perp() / wrkvrt.
vertexMom.Pt();
 
  868          double dphi1 = vDist.phi() - itrk->
phi(); 
while( dphi1 > TMath::Pi() ) { dphi1 -= TMath::TwoPi(); } 
while( dphi1 < -TMath::Pi() ) { dphi1 += TMath::TwoPi(); }
 
  869          double dphi2 = vDist.phi() - jtrk->
phi(); 
while( dphi2 > TMath::Pi() ) { dphi2 -= TMath::TwoPi(); } 
while( dphi2 < -TMath::Pi() ) { dphi2 += TMath::TwoPi(); }
 
  873          wrkprm.
dphi1       = dphi1;
 
  874          wrkprm.
dphi2       = dphi2;
 
  877                   ATH_MSG_DEBUG( 
": failed to pass the vPos cut. (both tracks are opposite against the vertex pos)" );
 
  881                   ATH_MSG_DEBUG( 
": failed to pass the vPos cut. (pos-mom directions are opposite)" );
 
  894          wrkvrt.
param = wrkprm;
 
  895          wrkvrt.
cuts  = wrkcuts;
 
  899          workVerticesContainer.push_back( std::move(wrkvrt) );
 
  902    ATH_MSG_DEBUG(
"Of " <<  nPairsAll  << 
" pairs : trkd0" << 
" / "  <<  
"intersect"      << 
" / " <<  
"intersectPos"         <<  
" / " <<   
"initPos"         <<  
" / " <<  
"initD0Z0"          <<  
" / " <<  
"vtxFit"        <<  
" / " <<  
"vtxChi2"       <<  
" / " <<  
"vtxComp = " 
  903                                                 << nPairsTrkd0     << 
" / "  <<  nPairsIntersect << 
" / " <<  nPairsIntersectPos   <<  
" / " <<   nPairsInitPos   <<  
" / " <<  nPairsInitTrkd0z0 <<  
" / " <<  nPairsVtxFit  <<  
" / " <<  nPairsVtxChi2 <<  
" / " <<  nPairsVtxComp );
 
  905    return StatusCode::SUCCESS;
 
  910 ( 
WrkVrtContainer& workVerticesContainer, std::vector<std::pair<size_t,size_t>>& incomp, std::vector<const xAOD::TrackParticle*>& selectedTracks, 
const EventContext& ctx )
 const 
  914    const auto compSize = selectedTracks.size()*(selectedTracks.size() - 1)/2 - incomp.size();
 
  916    auto pgraph = std::make_unique<Trk::PGraph>();
 
  918    ATH_MSG_DEBUG(
" > " << __FUNCTION__ << 
": compatible track pair size   = " << compSize );
 
  919    ATH_MSG_DEBUG(
" > " << __FUNCTION__ << 
": incompatible track pair size = " << incomp.size() );
 
  921    ATH_MSG_DEBUG(
" > " << __FUNCTION__ << 
": incompatibility graph finder mode" );
 
  924    workVerticesContainer.clear();
 
  931    std::vector<long int> 
weight;
 
  933    for( 
auto& pair : incomp ) {
 
  934       weight.emplace_back( pair.first  + 1 ); 
 
  935       weight.emplace_back( pair.second + 1 ); 
 
  940    std::vector<long int> solution( selectedTracks.size() );
 
  943    long int nEdges = incomp.size();
 
  946    long int nTracks = 
static_cast<long int>( selectedTracks.size() );
 
  954    long int solutionSize { 0 };
 
  957    std::vector<const xAOD::TrackParticle*>    baseTracks;
 
  958    std::vector<const xAOD::NeutralParticle*>  dummyNeutrals;
 
  963       pgraph->pgraphm_( 
weight.data(), nEdges, nTracks, solution.data(), &solutionSize, nth);
 
  965       ATH_MSG_VERBOSE(
" > " << __FUNCTION__ << 
": Trk::pgraphm_() output: solutionSize = " << solutionSize );
 
  967       if(solutionSize <= 0)  
break;      
 
  968       if(solutionSize == 1)  
continue;   
 
  972       std::string 
msg = 
"solution = [ ";
 
  973       for( 
int i=0; 
i< solutionSize; 
i++) {
 
  974          msg += Form( 
"%ld, ", solution[
i]-1 );
 
  987       for(
long int i = 0; 
i<solutionSize; 
i++) {
 
  989          baseTracks.emplace_back( selectedTracks.at(solution[
i]-1) );
 
  994       auto fitterState = 
m_fitSvc->makeState(ctx);
 
  997       if(
sc.isFailure()) 
ATH_MSG_DEBUG(
" > " << __FUNCTION__ << 
": fast crude estimation fails ");
 
  999       m_fitSvc->setApproximateVertex( initVertex.x(), initVertex.y(), initVertex.z(), *fitterState );
 
 1001       sc = 
m_fitSvc->VKalVrtFit(baseTracks, dummyNeutrals,
 
 1009                                 *fitterState, 
false);
 
 1011       ATH_MSG_VERBOSE(
" > " << __FUNCTION__ << 
": FoundAppVrt=" << solutionSize << 
", (r, z) = " << wrkvrt.
vertex.perp() << 
", " << wrkvrt.
vertex.z()  <<  
", chi2/ndof = "  <<  wrkvrt.
fitQuality() );
 
 1013       if( 
sc.isFailure() )  {
 
 1016           ATH_MSG_DEBUG(
" > " << __FUNCTION__ << 
": VKalVrtFit failed in 2-trk solution ==> give up.");
 
 1020         ATH_MSG_DEBUG(
" > " << __FUNCTION__ << 
": VKalVrtFit failed ==> retry...");
 
 1028             if( itrk == jtrk ) 
continue;
 
 1029             if( 
tmp.isGood ) 
break;
 
 1031             tmp.selectedTrackIndices().clear();
 
 1032             tmp.selectedTrackIndices().emplace_back( itrk );
 
 1033             tmp.selectedTrackIndices().emplace_back( jtrk );
 
 1036             baseTracks.emplace_back( selectedTracks.at( itrk ) );
 
 1037             baseTracks.emplace_back( selectedTracks.at( jtrk ) );
 
 1042             sc = 
m_fitSvc->VKalVrtFitFast( baseTracks, initVertex, *fitterState );
 
 1043             if( 
sc.isFailure() ) 
ATH_MSG_DEBUG(
" > " << __FUNCTION__ << 
": fast crude estimation fails ");
 
 1045             m_fitSvc->setApproximateVertex( initVertex.x(), initVertex.y(), initVertex.z(), *fitterState );
 
 1047             sc = 
m_fitSvc->VKalVrtFit(baseTracks, dummyNeutrals,
 
 1055                                       *fitterState, 
false);
 
 1057             if( 
sc.isFailure() ) 
continue;
 
 1065           ATH_MSG_DEBUG(
" > " << __FUNCTION__ << 
": Did not find any viable vertex in all 2-trk combinations. Give up.");
 
 1072           if( 
std::find( 
tmp.selectedTrackIndices().begin(), 
tmp.selectedTrackIndices().end(), itrk ) != 
tmp.selectedTrackIndices().end() ) 
continue;
 
 1076           tmp.selectedTrackIndices().emplace_back( itrk );
 
 1078           for( 
auto& jtrk : 
tmp.selectedTrackIndices() ) { baseTracks.emplace_back( selectedTracks.at(jtrk) ); }
 
 1083           sc = 
m_fitSvc->VKalVrtFitFast( baseTracks, initVertex, *fitterState );
 
 1084           if(
sc.isFailure()) 
ATH_MSG_DEBUG(
" > " << __FUNCTION__ << 
": fast crude estimation fails ");
 
 1086           m_fitSvc->setApproximateVertex( initVertex.x(), initVertex.y(), initVertex.z(), *fitterState );
 
 1087           sc = 
m_fitSvc->VKalVrtFit(baseTracks, dummyNeutrals,
 
 1095                                     *fitterState, 
false);
 
 1097           if( 
sc.isFailure() ) {
 
 1105         ATH_MSG_DEBUG(
" > " << __FUNCTION__ << 
": VKalVrtFit succeeded; register the vertex to the list.");
 
 1109         workVerticesContainer.emplace_back( wrkvrt );
 
 1113         ATH_MSG_DEBUG(
" > " << __FUNCTION__ << 
": VKalVrtFit succeeded; register the vertex to the list.");
 
 1117         workVerticesContainer.emplace_back( wrkvrt );
 
 1128       ATH_MSG_INFO(
"WrkVertex truncated. Too many vertices");
 
 1136   ATH_MSG_VERBOSE(
" > " << __FUNCTION__ << 
": Identify remaining 2-track vertices with very bad Chi2 and mass (b-tagging).");
 
 1137   for( 
auto& wrkvrt : workVerticesContainer ) {
 
 1140     if( wrkvrt.selectedTrackIndices().size() != 2 ) 
continue;
 
 1143   return StatusCode::SUCCESS;
 
 1149 template<
typename VrtType, 
typename Coord>
 
 1161   size_t n_vtx_pargraph = 0;
 
 1162   size_t n_vtx_simple   = 0;
 
 1164   for (
size_t i_clst = 0; i_clst < n_clst; i_clst++) {
 
 1166     timerRetrvFromMap.start();
 
 1168     ATH_MSG_DEBUG( 
"Retrieve cluster, track indices and incompatible pairs" );
 
 1171     auto selected_track_indices = clst.getSelectedTrackIndices();
 
 1172     auto incomp                 = clst.getIncompIndices();
 
 1176     std::vector<size_t> v_track_indices( selected_track_indices.begin(), selected_track_indices.end() );
 
 1178     timerRetrvFromMap.stop();
 
 1180     ATH_MSG_DEBUG( 
"Cluster number : " <<  i_clst << 
" | " << incomp.size() << 
" incompatible pairs | " << v_track_indices.size() << 
" tracks" );
 
 1181     ATH_MSG_DEBUG( 
"Pos avr : ( R: " << clst.PosCoord().at(0) << 
", eta: " << clst.PosCoord().at(1) << 
", phi: " << clst.PosCoord().at(2) << 
" )" );
 
 1184     if ( v_track_indices.size() > 
m_maxTrks ) {
 
 1191       timerMergeParGraph.start();
 
 1193       timerMergeParGraph.stop();
 
 1199       timerMergeSimple.start();
 
 1205       for (
size_t i_trk = 0; i_trk < v_track_indices.size(); i_trk++) {
 
 1210         workVerticesContainer.emplace_back( std::move(wrkvrt) );
 
 1213       timerMergeSimple.stop();
 
 1221   ATH_MSG_DEBUG( 
"Partial graph method / Simple method / All vertex = " << n_vtx_pargraph << 
" / " << n_vtx_simple << 
" / "  << n_vtx_pargraph+n_vtx_simple );
 
 1222   return StatusCode::SUCCESS;
 
 1244 ( 
TrigVrtSecInclusive::WrkVrtContainer& workVerticesContainer, 
const std::vector<std::pair<size_t,size_t>>& incomp, 
const std::vector<size_t>& trkIdx, 
const std::vector<const xAOD::TrackParticle*>& selectedTracks, 
const EventContext& ctx )
 const 
 1248   ATH_MSG_DEBUG(
"TrigVrtSecInclusive::mergeVertexFromDiTrkVrt : start");
 
 1252   auto pgraph = std::make_unique<Trk::PGraph>();
 
 1254   std::unordered_map<size_t,size_t> dict_trk_idx;
 
 1255   size_t n_trk = trkIdx.size(); 
 
 1257   for (
size_t i = 0; 
i < n_trk; 
i++) {
 
 1258     dict_trk_idx.emplace( trkIdx.at(
i), 
i );
 
 1261   const auto compSize = (n_trk*(n_trk - 1))/2 - incomp.size();
 
 1263   ATH_MSG_DEBUG(
" > " << __FUNCTION__ << 
": compatible track pair size   = " << compSize );
 
 1264   ATH_MSG_DEBUG(
" > " << __FUNCTION__ << 
": incompatible track pair size = " << incomp.size() );
 
 1268   std::vector<long int> 
weight;
 
 1270   for( 
auto& pair : incomp ) {
 
 1271     weight.emplace_back( dict_trk_idx[pair.first]  + 1 ); 
 
 1272     weight.emplace_back( dict_trk_idx[pair.second] + 1 ); 
 
 1277   std::vector<long int> solution( n_trk );
 
 1280   long int nEdges = incomp.size();
 
 1283   long int nTracks = 
static_cast<long int>( n_trk );
 
 1291   long int solutionSize { 0 };
 
 1293   ATH_MSG_DEBUG( 
"TrigVrtSecInclusive::mergeVertexFromDiTrkVrt : while loop start" );
 
 1299     pgraph->pgraphm_( 
weight.data(), nEdges, nTracks, solution.data(), &solutionSize, nth);
 
 1301     ATH_MSG_VERBOSE(
" > " << __FUNCTION__ << 
": Trk::pgraphm_() output: solutionSize = " << solutionSize );
 
 1302     ATH_MSG_DEBUG( 
"TrigVrtSecInclusive::mergeVertexFromDiTrkVrt : Trk::pgraphm_() output: solutionSize = " << solutionSize );
 
 1304     if(solutionSize <= 0)  
break;      
 
 1305     if(solutionSize == 1)  
continue;   
 
 1308     std::string 
msg = 
"solution = [ ";
 
 1309     for( 
int i=0; 
i< solutionSize; 
i++) {
 
 1310       msg += Form( 
"%ld, ", trkIdx[ solution[
i]-1 ] );
 
 1323     for(
long int i = 0; 
i<solutionSize; 
i++) {
 
 1328       workVerticesContainer.emplace_back( std::move(wrkvrt) );
 
 1333   return StatusCode::SUCCESS;
 
 1351 ( 
WrkVrt& wrkvrt, 
const std::vector<const xAOD::TrackParticle*>& selectedTracks, 
const EventContext& ctx )
 const 
 1354   std::vector<const xAOD::TrackParticle*>    baseTracks;
 
 1355   std::vector<const xAOD::NeutralParticle*>  dummyNeutrals; 
 
 1365   for(
size_t i = 0; 
i<n_trk; 
i++) {
 
 1371   auto fitterState = 
m_fitSvc->makeState(ctx);
 
 1374   if(
sc.isFailure()) 
ATH_MSG_DEBUG(
" > " << __FUNCTION__ << 
": fast crude estimation fails ");
 
 1376   m_fitSvc->setApproximateVertex( initVertex.x(), initVertex.y(), initVertex.z(), *fitterState );
 
 1378   sc = 
m_fitSvc->VKalVrtFit(baseTracks, dummyNeutrals,
 
 1386                             *fitterState, 
false);
 
 1388   ATH_MSG_VERBOSE(
" > " << __FUNCTION__ << 
": FoundAppVrt=" << n_trk << 
", (r, z) = " << wrkvrt.
vertex.perp() << 
", " << wrkvrt.
vertex.z()  <<  
", chi2/ndof = "  <<  wrkvrt.
fitQuality() );
 
 1390   if( 
sc.isFailure() )  {
 
 1392     ATH_MSG_DEBUG(
" > " << __FUNCTION__ << 
": VKalVrtFit failed ==> retry...");
 
 1400         if( itrk == jtrk ) 
continue;
 
 1401         if( 
tmp.isGood ) 
break;
 
 1403         tmp.selectedTrackIndices().clear();
 
 1404         tmp.selectedTrackIndices().emplace_back( itrk );
 
 1405         tmp.selectedTrackIndices().emplace_back( jtrk );
 
 1408         baseTracks.emplace_back( selectedTracks.at( itrk ) );
 
 1409         baseTracks.emplace_back( selectedTracks.at( jtrk ) );
 
 1414         sc = 
m_fitSvc->VKalVrtFitFast( baseTracks, initVertex, *fitterState );
 
 1415         if( 
sc.isFailure() ) 
ATH_MSG_DEBUG(
" > " << __FUNCTION__ << 
": fast crude estimation fails ");
 
 1417         m_fitSvc->setApproximateVertex( initVertex.x(), initVertex.y(), initVertex.z(), *fitterState );
 
 1419         sc = 
m_fitSvc->VKalVrtFit(baseTracks, dummyNeutrals,
 
 1427                                   *fitterState, 
false);
 
 1429         if( 
sc.isFailure() ) 
continue;
 
 1438       ATH_MSG_DEBUG(
" > " << __FUNCTION__ << 
": Did not find any viable vertex in all 2-trk combinations. Give up.");
 
 1439       wrkvrt = std::move(
tmp);
 
 1440       return StatusCode::FAILURE;
 
 1446       if( 
std::find( 
tmp.selectedTrackIndices().begin(), 
tmp.selectedTrackIndices().end(), itrk ) != 
tmp.selectedTrackIndices().end() ) 
continue;
 
 1450       tmp.selectedTrackIndices().emplace_back( itrk );
 
 1452       for( 
auto& jtrk : 
tmp.selectedTrackIndices() ) { baseTracks.emplace_back( selectedTracks.at(jtrk) ); }
 
 1457       sc = 
m_fitSvc->VKalVrtFitFast( baseTracks, initVertex, *fitterState );
 
 1458       if(
sc.isFailure()) 
ATH_MSG_DEBUG(
" > " << __FUNCTION__ << 
": fast crude estimation fails ");
 
 1460       m_fitSvc->setApproximateVertex( initVertex.x(), initVertex.y(), initVertex.z(), *fitterState );
 
 1461       sc = 
m_fitSvc->VKalVrtFit(baseTracks, dummyNeutrals,
 
 1469                                 *fitterState, 
false);
 
 1471       if( 
sc.isFailure() ) {
 
 1478     wrkvrt = std::move(
tmp);
 
 1482   ATH_MSG_DEBUG(
" > " << __FUNCTION__ << 
": VKalVrtFit succeeded; register the vertex to the list.");
 
 1487   return StatusCode::SUCCESS;
 
 1524    uint8_t SharedHits = PixShare + SCTShare;
 
 1529    if((PixelHits+SCTHits) < 
m_cutSiHits)     
return false;
 
 1544   auto& trackIndices1 = workVerticesContainer.at( pairIndex.first ).selectedTrackIndices();
 
 1545   auto& trackIndices2 = workVerticesContainer.at( pairIndex.second ).selectedTrackIndices();
 
 1547   if( trackIndices1.size() < 2 ) 
return 0;
 
 1548   if( trackIndices2.size() < 2 ) 
return 0;
 
 1552   for( 
auto& 
index : trackIndices1 ) {
 
 1553     if( 
std::find(trackIndices2.begin(),trackIndices2.end(), 
index) != trackIndices2.end()) nTrkCom++;
 
 1564   ATH_MSG_VERBOSE(
" > " << __FUNCTION__ << 
": Remove vertices fully contained in other vertices .");
 
 1565   size_t n_vtx = workVerticesContainer.size();
 
 1567   for (
size_t iv = 0; iv < n_vtx; iv++) {
 
 1568     for (
size_t jv = iv+1; jv < n_vtx; jv++) {
 
 1570       if ( !workVerticesContainer.at(iv).isGood ) 
continue;
 
 1571       if ( !workVerticesContainer.at(jv).isGood ) 
continue;
 
 1573       const auto nTCom = 
nTrkCommon( workVerticesContainer, {iv, jv} );
 
 1575       if(      nTCom == workVerticesContainer.at(iv).selectedTrackIndices().size() ) {  workVerticesContainer.at(iv).isGood = 
false; 
continue; }
 
 1576       else if( nTCom == workVerticesContainer.at(jv).selectedTrackIndices().size() ) {  workVerticesContainer.at(jv).isGood = 
false; 
continue; }
 
 1581   return StatusCode::SUCCESS;
 
 1587    return StatusCode::SUCCESS;