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 --------
33 //---- AliRoot headers -----
34 #include "AliITSStrLine.h"
35 #include "AliITStrackV2.h"
36 #include "AliESDVertex.h"
37 #include "AliITSVertexerTracks.h"
39 #include "AliESDtrack.h"
42 ClassImp(AliITSVertexerTracks)
45 //----------------------------------------------------------------------------
46 AliITSVertexerTracks::AliITSVertexerTracks():AliITSVertexer() {
48 // Default constructor
58 //----------------------------------------------------------------------------
59 AliITSVertexerTracks::AliITSVertexerTracks(TFile *inFile,TFile *outFile,
61 Double_t xStart,Double_t yStart) {
63 // Standard constructor
70 SetVtxStart(xStart,yStart);
77 //----------------------------------------------------------------------------
78 AliITSVertexerTracks::AliITSVertexerTracks(TString fn,
79 Double_t xStart,Double_t yStart)
82 // Alternative constructor
86 SetVtxStart(xStart,yStart);
92 //______________________________________________________________________
93 AliITSVertexerTracks::AliITSVertexerTracks(const AliITSVertexerTracks &vtxr) : AliITSVertexer(vtxr) {
95 // Copies are not allowed. The method is protected to avoid misuse.
96 Error("AliITSVertexerTracks","Copy constructor not allowed\n");
99 //______________________________________________________________________
100 AliITSVertexerTracks& AliITSVertexerTracks::operator=(const AliITSVertexerTracks& /* vtxr */){
101 // Assignment operator
102 // Assignment is not allowed. The method is protected to avoid misuse.
103 Error("= operator","Assignment operator not allowed\n");
107 //-----------------------------------------------------------------------------
108 AliITSVertexerTracks::~AliITSVertexerTracks() {
109 // Default Destructor
110 // The objects poited by the following pointers are not owned
111 // by this class and are not deleted
117 //-----------------------------------------------------------------------------
118 Bool_t AliITSVertexerTracks::CheckField() const {
120 // Check if the conv. const. has been set
123 Double_t cc = t.GetConvConst();
124 Double_t field = 100./0.299792458/cc;
126 if(field<0.1 || field>0.6) {
127 printf("AliITSVertexerTracks::CheckField():\n ERROR: AliKalmanTrack::fConvConst not set\n Use AliKalmanTrack::SetConvConst() or AliITSVertexerTracks::SetField()\n");
130 printf("AliITSVertexerTracks::CheckField(): Using B = %3.1f T\n",field);
133 //---------------------------------------------------------------------------
134 void AliITSVertexerTracks::ComputeMaxChi2PerTrack(Int_t nTracks) {
136 // Max. contr. to the chi2 has been tuned as a function of multiplicity
138 if(nTracks < 7) { fMaxChi2PerTrack = 1.e6;
139 } else { fMaxChi2PerTrack = 100.; }
143 //---------------------------------------------------------------------------
144 void AliITSVertexerTracks::FindVertices() {
146 // Vertices for all events from fFirstEvent to fLastEvent
149 // Check if the conv. const. has been set
150 if(!CheckField()) return;
152 TDirectory *curdir = 0;
155 for(Int_t ev=fFirstEvent; ev<=fLastEvent; ev++) {
156 if(ev % 100 == 0 || fDebug) printf("--- Processing event %d of %d ---\n",ev,fLastEvent);
158 FindPrimaryVertexForCurrentEvent(ev);
160 if(!fCurrentVertex) {
161 printf("AliITSVertexerTracks::FindVertixes(): no tracks tree for event %d\n",ev);
165 if(fDebug) fCurrentVertex->PrintStatus();
167 // write vertex to file
168 TString vtxName = "Vertex_";
170 fCurrentVertex->SetName(vtxName.Data());
171 fCurrentVertex->SetTitle("VertexerTracks");
172 //WriteCurrentVertex();
175 fCurrentVertex->Write();
178 } // loop over events
182 //---------------------------------------------------------------------------
183 void AliITSVertexerTracks::FindVerticesESD() {
185 // Vertices for all events from fFirstEvent to fLastEvent
188 // Check if the conv. const. has been set
189 if(!CheckField()) return;
191 TDirectory *curdir = 0;
194 TTree *esdTree = (TTree*)fInFile->Get("esdTree");
196 printf("AliITSVertexerTracks::FindVerticesESD(): no tree in file!\n");
199 Int_t nev = (Int_t)esdTree->GetEntries();
201 // loop on events in tree
202 for(Int_t i=0; i<nev; i++) {
203 AliESD *esdEvent = new AliESD;
204 esdTree->SetBranchAddress("ESD",&esdEvent);
205 if(!esdTree->GetEvent(i)) {
206 printf("AliITSVertexerTracks::FindVerticesESD(): not an ESD!\n");
210 ev = (Int_t)esdEvent->GetEventNumber();
211 if(ev<fFirstEvent || ev>fLastEvent) { delete esdEvent; continue; }
212 if(ev % 100 == 0 || fDebug)
213 printf("--- Processing event %d of %d ---\n",ev,fLastEvent-fFirstEvent);
215 FindPrimaryVertexForCurrentEvent(esdEvent);
217 if(!fCurrentVertex) {
218 printf("AliITSVertexerTracks::FindVertixesESD():\n no vertex for event %d\n",ev);
222 if(fDebug) fCurrentVertex->PrintStatus();
224 // write vertex to file
225 TString vtxName = "Vertex_";
227 fCurrentVertex->SetName(vtxName.Data());
228 fCurrentVertex->SetTitle("VertexerTracks");
229 //WriteCurrentVertex();
232 fCurrentVertex->Write();
237 } // end loop over events
241 //----------------------------------------------------------------------------
242 Int_t AliITSVertexerTracks::PrepareTracks(TTree &trkTree) {
244 // Propagate tracks to initial vertex position and store them in a TObjArray
246 Double_t maxd0rphi = 3.;
250 Int_t nEntries = (Int_t)trkTree.GetEntries();
252 if(!fTrkArray.IsEmpty()) fTrkArray.Clear();
253 fTrkArray.Expand(nEntries);
256 printf(" PrepareTracks()\n");
259 cout<<" entr tree its tracks = "<<nEntries<<endl;
260 for(Int_t i=0; i<nEntries; i++) {
261 // check tracks to skip
263 for(Int_t j=0; j<fNTrksToSkip; j++) {
264 if(i==fTrksToSkip[j]) {
265 if(fDebug) printf("skipping track: %d\n",i);
269 if(skipThis) continue;
271 AliITStrackV2 *itstrack = new AliITStrackV2;
272 trkTree.SetBranchAddress("tracks",&itstrack);
274 d0rphi=Prepare(itstrack);
275 if(d0rphi> maxd0rphi) { if(fDebug)cout<<" !!!! d0rphi "<<d0rphi<<endl;continue; }
276 fTrkArray.AddLast(itstrack);
279 if(fDebug)cout<<" :-) nTrks, d0rphi "<<nTrks<<" "<<d0rphi<<endl;
282 if(fTrksToSkip) delete [] fTrksToSkip;
286 //----------------------------------------------------------------------------
287 Int_t AliITSVertexerTracks::PrepareTracks(AliESD* esdEvent,Int_t nofCand, Int_t *trkPos) {
289 // Propagate tracks to initial vertex position and store them in a TObjArray
292 Double_t maxd0rphi = 3.;
295 if(!fTrkArray.IsEmpty()) fTrkArray.Clear();
296 fTrkArray.Expand(100);
299 printf(" PrepareTracks()\n");
301 AliITStrackV2* itstrack;
303 for(Int_t i=0; i<nofCand;i++){
304 AliESDtrack *esdTrack = (AliESDtrack*)esdEvent->GetTrack(trkPos[i]);
305 UInt_t status=esdTrack->GetStatus();
306 if ((status&AliESDtrack::kTPCin)==0)continue;
307 if ((status&AliESDtrack::kITSin)==0)continue;
308 if ((status&AliESDtrack::kITSrefit)==0) continue;
310 itstrack = new AliITStrackV2(*esdTrack);
311 d0rphi=Prepare(itstrack);
312 if(d0rphi> maxd0rphi) { if(fDebug)cout<<" !!!! d0rphi "<<d0rphi<<endl;continue; }
313 Int_t nclus=itstrack->GetNumberOfClusters();
315 if(nclus<6){delete itstrack;continue;}
316 fTrkArray.AddLast(itstrack);
319 if(fDebug)cout<<" :-) nTrks, d0rphi "<<nTrks<<" "<<d0rphi<<endl;
324 if(fTrksToSkip) delete [] fTrksToSkip;
327 //----------------------------------------------------------------------------
328 Double_t AliITSVertexerTracks::Prepare(AliITStrackV2* itstrack){
331 Double_t alpha,xlStart,d0rphi;
332 // propagate track to vtxSeed
333 alpha = itstrack->GetAlpha();
334 xlStart = fNominalPos[0]*TMath::Cos(alpha)+fNominalPos[1]*TMath::Sin(alpha);
335 if(itstrack->GetX()>3.)itstrack->PropagateTo(3.,0.0023,65.19); // to beam pipe (0.8 mm of Be)
336 itstrack->PropagateTo(xlStart,0.,0.);
337 // select tracks with d0rphi < maxd0rphi
338 d0rphi = TMath::Abs(itstrack->GetD(fNominalPos[0],fNominalPos[1]));
342 //----------------------------------------------------------------------------
343 void AliITSVertexerTracks::PrintStatus() const {
347 printf(" Initial position (%f,%f)\n",fNominalPos[0],fNominalPos[1]);
348 printf(" Vertex position after vertex finder:\n");
350 printf(" Number of tracks in array: %d\n",(Int_t)fTrkArray.GetEntriesFast());
351 printf(" Minimum # tracks required in fit: %d\n",fMinTracks);
355 //----------------------------------------------------------------------------
356 AliESDVertex* AliITSVertexerTracks::FindPrimaryVertexForCurrentEvent(Int_t evnumb) {
358 // Vertex for current event
362 // get tree with tracks from input file
363 TString treeName = "TreeT_ITS_";
365 TTree *trkTree=(TTree*)fInFile->Get(treeName.Data());
366 if(!trkTree) return fCurrentVertex;
369 // get tracks and propagate them to initial vertex position
370 Int_t nTrks = PrepareTracks(*trkTree);
372 if(fDebug) printf(" tracks prepared: %d\n",nTrks);
373 if(nTrks < fMinTracks) { TooFewTracks(); return fCurrentVertex; }
379 ComputeMaxChi2PerTrack(nTrks);
381 if(fDebug) printf(" vertex fit completed\n");
383 return fCurrentVertex;
385 //----------------------------------------------------------------------------
386 AliESDVertex* AliITSVertexerTracks::FindPrimaryVertexForCurrentEvent(AliESD *esdEvent)
389 // Vertex for current ESD event
392 Double_t vtx[3],cvtx[6];
394 // put tracks reco in ITS in a tree
395 Int_t entr = (Int_t)esdEvent->GetNumberOfTracks();
396 TTree *trkTree = new TTree("TreeT_ITS","its tracks");
397 AliITStrackV2 *itstrack = 0;
398 trkTree->Branch("tracks","AliITStrackV2",&itstrack,entr,0);
400 for(Int_t i=0; i<entr; i++) {
401 AliESDtrack *esdTrack = (AliESDtrack*)esdEvent->GetTrack(i);
402 if(!esdTrack->GetStatus()&AliESDtrack::kITSin)
403 { delete esdTrack; continue; }
405 itstrack = new AliITStrackV2(*esdTrack);
407 catch (const Char_t *msg) {
408 Warning("FindPrimaryVertexForCurrentEvent",msg);
419 // preselect tracks and propagate them to initial vertex position
420 Int_t nTrks = PrepareTracks(*trkTree);
422 if(fDebug) printf(" tracks prepared: %d\n",nTrks);
423 if(nTrks < fMinTracks) { TooFewTracks(); return fCurrentVertex; }
425 // Set initial vertex position from ESD
426 esdEvent->GetVertex()->GetXYZ(vtx);
427 SetVtxStart(vtx[0],vtx[1]);
432 ComputeMaxChi2PerTrack(nTrks);
434 if(fDebug) printf(" vertex fit completed\n");
436 // store vertex information in ESD
437 fCurrentVertex->GetXYZ(vtx);
438 fCurrentVertex->GetCovMatrix(cvtx);
441 esdEvent->GetVertex()->GetTruePos(tp);
442 fCurrentVertex->SetTruePos(tp);
444 esdEvent->SetVertex(fCurrentVertex);
446 cout<<"Vertex: "<<vtx[0]<<", "<<vtx[1]<<", "<<vtx[2]<<endl;
447 return fCurrentVertex;
449 //----------------------------------------------------------------------------
450 AliITSSimpleVertex* AliITSVertexerTracks::VertexForSelectedTracks(AliESD *esdEvent,Int_t nofCand, Int_t *trkPos, Int_t opt){
453 // Computes the vertex for selected tracks
454 // trkPos=vector with track positions in ESD
455 // values of opt -> see AliITSVertexerTracks.h
457 Double_t vtx[3]={0,0,0};
459 Int_t nTrks = PrepareTracks(esdEvent,nofCand, trkPos);
460 //delete trkTree;// :-))
461 if(fDebug) printf(" tracks prepared: %d\n",nTrks);
462 if(nTrks < fMinTracks) {
463 fSimpVert.SetXYZ(vtx);
464 fSimpVert.SetDispersion(999);
465 fSimpVert.SetNContributors(-5);
469 // Set initial vertex position from ESD
470 esdEvent->GetVertex()->GetXYZ(vtx);
471 SetVtxStart(vtx[0],vtx[1]);
472 if(opt==1) StrLinVertexFinderMinDist(1);
473 if(opt==2) StrLinVertexFinderMinDist(0);
474 if(opt==3) HelixVertexFinder();
475 if(opt==4) VertexFinder(1);
476 if(opt==5) VertexFinder(0);
480 //---------------------------------------------------------------------------
481 void AliITSVertexerTracks::SetSkipTracks(Int_t n,Int_t *skipped) {
483 // Mark the tracks not ot be used in the vertex finding
486 fTrksToSkip = new Int_t[n];
487 for(Int_t i=0;i<n;i++) fTrksToSkip[i] = skipped[i];
490 //---------------------------------------------------------------------------
491 void AliITSVertexerTracks::TooFewTracks() {
493 // When the number of tracks is < fMinTracks the vertex is set to (0,0,0)
494 // and the number of tracks to -1
496 fCurrentVertex = new AliESDVertex(0.,0.,-1);
499 //---------------------------------------------------------------------------
500 void AliITSVertexerTracks::VertexFinder(Int_t OptUseWeights) {
502 // Get estimate of vertex position in (x,y) from tracks DCA
503 // Then this estimate is stored to the data member fSimpVert
504 // (previous values are overwritten)
509 for(Int_t i=0;i<2;i++)initPos[i]=fNominalPos[i];
510 Int_t nacc = (Int_t)fTrkArray.GetEntriesFast();
511 Double_t aver[3]={0.,0.,0.};
512 Double_t aversq[3]={0.,0.,0.};
513 Double_t sigmasq[3]={0.,0.,0.};
516 AliITStrackV2 *track1;
517 AliITStrackV2 *track2;
518 Double_t alpha,mindist;
520 for(Int_t i=0; i<nacc; i++){
521 track1 = (AliITStrackV2*)fTrkArray.At(i);
522 alpha=track1->GetAlpha();
523 mindist = TMath::Cos(alpha)*fNominalPos[0]+TMath::Sin(alpha)*fNominalPos[1];
524 AliITSStrLine *line1 = new AliITSStrLine();
525 track1->ApproximateHelixWithLine(mindist,line1);
529 track1->GetExternalParameters(xv,par);
530 cout<<"Track in position "<<i<<" xr= "<<xv<<endl;
531 for(Int_t ii=0;ii<5;ii++)cout<<par[ii]<<" ";
535 for(Int_t j=i+1; j<nacc; j++){
536 track2 = (AliITStrackV2*)fTrkArray.At(j);
537 alpha=track2->GetAlpha();
538 mindist = TMath::Cos(alpha)*fNominalPos[0]+TMath::Sin(alpha)*fNominalPos[1];
539 AliITSStrLine *line2 = new AliITSStrLine();
540 track2->ApproximateHelixWithLine(mindist,line2);
541 Double_t distCA=line2->GetDCA(line1);
542 if(fDCAcut<=0 || (fDCAcut>0&&distCA<fDCAcut)){
543 Double_t pnt1[3],pnt2[3],crosspoint[3];
545 if(OptUseWeights<=0){
546 Int_t retcode = line2->Cross(line1,crosspoint);
548 if(fDebug>10)cout<<" i= "<<i<<", j= "<<j<<endl;
549 if(fDebug>10)cout<<"bad intersection\n";
550 line1->PrintStatus();
551 line2->PrintStatus();
555 for(Int_t jj=0;jj<3;jj++)aver[jj]+=crosspoint[jj];
556 for(Int_t jj=0;jj<3;jj++)aversq[jj]+=(crosspoint[jj]*crosspoint[jj]);
557 if(fDebug>10)cout<<" i= "<<i<<", j= "<<j<<endl;
558 if(fDebug>10)cout<<"\n Cross point: ";
559 if(fDebug>10)cout<<crosspoint[0]<<" "<<crosspoint[1]<<" "<<crosspoint[2]<<endl;
563 Int_t retcode = line1->CrossPoints(line2,pnt1,pnt2);
565 Double_t alpha, cs, sn;
566 alpha=track1->GetAlpha();
567 cs=TMath::Cos(alpha); sn=TMath::Sin(alpha);
568 Double_t sx1=sn*sn*track1->GetSigmaY2(), sy1=cs*cs*track1->GetSigmaY2();
569 alpha=track2->GetAlpha();
570 cs=TMath::Cos(alpha); sn=TMath::Sin(alpha);
571 Double_t sx2=sn*sn*track2->GetSigmaY2(), sy2=cs*cs*track2->GetSigmaY2();
572 Double_t sz1=track1->GetSigmaZ2(), sz2=track2->GetSigmaZ2();
573 Double_t wx1=sx2/(sx1+sx2), wx2=1.- wx1;
574 Double_t wy1=sy2/(sy1+sy2), wy2=1.- wy1;
575 Double_t wz1=sz2/(sz1+sz2), wz2=1.- wz1;
576 crosspoint[0]=wx1*pnt1[0] + wx2*pnt2[0];
577 crosspoint[1]=wy1*pnt1[1] + wy2*pnt2[1];
578 crosspoint[2]=wz1*pnt1[2] + wz2*pnt2[2];
581 for(Int_t jj=0;jj<3;jj++)aver[jj]+=crosspoint[jj];
582 for(Int_t jj=0;jj<3;jj++)aversq[jj]+=(crosspoint[jj]*crosspoint[jj]);
591 for(Int_t jj=0;jj<3;jj++){
592 initPos[jj] = aver[jj]/ncombi;
594 sigmasq[jj]=aversq[jj]-initPos[jj]*initPos[jj];
597 sigma=TMath::Sqrt(TMath::Abs(sigma));
600 Warning("VertexFinder","Finder did not succed");
603 fSimpVert.SetXYZ(initPos);
604 fSimpVert.SetDispersion(sigma);
605 fSimpVert.SetNContributors(ncombi);
607 //---------------------------------------------------------------------------
608 void AliITSVertexerTracks::HelixVertexFinder() {
610 // Get estimate of vertex position in (x,y) from tracks DCA
611 // Then this estimate is stored to the data member fSimpVert
612 // (previous values are overwritten)
617 for(Int_t i=0;i<2;i++)initPos[i]=fNominalPos[i];
619 Int_t nacc = (Int_t)fTrkArray.GetEntriesFast();
621 Double_t aver[3]={0.,0.,0.};
622 Double_t averquad[3]={0.,0.,0.};
623 Double_t sigmaquad[3]={0.,0.,0.};
626 AliITStrackV2 *track1;
627 AliITStrackV2 *track2;
630 Double_t alpha, cs, sn;
631 Double_t crosspoint[3];
632 for(Int_t i=0; i<nacc; i++){
633 track1 = (AliITStrackV2*)fTrkArray.At(i);
636 for(Int_t j=i+1; j<nacc; j++){
637 track2 = (AliITStrackV2*)fTrkArray.At(j);
640 distCA=track2->PropagateToDCA(track1);
642 if(fDCAcut<=0 ||(fDCAcut>0&&distCA<fDCAcut)){
643 track1->GetExternalParameters(x,par);
644 alpha=track1->GetAlpha();
645 cs=TMath::Cos(alpha); sn=TMath::Sin(alpha);
646 Double_t x1=x*cs - par[0]*sn;
647 Double_t y1=x*sn + par[0]*cs;
649 Double_t sx1=sn*sn*track1->GetSigmaY2(), sy1=cs*cs*track1->GetSigmaY2();
651 track2->GetExternalParameters(x,par);
652 alpha=track2->GetAlpha();
653 cs=TMath::Cos(alpha); sn=TMath::Sin(alpha);
654 Double_t x2=x*cs - par[0]*sn;
655 Double_t y2=x*sn + par[0]*cs;
657 Double_t sx2=sn*sn*track2->GetSigmaY2(), sy2=cs*cs*track2->GetSigmaY2();
658 // printf("Track %d pos=(%f,%f,%f) - dca=%f\n",i,x1,y1,z1,distCA);
659 //printf("Track %d pos=(%f,%f,%f)\n",j,x2,y2,z2);
661 Double_t sz1=track1->GetSigmaZ2(), sz2=track2->GetSigmaZ2();
662 Double_t wx1=sx2/(sx1+sx2), wx2=1.- wx1;
663 Double_t wy1=sy2/(sy1+sy2), wy2=1.- wy1;
664 Double_t wz1=sz2/(sz1+sz2), wz2=1.- wz1;
665 crosspoint[0]=wx1*x1 + wx2*x2;
666 crosspoint[1]=wy1*y1 + wy2*y2;
667 crosspoint[2]=wz1*z1 + wz2*z2;
670 for(Int_t jj=0;jj<3;jj++)aver[jj]+=crosspoint[jj];
671 for(Int_t jj=0;jj<3;jj++)averquad[jj]+=(crosspoint[jj]*crosspoint[jj]);
677 for(Int_t jj=0;jj<3;jj++){
678 initPos[jj] = aver[jj]/ncombi;
679 averquad[jj]/=ncombi;
680 sigmaquad[jj]=averquad[jj]-initPos[jj]*initPos[jj];
681 sigma+=sigmaquad[jj];
683 sigma=TMath::Sqrt(TMath::Abs(sigma));
686 Warning("VertexFinder","Finder did not succed");
689 fSimpVert.SetXYZ(initPos);
690 fSimpVert.SetDispersion(sigma);
691 fSimpVert.SetNContributors(ncombi);
693 //---------------------------------------------------------------------------
694 void AliITSVertexerTracks::StrLinVertexFinderMinDist(Int_t OptUseWeights){
696 // Calculate the point at minimum distance to prepared tracks
697 // Then this estimate is stored to the data member fSimpVert
698 // (previous values are overwritten)
703 for(Int_t i=0;i<2;i++)initPos[i]=fNominalPos[i];
704 const Int_t knacc = (Int_t)fTrkArray.GetEntriesFast();
706 AliITStrackV2 *track1;
707 Double_t (*vectP0)[3]=new Double_t [knacc][3];
708 Double_t (*vectP1)[3]=new Double_t [knacc][3];
711 Double_t dsum[3]={0,0,0};
712 for(Int_t i=0;i<3;i++)
713 for(Int_t j=0;j<3;j++)sum[i][j]=0;
714 for(Int_t i=0; i<knacc; i++){
715 track1 = (AliITStrackV2*)fTrkArray.At(i);
716 Double_t alpha=track1->GetAlpha();
717 Double_t mindist = TMath::Cos(alpha)*fNominalPos[0]+TMath::Sin(alpha)*fNominalPos[1];
718 AliITSStrLine *line1 = new AliITSStrLine();
719 track1->ApproximateHelixWithLine(mindist,line1);
721 Double_t p0[3],cd[3];
724 Double_t p1[3]={p0[0]+cd[0],p0[1]+cd[1],p0[2]+cd[2]};
734 if(OptUseWeights==0)GetStrLinDerivMatrix(p0,p1,matr,dknow);
735 if(OptUseWeights==1){
737 sigmasq[0]=track1->GetSigmaY2();
738 sigmasq[1]=track1->GetSigmaY2();
739 sigmasq[2]=track1->GetSigmaZ2();
740 GetStrLinDerivMatrix(p0,p1,sigmasq,matr,dknow);
743 for(Int_t iii=0;iii<3;iii++){
744 dsum[iii]+=dknow[iii];
745 for(Int_t lj=0;lj<3;lj++) sum[iii][lj]+=matr[iii][lj];
751 Double_t det=GetDeterminant3X3(sum);
754 for(Int_t zz=0;zz<3;zz++){
755 for(Int_t ww=0;ww<3;ww++){
756 for(Int_t kk=0;kk<3;kk++) vett[ww][kk]=sum[ww][kk];
758 for(Int_t kk=0;kk<3;kk++) vett[kk][zz]=dsum[kk];
759 initPos[zz]=GetDeterminant3X3(vett)/det;
763 for(Int_t i=0; i<knacc; i++){
764 Double_t p0[3]={0,0,0},p1[3]={0,0,0};
765 for(Int_t ii=0;ii<3;ii++){
766 p0[ii]=vectP0[i][ii];
767 p1[ii]=vectP1[i][ii];
769 sigma+=GetStrLinMinDist(p0,p1,initPos);
772 sigma=TMath::Sqrt(sigma);
774 Warning("VertexFinder","Finder did not succed");
779 fSimpVert.SetXYZ(initPos);
780 fSimpVert.SetDispersion(sigma);
781 fSimpVert.SetNContributors(knacc);
783 //_______________________________________________________________________
784 Double_t AliITSVertexerTracks::GetDeterminant3X3(Double_t matr[][3]){
786 Double_t det=matr[0][0]*matr[1][1]*matr[2][2]-matr[0][0]*matr[1][2]*matr[2][1]-matr[0][1]*matr[1][0]*matr[2][2]+matr[0][1]*matr[1][2]*matr[2][0]+matr[0][2]*matr[1][0]*matr[2][1]-matr[0][2]*matr[1][1]*matr[2][0];
789 //____________________________________________________________________________
790 void AliITSVertexerTracks::GetStrLinDerivMatrix(Double_t *p0,Double_t *p1,Double_t m[][3],Double_t *d){
793 Double_t x12=p0[0]-p1[0];
794 Double_t y12=p0[1]-p1[1];
795 Double_t z12=p0[2]-p1[2];
796 Double_t kk=x12*x12+y12*y12+z12*z12;
797 m[0][0]=2-2/kk*x12*x12;
798 m[0][1]=-2/kk*x12*y12;
799 m[0][2]=-2/kk*x12*z12;
800 m[1][0]=-2/kk*x12*y12;
801 m[1][1]=2-2/kk*y12*y12;
802 m[1][2]=-2/kk*y12*z12;
803 m[2][0]=-2/kk*x12*z12;
805 m[2][2]=2-2/kk*z12*z12;
806 d[0]=2*p0[0]-2/kk*p0[0]*x12*x12-2/kk*p0[2]*x12*z12-2/kk*p0[1]*x12*y12;
807 d[1]=2*p0[1]-2/kk*p0[1]*y12*y12-2/kk*p0[0]*x12*y12-2/kk*p0[2]*z12*y12;
808 d[2]=2*p0[2]-2/kk*p0[2]*z12*z12-2/kk*p0[0]*x12*z12-2/kk*p0[1]*z12*y12;
811 //____________________________________________________________________________
812 void AliITSVertexerTracks::GetStrLinDerivMatrix(Double_t *p0,Double_t *p1,Double_t *sigmasq,Double_t m[][3],Double_t *d){
814 Double_t x12=p1[0]-p0[0];
815 Double_t y12=p1[1]-p0[1];
816 Double_t z12=p1[2]-p0[2];
818 Double_t den= x12*x12*sigmasq[1]*sigmasq[2]+y12*y12*sigmasq[0]*sigmasq[2]+z12*z12*sigmasq[0]*sigmasq[1];
820 Double_t kk= 2*(x12*x12/sigmasq[0]+y12*y12/sigmasq[1]+z12*z12/sigmasq[2]);
823 cc[0]=-x12/sigmasq[0];
824 cc[1]=-y12/sigmasq[1];
825 cc[2]=-z12/sigmasq[2];
827 Double_t ww=(-p0[0]*x12*sigmasq[1]*sigmasq[2]-p0[1]*y12*sigmasq[0]*sigmasq[2]-p0[2]*z12*sigmasq[0]*sigmasq[1])/den;
829 Double_t ss= -p0[0]*cc[0]-p0[1]*cc[1]-p0[2]*cc[2];
832 aa[0]=x12*sigmasq[1]*sigmasq[2]/den;
833 aa[1]=y12*sigmasq[0]*sigmasq[2]/den;
834 aa[2]=z12*sigmasq[0]*sigmasq[1]/den;
836 m[0][0]=aa[0]*(aa[0]*kk+2*cc[0])+2*cc[0]*aa[0]+2/sigmasq[0];
837 m[0][1]=aa[1]*(aa[0]*kk+2*cc[0])+2*cc[1]*aa[0];
838 m[0][2]=aa[2]*(aa[0]*kk+2*cc[0])+2*cc[2]*aa[0];
840 m[1][0]=aa[0]*(aa[1]*kk+2*cc[1])+2*cc[0]*aa[1];
841 m[1][1]=aa[1]*(aa[1]*kk+2*cc[1])+2*cc[1]*aa[1]+2/sigmasq[1];
842 m[1][2]=aa[2]*(aa[1]*kk+2*cc[1])+2*cc[2]*aa[1];
844 m[2][0]=aa[0]*(aa[2]*kk+2*cc[2])+2*cc[0]*aa[2];
845 m[2][1]=aa[1]*(aa[2]*kk+2*cc[2])+2*cc[1]*aa[2];
846 m[2][2]=aa[2]*(aa[2]*kk+2*cc[2])+2*cc[2]*aa[2]+2/sigmasq[2];
848 d[0]=-ww*(aa[0]*kk+2*cc[0])-2*ss*aa[0]+2*p0[0]/sigmasq[0];
849 d[1]=-ww*(aa[1]*kk+2*cc[1])-2*ss*aa[1]+2*p0[1]/sigmasq[1];
850 d[2]=-ww*(aa[2]*kk+2*cc[2])-2*ss*aa[2]+2*p0[2]/sigmasq[2];
853 //_____________________________________________________________________________
854 Double_t AliITSVertexerTracks::GetStrLinMinDist(Double_t *p0,Double_t *p1,Double_t *x0){
856 Double_t x12=p0[0]-p1[0];
857 Double_t y12=p0[1]-p1[1];
858 Double_t z12=p0[2]-p1[2];
859 Double_t x10=p0[0]-x0[0];
860 Double_t y10=p0[1]-x0[1];
861 Double_t z10=p0[2]-x0[2];
862 return ((x10*x10+y10*y10+z10*z10)*(x12*x12+y12*y12+z12*z12)-(x10*x12+y10*y12+z10*z12)*(x10*x12+y10*y12+z10*z12))/(x12*x12+y12*y12+z12*z12);
865 //---------------------------------------------------------------------------
866 void AliITSVertexerTracks::VertexFitter() {
868 // The optimal estimate of the vertex position is given by a "weighted
869 // average of tracks positions"
870 // Original method: CMS Note 97/0051
873 printf(" VertexFitter(): start\n");
882 fSimpVert.GetXYZ(initPos);
883 rv(0,0) = initPos[0];
884 rv(1,0) = initPos[1];
886 Double_t xlStart,alpha;
888 Double_t cosRot,sinRot;
892 Int_t arrEntries = (Int_t)fTrkArray.GetEntries();
893 AliITStrackV2 *t = 0;
896 Int_t *skipTrack = new Int_t[arrEntries];
897 for(i=0; i<arrEntries; i++) skipTrack[i]=0;
900 // 1st - first estimate of vtx using all tracks
901 // 2nd - apply cut on chi2 max per track
902 // 3rd - estimate of global chi2
903 for(step=0; step<3; step++) {
904 if(fDebug) printf(" step = %d\n",step);
908 TMatrixD sumWiri(3,1);
912 for(j=0; j<3; j++) sumWi(j,i) = 0.;
916 for(k=0; k<arrEntries; k++) {
917 if(skipTrack[k]) continue;
918 // get track from track array
919 t = (AliITStrackV2*)fTrkArray.At(k);
920 alpha = t->GetAlpha();
921 xlStart = initPos[0]*TMath::Cos(alpha)+initPos[1]*TMath::Sin(alpha);
922 t->PropagateTo(xlStart,0.,0.); // to vtxSeed
924 if(alpha<0.) rotAngle += 2.*TMath::Pi();
925 cosRot = TMath::Cos(rotAngle);
926 sinRot = TMath::Sin(rotAngle);
928 // vector of track global coordinates
930 ri(0,0) = t->GetX()*cosRot-t->GetY()*sinRot;
931 ri(1,0) = t->GetX()*sinRot+t->GetY()*cosRot;
934 // matrix to go from global (x,y,z) to local (y,z);
943 // covariance matrix of local (y,z) - inverted
945 t->GetExternalCovariance(cc);
951 // weights matrix: wWi = qQiT * uUiInv * qQi
952 if(uUi.Determinant() <= 0.) continue;
953 TMatrixD uUiInv(TMatrixD::kInverted,uUi);
954 TMatrixD uUiInvQi(uUiInv,TMatrixD::kMult,qQi);
955 TMatrixD wWi(qQi,TMatrixD::kTransposeMult,uUiInvQi);
958 TMatrixD deltar = rv; deltar -= ri;
959 TMatrixD wWideltar(wWi,TMatrixD::kMult,deltar);
960 chi2i = deltar(0,0)*wWideltar(0,0)+
961 deltar(1,0)*wWideltar(1,0)+
962 deltar(2,0)*wWideltar(2,0);
965 if(step==1 && chi2i > fMaxChi2PerTrack) {
973 TMatrixD wWiri(wWi,TMatrixD::kMult,ri);
979 } // end loop on tracks
981 if(nUsedTrks < fMinTracks) {
986 Double_t determinant = sumWi.Determinant();
987 //cerr<<" determinant: "<<determinant<<endl;
988 if(determinant < 100.) {
989 printf("det(V) = 0\n");
994 // inverted of weights matrix
995 TMatrixD invsumWi(TMatrixD::kInverted,sumWi);
998 // position of primary vertex
1001 } // end loop on the 3 steps
1003 delete [] skipTrack;
1011 Double_t position[3];
1012 position[0] = rv(0,0);
1013 position[1] = rv(1,0);
1014 position[2] = rv(2,0);
1015 Double_t covmatrix[6];
1016 covmatrix[0] = vV(0,0);
1017 covmatrix[1] = vV(0,1);
1018 covmatrix[2] = vV(1,1);
1019 covmatrix[3] = vV(0,2);
1020 covmatrix[4] = vV(1,2);
1021 covmatrix[5] = vV(2,2);
1023 // store data in the vertex object
1024 fCurrentVertex = new AliESDVertex(position,covmatrix,chi2,nUsedTrks);
1027 printf(" VertexFitter(): finish\n");
1028 printf(" rv = ( %f , %f , %f )\n\n",rv(0,0),rv(1,0),rv(2,0));
1029 fCurrentVertex->PrintStatus();
1034 //----------------------------------------------------------------------------
1035 AliESDVertex *AliITSVertexerTracks::VertexOnTheFly(TTree &trkTree) {
1037 // Return vertex from tracks in trkTree
1039 if(fCurrentVertex) fCurrentVertex = 0;
1041 // get tracks and propagate them to initial vertex position
1042 Int_t nTrks = PrepareTracks(*(&trkTree));
1043 if(fDebug) printf(" tracks prepared: %d\n",nTrks);
1044 if(nTrks < fMinTracks) { TooFewTracks(); return fCurrentVertex; }
1050 ComputeMaxChi2PerTrack(nTrks);
1052 if(fDebug) printf(" vertex fit completed\n");
1054 return fCurrentVertex;
1056 //----------------------------------------------------------------------------