1 /**************************************************************************
2 * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 //-----------------------------------------------------------------
17 // Implementation of the vertexer from tracks
18 // It accepts V2 and ESD tracks
20 // Origin: A.Dainese, Padova,
21 // andrea.dainese@pd.infn.it
23 // massimo.masera@to.infn.it
24 //-----------------------------------------------------------------
26 //---- standard headers ----
27 #include <Riostream.h>
28 //---- Root headers --------
32 //---- AliRoot headers -----
33 #include "AliESDVertex.h"
34 #include "AliITSVertexerTracks.h"
36 #include "AliESDtrack.h"
37 #include "AliVertexerTracks.h"
40 ClassImp(AliITSVertexerTracks)
43 //----------------------------------------------------------------------------
44 AliITSVertexerTracks::AliITSVertexerTracks():AliITSVertexer() {
46 // Default constructor
56 //----------------------------------------------------------------------------
57 AliITSVertexerTracks::AliITSVertexerTracks(TFile *inFile,TFile *outFile,
59 Double_t xStart,Double_t yStart) {
61 // Standard constructor
68 SetVtxStart(xStart,yStart);
74 //----------------------------------------------------------------------------
75 AliITSVertexerTracks::AliITSVertexerTracks(TString fn,
76 Double_t xStart,Double_t yStart)
79 // Alternative constructor
83 SetVtxStart(xStart,yStart);
88 //______________________________________________________________________
89 AliITSVertexerTracks::AliITSVertexerTracks(const AliITSVertexerTracks &vtxr) : AliITSVertexer(vtxr) {
91 // Copies are not allowed. The method is protected to avoid misuse.
92 Error("AliITSVertexerTracks","Copy constructor not allowed\n");
95 //______________________________________________________________________
96 AliITSVertexerTracks& AliITSVertexerTracks::operator=(const AliITSVertexerTracks& /* vtxr */){
97 // Assignment operator
98 // Assignment is not allowed. The method is protected to avoid misuse.
99 Error("= operator","Assignment operator not allowed\n");
103 //-----------------------------------------------------------------------------
104 AliITSVertexerTracks::~AliITSVertexerTracks() {
105 // Default Destructor
106 // The objects poited by the following pointers are not owned
107 // by this class and are not deleted
113 //-----------------------------------------------------------------------------
114 Bool_t AliITSVertexerTracks::CheckField() const {
116 // Check if the conv. const. has been set
118 Double_t field = AliTracker::GetBz(); // in kG
120 if(field<1 || field>6) {
121 printf("AliITSVertexerTracks::CheckField():\n ERROR: AliKalmanTrack::fConvConst not set\n Use AliKalmanTrack::SetConvConst() or AliITSVertexerTracks::SetField()\n");
124 printf("AliITSVertexerTracks::CheckField(): Using B = %3.1f T\n",field);
127 //---------------------------------------------------------------------------
128 void AliITSVertexerTracks::ComputeMaxChi2PerTrack(Int_t nTracks) {
130 // Max. contr. to the chi2 has been tuned as a function of multiplicity
132 if(nTracks < 7) { fMaxChi2PerTrack = 1.e6;
133 } else { fMaxChi2PerTrack = 100.; }
137 //---------------------------------------------------------------------------
138 void AliITSVertexerTracks::FindVertices() {
140 // Vertices for all events from fFirstEvent to fLastEvent
143 // Check if the conv. const. has been set
144 if(!CheckField()) return;
146 TDirectory *curdir = 0;
149 for(Int_t ev=fFirstEvent; ev<=fLastEvent; ev++) {
150 if(ev % 100 == 0 || fDebug) printf("--- Processing event %d of %d ---\n",ev,fLastEvent);
152 FindPrimaryVertexForCurrentEvent(ev);
154 if(!fCurrentVertex) {
155 printf("AliITSVertexerTracks::FindVertices(): no tracks tree for event %d\n",ev);
159 if(fDebug) fCurrentVertex->PrintStatus();
161 // write vertex to file
162 TString vtxName = "Vertex_";
164 fCurrentVertex->SetName(vtxName.Data());
165 fCurrentVertex->SetTitle("VertexerTracks");
166 //WriteCurrentVertex();
169 fCurrentVertex->Write();
172 } // loop over events
176 //---------------------------------------------------------------------------
177 void AliITSVertexerTracks::FindVerticesESD() {
179 // Vertices for all events from fFirstEvent to fLastEvent
182 // Check if the conv. const. has been set
183 if(!CheckField()) return;
185 TDirectory *curdir = 0;
188 TTree *esdTree = (TTree*)fInFile->Get("esdTree");
190 printf("AliITSVertexerTracks::FindVerticesESD(): no tree in file!\n");
193 Int_t nev = (Int_t)esdTree->GetEntries();
195 // loop on events in tree
196 for(Int_t i=0; i<nev; i++) {
197 AliESD *esdEvent = new AliESD;
198 esdTree->SetBranchAddress("ESD",&esdEvent);
199 if(!esdTree->GetEvent(i)) {
200 printf("AliITSVertexerTracks::FindVerticesESD(): not an ESD!\n");
204 ev = (Int_t)esdEvent->GetEventNumber();
205 if(ev<fFirstEvent || ev>fLastEvent) { delete esdEvent; continue; }
206 if(ev % 100 == 0 || fDebug)
207 printf("--- Processing event %d of %d ---\n",ev,fLastEvent-fFirstEvent);
209 FindPrimaryVertexForCurrentEvent(esdEvent);
211 if(!fCurrentVertex) {
212 printf("AliITSVertexerTracks::FindVertixesESD():\n no vertex for event %d\n",ev);
216 if(fDebug) fCurrentVertex->PrintStatus();
218 // write vertex to file
219 TString vtxName = "Vertex_";
221 fCurrentVertex->SetName(vtxName.Data());
222 fCurrentVertex->SetTitle("VertexerTracks");
223 //WriteCurrentVertex();
226 fCurrentVertex->Write();
231 } // end loop over events
235 //----------------------------------------------------------------------------
236 Int_t AliITSVertexerTracks::PrepareTracks(TTree &trkTree) {
238 // Propagate tracks to initial vertex position and store them in a TObjArray
240 Double_t maxd0rphi = 3.;
241 Double_t alpha,xlStart,d0rphi;
244 Int_t nEntries = (Int_t)trkTree.GetEntries();
246 Double_t field=AliTracker::GetBz();
248 if(!fTrkArray.IsEmpty()) fTrkArray.Clear();
249 fTrkArray.Expand(nEntries);
252 printf(" PrepareTracks()\n");
256 for(Int_t i=0; i<nEntries; i++) {
257 // check tracks to skip
259 for(Int_t j=0; j<fNTrksToSkip; j++) {
260 if(i==fTrksToSkip[j]) {
261 if(fDebug) printf("skipping track: %d\n",i);
265 if(skipThis) continue;
267 AliESDtrack *track = new AliESDtrack;
268 trkTree.SetBranchAddress("tracks",&track);
271 // propagate track to vtxSeed
272 alpha = track->GetAlpha();
273 xlStart = fNominalPos[0]*TMath::Cos(alpha)+fNominalPos[1]*TMath::Sin(alpha);
274 track->PropagateTo(xlStart,field); // to vtxSeed
276 // select tracks with d0rphi < maxd0rphi
278 d0rphi = TMath::Abs(track->GetD(fNominalPos[0],fNominalPos[1],field));
279 if(d0rphi > maxd0rphi) { delete track; continue; }
282 fTrkArray.AddLast(track);
285 if(fDebug)cout<<" :-) nTrks, d0rphi "<<nTrks<<" "<<d0rphi<<endl;
288 if(fTrksToSkip) delete [] fTrksToSkip;
292 //----------------------------------------------------------------------------
293 void AliITSVertexerTracks::PrintStatus() const {
296 // printf(" Initial position (%f,%f)\n",fNominalPos[0],fNominalPos[1]);
297 printf(" Number of tracks in array: %d\n",(Int_t)fTrkArray.GetEntriesFast());
298 printf(" Minimum # tracks required in fit: %d\n",fMinTracks);
302 //----------------------------------------------------------------------------
303 AliVertex* AliITSVertexerTracks::VertexForSelectedTracks(AliESD *esdEvent,Int_t nofCand, Int_t *trkPos, Int_t opt){
306 // Computes the vertex for selected tracks
307 // trkPos=vector with track positions in ESD
310 esdEvent->GetVertex()->GetXYZ(vtx);
311 TTree *trkTree = new TTree("TreeT","tracks");
312 AliESDtrack *esdTrack = 0;
313 trkTree->Branch("tracks","AliESDtrack",&esdTrack);
314 for(Int_t i=0; i<nofCand;i++){
315 esdTrack = (AliESDtrack*)esdEvent->GetTrack(trkPos[i]);
317 if(!esdTrack->GetStatus()&AliESDtrack::kTPCin) continue;
318 if(!esdTrack->GetStatus()&AliESDtrack::kITSin) continue;
319 if(!esdTrack->GetStatus()&AliESDtrack::kITSrefit) continue;
321 Int_t nclus=esdTrack->GetNcls(0); // check number of clusters in ITS
322 if(nclus<6) continue;
326 Int_t nTrks = PrepareTracks(*trkTree);
327 //delete trkTree;// :-))
328 if(fDebug) printf(" tracks prepared: %d\n",nTrks);
329 if(nTrks < fMinTracks) {
330 printf("TooFewTracks\n");
331 AliVertex *theVert=new AliVertex();
332 theVert->SetDispersion(999);
333 theVert->SetNContributors(-5);
337 AliVertexerTracks *vertexer=new AliVertexerTracks(vtx[0],vtx[1]);
338 vertexer->SetFinderAlgorithm(opt);
339 AliVertex *theVert=(AliVertex*)vertexer->VertexForSelectedTracks(&fTrkArray);
340 // beware: newvt object should be deleted by the caller
341 AliVertex *newvt = new AliVertex(*theVert);
345 //----------------------------------------------------------------------------
346 AliESDVertex* AliITSVertexerTracks::FindPrimaryVertexForCurrentEvent(Int_t evnumb) {
348 // Vertex for current event
352 // get tree with tracks from input file
354 TTree *esdTree = (TTree*)fInFile->Get("esdTree");
357 printf("AliITSVertexerTracks::FindPrimaryVertexForCurrentEvent(): no tree in file!\n");
358 return fCurrentVertex;
360 AliESD *esdEvent = new AliESD;
361 esdTree->SetBranchAddress("ESD",&esdEvent);
362 esdTree->GetEvent(evnumb);
363 return FindPrimaryVertexForCurrentEvent(esdEvent);
365 //----------------------------------------------------------------------------
366 AliESDVertex* AliITSVertexerTracks::FindPrimaryVertexForCurrentEvent(AliESD *esdEvent)
369 // Vertex for current ESD event
372 Double_t vtx[3],cvtx[6];
374 Int_t entr = (Int_t)esdEvent->GetNumberOfTracks();
375 TTree *trkTree = new TTree("TreeT","tracks");
376 AliESDtrack *esdTrack = 0;
377 trkTree->Branch("tracks","AliESDtrack",&esdTrack);
379 for(Int_t i=0; i<entr; i++) {
380 AliESDtrack *et = esdEvent->GetTrack(i);
381 esdTrack = new AliESDtrack(*et);
382 if(!esdTrack->GetStatus()&AliESDtrack::kITSin) continue;
383 if(!esdTrack->GetStatus()&AliESDtrack::kITSrefit) continue;
384 Int_t nclus=esdTrack->GetNcls(0); // check number of clusters in ITS
385 if(nclus<5) continue;
391 // preselect tracks and propagate them to initial vertex position
392 Int_t nTrks = PrepareTracks(*trkTree);
394 if(fDebug) printf(" tracks prepared: %d\n",nTrks);
395 if(nTrks < fMinTracks) { TooFewTracks(); return fCurrentVertex; }
397 // Set initial vertex position from ESD
398 esdEvent->GetVertex()->GetXYZ(vtx);
399 SetVtxStart(vtx[0],vtx[1]);
402 ComputeMaxChi2PerTrack(nTrks);
404 if(fDebug) printf(" vertex fit completed\n");
406 // store vertex information in ESD
407 fCurrentVertex->GetXYZ(vtx);
408 fCurrentVertex->GetCovMatrix(cvtx);
411 esdEvent->GetVertex()->GetTruePos(tp);
412 fCurrentVertex->SetTruePos(tp);
414 return fCurrentVertex;
416 //---------------------------------------------------------------------------
417 void AliITSVertexerTracks::SetSkipTracks(Int_t n,Int_t *skipped) {
419 // Mark the tracks not ot be used in the vertex finding
422 fTrksToSkip = new Int_t[n];
423 for(Int_t i=0;i<n;i++) fTrksToSkip[i] = skipped[i];
426 //---------------------------------------------------------------------------
427 void AliITSVertexerTracks::TooFewTracks() {
429 // When the number of tracks is < fMinTracks the vertex is set to (0,0,0)
430 // and the number of tracks to -1
432 fCurrentVertex = new AliESDVertex(0.,0.,-1);
435 //---------------------------------------------------------------------------
436 void AliITSVertexerTracks::VertexFitter() {
438 // The optimal estimate of the vertex position is given by a "weighted
439 // average of tracks positions"
440 // Original method: CMS Note 97/0051
443 printf(" VertexFitter(): start\n");
446 AliVertexerTracks *vertexer=new AliVertexerTracks(fNominalPos[0],fNominalPos[1]);
447 vertexer->SetFinderAlgorithm(1);
448 AliVertex *thevert=(AliVertex*)vertexer->VertexForSelectedTracks(&fTrkArray);
450 thevert->GetXYZ(initPos);
451 // cout<<"Finder: "<<initPos[0]<<"; "<<initPos[1]<<"; "<<initPos[2]<<endl;
458 rv(0,0) = initPos[0];
459 rv(1,0) = initPos[1];
461 Double_t xlStart,alpha;
463 Double_t cosRot,sinRot;
467 Int_t arrEntries = (Int_t)fTrkArray.GetEntries();
471 Int_t *skipTrack = new Int_t[arrEntries];
472 for(i=0; i<arrEntries; i++) skipTrack[i]=0;
475 // 1st - first estimate of vtx using all tracks
476 // 2nd - apply cut on chi2 max per track
477 // 3rd - estimate of global chi2
478 for(step=0; step<3; step++) {
479 if(fDebug) printf(" step = %d\n",step);
483 TMatrixD sumWiri(3,1);
487 for(j=0; j<3; j++) sumWi(j,i) = 0.;
491 for(k=0; k<arrEntries; k++) {
492 if(skipTrack[k]) continue;
493 // get track from track array
494 t = (AliESDtrack*)fTrkArray.At(k);
495 alpha = t->GetAlpha();
496 xlStart = initPos[0]*TMath::Cos(alpha)+initPos[1]*TMath::Sin(alpha);
497 t->PropagateTo(xlStart,AliTracker::GetBz()); // to vtxSeed
499 if(alpha<0.) rotAngle += 2.*TMath::Pi();
500 cosRot = TMath::Cos(rotAngle);
501 sinRot = TMath::Sin(rotAngle);
503 // vector of track global coordinates
505 ri(0,0) = t->GetX()*cosRot-t->GetY()*sinRot;
506 ri(1,0) = t->GetX()*sinRot+t->GetY()*cosRot;
509 // matrix to go from global (x,y,z) to local (y,z);
518 // covariance matrix of local (y,z) - inverted
520 t->GetExternalCovariance(cc);
526 // weights matrix: wWi = qQiT * uUiInv * qQi
527 if(uUi.Determinant() <= 0.) continue;
528 TMatrixD uUiInv(TMatrixD::kInverted,uUi);
529 TMatrixD uUiInvQi(uUiInv,TMatrixD::kMult,qQi);
530 TMatrixD wWi(qQi,TMatrixD::kTransposeMult,uUiInvQi);
533 TMatrixD deltar = rv; deltar -= ri;
534 TMatrixD wWideltar(wWi,TMatrixD::kMult,deltar);
535 chi2i = deltar(0,0)*wWideltar(0,0)+
536 deltar(1,0)*wWideltar(1,0)+
537 deltar(2,0)*wWideltar(2,0);
540 if(step==1 && chi2i > fMaxChi2PerTrack) {
548 TMatrixD wWiri(wWi,TMatrixD::kMult,ri);
554 } // end loop on tracks
556 if(nUsedTrks < fMinTracks) {
561 Double_t determinant = sumWi.Determinant();
562 //cerr<<" determinant: "<<determinant<<endl;
563 if(determinant < 100.) {
564 printf("det(V) = 0\n");
569 // inverted of weights matrix
570 TMatrixD invsumWi(TMatrixD::kInverted,sumWi);
573 // position of primary vertex
576 } // end loop on the 3 steps
586 Double_t position[3];
587 position[0] = rv(0,0);
588 position[1] = rv(1,0);
589 position[2] = rv(2,0);
590 Double_t covmatrix[6];
591 covmatrix[0] = vV(0,0);
592 covmatrix[1] = vV(0,1);
593 covmatrix[2] = vV(1,1);
594 covmatrix[3] = vV(0,2);
595 covmatrix[4] = vV(1,2);
596 covmatrix[5] = vV(2,2);
598 // store data in the vertex object
599 fCurrentVertex = new AliESDVertex(position,covmatrix,chi2,nUsedTrks);
602 printf(" VertexFitter(): finish\n");
603 printf(" rv = ( %f , %f , %f )\n\n",rv(0,0),rv(1,0),rv(2,0));
604 fCurrentVertex->PrintStatus();
609 //----------------------------------------------------------------------------
610 AliESDVertex *AliITSVertexerTracks::VertexOnTheFly(TTree &trkTree) {
612 // Return vertex from tracks in trkTree
614 if(fCurrentVertex) fCurrentVertex = 0;
616 // get tracks and propagate them to initial vertex position
617 Int_t nTrks = PrepareTracks(*(&trkTree));
618 if(fDebug) printf(" tracks prepared: %d\n",nTrks);
619 if(nTrks < fMinTracks) { TooFewTracks(); return fCurrentVertex; }
622 ComputeMaxChi2PerTrack(nTrks);
624 if(fDebug) printf(" vertex fit completed\n");
626 return fCurrentVertex;
628 //----------------------------------------------------------------------------