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,
62 Double_t xStart,Double_t yStart) {
64 // Standard constructor
72 SetVtxStart(xStart,yStart);
79 //----------------------------------------------------------------------------
80 AliITSVertexerTracks::AliITSVertexerTracks(const AliMagF *map, TString fn,
81 Double_t xStart,Double_t yStart)
84 // Alternative constructor
89 SetVtxStart(xStart,yStart);
95 //______________________________________________________________________
96 AliITSVertexerTracks::AliITSVertexerTracks(const AliITSVertexerTracks &vtxr) : AliITSVertexer(vtxr) {
98 // Copies are not allowed. The method is protected to avoid misuse.
99 Error("AliITSVertexerTracks","Copy constructor not allowed\n");
102 //______________________________________________________________________
103 AliITSVertexerTracks& AliITSVertexerTracks::operator=(const AliITSVertexerTracks& /* vtxr */){
104 // Assignment operator
105 // Assignment is not allowed. The method is protected to avoid misuse.
106 Error("= operator","Assignment operator not allowed\n");
110 //-----------------------------------------------------------------------------
111 AliITSVertexerTracks::~AliITSVertexerTracks() {
112 // Default Destructor
113 // The objects poited by the following pointers are not owned
114 // by this class and are not deleted
120 //-----------------------------------------------------------------------------
121 Bool_t AliITSVertexerTracks::CheckField() const {
123 // Check if the conv. const. has been set
126 Double_t cc = t.GetConvConst();
127 Double_t field = 100./0.299792458/cc;
129 if(field<0.1 || field>0.6) {
130 printf("AliITSVertexerTracks::CheckField():\n ERROR: AliKalmanTrack::fConvConst not set\n Use AliKalmanTrack::SetConvConst() or AliITSVertexerTracks::SetField()\n");
133 printf("AliITSVertexerTracks::CheckField(): Using B = %3.1f T\n",field);
136 //---------------------------------------------------------------------------
137 void AliITSVertexerTracks::ComputeMaxChi2PerTrack(Int_t nTracks) {
139 // Max. contr. to the chi2 has been tuned as a function of multiplicity
141 if(nTracks < 7) { fMaxChi2PerTrack = 1.e6;
142 } else { fMaxChi2PerTrack = 100.; }
146 //---------------------------------------------------------------------------
147 void AliITSVertexerTracks::FindVertices() {
149 // Vertices for all events from fFirstEvent to fLastEvent
152 // Check if the conv. const. has been set
153 if(!CheckField()) return;
155 TDirectory *curdir = 0;
158 for(Int_t ev=fFirstEvent; ev<=fLastEvent; ev++) {
159 if(ev % 100 == 0 || fDebug) printf("--- Processing event %d of %d ---\n",ev,fLastEvent);
161 FindPrimaryVertexForCurrentEvent(ev);
163 if(!fCurrentVertex) {
164 printf("AliITSVertexerTracks::FindVertixes(): no tracks tree for event %d\n",ev);
168 if(fDebug) fCurrentVertex->PrintStatus();
170 // write vertex to file
171 TString vtxName = "Vertex_";
173 fCurrentVertex->SetName(vtxName.Data());
174 fCurrentVertex->SetTitle("VertexerTracks");
175 //WriteCurrentVertex();
178 fCurrentVertex->Write();
181 } // loop over events
185 //---------------------------------------------------------------------------
186 void AliITSVertexerTracks::FindVerticesESD() {
188 // Vertices for all events from fFirstEvent to fLastEvent
191 // Check if the conv. const. has been set
192 if(!CheckField()) return;
194 TDirectory *curdir = 0;
198 TIter next(fInFile->GetListOfKeys());
199 // loop on events in file
200 while ((key=(TKey*)next())!=0) {
201 AliESD *esdEvent=(AliESD*)key->ReadObj();
203 printf("AliITSVertexerTracks::FindVerticesESD(): not an ESD!\n");
206 Int_t ev = (Int_t)esdEvent->GetEventNumber();
207 if(ev<fFirstEvent || ev>fLastEvent) { delete esdEvent; continue; }
208 if(ev % 100 == 0 || fDebug)
209 printf("--- Processing event %d of %d ---\n",ev,fLastEvent-fFirstEvent);
211 FindPrimaryVertexForCurrentEvent(esdEvent);
213 if(!fCurrentVertex) {
214 printf("AliITSVertexerTracks::FindVertixesESD():\n no vertex for event %d\n",ev);
219 if(fDebug) fCurrentVertex->PrintStatus();
221 // write the ESD to file
224 sprintf(ename,"%d",ev);
227 esdEvent->Write(ename,TObject::kOverwrite);
230 } // loop over events
234 //----------------------------------------------------------------------------
235 Int_t AliITSVertexerTracks::PrepareTracks(TTree &trkTree) {
237 // Propagate tracks to initial vertex position and store them in a TObjArray
239 Double_t maxd0rphi = 3.;
243 Int_t nEntries = (Int_t)trkTree.GetEntries();
245 if(!fTrkArray.IsEmpty()) fTrkArray.Clear();
246 fTrkArray.Expand(nEntries);
249 printf(" PrepareTracks()\n");
252 cout<<" entr tree its tracks = "<<nEntries<<endl;
253 for(Int_t i=0; i<nEntries; i++) {
254 // check tracks to skip
256 for(Int_t j=0; j<fNTrksToSkip; j++) {
257 if(i==fTrksToSkip[j]) {
258 if(fDebug) printf("skipping track: %d\n",i);
262 if(skipThis) continue;
264 AliITStrackV2 *itstrack = new AliITStrackV2;
265 trkTree.SetBranchAddress("tracks",&itstrack);
267 d0rphi=Prepare(itstrack);
268 if(d0rphi> maxd0rphi) { if(fDebug)cout<<" !!!! d0rphi "<<d0rphi<<endl;continue; }
269 fTrkArray.AddLast(itstrack);
272 if(fDebug)cout<<" :-) nTrks, d0rphi "<<nTrks<<" "<<d0rphi<<endl;
275 if(fTrksToSkip) delete [] fTrksToSkip;
279 //----------------------------------------------------------------------------
280 Int_t AliITSVertexerTracks::PrepareTracks(AliESD* esdEvent,Int_t nofCand, Int_t *trkPos) {
282 // Propagate tracks to initial vertex position and store them in a TObjArray
285 Double_t maxd0rphi = 3.;
288 if(!fTrkArray.IsEmpty()) fTrkArray.Clear();
289 fTrkArray.Expand(100);
292 printf(" PrepareTracks()\n");
294 AliITStrackV2* itstrack;
296 for(Int_t i=0; i<nofCand;i++){
297 AliESDtrack *esdTrack = (AliESDtrack*)esdEvent->GetTrack(trkPos[i]);
298 UInt_t status=esdTrack->GetStatus();
299 if ((status&AliESDtrack::kTPCin)==0)continue;
300 if ((status&AliESDtrack::kITSin)==0)continue;
301 if ((status&AliESDtrack::kITSrefit)==0) continue;
303 itstrack = new AliITStrackV2(*esdTrack);
304 d0rphi=Prepare(itstrack);
305 if(d0rphi> maxd0rphi) { if(fDebug)cout<<" !!!! d0rphi "<<d0rphi<<endl;continue; }
306 Int_t nclus=itstrack->GetNumberOfClusters();
308 if(nclus<6){delete itstrack;continue;}
309 fTrkArray.AddLast(itstrack);
312 if(fDebug)cout<<" :-) nTrks, d0rphi "<<nTrks<<" "<<d0rphi<<endl;
317 if(fTrksToSkip) delete [] fTrksToSkip;
320 //----------------------------------------------------------------------------
321 Double_t AliITSVertexerTracks::Prepare(AliITStrackV2* itstrack){
324 Double_t alpha,xlStart,d0rphi;
325 // propagate track to vtxSeed
326 alpha = itstrack->GetAlpha();
327 xlStart = fNominalPos[0]*TMath::Cos(alpha)+fNominalPos[1]*TMath::Sin(alpha);
328 if(itstrack->GetX()>3.)itstrack->PropagateTo(3.,0.0023,65.19); // to beam pipe (0.8 mm of Be)
329 itstrack->PropagateTo(xlStart,0.,0.);
330 // select tracks with d0rphi < maxd0rphi
331 d0rphi = TMath::Abs(itstrack->GetD(fNominalPos[0],fNominalPos[1]));
335 //----------------------------------------------------------------------------
336 void AliITSVertexerTracks::PrintStatus() const {
340 printf(" Initial position (%f,%f)\n",fNominalPos[0],fNominalPos[1]);
341 printf(" Vertex position after vertex finder:\n");
343 printf(" Number of tracks in array: %d\n",(Int_t)fTrkArray.GetEntriesFast());
344 printf(" Minimum # tracks required in fit: %d\n",fMinTracks);
348 //----------------------------------------------------------------------------
349 AliESDVertex* AliITSVertexerTracks::FindPrimaryVertexForCurrentEvent(Int_t evnumb) {
351 // Vertex for current event
355 // get tree with tracks from input file
356 TString treeName = "TreeT_ITS_";
358 TTree *trkTree=(TTree*)fInFile->Get(treeName.Data());
359 if(!trkTree) return fCurrentVertex;
362 // get tracks and propagate them to initial vertex position
363 Int_t nTrks = PrepareTracks(*trkTree);
365 if(fDebug) printf(" tracks prepared: %d\n",nTrks);
366 if(nTrks < fMinTracks) { TooFewTracks(); return fCurrentVertex; }
372 ComputeMaxChi2PerTrack(nTrks);
374 if(fDebug) printf(" vertex fit completed\n");
376 return fCurrentVertex;
378 //----------------------------------------------------------------------------
379 AliESDVertex* AliITSVertexerTracks::FindPrimaryVertexForCurrentEvent(AliESD *esdEvent)
382 // Vertex for current ESD event
385 Double_t vtx[3],cvtx[6];
387 // put tracks reco in ITS in a tree
388 Int_t entr = (Int_t)esdEvent->GetNumberOfTracks();
389 TTree *trkTree = new TTree("TreeT_ITS","its tracks");
390 AliITStrackV2 *itstrack = 0;
391 trkTree->Branch("tracks","AliITStrackV2",&itstrack,entr,0);
393 for(Int_t i=0; i<entr; i++) {
394 AliESDtrack *esdTrack = (AliESDtrack*)esdEvent->GetTrack(i);
395 if(!esdTrack->GetStatus()&AliESDtrack::kITSin)
396 { delete esdTrack; continue; }
398 itstrack = new AliITStrackV2(*esdTrack);
400 catch (const Char_t *msg) {
401 Warning("FindPrimaryVertexForCurrentEvent",msg);
412 // preselect tracks and propagate them to initial vertex position
413 Int_t nTrks = PrepareTracks(*trkTree);
415 if(fDebug) printf(" tracks prepared: %d\n",nTrks);
416 if(nTrks < fMinTracks) { TooFewTracks(); return fCurrentVertex; }
418 // Set initial vertex position from ESD
419 esdEvent->GetVertex()->GetXYZ(vtx);
420 SetVtxStart(vtx[0],vtx[1]);
425 ComputeMaxChi2PerTrack(nTrks);
427 if(fDebug) printf(" vertex fit completed\n");
429 // store vertex information in ESD
430 fCurrentVertex->GetXYZ(vtx);
431 fCurrentVertex->GetCovMatrix(cvtx);
434 esdEvent->GetVertex()->GetTruePos(tp);
435 fCurrentVertex->SetTruePos(tp);
437 esdEvent->SetVertex(fCurrentVertex);
439 cout<<"Vertex: "<<vtx[0]<<", "<<vtx[1]<<", "<<vtx[2]<<endl;
440 return fCurrentVertex;
442 //----------------------------------------------------------------------------
443 AliITSSimpleVertex* AliITSVertexerTracks::VertexForSelectedTracks(AliESD *esdEvent,Int_t nofCand, Int_t *trkPos, Int_t opt){
446 // Computes the vertex for selected tracks
447 // trkPos=vector with track positions in ESD
448 // values of opt -> see AliITSVertexerTracks.h
450 Double_t vtx[3]={0,0,0};
452 Int_t nTrks = PrepareTracks(esdEvent,nofCand, trkPos);
453 //delete trkTree;// :-))
454 if(fDebug) printf(" tracks prepared: %d\n",nTrks);
455 if(nTrks < fMinTracks) {
456 fSimpVert.SetXYZ(vtx);
457 fSimpVert.SetDispersion(999);
458 fSimpVert.SetNContributors(-5);
462 // Set initial vertex position from ESD
463 esdEvent->GetVertex()->GetXYZ(vtx);
464 SetVtxStart(vtx[0],vtx[1]);
465 if(opt==1) StrLinVertexFinderMinDist(1);
466 if(opt==2) StrLinVertexFinderMinDist(0);
467 if(opt==3) HelixVertexFinder();
468 if(opt==4) VertexFinder(1);
469 if(opt==5) VertexFinder(0);
473 //---------------------------------------------------------------------------
474 void AliITSVertexerTracks::SetSkipTracks(Int_t n,Int_t *skipped) {
476 // Mark the tracks not ot be used in the vertex finding
479 fTrksToSkip = new Int_t[n];
480 for(Int_t i=0;i<n;i++) fTrksToSkip[i] = skipped[i];
483 //---------------------------------------------------------------------------
484 void AliITSVertexerTracks::TooFewTracks() {
486 // When the number of tracks is < fMinTracks the vertex is set to (0,0,0)
487 // and the number of tracks to -1
489 fCurrentVertex = new AliESDVertex(0.,0.,-1);
492 //---------------------------------------------------------------------------
493 void AliITSVertexerTracks::VertexFinder(Int_t OptUseWeights) {
495 // Get estimate of vertex position in (x,y) from tracks DCA
496 // Then this estimate is stored to the data member fSimpVert
497 // (previous values are overwritten)
502 for(Int_t i=0;i<2;i++)initPos[i]=fNominalPos[i];
503 Int_t nacc = (Int_t)fTrkArray.GetEntriesFast();
504 Double_t aver[3]={0.,0.,0.};
505 Double_t aversq[3]={0.,0.,0.};
506 Double_t sigmasq[3]={0.,0.,0.};
509 AliITStrackV2 *track1;
510 AliITStrackV2 *track2;
511 Double_t alpha,mindist;
513 for(Int_t i=0; i<nacc; i++){
514 track1 = (AliITStrackV2*)fTrkArray.At(i);
515 alpha=track1->GetAlpha();
516 mindist = TMath::Cos(alpha)*fNominalPos[0]+TMath::Sin(alpha)*fNominalPos[1];
517 AliITSStrLine *line1 = new AliITSStrLine();
518 track1->ApproximateHelixWithLine(mindist,line1);
522 track1->GetExternalParameters(xv,par);
523 cout<<"Track in position "<<i<<" xr= "<<xv<<endl;
524 for(Int_t ii=0;ii<5;ii++)cout<<par[ii]<<" ";
528 for(Int_t j=i+1; j<nacc; j++){
529 track2 = (AliITStrackV2*)fTrkArray.At(j);
530 alpha=track2->GetAlpha();
531 mindist = TMath::Cos(alpha)*fNominalPos[0]+TMath::Sin(alpha)*fNominalPos[1];
532 AliITSStrLine *line2 = new AliITSStrLine();
533 track2->ApproximateHelixWithLine(mindist,line2);
534 Double_t distCA=line2->GetDCA(line1);
535 if(fDCAcut<=0 || (fDCAcut>0&&distCA<fDCAcut)){
536 Double_t pnt1[3],pnt2[3],crosspoint[3];
538 if(OptUseWeights<=0){
539 Int_t retcode = line2->Cross(line1,crosspoint);
541 if(fDebug>10)cout<<" i= "<<i<<", j= "<<j<<endl;
542 if(fDebug>10)cout<<"bad intersection\n";
543 line1->PrintStatus();
544 line2->PrintStatus();
548 for(Int_t jj=0;jj<3;jj++)aver[jj]+=crosspoint[jj];
549 for(Int_t jj=0;jj<3;jj++)aversq[jj]+=(crosspoint[jj]*crosspoint[jj]);
550 if(fDebug>10)cout<<" i= "<<i<<", j= "<<j<<endl;
551 if(fDebug>10)cout<<"\n Cross point: ";
552 if(fDebug>10)cout<<crosspoint[0]<<" "<<crosspoint[1]<<" "<<crosspoint[2]<<endl;
556 Int_t retcode = line1->CrossPoints(line2,pnt1,pnt2);
558 Double_t alpha, cs, sn;
559 alpha=track1->GetAlpha();
560 cs=TMath::Cos(alpha); sn=TMath::Sin(alpha);
561 Double_t sx1=sn*sn*track1->GetSigmaY2(), sy1=cs*cs*track1->GetSigmaY2();
562 alpha=track2->GetAlpha();
563 cs=TMath::Cos(alpha); sn=TMath::Sin(alpha);
564 Double_t sx2=sn*sn*track2->GetSigmaY2(), sy2=cs*cs*track2->GetSigmaY2();
565 Double_t sz1=track1->GetSigmaZ2(), sz2=track2->GetSigmaZ2();
566 Double_t wx1=sx2/(sx1+sx2), wx2=1.- wx1;
567 Double_t wy1=sy2/(sy1+sy2), wy2=1.- wy1;
568 Double_t wz1=sz2/(sz1+sz2), wz2=1.- wz1;
569 crosspoint[0]=wx1*pnt1[0] + wx2*pnt2[0];
570 crosspoint[1]=wy1*pnt1[1] + wy2*pnt2[1];
571 crosspoint[2]=wz1*pnt1[2] + wz2*pnt2[2];
574 for(Int_t jj=0;jj<3;jj++)aver[jj]+=crosspoint[jj];
575 for(Int_t jj=0;jj<3;jj++)aversq[jj]+=(crosspoint[jj]*crosspoint[jj]);
584 for(Int_t jj=0;jj<3;jj++){
585 initPos[jj] = aver[jj]/ncombi;
587 sigmasq[jj]=aversq[jj]-initPos[jj]*initPos[jj];
590 sigma=TMath::Sqrt(TMath::Abs(sigma));
593 Warning("VertexFinder","Finder did not succed");
596 fSimpVert.SetXYZ(initPos);
597 fSimpVert.SetDispersion(sigma);
598 fSimpVert.SetNContributors(ncombi);
600 //---------------------------------------------------------------------------
601 void AliITSVertexerTracks::HelixVertexFinder() {
603 // Get estimate of vertex position in (x,y) from tracks DCA
604 // Then this estimate is stored to the data member fSimpVert
605 // (previous values are overwritten)
610 for(Int_t i=0;i<2;i++)initPos[i]=fNominalPos[i];
612 Int_t nacc = (Int_t)fTrkArray.GetEntriesFast();
614 Double_t aver[3]={0.,0.,0.};
615 Double_t averquad[3]={0.,0.,0.};
616 Double_t sigmaquad[3]={0.,0.,0.};
619 AliITStrackV2 *track1;
620 AliITStrackV2 *track2;
623 Double_t alpha, cs, sn;
624 Double_t crosspoint[3];
625 for(Int_t i=0; i<nacc; i++){
626 track1 = (AliITStrackV2*)fTrkArray.At(i);
629 for(Int_t j=i+1; j<nacc; j++){
630 track2 = (AliITStrackV2*)fTrkArray.At(j);
633 distCA=track2->PropagateToDCA(track1);
635 if(fDCAcut<=0 ||(fDCAcut>0&&distCA<fDCAcut)){
636 track1->GetExternalParameters(x,par);
637 alpha=track1->GetAlpha();
638 cs=TMath::Cos(alpha); sn=TMath::Sin(alpha);
639 Double_t x1=x*cs - par[0]*sn;
640 Double_t y1=x*sn + par[0]*cs;
642 Double_t sx1=sn*sn*track1->GetSigmaY2(), sy1=cs*cs*track1->GetSigmaY2();
644 track2->GetExternalParameters(x,par);
645 alpha=track2->GetAlpha();
646 cs=TMath::Cos(alpha); sn=TMath::Sin(alpha);
647 Double_t x2=x*cs - par[0]*sn;
648 Double_t y2=x*sn + par[0]*cs;
650 Double_t sx2=sn*sn*track2->GetSigmaY2(), sy2=cs*cs*track2->GetSigmaY2();
651 // printf("Track %d pos=(%f,%f,%f) - dca=%f\n",i,x1,y1,z1,distCA);
652 //printf("Track %d pos=(%f,%f,%f)\n",j,x2,y2,z2);
654 Double_t sz1=track1->GetSigmaZ2(), sz2=track2->GetSigmaZ2();
655 Double_t wx1=sx2/(sx1+sx2), wx2=1.- wx1;
656 Double_t wy1=sy2/(sy1+sy2), wy2=1.- wy1;
657 Double_t wz1=sz2/(sz1+sz2), wz2=1.- wz1;
658 crosspoint[0]=wx1*x1 + wx2*x2;
659 crosspoint[1]=wy1*y1 + wy2*y2;
660 crosspoint[2]=wz1*z1 + wz2*z2;
663 for(Int_t jj=0;jj<3;jj++)aver[jj]+=crosspoint[jj];
664 for(Int_t jj=0;jj<3;jj++)averquad[jj]+=(crosspoint[jj]*crosspoint[jj]);
670 for(Int_t jj=0;jj<3;jj++){
671 initPos[jj] = aver[jj]/ncombi;
672 averquad[jj]/=ncombi;
673 sigmaquad[jj]=averquad[jj]-initPos[jj]*initPos[jj];
674 sigma+=sigmaquad[jj];
676 sigma=TMath::Sqrt(TMath::Abs(sigma));
679 Warning("VertexFinder","Finder did not succed");
682 fSimpVert.SetXYZ(initPos);
683 fSimpVert.SetDispersion(sigma);
684 fSimpVert.SetNContributors(ncombi);
686 //---------------------------------------------------------------------------
687 void AliITSVertexerTracks::StrLinVertexFinderMinDist(Int_t OptUseWeights){
689 // Calculate the point at minimum distance to prepared tracks
690 // Then this estimate is stored to the data member fSimpVert
691 // (previous values are overwritten)
696 for(Int_t i=0;i<2;i++)initPos[i]=fNominalPos[i];
697 const Int_t knacc = (Int_t)fTrkArray.GetEntriesFast();
699 AliITStrackV2 *track1;
700 Double_t (*vectP0)[3]=new Double_t [knacc][3];
701 Double_t (*vectP1)[3]=new Double_t [knacc][3];
704 Double_t dsum[3]={0,0,0};
705 for(Int_t i=0;i<3;i++)
706 for(Int_t j=0;j<3;j++)sum[i][j]=0;
707 for(Int_t i=0; i<knacc; i++){
708 track1 = (AliITStrackV2*)fTrkArray.At(i);
709 Double_t alpha=track1->GetAlpha();
710 Double_t mindist = TMath::Cos(alpha)*fNominalPos[0]+TMath::Sin(alpha)*fNominalPos[1];
711 AliITSStrLine *line1 = new AliITSStrLine();
712 track1->ApproximateHelixWithLine(mindist,line1);
714 Double_t p0[3],cd[3];
717 Double_t p1[3]={p0[0]+cd[0],p0[1]+cd[1],p0[2]+cd[2]};
727 if(OptUseWeights==0)GetStrLinDerivMatrix(p0,p1,matr,dknow);
728 if(OptUseWeights==1){
730 sigmasq[0]=track1->GetSigmaY2();
731 sigmasq[1]=track1->GetSigmaY2();
732 sigmasq[2]=track1->GetSigmaZ2();
733 GetStrLinDerivMatrix(p0,p1,sigmasq,matr,dknow);
736 for(Int_t iii=0;iii<3;iii++){
737 dsum[iii]+=dknow[iii];
738 for(Int_t lj=0;lj<3;lj++) sum[iii][lj]+=matr[iii][lj];
744 Double_t det=GetDeterminant3X3(sum);
747 for(Int_t zz=0;zz<3;zz++){
748 for(Int_t ww=0;ww<3;ww++){
749 for(Int_t kk=0;kk<3;kk++) vett[ww][kk]=sum[ww][kk];
751 for(Int_t kk=0;kk<3;kk++) vett[kk][zz]=dsum[kk];
752 initPos[zz]=GetDeterminant3X3(vett)/det;
756 for(Int_t i=0; i<knacc; i++){
757 Double_t p0[3]={0,0,0},p1[3]={0,0,0};
758 for(Int_t ii=0;ii<3;ii++){
759 p0[ii]=vectP0[i][ii];
760 p1[ii]=vectP1[i][ii];
762 sigma+=GetStrLinMinDist(p0,p1,initPos);
765 sigma=TMath::Sqrt(sigma);
767 Warning("VertexFinder","Finder did not succed");
772 fSimpVert.SetXYZ(initPos);
773 fSimpVert.SetDispersion(sigma);
774 fSimpVert.SetNContributors(knacc);
776 //_______________________________________________________________________
777 Double_t AliITSVertexerTracks::GetDeterminant3X3(Double_t matr[][3]){
779 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];
782 //____________________________________________________________________________
783 void AliITSVertexerTracks::GetStrLinDerivMatrix(Double_t *p0,Double_t *p1,Double_t m[][3],Double_t *d){
786 Double_t x12=p0[0]-p1[0];
787 Double_t y12=p0[1]-p1[1];
788 Double_t z12=p0[2]-p1[2];
789 Double_t kk=x12*x12+y12*y12+z12*z12;
790 m[0][0]=2-2/kk*x12*x12;
791 m[0][1]=-2/kk*x12*y12;
792 m[0][2]=-2/kk*x12*z12;
793 m[1][0]=-2/kk*x12*y12;
794 m[1][1]=2-2/kk*y12*y12;
795 m[1][2]=-2/kk*y12*z12;
796 m[2][0]=-2/kk*x12*z12;
798 m[2][2]=2-2/kk*z12*z12;
799 d[0]=2*p0[0]-2/kk*p0[0]*x12*x12-2/kk*p0[2]*x12*z12-2/kk*p0[1]*x12*y12;
800 d[1]=2*p0[1]-2/kk*p0[1]*y12*y12-2/kk*p0[0]*x12*y12-2/kk*p0[2]*z12*y12;
801 d[2]=2*p0[2]-2/kk*p0[2]*z12*z12-2/kk*p0[0]*x12*z12-2/kk*p0[1]*z12*y12;
804 //____________________________________________________________________________
805 void AliITSVertexerTracks::GetStrLinDerivMatrix(Double_t *p0,Double_t *p1,Double_t *sigmasq,Double_t m[][3],Double_t *d){
807 Double_t x12=p1[0]-p0[0];
808 Double_t y12=p1[1]-p0[1];
809 Double_t z12=p1[2]-p0[2];
811 Double_t den= x12*x12*sigmasq[1]*sigmasq[2]+y12*y12*sigmasq[0]*sigmasq[2]+z12*z12*sigmasq[0]*sigmasq[1];
813 Double_t kk= 2*(x12*x12/sigmasq[0]+y12*y12/sigmasq[1]+z12*z12/sigmasq[2]);
816 cc[0]=-x12/sigmasq[0];
817 cc[1]=-y12/sigmasq[1];
818 cc[2]=-z12/sigmasq[2];
820 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;
822 Double_t ss= -p0[0]*cc[0]-p0[1]*cc[1]-p0[2]*cc[2];
825 aa[0]=x12*sigmasq[1]*sigmasq[2]/den;
826 aa[1]=y12*sigmasq[0]*sigmasq[2]/den;
827 aa[2]=z12*sigmasq[0]*sigmasq[1]/den;
829 m[0][0]=aa[0]*(aa[0]*kk+2*cc[0])+2*cc[0]*aa[0]+2/sigmasq[0];
830 m[0][1]=aa[1]*(aa[0]*kk+2*cc[0])+2*cc[1]*aa[0];
831 m[0][2]=aa[2]*(aa[0]*kk+2*cc[0])+2*cc[2]*aa[0];
833 m[1][0]=aa[0]*(aa[1]*kk+2*cc[1])+2*cc[0]*aa[1];
834 m[1][1]=aa[1]*(aa[1]*kk+2*cc[1])+2*cc[1]*aa[1]+2/sigmasq[1];
835 m[1][2]=aa[2]*(aa[1]*kk+2*cc[1])+2*cc[2]*aa[1];
837 m[2][0]=aa[0]*(aa[2]*kk+2*cc[2])+2*cc[0]*aa[2];
838 m[2][1]=aa[1]*(aa[2]*kk+2*cc[2])+2*cc[1]*aa[2];
839 m[2][2]=aa[2]*(aa[2]*kk+2*cc[2])+2*cc[2]*aa[2]+2/sigmasq[2];
841 d[0]=-ww*(aa[0]*kk+2*cc[0])-2*ss*aa[0]+2*p0[0]/sigmasq[0];
842 d[1]=-ww*(aa[1]*kk+2*cc[1])-2*ss*aa[1]+2*p0[1]/sigmasq[1];
843 d[2]=-ww*(aa[2]*kk+2*cc[2])-2*ss*aa[2]+2*p0[2]/sigmasq[2];
846 //_____________________________________________________________________________
847 Double_t AliITSVertexerTracks::GetStrLinMinDist(Double_t *p0,Double_t *p1,Double_t *x0){
849 Double_t x12=p0[0]-p1[0];
850 Double_t y12=p0[1]-p1[1];
851 Double_t z12=p0[2]-p1[2];
852 Double_t x10=p0[0]-x0[0];
853 Double_t y10=p0[1]-x0[1];
854 Double_t z10=p0[2]-x0[2];
855 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);
858 //---------------------------------------------------------------------------
859 void AliITSVertexerTracks::VertexFitter() {
861 // The optimal estimate of the vertex position is given by a "weighted
862 // average of tracks positions"
863 // Original method: CMS Note 97/0051
866 printf(" VertexFitter(): start\n");
875 fSimpVert.GetXYZ(initPos);
876 rv(0,0) = initPos[0];
877 rv(1,0) = initPos[1];
879 Double_t xlStart,alpha;
881 Double_t cosRot,sinRot;
885 Int_t arrEntries = (Int_t)fTrkArray.GetEntries();
886 AliITStrackV2 *t = 0;
889 Int_t *skipTrack = new Int_t[arrEntries];
890 for(i=0; i<arrEntries; i++) skipTrack[i]=0;
893 // 1st - first estimate of vtx using all tracks
894 // 2nd - apply cut on chi2 max per track
895 // 3rd - estimate of global chi2
896 for(step=0; step<3; step++) {
897 if(fDebug) printf(" step = %d\n",step);
901 TMatrixD sumWiri(3,1);
905 for(j=0; j<3; j++) sumWi(j,i) = 0.;
909 for(k=0; k<arrEntries; k++) {
910 if(skipTrack[k]) continue;
911 // get track from track array
912 t = (AliITStrackV2*)fTrkArray.At(k);
913 alpha = t->GetAlpha();
914 xlStart = initPos[0]*TMath::Cos(alpha)+initPos[1]*TMath::Sin(alpha);
915 t->PropagateTo(xlStart,0.,0.); // to vtxSeed
917 if(alpha<0.) rotAngle += 2.*TMath::Pi();
918 cosRot = TMath::Cos(rotAngle);
919 sinRot = TMath::Sin(rotAngle);
921 // vector of track global coordinates
923 ri(0,0) = t->GetX()*cosRot-t->GetY()*sinRot;
924 ri(1,0) = t->GetX()*sinRot+t->GetY()*cosRot;
927 // matrix to go from global (x,y,z) to local (y,z);
936 // covariance matrix of local (y,z) - inverted
938 t->GetExternalCovariance(cc);
944 // weights matrix: wWi = qQiT * uUiInv * qQi
945 if(uUi.Determinant() <= 0.) continue;
946 TMatrixD uUiInv(TMatrixD::kInverted,uUi);
947 TMatrixD uUiInvQi(uUiInv,TMatrixD::kMult,qQi);
948 TMatrixD wWi(qQi,TMatrixD::kTransposeMult,uUiInvQi);
951 TMatrixD deltar = rv; deltar -= ri;
952 TMatrixD wWideltar(wWi,TMatrixD::kMult,deltar);
953 chi2i = deltar(0,0)*wWideltar(0,0)+
954 deltar(1,0)*wWideltar(1,0)+
955 deltar(2,0)*wWideltar(2,0);
958 if(step==1 && chi2i > fMaxChi2PerTrack) {
966 TMatrixD wWiri(wWi,TMatrixD::kMult,ri);
972 } // end loop on tracks
974 if(nUsedTrks < fMinTracks) {
979 Double_t determinant = sumWi.Determinant();
980 //cerr<<" determinant: "<<determinant<<endl;
981 if(determinant < 100.) {
982 printf("det(V) = 0\n");
987 // inverted of weights matrix
988 TMatrixD invsumWi(TMatrixD::kInverted,sumWi);
991 // position of primary vertex
994 } // end loop on the 3 steps
1004 Double_t position[3];
1005 position[0] = rv(0,0);
1006 position[1] = rv(1,0);
1007 position[2] = rv(2,0);
1008 Double_t covmatrix[6];
1009 covmatrix[0] = vV(0,0);
1010 covmatrix[1] = vV(0,1);
1011 covmatrix[2] = vV(1,1);
1012 covmatrix[3] = vV(0,2);
1013 covmatrix[4] = vV(1,2);
1014 covmatrix[5] = vV(2,2);
1016 // store data in the vertex object
1017 fCurrentVertex = new AliESDVertex(position,covmatrix,chi2,nUsedTrks);
1020 printf(" VertexFitter(): finish\n");
1021 printf(" rv = ( %f , %f , %f )\n\n",rv(0,0),rv(1,0),rv(2,0));
1022 fCurrentVertex->PrintStatus();
1027 //----------------------------------------------------------------------------
1028 AliESDVertex *AliITSVertexerTracks::VertexOnTheFly(TTree &trkTree) {
1030 // Return vertex from tracks in trkTree
1032 if(fCurrentVertex) fCurrentVertex = 0;
1034 // get tracks and propagate them to initial vertex position
1035 Int_t nTrks = PrepareTracks(*(&trkTree));
1036 if(fDebug) printf(" tracks prepared: %d\n",nTrks);
1037 if(nTrks < fMinTracks) { TooFewTracks(); return fCurrentVertex; }
1043 ComputeMaxChi2PerTrack(nTrks);
1045 if(fDebug) printf(" vertex fit completed\n");
1047 return fCurrentVertex;
1049 //----------------------------------------------------------------------------