ATLAS Offline Software
Loading...
Searching...
No Matches
MultiUtilities.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
7// Header include
9//-------------------------------------------------
10// Other stuff
14#include "TMath.h"
15#include <algorithm>
16//
17
18
19namespace Rec{
20
21
22 /* Service routines*/
23
24//-----------------------------------------------------------------------------------
25// Find track contributing most to the vertex invariant mass
26 int NewVrtSecInclusiveTool::mostHeavyTrk(WrkVrt V, std::vector<const xAOD::TrackParticle*> AllTracks)
27
28 {
29 int NTrk=V.selTrk.size(), SelT=-1;
30 if(NTrk<3)return -1;
31//--------------------------------------------------
32 TLorentzVector TSum;
33 for(int i=0; i<NTrk; i++){
34 TSum += AllTracks.at(V.selTrk[i])->p4();
35 }
36 double massMin=1.e9;
37 for(int i=0; i<NTrk; i++){
38 TLorentzVector TSum_m1 = TSum - AllTracks[V.selTrk[i]]->p4();
39 if(TSum_m1.M()<massMin){massMin=TSum_m1.M(); SelT=i;}
40 }
41 return SelT;
42 }
43
44
45//
46// Number of common tracks for 2 vertices
47//
48 int NewVrtSecInclusiveTool::nTrkCommon( std::vector<WrkVrt> *wrkVrtSet, int V1, int V2)
49
50 {
51 int nTrk_V1 = (*wrkVrtSet).at(V1).selTrk.size(); if( nTrk_V1< 2) return 0; /* Bad vertex */
52 int nTrk_V2 = (*wrkVrtSet).at(V2).selTrk.size(); if( nTrk_V2< 2) return 0; /* Bad vertex */
53 int nTrkCom=0;
54 if(nTrk_V1 < nTrk_V2){
55 for(int i=0; i<nTrk_V1; i++){
56 int trk=(*wrkVrtSet)[V1].selTrk[i];
57 for(int j=0; j<nTrk_V2; j++){ if( trk==(*wrkVrtSet)[V2].selTrk[j]){ nTrkCom++; break;} }
58 }
59 }else{
60 for(int i=0; i<nTrk_V2; i++){
61 int trk=(*wrkVrtSet)[V2].selTrk[i];
62 for(int j=0; j<nTrk_V1; j++){ if( trk==(*wrkVrtSet)[V1].selTrk[j]){ nTrkCom++; break;} }
63 }
64 }
65 return nTrkCom;
66 }
67//
68// Minimal normalized vertex-vertex distance
69//
70 double NewVrtSecInclusiveTool::minVrtVrtDist( std::vector<WrkVrt> *wrkVrtSet, int & V1, int & V2, std::vector<double> & checked)
71 const
72 {
73 V1=V2=-1;
74 double foundMinVrtDst=1000000.;
75
76 for(int iv=0; iv<(int)wrkVrtSet->size()-1; iv++) {
77 if( (*wrkVrtSet)[iv].selTrk.size()< 2) continue; /* Bad vertices */
78 if(!(*wrkVrtSet)[iv].Good ) continue; /* Bad vertices */
79 for(int jv=iv+1; jv<(int)wrkVrtSet->size(); jv++) {
80 if( (*wrkVrtSet)[jv].selTrk.size()< 2) continue; /* Bad vertices */
81 if(!(*wrkVrtSet)[jv].Good ) continue; /* Bad vertices */
82 double tmp= std::abs((*wrkVrtSet)[iv].vertex.x()-(*wrkVrtSet)[jv].vertex.x())
83 +std::abs((*wrkVrtSet)[iv].vertex.y()-(*wrkVrtSet)[jv].vertex.y())
84 +std::abs((*wrkVrtSet)[iv].vertex.z()-(*wrkVrtSet)[jv].vertex.z());
85 if(tmp>20.) continue;
86 double tmpDst = vrtVrtDist((*wrkVrtSet)[iv].vertex,(*wrkVrtSet)[iv].vertexCov,
87 (*wrkVrtSet)[jv].vertex,(*wrkVrtSet)[jv].vertexCov);
88 if(std::find(checked.begin(),checked.end(),tmpDst) != checked.end()) continue; //Alreasy tried
89 if( tmpDst < foundMinVrtDst){foundMinVrtDst = tmpDst; V1=iv; V2=jv;}
90 }
91 }
92 return foundMinVrtDst;
93 }
94
95//
96// Refine two vertices with common tracks.
97// Main logics for clique->vertex conversion is implemented here.
98// Common tracks are removed from "bad" vertex and left in "good" vertex.
99//
101 std::vector<const xAOD::TrackParticle*> & allTrackList,
102 Trk::IVKalState& istate)
103 const
104 {
105 if(!v1.Good || !v2.Good)return -1.; //bad vertex check for safety
106
107 int ntv1=v1.selTrk.size();
108 int ntv2=v2.selTrk.size();
109 if( ntv1<2 || ntv2<2 ) return -1.; //for safety
110 double prb_v1=TMath::Prob( v1.chi2, 2*ntv1-3);
111 double prb_v2=TMath::Prob( v2.chi2, 2*ntv2-3);
112 WrkVrt * badV =&v1;
113 WrkVrt * goodV=&v2;
114 bool swap=false;
115 //---- Good vertex selection
116 if(prb_v1>0.01&&prb_v2>0.01){ //Both vertices are good Prob>1%
117 if( ntv1==ntv2 ) {if(prb_v1>prb_v2) swap=true;} //If multiplicities are equal- select better Chi2
118 else {if(ntv1>ntv2) swap=true;}
119 }
120 if(prb_v1<0.01&&prb_v2<0.01){ //Both vertices are bad Prob<1%
121 if(prb_v1>prb_v2) swap=true; // select better Chi2
122 }
123 if(prb_v1>0.01&&prb_v2<0.01){ //Second vertex is bad Prob<1%
124 if(prb_v1>prb_v2) swap=true;
125 }
126 if(swap) {badV =&v2; goodV =&v1;}
127 int badVNtrk=(*badV).selTrk.size();
128 //-----------------
129 unsigned int it=0;
130 while( it<(*badV).selTrk.size() ){
131 int trk=(*badV).selTrk[it];
132 if(std::find((*goodV).selTrk.begin(),(*goodV).selTrk.end(),trk) != (*goodV).selTrk.end()){
133 (*badV).selTrk.erase((*badV).selTrk.begin()+it);
134 (*badV).detachedTrack=trk;
135 } else it++;
136 }
137 if((*badV).selTrk.size()<2){
138 (*badV).Good=false;
139 if((*badV).selTrk.size()==1 && m_multiWithOneTrkVrt){ //Special case if 1-track vertices are allowed
140 (*badV).vertexCharge=allTrackList[(*badV).selTrk.at(0)]->charge();
141 (*badV).vertexMom=allTrackList[(*badV).selTrk.at(0)]->p4();
142 if( badVNtrk>=2 && TMath::Prob((*badV).chi2,2*badVNtrk-3)>0.1 ) (*badV).Good=true; //Accept only if original vertex prob>10%!
143 }
144 return -1.;
145 }
146 return refitVertex((*badV),allTrackList, istate, false);
147 }
148//
149// Check two close vertices by explicit vertex fit and create combined vertex if successful
150//
152 std::vector<const xAOD::TrackParticle*> & AllTrackList,
153 Trk::IVKalState& istate, int robKey)
154 const
155 {
156 if(!v1.Good)return -1.; //bad vertex
157 if(!v2.Good)return -1.; //bad vertex
158 std::vector<const xAOD::NeutralParticle*> neutralPartDummy(0);
159 newvrt.Good=true;
160 int nTrk_V1=v1.selTrk.size();
161 int nTrk_V2=v2.selTrk.size();
162 newvrt.selTrk.resize(nTrk_V1+nTrk_V2);
163 std::copy(v1.selTrk.begin(),v1.selTrk.end(), newvrt.selTrk.begin());
164 std::copy(v2.selTrk.begin(),v2.selTrk.end(), newvrt.selTrk.begin()+nTrk_V1);
165
166 std::deque<long int>::iterator TransfEnd ;
167 sort( newvrt.selTrk.begin(), newvrt.selTrk.end() );
168 TransfEnd = unique( newvrt.selTrk.begin(), newvrt.selTrk.end() );
169 newvrt.selTrk.erase( TransfEnd, newvrt.selTrk.end());
170 std::vector<const xAOD::TrackParticle*> fitTrackList(0);
171 for(int it=0; it<(int)newvrt.selTrk.size(); it++)fitTrackList.push_back( AllTrackList[newvrt.selTrk[it]] );
172 m_fitSvc->setApproximateVertex( 0.5*(v1.vertex[0]+v2.vertex[0]),
173 0.5*(v1.vertex[1]+v2.vertex[1]),
174 0.5*(v1.vertex[2]+v2.vertex[2]),
175 istate);
176 m_fitSvc->setRobustness(robKey,istate);
177
178 StatusCode sc=m_fitSvc->VKalVrtFit(fitTrackList,neutralPartDummy,
179 newvrt.vertex, newvrt.vertexMom, newvrt.vertexCharge, newvrt.vertexCov,
180 newvrt.chi2PerTrk, newvrt.trkAtVrt, newvrt.chi2,
181 istate, false);
182 if( sc.isFailure() ) return -1.;
183 if( newvrt.chi2>500. ) return -1.; //VK protection
184 if( newvrt.chi2PerTrk.size()==2) newvrt.chi2PerTrk[0]=newvrt.chi2PerTrk[1]=newvrt.chi2/2.;
185
186 m_fitSvc->setRobustness(0,istate); //restore default behaviour
187
188 return TMath::Prob( newvrt.chi2, 2*newvrt.selTrk.size()-3);
189 }
190
191//
192// Iterate track removal until vertex get good Chi2
193//
194
195 double NewVrtSecInclusiveTool::improveVertexChi2( WrkVrt &vertex, std::vector<const xAOD::TrackParticle*> & allTrackList,
196 Trk::IVKalState& istate,
197 bool ifCovV0)
198 const
199 {
200
201 int nTrk=vertex.selTrk.size();
202 if( nTrk<2 )return 0.;
203 double prob=TMath::Prob( vertex.chi2, 2*nTrk-3);
204 //
205 //----Start track removal iterations
206 while(prob<0.01){
207 nTrk=vertex.selTrk.size();
208 if(nTrk==2)return prob;
209 int selT=0;
210 for(int i=0; i<nTrk; i++){ if( vertex.chi2PerTrk[i]>vertex.chi2PerTrk[selT]) selT=i; }
211 vertex.detachedTrack=vertex.selTrk[selT];
212 vertex.selTrk.erase( vertex.selTrk.begin() + selT ); //remove track
213 prob = refitVertex( vertex, allTrackList, istate, ifCovV0);
214 if(prob<0.)return 0.;
215 }
216 return prob;
217 }
218
219
220
222 std::vector<const xAOD::TrackParticle*> & selectedTracks,
223 Trk::IVKalState& istate,
224 bool ifCovV0) const
225 {
226 int i,j;
227 int nth = vrt.selTrk.size();
228
229 if(nth<2) return -1.;
230
231 std::vector<const xAOD::NeutralParticle*> neutralPartDummy(0);
232 std::vector<const xAOD::TrackParticle*> listTracks(0);
233 for(i=0;i<nth;i++) {
234 j=vrt.selTrk[i]; /*Track number*/
235 listTracks.push_back( selectedTracks[j] );
236 }
237 vrt.Good = false;
238 vrt.chi2PerTrk.resize(nth);
239 for(i=0;i<nth;i++)vrt.chi2PerTrk[i]=100000.+i; //VK safety
240
241 m_fitSvc->setApproximateVertex(vrt.vertex[0],vrt.vertex[1],vrt.vertex[2],istate);
242 StatusCode sc=m_fitSvc->VKalVrtFit(listTracks,neutralPartDummy,vrt.vertex,vrt.vertexMom,vrt.vertexCharge,
243 vrt.vertexCov,vrt.chi2PerTrk, vrt.trkAtVrt,vrt.chi2,
244 istate, ifCovV0);
245 if(sc.isSuccess())vrt.Good = true;
246 else {vrt.Good = false; return -1.;}
247 if(vrt.chi2PerTrk.size()==2) vrt.chi2PerTrk[0]=vrt.chi2PerTrk[1]=vrt.chi2/2.;
248 return TMath::Prob( vrt.chi2, 2*nth-1);
249 }
250
251
252 bool NewVrtSecInclusiveTool::isPart( const std::deque<long int>& test, std::deque<long int> base)
253
254 {
255 for (long int trk : test)
256 if(std::find(base.begin(), base.end(), trk) == base.end()) return false; //element not found => test is not part of base
257 return true;
258 }
259
260 double NewVrtSecInclusiveTool::MomProjDist(const Amg::Vector3D & SecVrt,const xAOD::Vertex &primVrt,const TLorentzVector &Mom)
261
262 {
263 Amg::Vector3D vv=SecVrt-primVrt.position();
264 return ( vv.x()*Mom.X()+vv.y()*Mom.Y()+vv.z()*Mom.Z() )/ Mom.P();
265 }
266
267} //end namespace
268
269
270
void swap(DataVector< T > &a, DataVector< T > &b)
See DataVector<T, BASE>::swap().
static Double_t sc
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
double improveVertexChi2(WrkVrt &vertex, std::vector< const xAOD::TrackParticle * > &allTracks, Trk::IVKalState &istate, bool ifCovV0) const
double mergeAndRefitVertices(WrkVrt &v1, WrkVrt &v2, WrkVrt &newvrt, std::vector< const xAOD::TrackParticle * > &AllTrackList, Trk::IVKalState &istate, int robKey=0) const
double refitVertex(WrkVrt &Vrt, std::vector< const xAOD::TrackParticle * > &SelectedTracks, Trk::IVKalState &istate, bool ifCovV0) const
double refineVerticesWithCommonTracks(WrkVrt &v1, WrkVrt &v2, std::vector< const xAOD::TrackParticle * > &allTrackList, Trk::IVKalState &istate) const
static int nTrkCommon(std::vector< WrkVrt > *WrkVrtSet, int indexV1, int indexV2)
static bool isPart(const std::deque< long int > &test, std::deque< long int > base)
ToolHandle< Trk::TrkVKalVrtFitter > m_fitSvc
static double MomProjDist(const Amg::Vector3D &SV, const xAOD::Vertex &PV, const TLorentzVector &Direction)
static int mostHeavyTrk(WrkVrt V, std::vector< const xAOD::TrackParticle * > AllTracks)
static double vrtVrtDist(const xAOD::Vertex &primVrt, const Amg::Vector3D &secVrt, const std::vector< double > &vrtErr, double &signif)
double minVrtVrtDist(std::vector< WrkVrt > *WrkVrtSet, int &indexV1, int &indexV2, std::vector< double > &check) const
Gaudi::Property< bool > m_multiWithOneTrkVrt
const Amg::Vector3D & position() const
Returns the 3-pos.
std::string base
Definition hcg.cxx:81
Eigen::Matrix< double, 3, 1 > Vector3D
Gaudi Tools.
Vertex_v1 Vertex
Define the latest version of the vertex class.
std::vector< std::vector< double > > trkAtVrt