]>
Commit | Line | Data |
---|---|---|
cab6ff9b | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
7 | * Permission to use, copy, modify and distribute this software and its * | |
8 | * documentation strictly for non-commercial purposes is hereby granted * | |
9 | * without fee, provided that the above copyright notice appears in all * | |
10 | * copies and that both the copyright notice and this permission notice * | |
11 | * appear in the supporting documentation. The authors make no claims * | |
12 | * about the suitability of this software for any purpose. It is * | |
13 | * provided "as is" without express or implied warranty. * | |
14 | **************************************************************************/ | |
15 | ||
16 | //----------------------------------------------------------------- | |
17 | // Implementation of the vertexer from tracks | |
18 | // | |
19 | // Origin: A.Dainese, Padova, andrea.dainese@pd.infn.it | |
20 | // M.Masera, Torino, massimo.masera@to.infn.it | |
21 | //----------------------------------------------------------------- | |
22 | ||
23 | //---- standard headers ---- | |
24 | #include <Riostream.h> | |
25 | //---- Root headers -------- | |
26 | #include <TFile.h> | |
27 | #include <TTree.h> | |
28 | #include <TVector3.h> | |
29 | #include <TMatrixD.h> | |
30 | #include <TObjArray.h> | |
31 | #include <TRandom.h> // TEMPORARY !!!!!!! | |
32 | //---- AliRoot headers ----- | |
33 | #include <AliRun.h> | |
34 | #include "AliKalmanTrack.h" | |
35 | #include "AliITSStrLine.h" | |
36 | #include "AliITStrackV2.h" | |
37 | #include "AliITSVertex.h" | |
38 | #include "AliITSVertexerTracks.h" | |
39 | ||
40 | ||
41 | ClassImp(AliITSVertexerTracks) | |
42 | ||
43 | ||
44 | //---------------------------------------------------------------------------- | |
45 | AliITSVertexerTracks::AliITSVertexerTracks():AliITSVertexer() { | |
46 | // | |
47 | // Default constructor | |
48 | // | |
49 | ||
50 | SetVtxStart(); | |
51 | SetMinTracks(); | |
52 | SetUseThrustFrame(); | |
53 | SetPhiThrust(); | |
54 | fTrksToSkip = 0; | |
55 | fNTrksToSkip = 0; | |
56 | for(Int_t i=0; i<3; i++)fInitPos[i] = 0.; | |
57 | } | |
58 | ||
59 | //---------------------------------------------------------------------------- | |
60 | AliITSVertexerTracks::AliITSVertexerTracks(TFile *inFile,TFile *outFile, | |
61 | Double_t field, | |
62 | Double_t xStart,Double_t yStart, | |
63 | Int_t useThFr) | |
64 | :AliITSVertexer(inFile,outFile) { | |
65 | // | |
66 | // Standard constructor | |
67 | // | |
68 | ||
69 | SetField(field); | |
70 | SetVtxStart(xStart,yStart); | |
71 | SetMinTracks(); | |
72 | SetUseThrustFrame(useThFr); | |
73 | SetPhiThrust(); | |
74 | fTrksToSkip = 0; | |
75 | fNTrksToSkip = 0; | |
76 | for(Int_t i=0; i<3; i++)fInitPos[i] = 0.; | |
77 | } | |
78 | //---------------------------------------------------------------------------- | |
79 | Bool_t AliITSVertexerTracks::CheckField() const { | |
80 | // | |
81 | // Check if the conv. const. has been set | |
82 | // | |
83 | AliITStrackV2 t; | |
84 | Double_t cc = t.GetConvConst(); | |
85 | Double_t field = 100./0.299792458/cc; | |
86 | ||
87 | if(field<0.1 || field>0.6) { | |
88 | printf("AliITSVertexerTracks::CheckField():\n ERROR: AliKalmanTrack::fConvConst not set\n Use AliKalmanTrack::SetConvConst() or AliITSVertexerTracks::SetField()\n"); | |
89 | return kFALSE; | |
90 | } | |
91 | printf("AliITSVertexerTracks::CheckField(): Using B = %3.1f T\n",field); | |
92 | return kTRUE; | |
93 | } | |
94 | //--------------------------------------------------------------------------- | |
95 | void AliITSVertexerTracks::ComputeMaxChi2PerTrack(Int_t nTracks) { | |
96 | // | |
97 | // Max. contr. to the chi2 has been tuned as a function of multiplicity | |
98 | // | |
99 | if(nTracks < 7) { fMaxChi2PerTrack = 1.e6; | |
100 | } else { fMaxChi2PerTrack = 100.; } | |
101 | ||
102 | return; | |
103 | } | |
104 | //--------------------------------------------------------------------------- | |
105 | void AliITSVertexerTracks::FindVertices() { | |
106 | // | |
107 | // Vertices for all events from fFirstEvent to fLastEvent | |
108 | // | |
109 | ||
110 | // Check if the conv. const. has been set | |
111 | if(!CheckField()) return; | |
112 | ||
113 | ||
114 | // loop over events | |
115 | for(Int_t ev=fFirstEvent; ev<=fLastEvent; ev++) { | |
116 | if(ev % 100 == 0 || fDebug) printf("--- Processing event %d of %d ---\n",ev,fLastEvent); | |
117 | ||
118 | FindVertexForCurrentEvent(ev); | |
119 | ||
120 | if(!fCurrentVertex) { | |
121 | printf("AliITSVertexerTracks::FindVertixes(): no tracks tree for event %d\n",ev); | |
122 | continue; | |
123 | } | |
124 | ||
125 | if(fDebug) fCurrentVertex->PrintStatus(); | |
d4221964 | 126 | TString vtxName = "Vertex_"; |
127 | vtxName += ev; | |
128 | fCurrentVertex->SetName(vtxName.Data()); | |
129 | fCurrentVertex->SetTitle("VertexerTracks"); | |
cab6ff9b | 130 | WriteCurrentVertex(); |
131 | } // loop over events | |
132 | ||
133 | return; | |
134 | } | |
135 | //---------------------------------------------------------------------------- | |
136 | Int_t AliITSVertexerTracks::PrepareTracks(TTree &trkTree) { | |
137 | // | |
138 | // Propagate tracks to initial vertex position and store them in a TObjArray | |
139 | // | |
140 | Double_t maxd0rphi = 3.; | |
141 | Double_t alpha,xlStart,d0rphi; | |
142 | Int_t nTrks = 0; | |
143 | Bool_t skipThis; | |
144 | ||
145 | Int_t nEntries = (Int_t)trkTree.GetEntries(); | |
146 | ||
147 | if(!fTrkArray.IsEmpty()) fTrkArray.Clear(); | |
148 | fTrkArray.Expand(nEntries); | |
149 | ||
150 | if(fDebug) { | |
151 | printf(" PrepareTracks()\n"); | |
152 | trkTree.Print(); | |
153 | } | |
154 | ||
155 | for(Int_t i=0; i<nEntries; i++) { | |
156 | // check tracks to skip | |
157 | skipThis = kFALSE; | |
158 | for(Int_t j=0; j<fNTrksToSkip; j++) { | |
159 | if(i==fTrksToSkip[j]) { | |
160 | if(fDebug) printf("skipping track: %d\n",i); | |
161 | skipThis = kTRUE; | |
162 | } | |
163 | } | |
164 | if(skipThis) continue; | |
165 | ||
166 | AliITStrackV2 *itstrack = new AliITStrackV2; | |
167 | trkTree.SetBranchAddress("tracks",&itstrack); | |
168 | trkTree.GetEvent(i); | |
169 | ||
170 | ||
171 | // propagate track to vtxSeed | |
172 | alpha = itstrack->GetAlpha(); | |
173 | xlStart = fNominalPos[0]*TMath::Cos(alpha)+fNominalPos[1]*TMath::Sin(alpha); | |
174 | itstrack->PropagateTo(3.,0.0023,65.19); // to beam pipe (0.8 mm of Be) | |
175 | itstrack->PropagateTo(xlStart,0.,0.); // to vtxSeed | |
176 | ||
177 | // select tracks with d0rphi < maxd0rphi | |
178 | d0rphi = TMath::Abs(itstrack->GetD(fNominalPos[0],fNominalPos[1])); | |
179 | if(d0rphi > maxd0rphi) { delete itstrack; continue; } | |
180 | ||
181 | fTrkArray.AddLast(itstrack); | |
182 | ||
183 | nTrks++; | |
184 | } | |
185 | ||
186 | if(fTrksToSkip) delete [] fTrksToSkip; | |
187 | ||
188 | return nTrks; | |
189 | } | |
190 | //---------------------------------------------------------------------------- | |
191 | void AliITSVertexerTracks::PrintStatus() const { | |
192 | // | |
193 | // Print status | |
194 | // | |
195 | printf(" Initial position (%f,%f)\n",fNominalPos[0],fNominalPos[1]); | |
196 | printf(" Vertex position after vertex finder (%f, %f, %f)\n",fInitPos[0],fInitPos[1],fInitPos[2]); | |
197 | printf(" Number of tracks in array: %d\n",(Int_t)fTrkArray.GetEntriesFast()); | |
198 | printf(" Minimum # tracks required in fit: %d\n",fMinTracks); | |
199 | printf(" Using Thrust Frame: %d fPhiThrust = %f\n",fUseThrustFrame,fPhiThrust); | |
200 | ||
201 | return; | |
202 | } | |
203 | //---------------------------------------------------------------------------- | |
204 | AliITSVertex* AliITSVertexerTracks::FindVertexForCurrentEvent(Int_t evnumb) { | |
205 | // | |
206 | // Vertex for current event | |
207 | // | |
208 | fCurrentVertex = 0; | |
209 | ||
210 | // get tree with tracks from input file | |
211 | TString treeName = "TreeT_ITS_"; | |
212 | treeName += evnumb; | |
213 | TTree *trkTree=(TTree*)fInFile->Get(treeName.Data()); | |
214 | if(!trkTree) return fCurrentVertex; | |
215 | ||
216 | ||
217 | // get tracks and propagate them to initial vertex position | |
218 | Int_t nTrks = PrepareTracks(*trkTree); | |
219 | delete trkTree; | |
220 | if(fDebug) printf(" tracks prepared: %d\n",nTrks); | |
221 | if(nTrks < fMinTracks) { TooFewTracks(); return fCurrentVertex; } | |
222 | ||
223 | // VERTEX FINDER | |
224 | VertexFinder(); | |
225 | ||
226 | // VERTEX FITTER | |
227 | ComputeMaxChi2PerTrack(nTrks); | |
228 | if(fUseThrustFrame) ThrustFinderXY(); | |
229 | if(fDebug) printf(" thrust found: phi = %f\n",fPhiThrust); | |
230 | VertexFitter(); | |
231 | if(fDebug) printf(" vertex fit completed\n"); | |
232 | ||
233 | TString vtxName; | |
d4221964 | 234 | vtxName = "Vertex_"; |
cab6ff9b | 235 | vtxName += evnumb; |
236 | fCurrentVertex->SetName(vtxName.Data()); | |
237 | return fCurrentVertex; | |
238 | } | |
239 | //--------------------------------------------------------------------------- | |
240 | void AliITSVertexerTracks::SetSkipTracks(Int_t n,Int_t *skipped) { | |
241 | // | |
242 | // Mark the tracks not ot be used in the vertex finding | |
243 | // | |
244 | fNTrksToSkip = n; | |
245 | fTrksToSkip = new Int_t[n]; | |
246 | for(Int_t i=0;i<n;i++) fTrksToSkip[i] = skipped[i]; | |
247 | return; | |
248 | } | |
249 | //---------------------------------------------------------------------------- | |
250 | Double_t AliITSVertexerTracks::SumPl(TTree &momTree,Double_t phi) const { | |
251 | // | |
252 | // Function to be maximized for thrust determination | |
253 | // | |
254 | TVector3 u(1.,1.,0); | |
255 | u.SetMag(1.); | |
256 | u.SetPhi(phi); | |
257 | Double_t pl; | |
258 | ||
259 | Double_t sum = 0.; | |
260 | ||
261 | TVector3* mom=0; | |
262 | momTree.SetBranchAddress("momenta",&mom); | |
263 | Int_t entries = (Int_t)momTree.GetEntries(); | |
264 | ||
265 | for(Int_t i=0; i<entries; i++) { | |
266 | momTree.GetEvent(i); | |
267 | pl = mom->Dot(u); | |
268 | if(pl>0.) sum += pl; | |
269 | } | |
270 | ||
271 | delete mom; | |
272 | ||
273 | return sum; | |
274 | } | |
275 | //--------------------------------------------------------------------------- | |
276 | void AliITSVertexerTracks::ThrustFinderXY() { | |
277 | // | |
278 | // This function looks for the thrust direction, \vec{u}, in the (x,y) plane. | |
279 | // The following function is maximized: | |
280 | // \Sum_{\vec{p}\cdot\vec{u}} \vec{p}\cdot\vec{u} / \Sum |\vec{p}| | |
281 | // where \vec{p} = (p_x,p_y) | |
282 | // | |
283 | Double_t pt,alpha,phi; | |
284 | Double_t totPt; | |
285 | ||
286 | // tree for thrust determination | |
287 | TVector3 *ioMom = new TVector3; | |
288 | TTree *t = new TTree("Tree_Momenta","Tree with momenta"); | |
289 | t->Branch("momenta","TVector3",&ioMom); | |
290 | totPt = 0.; | |
291 | ||
292 | AliITStrackV2 *itstrack = 0; | |
293 | Int_t arrEntries = (Int_t)fTrkArray.GetEntries(); | |
294 | ||
295 | // loop on tracks | |
296 | for(Int_t i=0; i<arrEntries; i++) { | |
297 | itstrack = (AliITStrackV2*)fTrkArray.At(i); | |
298 | // momentum of the track at the vertex | |
299 | pt = 1./TMath::Abs(itstrack->Get1Pt()); | |
300 | alpha = itstrack->GetAlpha(); | |
301 | phi = alpha+TMath::ASin(itstrack->GetSnp()); | |
302 | ioMom->SetX(pt*TMath::Cos(phi)); | |
303 | ioMom->SetY(pt*TMath::Sin(phi)); | |
304 | ioMom->SetZ(0.); | |
305 | ||
306 | totPt += ioMom->Pt(); | |
307 | t->Fill(); | |
308 | } // end loop on tracks | |
309 | ||
310 | Double_t tValue=0.,tPhi=0.; | |
311 | Double_t maxSumPl = 0.; | |
312 | Double_t thisSumPl; | |
313 | Double_t dPhi; | |
314 | Int_t nSteps,iStep; | |
315 | ||
316 | phi = 0.; | |
317 | nSteps = 100; | |
318 | dPhi = 2.*TMath::Pi()/(Double_t)nSteps; | |
319 | ||
320 | for(iStep=0; iStep<nSteps; iStep++) { | |
321 | phi += dPhi; | |
322 | thisSumPl = SumPl(*t,phi); | |
323 | if(thisSumPl > maxSumPl) { | |
324 | maxSumPl = thisSumPl; | |
325 | tPhi = phi; | |
326 | } | |
327 | } | |
328 | ||
329 | phi = tPhi-dPhi; | |
330 | nSteps = 10; | |
331 | dPhi /= 5.; | |
332 | ||
333 | for(iStep=0; iStep<nSteps; iStep++) { | |
334 | phi += dPhi; | |
335 | thisSumPl = SumPl(*t,phi); | |
336 | if(thisSumPl > maxSumPl) { | |
337 | maxSumPl = thisSumPl; | |
338 | tPhi = phi; | |
339 | } | |
340 | } | |
341 | ||
342 | tValue = 2.*maxSumPl/totPt; | |
343 | if(tPhi<0.) tPhi += 2.*TMath::Pi(); | |
344 | if(tPhi>2.*TMath::Pi()) tPhi -= 2.*TMath::Pi(); | |
345 | ||
346 | SetPhiThrust(tPhi); | |
347 | ||
348 | delete t; | |
349 | delete ioMom; | |
350 | ||
351 | return; | |
352 | } | |
353 | //--------------------------------------------------------------------------- | |
354 | void AliITSVertexerTracks::TooFewTracks() { | |
355 | // | |
356 | // When the number of tracks is < fMinTracks the vertex is set to (0,0,0) | |
357 | // and the number of tracks to -1 | |
358 | // | |
359 | fCurrentVertex = new AliITSVertex(0.,0.,-1); | |
360 | return; | |
361 | } | |
362 | //--------------------------------------------------------------------------- | |
363 | void AliITSVertexerTracks::VertexFinder() { | |
364 | ||
365 | // Get estimate of vertex position in (x,y) from tracks DCA | |
366 | // Then this estimate is stored to the data member fInitPos | |
367 | // (previous values are overwritten) | |
368 | ||
369 | ||
370 | ||
371 | /* | |
372 | ******* TEMPORARY!!! FOR TEST ONLY!!! ********************************** | |
373 | ||
374 | fInitPos[0] = fNominalPos[0]+gRandom->Gaus(0.,0.0100); // 100 micron gaussian smearing | |
375 | fInitPos[1] = fNominalPos[1]+gRandom->Gaus(0.,0.0100); // 100 micron gaussian smearing | |
376 | */ | |
377 | ||
378 | fInitPos[2] = 0.; | |
379 | for(Int_t i=0;i<2;i++)fInitPos[i]=fNominalPos[i]; | |
380 | ||
381 | Int_t nacc = (Int_t)fTrkArray.GetEntriesFast(); | |
382 | ||
383 | Double_t aver[3]={0.,0.,0.}; | |
384 | Int_t ncombi = 0; | |
385 | AliITStrackV2 *track1; | |
386 | AliITStrackV2 *track2; | |
387 | for(Int_t i=0; i<nacc; i++){ | |
388 | track1 = (AliITStrackV2*)fTrkArray.At(i); | |
389 | if(fDebug>5){ | |
390 | Double_t xv,par[5]; | |
391 | track1->GetExternalParameters(xv,par); | |
392 | cout<<"Track in position "<<i<<" xr= "<<xv<<endl; | |
393 | for(Int_t ii=0;ii<5;ii++)cout<<par[ii]<<" "; | |
394 | cout<<endl; | |
395 | } | |
396 | Double_t mom1[3]; | |
397 | Double_t alpha = track1->GetAlpha(); | |
398 | Double_t azim = TMath::ASin(track1->GetSnp())+alpha; | |
399 | Double_t theta = TMath::Pi()/2. - TMath::ATan(track1->GetTgl()); | |
400 | mom1[0] = TMath::Sin(theta)*TMath::Cos(azim); | |
401 | mom1[1] = TMath::Sin(theta)*TMath::Sin(azim); | |
402 | mom1[2] = TMath::Cos(theta); | |
403 | ||
404 | Double_t pos1[3]; | |
405 | Double_t mindist = TMath::Cos(alpha)*fNominalPos[0]+TMath::Sin(alpha)*fNominalPos[1]; | |
406 | track1->GetGlobalXYZat(mindist,pos1[0],pos1[1],pos1[2]); | |
407 | AliITSStrLine *line1 = new AliITSStrLine(pos1,mom1); | |
408 | for(Int_t j=i+1; j<nacc; j++){ | |
409 | track2 = (AliITStrackV2*)fTrkArray.At(j); | |
410 | Double_t mom2[3]; | |
411 | alpha = track2->GetAlpha(); | |
412 | azim = TMath::ASin(track2->GetSnp())+alpha; | |
413 | theta = TMath::Pi()/2. - TMath::ATan(track2->GetTgl()); | |
414 | mom2[0] = TMath::Sin(theta)*TMath::Cos(azim); | |
415 | mom2[1] = TMath::Sin(theta)*TMath::Sin(azim); | |
416 | mom2[2] = TMath::Cos(theta); | |
417 | Double_t pos2[3]; | |
418 | mindist = TMath::Cos(alpha)*fNominalPos[0]+TMath::Sin(alpha)*fNominalPos[1]; | |
419 | track2->GetGlobalXYZat(mindist,pos2[0],pos2[1],pos2[2]); | |
420 | AliITSStrLine *line2 = new AliITSStrLine(pos2,mom2); | |
421 | Double_t crosspoint[3]; | |
422 | Int_t retcode = line2->Cross(line1,crosspoint); | |
423 | if(retcode<0){ | |
424 | if(fDebug>10)cout<<" i= "<<i<<", j= "<<j<<endl; | |
425 | if(fDebug>10)cout<<"bad intersection\n"; | |
426 | line1->PrintStatus(); | |
427 | line2->PrintStatus(); | |
428 | } | |
429 | else { | |
430 | ncombi++; | |
431 | for(Int_t jj=0;jj<3;jj++)aver[jj]+=crosspoint[jj]; | |
432 | if(fDebug>10)cout<<" i= "<<i<<", j= "<<j<<endl; | |
433 | if(fDebug>10)cout<<"\n Cross point: "; | |
434 | if(fDebug>10)cout<<crosspoint[0]<<" "<<crosspoint[1]<<" "<<crosspoint[2]<<endl; | |
435 | } | |
436 | delete line2; | |
437 | } | |
438 | delete line1; | |
439 | } | |
440 | if(ncombi>0){ | |
441 | for(Int_t jj=0;jj<3;jj++)fInitPos[jj] = aver[jj]/ncombi; | |
442 | } | |
443 | else { | |
444 | Warning("VertexFinder","Finder did not succed"); | |
445 | } | |
446 | ||
447 | ||
448 | //************************************************************************ | |
449 | return; | |
450 | ||
451 | } | |
452 | ||
453 | //--------------------------------------------------------------------------- | |
454 | void AliITSVertexerTracks::VertexFitter() { | |
455 | // | |
456 | // The optimal estimate of the vertex position is given by a "weighted | |
457 | // average of tracks positions" | |
458 | // Original method: CMS Note 97/0051 | |
459 | // | |
460 | if(fDebug) { | |
461 | printf(" VertexFitter(): start\n"); | |
462 | PrintStatus(); | |
463 | } | |
464 | ||
465 | ||
466 | Int_t i,j,k,step=0; | |
467 | TMatrixD rv(3,1); | |
468 | TMatrixD V(3,3); | |
469 | rv(0,0) = fInitPos[0]; | |
470 | rv(1,0) = fInitPos[1]; | |
471 | rv(2,0) = 0.; | |
472 | Double_t xlStart,alpha; | |
473 | Double_t rotAngle; | |
474 | Double_t cosRot,sinRot; | |
475 | Double_t cc[15]; | |
476 | Int_t nUsedTrks; | |
477 | Double_t chi2,chi2i; | |
478 | Int_t arrEntries = (Int_t)fTrkArray.GetEntries(); | |
479 | AliITStrackV2 *t = 0; | |
480 | Int_t failed = 0; | |
481 | ||
482 | Int_t *skipTrack = new Int_t[arrEntries]; | |
483 | for(i=0; i<arrEntries; i++) skipTrack[i]=0; | |
484 | ||
485 | // 3 steps: | |
486 | // 1st - first estimate of vtx using all tracks | |
487 | // 2nd - apply cut on chi2 max per track | |
488 | // 3rd - estimate of global chi2 | |
489 | for(step=0; step<3; step++) { | |
490 | if(fDebug) printf(" step = %d\n",step); | |
491 | chi2 = 0.; | |
492 | nUsedTrks = 0; | |
493 | ||
494 | TMatrixD SumWiri(3,1); | |
495 | TMatrixD SumWi(3,3); | |
496 | for(i=0; i<3; i++) { | |
497 | SumWiri(i,0) = 0.; | |
498 | for(j=0; j<3; j++) SumWi(j,i) = 0.; | |
499 | } | |
500 | ||
501 | // loop on tracks | |
502 | for(k=0; k<arrEntries; k++) { | |
503 | if(skipTrack[k]) continue; | |
504 | // get track from track array | |
505 | t = (AliITStrackV2*)fTrkArray.At(k); | |
506 | alpha = t->GetAlpha(); | |
507 | xlStart = fInitPos[0]*TMath::Cos(alpha)+fInitPos[1]*TMath::Sin(alpha); | |
508 | t->PropagateTo(xlStart,0.,0.); // to vtxSeed | |
509 | rotAngle = alpha-fPhiThrust; | |
510 | if(alpha<0.) rotAngle += 2.*TMath::Pi(); | |
511 | cosRot = TMath::Cos(rotAngle); | |
512 | sinRot = TMath::Sin(rotAngle); | |
513 | ||
514 | // vector of track global coordinates | |
515 | TMatrixD ri(3,1); | |
516 | ri(0,0) = t->GetX()*cosRot-t->GetY()*sinRot; | |
517 | ri(1,0) = t->GetX()*sinRot+t->GetY()*cosRot; | |
518 | ri(2,0) = t->GetZ(); | |
519 | ||
520 | // matrix to go from global (x,y,z) to local (y,z); | |
521 | TMatrixD Qi(2,3); | |
522 | Qi(0,0) = -sinRot; | |
523 | Qi(0,1) = cosRot; | |
524 | Qi(0,2) = 0.; | |
525 | Qi(1,0) = 0.; | |
526 | Qi(1,1) = 0.; | |
527 | Qi(1,2) = 1.; | |
528 | ||
529 | // covariance matrix of local (y,z) - inverted | |
530 | TMatrixD Ui(2,2); | |
531 | t->GetExternalCovariance(cc); | |
532 | Ui(0,0) = cc[0]; | |
533 | Ui(0,1) = cc[1]; | |
534 | Ui(1,0) = cc[1]; | |
535 | Ui(1,1) = cc[2]; | |
536 | ||
537 | // weights matrix: Wi = QiT * UiInv * Qi | |
538 | if(Ui.Determinant() <= 0.) continue; | |
539 | TMatrixD UiInv(TMatrixD::kInverted,Ui); | |
540 | TMatrixD UiInvQi(UiInv,TMatrixD::kMult,Qi); | |
541 | TMatrixD Wi(Qi,TMatrixD::kTransposeMult,UiInvQi); | |
542 | ||
543 | // track chi2 | |
544 | TMatrixD deltar = rv; deltar -= ri; | |
545 | TMatrixD Wideltar(Wi,TMatrixD::kMult,deltar); | |
546 | chi2i = deltar(0,0)*Wideltar(0,0)+ | |
547 | deltar(1,0)*Wideltar(1,0)+ | |
548 | deltar(2,0)*Wideltar(2,0); | |
549 | ||
550 | ||
551 | if(step==1 && chi2i > fMaxChi2PerTrack) { | |
552 | skipTrack[k] = 1; | |
553 | continue; | |
554 | } | |
555 | ||
556 | // add to total chi2 | |
557 | chi2 += chi2i; | |
558 | ||
559 | TMatrixD Wiri(Wi,TMatrixD::kMult,ri); | |
560 | ||
561 | SumWiri += Wiri; | |
562 | SumWi += Wi; | |
563 | ||
564 | nUsedTrks++; | |
565 | } // end loop on tracks | |
566 | ||
567 | if(nUsedTrks < fMinTracks) { | |
568 | failed=1; | |
569 | continue; | |
570 | } | |
571 | ||
572 | Double_t determinant = SumWi.Determinant(); | |
573 | //cerr<<" determinant: "<<determinant<<endl; | |
574 | if(determinant < 100.) { | |
575 | printf("det(V) = 0\n"); | |
576 | failed=1; | |
577 | continue; | |
578 | } | |
579 | ||
580 | // inverted of weights matrix | |
581 | TMatrixD InvSumWi(TMatrixD::kInverted,SumWi); | |
582 | V = InvSumWi; | |
583 | ||
584 | // position of primary vertex | |
585 | rv.Mult(V,SumWiri); | |
586 | ||
587 | } // end loop on the 3 steps | |
588 | ||
589 | delete [] skipTrack; | |
590 | delete t; | |
591 | ||
592 | if(failed) { | |
593 | TooFewTracks(); | |
594 | return; | |
595 | } | |
596 | ||
597 | Double_t position[3]; | |
598 | position[0] = rv(0,0); | |
599 | position[1] = rv(1,0); | |
600 | position[2] = rv(2,0); | |
601 | Double_t covmatrix[6]; | |
602 | covmatrix[0] = V(0,0); | |
603 | covmatrix[1] = V(0,1); | |
604 | covmatrix[2] = V(1,1); | |
605 | covmatrix[3] = V(0,2); | |
606 | covmatrix[4] = V(1,2); | |
607 | covmatrix[5] = V(2,2); | |
608 | ||
609 | // store data in the vertex object | |
610 | fCurrentVertex = new AliITSVertex(fPhiThrust,position,covmatrix,chi2,nUsedTrks); | |
611 | ||
612 | if(fDebug) { | |
613 | printf(" VertexFitter(): finish\n"); | |
614 | printf(" rv = ( %f , %f , %f )\n\n",rv(0,0),rv(1,0),rv(2,0)); | |
615 | fCurrentVertex->PrintStatus(); | |
616 | } | |
617 | ||
618 | return; | |
619 | } | |
620 | //---------------------------------------------------------------------------- | |
621 | AliITSVertex *AliITSVertexerTracks::VertexOnTheFly(TTree &trkTree) { | |
622 | // | |
623 | // Return vertex from tracks in trkTree | |
624 | // | |
625 | if(fCurrentVertex) fCurrentVertex = 0; | |
626 | ||
627 | // get tracks and propagate them to initial vertex position | |
628 | Int_t nTrks = PrepareTracks(*(&trkTree)); | |
629 | if(fDebug) printf(" tracks prepared: %d\n",nTrks); | |
630 | if(nTrks < fMinTracks) { TooFewTracks(); return fCurrentVertex; } | |
631 | ||
632 | // VERTEX FINDER | |
633 | VertexFinder(); | |
634 | ||
635 | // VERTEX FITTER | |
636 | ComputeMaxChi2PerTrack(nTrks); | |
637 | if(fUseThrustFrame) ThrustFinderXY(); | |
638 | if(fDebug) printf(" thrust found: phi = %f\n",fPhiThrust); | |
639 | VertexFitter(); | |
640 | if(fDebug) printf(" vertex fit completed\n"); | |
641 | ||
642 | return fCurrentVertex; | |
643 | } | |
644 | //---------------------------------------------------------------------------- | |
645 | ||
646 | ||
647 |