ATLAS Offline Software
Loading...
Searching...
No Matches
Sel2TrkVertices.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
7// Header include
10#include "MVAUtils/BDT.h"
11//-------------------------------------------------
12// Other stuff
15
16#include "TMath.h"
17#include "TH1.h"
18#include "TH2D.h"
19//
20
21
22namespace Rec{
23
24
25//
26//
27//--------------------------------------------------------
28// Template routine for 2track secondary vertices selection
29//
30
31 void NewVrtSecInclusiveTool::select2TrVrt(std::vector<const xAOD::TrackParticle*> & selectedTracks,
32 const xAOD::Vertex & primVrt,
33 std::map<long int,std::vector<double>> & goodVrt,
34 compatibilityGraph_t& compatibilityGraph )
35 const
36 {
37 std::vector<const xAOD::NeutralParticle*> neutralPartDummy(0);
38 std::vector<const xAOD::TrackParticle*> tracksForFit(2,nullptr);
39 std::vector<double> impact,impactError;
40 std::vector<double> inpMass(2,m_massPi);
41 long int Charge;
42 int i,j;
43 StatusCode sc;
44 Vrt2Tr tmpVrt;
45 std::vector<Vrt2Tr> all2TrVrt(0);
46 TLorentzVector PSum2T;
47 Amg::Vector3D iniVrt(0.,0.,0.);
48//
49 int NTracks = (int) (selectedTracks.size());
50//
51// impact parameters with sign calculations
52//
53 uint8_t nPixelHits;
54 double signifR=0.,signifZ=0.;
55 std::vector<int> nPixHits(NTracks,0);
56 std::vector<double> trackSignif(NTracks),dRdZratio(NTracks);
57 for (i=0; i<NTracks; i++) {
58 m_fitSvc->VKalGetImpact(selectedTracks[i], primVrt.position(), 1, impact, impactError);
59 signifR = impact[0]/ sqrt(impactError[0]);
60 signifZ = impact[1]/ sqrt(impactError[2]);
61 trackSignif[i] = sqrt( signifR*signifR + signifZ*signifZ);
62 dRdZratio[i] = std::abs(signifR/signifZ);
63 if( !(selectedTracks[i]->summaryValue(nPixelHits,xAOD::numberOfPixelHits)) ) nPixelHits=0;
64 nPixHits[i]=nPixelHits;
65 if(m_fillHist){
66 Hists& h = getHists();
67 h.m_hb_impactR->Fill( signifR, m_w_1);
68 h.m_hb_impactZ->Fill( signifZ, m_w_1);
69 h.m_hb_impactRZ->Fill(signifR, signifZ, m_w_1);
70 h.m_hb_impact->Fill( trackSignif[i], m_w_1);
71 if( i<DevTuple::maxNTrk){
72 Hists& h = getHists();
73 h.m_curTup->pttrk[i]=selectedTracks[i]->pt();
74 h.m_curTup->d0trk[i]=selectedTracks[i]->d0();
75 h.m_curTup->Sig3D[i]=trackSignif[i];
76 h.m_curTup->idHF[i] =getIdHF(selectedTracks[i]);
77 h.m_curTup->dRdZrat[i] =dRdZratio[i];
78 h.m_curTup->displaced[i]=isDisplaced(selectedTracks[i]);
79
80 uint8_t TRTHits;
81 if( !(selectedTracks[i]->summaryValue( TRTHits,xAOD::numberOfTRTHits))) TRTHits=0;
82 h.m_curTup->trkTRT[i] =TRTHits;
83 h.m_curTup->etatrk[i] =selectedTracks[i]->eta();
84 }
85 }
86 }
87
88 if( m_fillHist ){
89 Hists& h = getHists();
90 h.m_curTup->nTrk=NTracks < DevTuple::maxNTrk ? NTracks : DevTuple::maxNTrk ;
91 h.m_curTup->n2Vrt=0;
92 }
93
94 std::vector<std::vector<std::tuple<int,float>>> trkCount(NTracks);
95 std::unique_ptr<Trk::IVKalState> state = m_fitSvc->makeState();
96 m_fitSvc->setMassInputParticles( inpMass, *state ); // Use pion masses for fit
97 for (i=0; i<NTracks-1; i++) {
98 if(trackSignif[i]<m_trkSigCut || dRdZratio[i]<m_dRdZRatioCut )continue;
99 for (j=i+1; j<NTracks; j++) {
100 if(trackSignif[j]<m_trkSigCut || dRdZratio[j]<m_dRdZRatioCut )continue;
101 PSum2T=selectedTracks[i]->p4()+selectedTracks[j]->p4();
102 if( std::abs(selectedTracks[i]->eta()-selectedTracks[j]->eta())==0 &&
103 std::abs(selectedTracks[i]->phi()-selectedTracks[j]->phi())==0 &&
104 std::abs(selectedTracks[i]->pt() -selectedTracks[j]->pt())==0 ) continue; //remove duplicated tracks
105 tracksForFit[0]=selectedTracks[i];
106 tracksForFit[1]=selectedTracks[j];
107 double minDZ=0.;
108 sc=m_fitSvc->VKalVrtFitFast(tracksForFit,tmpVrt.fitVertex,minDZ,*state); /* Fast crude estimation*/
109 if( sc.isFailure() ) { /* No initial estimation */
110 iniVrt=primVrt.position();
111 } else {
112 double cosMomVrtDir = projSV_PV(tmpVrt.fitVertex,primVrt,PSum2T);
113 if( cosMomVrtDir>0. ) iniVrt=tmpVrt.fitVertex; /* Good initial estimation */
114 else iniVrt=primVrt.position();
115 }
116 if(nPixHits[i]>0 && nPixHits[j]>0){ if(minDZ> m_fastZSVCut) continue; } // Drop SV candidates with big Z track-track distance.
117 else{ if(minDZ>2.*m_fastZSVCut) continue; } // Drop SV candidates with big Z track-track distance.
118 m_fitSvc->setApproximateVertex(iniVrt.x(), iniVrt.y(), iniVrt.z(), *state);
119 sc=m_fitSvc->VKalVrtFit(tracksForFit, neutralPartDummy, tmpVrt.fitVertex, tmpVrt.momentum, Charge,
120 tmpVrt.errorMatrix, tmpVrt.chi2PerTrk, tmpVrt.trkAtVrt, tmpVrt.chi2, *state, false );
121 if(sc.isFailure()) continue; /* No fit */
122 if(tmpVrt.chi2>20.) continue; /*Too bad Chi2 for nDoF=1 fit*/
125 float vQuality;
126 xAOD::Vertex testV;
127 testV.makePrivateStore();
128 testV.setPosition(tmpVrt.fitVertex);
129 std::vector<float> testVcov(tmpVrt.errorMatrix.begin(),tmpVrt.errorMatrix.end());
130 testV.setCovariance(testVcov);
131 testV.setFitQuality(tmpVrt.chi2,1.);
132 bool acceptV=m_ini_v2trselector->isgood(std::make_pair(selectedTracks[i],selectedTracks[j]), testV,
133 std::make_pair(momAtVrt(tmpVrt.trkAtVrt[0]),momAtVrt(tmpVrt.trkAtVrt[1])), primVrt, vQuality);
134 if(!acceptV) continue; // Main 2-track vertex selection
135
136
137//Check close material layer. Not validated in detail, use with care.
138 double vrtR=tmpVrt.fitVertex.perp();
139 double dstMatSignif=1.e4;
140 if(m_removeTrkMatSignif>0. && vrtR>20.){
141 double vrtRErr=vrtRadiusError(tmpVrt.fitVertex,tmpVrt.errorMatrix );
142 if(vrtR<30.){ dstMatSignif=std::abs(vrtR-m_beampipeR)/vrtRErr;}
143 else { dstMatSignif=distToMatLayerSignificance(tmpVrt);} //Material in Pixel volume
144 if(dstMatSignif<m_removeTrkMatSignif)continue;
145 }
146//
147// Debugging and BDT
148 double minPtT = std::min(tracksForFit[0]->pt(),tracksForFit[1]->pt());
149 if( m_fillHist ){
150 float ihitR = selectedTracks[i]->radiusOfFirstHit();
151 float jhitR = selectedTracks[j]->radiusOfFirstHit();
152 int ihitIBL = getIBLHit(selectedTracks[i]);
153 int jhitIBL = getIBLHit(selectedTracks[j]);
154 int ihitBL = getBLHit (selectedTracks[i]);
155 int jhitBL = getBLHit (selectedTracks[j]);
156 double Prob2v=TMath::Prob(tmpVrt.chi2,1);
157 double cosSVPV=projSV_PV(tmpVrt.fitVertex, primVrt, tmpVrt.momentum);
158 ROOT::Math::PxPyPzMVector SVPV(tmpVrt.fitVertex.x()-primVrt.x(),
159 tmpVrt.fitVertex.y()-primVrt.y(),
160 tmpVrt.fitVertex.z()-primVrt.z(), 10.);
161
162 Hists& h = getHists();
163
164 if(Charge==0){h.m_hb_massPiPi->Fill(tmpVrt.momentum.M(),1.);}
165 h.m_hb_cosSVMom->Fill(cosSVPV,1.);
166 h.m_hb_etaSV->Fill(SVPV.Eta(),1.);
167
168 double Sig3D=0.,Sig2D=0., Dist2D=0.;
169 int idisk1=0,idisk2=0,idisk3=0,jdisk1=0,jdisk2=0,jdisk3=0;
170 int sumIBLHits = std::max(ihitIBL,0)+std::max(jhitIBL,0);
171 int sumBLHits = std::max(ihitBL, 0)+std::max(jhitBL, 0);
172 getPixelDiscs(selectedTracks[i],idisk1,idisk2,idisk3);
173 getPixelDiscs(selectedTracks[j],jdisk1,jdisk2,jdisk3);
174 vrtVrtDist(primVrt, tmpVrt.fitVertex, tmpVrt.errorMatrix, Sig3D);
175 Dist2D=vrtVrtDist2D(primVrt, tmpVrt.fitVertex, tmpVrt.errorMatrix, Sig2D);
176 int barVrt1=getProdVrtBarcode(tracksForFit[0],0.1); // FIXME barcode-based
177 int barVrt2=getProdVrtBarcode(tracksForFit[1],0.1); // FIXME barcode-based
178 h.m_hb_signif3D->Fill(Sig3D,1.);
179 h.m_curTup->VrtTrkHF [h.m_curTup->n2Vrt] = getIdHF(tracksForFit[0])+ getIdHF(tracksForFit[1]);
180 h.m_curTup->VrtTrkI [h.m_curTup->n2Vrt] = getG4Inter(tracksForFit[0])+ getG4Inter(tracksForFit[1]);
181 h.m_curTup->VrtTrueBar[h.m_curTup->n2Vrt] = (barVrt1 && barVrt2 && barVrt1==barVrt2) ? 1 : 0;
182 h.m_curTup->VrtTrueNear[h.m_curTup->n2Vrt] = checkTrue2TrVrt(tracksForFit[0],tracksForFit[1],0.1);
183 h.m_curTup->VrtCh [h.m_curTup->n2Vrt] = Charge;
184 h.m_curTup->VrtProb [h.m_curTup->n2Vrt] = Prob2v;
185 h.m_curTup->VrtSig3D [h.m_curTup->n2Vrt] = Sig3D;
186 h.m_curTup->VrtSig2D [h.m_curTup->n2Vrt] = Sig2D;
187 h.m_curTup->VrtDist2D[h.m_curTup->n2Vrt] = vrtR<20. ? Dist2D : vrtR;
188 h.m_curTup->VrtM [h.m_curTup->n2Vrt] = tmpVrt.momentum.M();
189 h.m_curTup->VrtZ [h.m_curTup->n2Vrt] = tmpVrt.fitVertex.z();
190 h.m_curTup->VrtPt [h.m_curTup->n2Vrt] = tmpVrt.momentum.Pt();
191 h.m_curTup->VrtEta [h.m_curTup->n2Vrt] = SVPV.Eta();
192 h.m_curTup->VrtIBL [h.m_curTup->n2Vrt] = sumIBLHits;
193 h.m_curTup->VrtBL [h.m_curTup->n2Vrt] = sumBLHits;
194 h.m_curTup->VrtCosSPM[h.m_curTup->n2Vrt] = cosSVPV;
195 h.m_curTup->VMinPtT [h.m_curTup->n2Vrt] = minPtT;
196 h.m_curTup->VMinS3DT [h.m_curTup->n2Vrt] = std::min(trackSignif[i],trackSignif[j]);
197 h.m_curTup->VMaxS3DT [h.m_curTup->n2Vrt] = std::max(trackSignif[i],trackSignif[j]);
198 h.m_curTup->VrtBDT [h.m_curTup->n2Vrt] = vQuality;
199 h.m_curTup->VrtHR1 [h.m_curTup->n2Vrt] = ihitR;
200 h.m_curTup->VrtHR2 [h.m_curTup->n2Vrt] = jhitR;
201 h.m_curTup->VrtDZ [h.m_curTup->n2Vrt] = minDZ;
202 h.m_curTup->VrtDisk [h.m_curTup->n2Vrt] = idisk1+10*idisk2+20*idisk3+30*jdisk1+40*jdisk2+50*jdisk3;
203 h.m_curTup->VSigMat [h.m_curTup->n2Vrt] = dstMatSignif;
204 h.m_curTup->VrtIT [h.m_curTup->n2Vrt] = i;
205 h.m_curTup->VrtJT [h.m_curTup->n2Vrt] = j;
206 if(h.m_curTup->n2Vrt<DevTuple::maxNVrt-1)h.m_curTup->n2Vrt++;
207 }
208//
209//--- Save good candidate for multi-vertex fit
210//
211 add_edge(i,j,compatibilityGraph);
212 goodVrt[NTracks*i+j]=std::vector<double>{tmpVrt.fitVertex.x(),tmpVrt.fitVertex.y(),tmpVrt.fitVertex.z()};
213 trkCount[i].emplace_back(j,vQuality); trkCount[j].emplace_back(i,vQuality);
214 }
215 }
216 //=== Resolve -!----!- case to speed up cluster finding
217 for(int t=0; t<NTracks; t++){
218 if(trkCount[t].size()==2){
219 i=std::get<0>(trkCount[t][0]);
220 j=std::get<0>(trkCount[t][1]);
221 if(trkCount[i].size()==1 && trkCount[j].size()==1 ){
222 if( std::get<1>(trkCount[t][0]) < std::get<1>(trkCount[t][1]) ) {
223 remove_edge(t,i,compatibilityGraph);
224 if(t<i)goodVrt.erase(NTracks*t+i); else goodVrt.erase(NTracks*i+t);
225 trkCount[i].clear();
226 trkCount[t].erase(trkCount[t].begin()+0);
227 } else {
228 remove_edge(t,j,compatibilityGraph);
229 if(t<j)goodVrt.erase(NTracks*t+j); else goodVrt.erase(NTracks*j+t);
230 trkCount[j].clear();
231 trkCount[t].erase(trkCount[t].begin()+1);
232 }
233 }
234 }
235 }
236
237 }
238
239
240} //end of namespace
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
static Double_t sc
Header file for AthHistogramAlgorithm.
ToolHandle< Rec::ITwoTrackVertexSelector > m_ini_v2trselector
static double vrtVrtDist2D(const xAOD::Vertex &primVrt, const Amg::Vector3D &secVrt, const std::vector< double > &vrtErr, double &signif)
static int getProdVrtBarcode(const xAOD::TrackParticle *TP, float resolLimit=0.1)
static double projSV_PV(const Amg::Vector3D &SV, const xAOD::Vertex &PV, const TLorentzVector &Direction)
boost::adjacency_list< boost::listS, boost::vecS, boost::undirectedS > compatibilityGraph_t
ToolHandle< Trk::TrkVKalVrtFitter > m_fitSvc
static void getPixelDiscs(const xAOD::TrackParticle *Part, int &d0Hit, int &d1Hit, int &d2Hit)
void select2TrVrt(std::vector< const xAOD::TrackParticle * > &SelectedTracks, const xAOD::Vertex &primVrt, std::map< long int, std::vector< double > > &vrt, compatibilityGraph_t &compatibilityGraph) const
Gaudi::Property< float > m_trkSigCut
ROOT::Math::PxPyPzEVector momAtVrt(const std::vector< double > &inpTrk) const
Gaudi::Property< float > m_removeTrkMatSignif
Gaudi::Property< float > m_fastZSVCut
Gaudi::Property< float > m_dRdZRatioCut
static double vrtVrtDist(const xAOD::Vertex &primVrt, const Amg::Vector3D &secVrt, const std::vector< double > &vrtErr, double &signif)
Gaudi::Property< bool > m_fillHist
static double vrtRadiusError(const Amg::Vector3D &secVrt, const std::vector< double > &vrtErr)
static bool checkTrue2TrVrt(const xAOD::TrackParticle *TP1, const xAOD::TrackParticle *TP2, float nearCut=0.1)
Gaudi::Property< float > m_beampipeR
void makePrivateStore()
Create a new (empty) private store for this object.
float z() const
Returns the z position.
float y() const
Returns the y position.
void setCovariance(const std::vector< float > &value)
Sets the covariance matrix as a simple vector of values.
void setPosition(const Amg::Vector3D &position)
Sets the 3-position.
void setFitQuality(float chiSquared, float numberDoF)
Set the 'Fit Quality' information.
const Amg::Vector3D & position() const
Returns the 3-pos.
float x() const
Returns the x position.
Eigen::Matrix< double, 3, 1 > Vector3D
Gaudi Tools.
Vertex_v1 Vertex
Define the latest version of the vertex class.
@ numberOfTRTHits
number of TRT hits [unit8_t].
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].
std::vector< std::vector< double > > trkAtVrt