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;
195 TIter next(fInFile->GetListOfKeys());
196 // loop on events in file
197 while ((key=(TKey*)next())!=0) {
198 AliESD *esdEvent=(AliESD*)key->ReadObj();
200 printf("AliITSVertexerTracks::FindVerticesESD(): not an ESD!\n");
203 Int_t ev = (Int_t)esdEvent->GetEventNumber();
204 if(ev<fFirstEvent || ev>fLastEvent) { delete esdEvent; continue; }
205 if(ev % 100 == 0 || fDebug)
206 printf("--- Processing event %d of %d ---\n",ev,fLastEvent-fFirstEvent);
208 FindPrimaryVertexForCurrentEvent(esdEvent);
210 if(!fCurrentVertex) {
211 printf("AliITSVertexerTracks::FindVertixesESD():\n no vertex for event %d\n",ev);
216 if(fDebug) fCurrentVertex->PrintStatus();
218 // write the ESD to file
221 sprintf(ename,"%d",ev);
224 esdEvent->Write(ename,TObject::kOverwrite);
227 } // loop over events
231 //----------------------------------------------------------------------------
232 Int_t AliITSVertexerTracks::PrepareTracks(TTree &trkTree) {
234 // Propagate tracks to initial vertex position and store them in a TObjArray
236 Double_t maxd0rphi = 3.;
240 Int_t nEntries = (Int_t)trkTree.GetEntries();
242 if(!fTrkArray.IsEmpty()) fTrkArray.Clear();
243 fTrkArray.Expand(nEntries);
246 printf(" PrepareTracks()\n");
249 cout<<" entr tree its tracks = "<<nEntries<<endl;
250 for(Int_t i=0; i<nEntries; i++) {
251 // check tracks to skip
253 for(Int_t j=0; j<fNTrksToSkip; j++) {
254 if(i==fTrksToSkip[j]) {
255 if(fDebug) printf("skipping track: %d\n",i);
259 if(skipThis) continue;
261 AliITStrackV2 *itstrack = new AliITStrackV2;
262 trkTree.SetBranchAddress("tracks",&itstrack);
264 d0rphi=Prepare(itstrack);
265 if(d0rphi> maxd0rphi) { if(fDebug)cout<<" !!!! d0rphi "<<d0rphi<<endl;continue; }
266 fTrkArray.AddLast(itstrack);
269 if(fDebug)cout<<" :-) nTrks, d0rphi "<<nTrks<<" "<<d0rphi<<endl;
272 if(fTrksToSkip) delete [] fTrksToSkip;
276 //----------------------------------------------------------------------------
277 Int_t AliITSVertexerTracks::PrepareTracks(AliESD* esdEvent,Int_t nofCand, Int_t *trkPos) {
279 // Propagate tracks to initial vertex position and store them in a TObjArray
282 Double_t maxd0rphi = 3.;
285 if(!fTrkArray.IsEmpty()) fTrkArray.Clear();
286 fTrkArray.Expand(100);
289 printf(" PrepareTracks()\n");
291 AliITStrackV2* itstrack;
293 for(Int_t i=0; i<nofCand;i++){
294 AliESDtrack *esdTrack = (AliESDtrack*)esdEvent->GetTrack(trkPos[i]);
295 UInt_t status=esdTrack->GetStatus();
296 if ((status&AliESDtrack::kTPCin)==0)continue;
297 if ((status&AliESDtrack::kITSin)==0)continue;
298 if ((status&AliESDtrack::kITSrefit)==0) continue;
300 itstrack = new AliITStrackV2(*esdTrack);
301 d0rphi=Prepare(itstrack);
302 if(d0rphi> maxd0rphi) { if(fDebug)cout<<" !!!! d0rphi "<<d0rphi<<endl;continue; }
303 Int_t nclus=itstrack->GetNumberOfClusters();
305 if(nclus<6){delete itstrack;continue;}
306 fTrkArray.AddLast(itstrack);
309 if(fDebug)cout<<" :-) nTrks, d0rphi "<<nTrks<<" "<<d0rphi<<endl;
314 if(fTrksToSkip) delete [] fTrksToSkip;
317 //----------------------------------------------------------------------------
318 Double_t AliITSVertexerTracks::Prepare(AliITStrackV2* itstrack){
321 Double_t alpha,xlStart,d0rphi;
322 // propagate track to vtxSeed
323 alpha = itstrack->GetAlpha();
324 xlStart = fNominalPos[0]*TMath::Cos(alpha)+fNominalPos[1]*TMath::Sin(alpha);
325 if(itstrack->GetX()>3.)itstrack->PropagateTo(3.,0.0023,65.19); // to beam pipe (0.8 mm of Be)
326 itstrack->PropagateTo(xlStart,0.,0.);
327 // select tracks with d0rphi < maxd0rphi
328 d0rphi = TMath::Abs(itstrack->GetD(fNominalPos[0],fNominalPos[1]));
332 //----------------------------------------------------------------------------
333 void AliITSVertexerTracks::PrintStatus() const {
337 printf(" Initial position (%f,%f)\n",fNominalPos[0],fNominalPos[1]);
338 printf(" Vertex position after vertex finder:\n");
340 printf(" Number of tracks in array: %d\n",(Int_t)fTrkArray.GetEntriesFast());
341 printf(" Minimum # tracks required in fit: %d\n",fMinTracks);
345 //----------------------------------------------------------------------------
346 AliESDVertex* AliITSVertexerTracks::FindPrimaryVertexForCurrentEvent(Int_t evnumb) {
348 // Vertex for current event
352 // get tree with tracks from input file
353 TString treeName = "TreeT_ITS_";
355 TTree *trkTree=(TTree*)fInFile->Get(treeName.Data());
356 if(!trkTree) return fCurrentVertex;
359 // get tracks and propagate them to initial vertex position
360 Int_t nTrks = PrepareTracks(*trkTree);
362 if(fDebug) printf(" tracks prepared: %d\n",nTrks);
363 if(nTrks < fMinTracks) { TooFewTracks(); return fCurrentVertex; }
369 ComputeMaxChi2PerTrack(nTrks);
371 if(fDebug) printf(" vertex fit completed\n");
373 return fCurrentVertex;
375 //----------------------------------------------------------------------------
376 AliESDVertex* AliITSVertexerTracks::FindPrimaryVertexForCurrentEvent(AliESD *esdEvent)
379 // Vertex for current ESD event
382 Double_t vtx[3],cvtx[6];
384 // put tracks reco in ITS in a tree
385 Int_t entr = (Int_t)esdEvent->GetNumberOfTracks();
386 TTree *trkTree = new TTree("TreeT_ITS","its tracks");
387 AliITStrackV2 *itstrack = 0;
388 trkTree->Branch("tracks","AliITStrackV2",&itstrack,entr,0);
390 for(Int_t i=0; i<entr; i++) {
391 AliESDtrack *esdTrack = (AliESDtrack*)esdEvent->GetTrack(i);
392 if(!esdTrack->GetStatus()&AliESDtrack::kITSin)
393 { delete esdTrack; continue; }
395 itstrack = new AliITStrackV2(*esdTrack);
397 catch (const Char_t *msg) {
398 Warning("FindPrimaryVertexForCurrentEvent",msg);
409 // preselect tracks and propagate them to initial vertex position
410 Int_t nTrks = PrepareTracks(*trkTree);
412 if(fDebug) printf(" tracks prepared: %d\n",nTrks);
413 if(nTrks < fMinTracks) { TooFewTracks(); return fCurrentVertex; }
415 // Set initial vertex position from ESD
416 esdEvent->GetVertex()->GetXYZ(vtx);
417 SetVtxStart(vtx[0],vtx[1]);
422 ComputeMaxChi2PerTrack(nTrks);
424 if(fDebug) printf(" vertex fit completed\n");
426 // store vertex information in ESD
427 fCurrentVertex->GetXYZ(vtx);
428 fCurrentVertex->GetCovMatrix(cvtx);
431 esdEvent->GetVertex()->GetTruePos(tp);
432 fCurrentVertex->SetTruePos(tp);
434 esdEvent->SetVertex(fCurrentVertex);
436 cout<<"Vertex: "<<vtx[0]<<", "<<vtx[1]<<", "<<vtx[2]<<endl;
437 return fCurrentVertex;
439 //----------------------------------------------------------------------------
440 AliITSSimpleVertex* AliITSVertexerTracks::VertexForSelectedTracks(AliESD *esdEvent,Int_t nofCand, Int_t *trkPos, Int_t opt){
443 // Computes the vertex for selected tracks
444 // trkPos=vector with track positions in ESD
445 // values of opt -> see AliITSVertexerTracks.h
447 Double_t vtx[3]={0,0,0};
449 Int_t nTrks = PrepareTracks(esdEvent,nofCand, trkPos);
450 //delete trkTree;// :-))
451 if(fDebug) printf(" tracks prepared: %d\n",nTrks);
452 if(nTrks < fMinTracks) {
453 fSimpVert.SetXYZ(vtx);
454 fSimpVert.SetDispersion(999);
455 fSimpVert.SetNContributors(-5);
459 // Set initial vertex position from ESD
460 esdEvent->GetVertex()->GetXYZ(vtx);
461 SetVtxStart(vtx[0],vtx[1]);
462 if(opt==1) StrLinVertexFinderMinDist(1);
463 if(opt==2) StrLinVertexFinderMinDist(0);
464 if(opt==3) HelixVertexFinder();
465 if(opt==4) VertexFinder(1);
466 if(opt==5) VertexFinder(0);
470 //---------------------------------------------------------------------------
471 void AliITSVertexerTracks::SetSkipTracks(Int_t n,Int_t *skipped) {
473 // Mark the tracks not ot be used in the vertex finding
476 fTrksToSkip = new Int_t[n];
477 for(Int_t i=0;i<n;i++) fTrksToSkip[i] = skipped[i];
480 //---------------------------------------------------------------------------
481 void AliITSVertexerTracks::TooFewTracks() {
483 // When the number of tracks is < fMinTracks the vertex is set to (0,0,0)
484 // and the number of tracks to -1
486 fCurrentVertex = new AliESDVertex(0.,0.,-1);
489 //---------------------------------------------------------------------------
490 void AliITSVertexerTracks::VertexFinder(Int_t OptUseWeights) {
492 // Get estimate of vertex position in (x,y) from tracks DCA
493 // Then this estimate is stored to the data member fSimpVert
494 // (previous values are overwritten)
499 for(Int_t i=0;i<2;i++)initPos[i]=fNominalPos[i];
500 Int_t nacc = (Int_t)fTrkArray.GetEntriesFast();
501 Double_t aver[3]={0.,0.,0.};
502 Double_t aversq[3]={0.,0.,0.};
503 Double_t sigmasq[3]={0.,0.,0.};
506 AliITStrackV2 *track1;
507 AliITStrackV2 *track2;
508 Double_t alpha,mindist;
510 for(Int_t i=0; i<nacc; i++){
511 track1 = (AliITStrackV2*)fTrkArray.At(i);
512 alpha=track1->GetAlpha();
513 mindist = TMath::Cos(alpha)*fNominalPos[0]+TMath::Sin(alpha)*fNominalPos[1];
514 AliITSStrLine *line1 = new AliITSStrLine();
515 track1->ApproximateHelixWithLine(mindist,line1);
519 track1->GetExternalParameters(xv,par);
520 cout<<"Track in position "<<i<<" xr= "<<xv<<endl;
521 for(Int_t ii=0;ii<5;ii++)cout<<par[ii]<<" ";
525 for(Int_t j=i+1; j<nacc; j++){
526 track2 = (AliITStrackV2*)fTrkArray.At(j);
527 alpha=track2->GetAlpha();
528 mindist = TMath::Cos(alpha)*fNominalPos[0]+TMath::Sin(alpha)*fNominalPos[1];
529 AliITSStrLine *line2 = new AliITSStrLine();
530 track2->ApproximateHelixWithLine(mindist,line2);
531 Double_t distCA=line2->GetDCA(line1);
532 if(fDCAcut<=0 || (fDCAcut>0&&distCA<fDCAcut)){
533 Double_t pnt1[3],pnt2[3],crosspoint[3];
535 if(OptUseWeights<=0){
536 Int_t retcode = line2->Cross(line1,crosspoint);
538 if(fDebug>10)cout<<" i= "<<i<<", j= "<<j<<endl;
539 if(fDebug>10)cout<<"bad intersection\n";
540 line1->PrintStatus();
541 line2->PrintStatus();
545 for(Int_t jj=0;jj<3;jj++)aver[jj]+=crosspoint[jj];
546 for(Int_t jj=0;jj<3;jj++)aversq[jj]+=(crosspoint[jj]*crosspoint[jj]);
547 if(fDebug>10)cout<<" i= "<<i<<", j= "<<j<<endl;
548 if(fDebug>10)cout<<"\n Cross point: ";
549 if(fDebug>10)cout<<crosspoint[0]<<" "<<crosspoint[1]<<" "<<crosspoint[2]<<endl;
553 Int_t retcode = line1->CrossPoints(line2,pnt1,pnt2);
555 Double_t alpha, cs, sn;
556 alpha=track1->GetAlpha();
557 cs=TMath::Cos(alpha); sn=TMath::Sin(alpha);
558 Double_t sx1=sn*sn*track1->GetSigmaY2(), sy1=cs*cs*track1->GetSigmaY2();
559 alpha=track2->GetAlpha();
560 cs=TMath::Cos(alpha); sn=TMath::Sin(alpha);
561 Double_t sx2=sn*sn*track2->GetSigmaY2(), sy2=cs*cs*track2->GetSigmaY2();
562 Double_t sz1=track1->GetSigmaZ2(), sz2=track2->GetSigmaZ2();
563 Double_t wx1=sx2/(sx1+sx2), wx2=1.- wx1;
564 Double_t wy1=sy2/(sy1+sy2), wy2=1.- wy1;
565 Double_t wz1=sz2/(sz1+sz2), wz2=1.- wz1;
566 crosspoint[0]=wx1*pnt1[0] + wx2*pnt2[0];
567 crosspoint[1]=wy1*pnt1[1] + wy2*pnt2[1];
568 crosspoint[2]=wz1*pnt1[2] + wz2*pnt2[2];
571 for(Int_t jj=0;jj<3;jj++)aver[jj]+=crosspoint[jj];
572 for(Int_t jj=0;jj<3;jj++)aversq[jj]+=(crosspoint[jj]*crosspoint[jj]);
581 for(Int_t jj=0;jj<3;jj++){
582 initPos[jj] = aver[jj]/ncombi;
584 sigmasq[jj]=aversq[jj]-initPos[jj]*initPos[jj];
587 sigma=TMath::Sqrt(TMath::Abs(sigma));
590 Warning("VertexFinder","Finder did not succed");
593 fSimpVert.SetXYZ(initPos);
594 fSimpVert.SetDispersion(sigma);
595 fSimpVert.SetNContributors(ncombi);
597 //---------------------------------------------------------------------------
598 void AliITSVertexerTracks::HelixVertexFinder() {
600 // Get estimate of vertex position in (x,y) from tracks DCA
601 // Then this estimate is stored to the data member fSimpVert
602 // (previous values are overwritten)
607 for(Int_t i=0;i<2;i++)initPos[i]=fNominalPos[i];
609 Int_t nacc = (Int_t)fTrkArray.GetEntriesFast();
611 Double_t aver[3]={0.,0.,0.};
612 Double_t averquad[3]={0.,0.,0.};
613 Double_t sigmaquad[3]={0.,0.,0.};
616 AliITStrackV2 *track1;
617 AliITStrackV2 *track2;
620 Double_t alpha, cs, sn;
621 Double_t crosspoint[3];
622 for(Int_t i=0; i<nacc; i++){
623 track1 = (AliITStrackV2*)fTrkArray.At(i);
626 for(Int_t j=i+1; j<nacc; j++){
627 track2 = (AliITStrackV2*)fTrkArray.At(j);
630 distCA=track2->PropagateToDCA(track1);
632 if(fDCAcut<=0 ||(fDCAcut>0&&distCA<fDCAcut)){
633 track1->GetExternalParameters(x,par);
634 alpha=track1->GetAlpha();
635 cs=TMath::Cos(alpha); sn=TMath::Sin(alpha);
636 Double_t x1=x*cs - par[0]*sn;
637 Double_t y1=x*sn + par[0]*cs;
639 Double_t sx1=sn*sn*track1->GetSigmaY2(), sy1=cs*cs*track1->GetSigmaY2();
641 track2->GetExternalParameters(x,par);
642 alpha=track2->GetAlpha();
643 cs=TMath::Cos(alpha); sn=TMath::Sin(alpha);
644 Double_t x2=x*cs - par[0]*sn;
645 Double_t y2=x*sn + par[0]*cs;
647 Double_t sx2=sn*sn*track2->GetSigmaY2(), sy2=cs*cs*track2->GetSigmaY2();
648 // printf("Track %d pos=(%f,%f,%f) - dca=%f\n",i,x1,y1,z1,distCA);
649 //printf("Track %d pos=(%f,%f,%f)\n",j,x2,y2,z2);
651 Double_t sz1=track1->GetSigmaZ2(), sz2=track2->GetSigmaZ2();
652 Double_t wx1=sx2/(sx1+sx2), wx2=1.- wx1;
653 Double_t wy1=sy2/(sy1+sy2), wy2=1.- wy1;
654 Double_t wz1=sz2/(sz1+sz2), wz2=1.- wz1;
655 crosspoint[0]=wx1*x1 + wx2*x2;
656 crosspoint[1]=wy1*y1 + wy2*y2;
657 crosspoint[2]=wz1*z1 + wz2*z2;
660 for(Int_t jj=0;jj<3;jj++)aver[jj]+=crosspoint[jj];
661 for(Int_t jj=0;jj<3;jj++)averquad[jj]+=(crosspoint[jj]*crosspoint[jj]);
667 for(Int_t jj=0;jj<3;jj++){
668 initPos[jj] = aver[jj]/ncombi;
669 averquad[jj]/=ncombi;
670 sigmaquad[jj]=averquad[jj]-initPos[jj]*initPos[jj];
671 sigma+=sigmaquad[jj];
673 sigma=TMath::Sqrt(TMath::Abs(sigma));
676 Warning("VertexFinder","Finder did not succed");
679 fSimpVert.SetXYZ(initPos);
680 fSimpVert.SetDispersion(sigma);
681 fSimpVert.SetNContributors(ncombi);
683 //---------------------------------------------------------------------------
684 void AliITSVertexerTracks::StrLinVertexFinderMinDist(Int_t OptUseWeights){
686 // Calculate the point at minimum distance to prepared tracks
687 // Then this estimate is stored to the data member fSimpVert
688 // (previous values are overwritten)
693 for(Int_t i=0;i<2;i++)initPos[i]=fNominalPos[i];
694 const Int_t knacc = (Int_t)fTrkArray.GetEntriesFast();
696 AliITStrackV2 *track1;
697 Double_t (*vectP0)[3]=new Double_t [knacc][3];
698 Double_t (*vectP1)[3]=new Double_t [knacc][3];
701 Double_t dsum[3]={0,0,0};
702 for(Int_t i=0;i<3;i++)
703 for(Int_t j=0;j<3;j++)sum[i][j]=0;
704 for(Int_t i=0; i<knacc; i++){
705 track1 = (AliITStrackV2*)fTrkArray.At(i);
706 Double_t alpha=track1->GetAlpha();
707 Double_t mindist = TMath::Cos(alpha)*fNominalPos[0]+TMath::Sin(alpha)*fNominalPos[1];
708 AliITSStrLine *line1 = new AliITSStrLine();
709 track1->ApproximateHelixWithLine(mindist,line1);
711 Double_t p0[3],cd[3];
714 Double_t p1[3]={p0[0]+cd[0],p0[1]+cd[1],p0[2]+cd[2]};
724 if(OptUseWeights==0)GetStrLinDerivMatrix(p0,p1,matr,dknow);
725 if(OptUseWeights==1){
727 sigmasq[0]=track1->GetSigmaY2();
728 sigmasq[1]=track1->GetSigmaY2();
729 sigmasq[2]=track1->GetSigmaZ2();
730 GetStrLinDerivMatrix(p0,p1,sigmasq,matr,dknow);
733 for(Int_t iii=0;iii<3;iii++){
734 dsum[iii]+=dknow[iii];
735 for(Int_t lj=0;lj<3;lj++) sum[iii][lj]+=matr[iii][lj];
741 Double_t det=GetDeterminant3X3(sum);
744 for(Int_t zz=0;zz<3;zz++){
745 for(Int_t ww=0;ww<3;ww++){
746 for(Int_t kk=0;kk<3;kk++) vett[ww][kk]=sum[ww][kk];
748 for(Int_t kk=0;kk<3;kk++) vett[kk][zz]=dsum[kk];
749 initPos[zz]=GetDeterminant3X3(vett)/det;
753 for(Int_t i=0; i<knacc; i++){
754 Double_t p0[3]={0,0,0},p1[3]={0,0,0};
755 for(Int_t ii=0;ii<3;ii++){
756 p0[ii]=vectP0[i][ii];
757 p1[ii]=vectP1[i][ii];
759 sigma+=GetStrLinMinDist(p0,p1,initPos);
762 sigma=TMath::Sqrt(sigma);
764 Warning("VertexFinder","Finder did not succed");
769 fSimpVert.SetXYZ(initPos);
770 fSimpVert.SetDispersion(sigma);
771 fSimpVert.SetNContributors(knacc);
773 //_______________________________________________________________________
774 Double_t AliITSVertexerTracks::GetDeterminant3X3(Double_t matr[][3]){
776 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];
779 //____________________________________________________________________________
780 void AliITSVertexerTracks::GetStrLinDerivMatrix(Double_t *p0,Double_t *p1,Double_t m[][3],Double_t *d){
783 Double_t x12=p0[0]-p1[0];
784 Double_t y12=p0[1]-p1[1];
785 Double_t z12=p0[2]-p1[2];
786 Double_t kk=x12*x12+y12*y12+z12*z12;
787 m[0][0]=2-2/kk*x12*x12;
788 m[0][1]=-2/kk*x12*y12;
789 m[0][2]=-2/kk*x12*z12;
790 m[1][0]=-2/kk*x12*y12;
791 m[1][1]=2-2/kk*y12*y12;
792 m[1][2]=-2/kk*y12*z12;
793 m[2][0]=-2/kk*x12*z12;
795 m[2][2]=2-2/kk*z12*z12;
796 d[0]=2*p0[0]-2/kk*p0[0]*x12*x12-2/kk*p0[2]*x12*z12-2/kk*p0[1]*x12*y12;
797 d[1]=2*p0[1]-2/kk*p0[1]*y12*y12-2/kk*p0[0]*x12*y12-2/kk*p0[2]*z12*y12;
798 d[2]=2*p0[2]-2/kk*p0[2]*z12*z12-2/kk*p0[0]*x12*z12-2/kk*p0[1]*z12*y12;
801 //____________________________________________________________________________
802 void AliITSVertexerTracks::GetStrLinDerivMatrix(Double_t *p0,Double_t *p1,Double_t *sigmasq,Double_t m[][3],Double_t *d){
804 Double_t x12=p1[0]-p0[0];
805 Double_t y12=p1[1]-p0[1];
806 Double_t z12=p1[2]-p0[2];
808 Double_t den= x12*x12*sigmasq[1]*sigmasq[2]+y12*y12*sigmasq[0]*sigmasq[2]+z12*z12*sigmasq[0]*sigmasq[1];
810 Double_t kk= 2*(x12*x12/sigmasq[0]+y12*y12/sigmasq[1]+z12*z12/sigmasq[2]);
813 cc[0]=-x12/sigmasq[0];
814 cc[1]=-y12/sigmasq[1];
815 cc[2]=-z12/sigmasq[2];
817 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;
819 Double_t ss= -p0[0]*cc[0]-p0[1]*cc[1]-p0[2]*cc[2];
822 aa[0]=x12*sigmasq[1]*sigmasq[2]/den;
823 aa[1]=y12*sigmasq[0]*sigmasq[2]/den;
824 aa[2]=z12*sigmasq[0]*sigmasq[1]/den;
826 m[0][0]=aa[0]*(aa[0]*kk+2*cc[0])+2*cc[0]*aa[0]+2/sigmasq[0];
827 m[0][1]=aa[1]*(aa[0]*kk+2*cc[0])+2*cc[1]*aa[0];
828 m[0][2]=aa[2]*(aa[0]*kk+2*cc[0])+2*cc[2]*aa[0];
830 m[1][0]=aa[0]*(aa[1]*kk+2*cc[1])+2*cc[0]*aa[1];
831 m[1][1]=aa[1]*(aa[1]*kk+2*cc[1])+2*cc[1]*aa[1]+2/sigmasq[1];
832 m[1][2]=aa[2]*(aa[1]*kk+2*cc[1])+2*cc[2]*aa[1];
834 m[2][0]=aa[0]*(aa[2]*kk+2*cc[2])+2*cc[0]*aa[2];
835 m[2][1]=aa[1]*(aa[2]*kk+2*cc[2])+2*cc[1]*aa[2];
836 m[2][2]=aa[2]*(aa[2]*kk+2*cc[2])+2*cc[2]*aa[2]+2/sigmasq[2];
838 d[0]=-ww*(aa[0]*kk+2*cc[0])-2*ss*aa[0]+2*p0[0]/sigmasq[0];
839 d[1]=-ww*(aa[1]*kk+2*cc[1])-2*ss*aa[1]+2*p0[1]/sigmasq[1];
840 d[2]=-ww*(aa[2]*kk+2*cc[2])-2*ss*aa[2]+2*p0[2]/sigmasq[2];
843 //_____________________________________________________________________________
844 Double_t AliITSVertexerTracks::GetStrLinMinDist(Double_t *p0,Double_t *p1,Double_t *x0){
846 Double_t x12=p0[0]-p1[0];
847 Double_t y12=p0[1]-p1[1];
848 Double_t z12=p0[2]-p1[2];
849 Double_t x10=p0[0]-x0[0];
850 Double_t y10=p0[1]-x0[1];
851 Double_t z10=p0[2]-x0[2];
852 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);
855 //---------------------------------------------------------------------------
856 void AliITSVertexerTracks::VertexFitter() {
858 // The optimal estimate of the vertex position is given by a "weighted
859 // average of tracks positions"
860 // Original method: CMS Note 97/0051
863 printf(" VertexFitter(): start\n");
872 fSimpVert.GetXYZ(initPos);
873 rv(0,0) = initPos[0];
874 rv(1,0) = initPos[1];
876 Double_t xlStart,alpha;
878 Double_t cosRot,sinRot;
882 Int_t arrEntries = (Int_t)fTrkArray.GetEntries();
883 AliITStrackV2 *t = 0;
886 Int_t *skipTrack = new Int_t[arrEntries];
887 for(i=0; i<arrEntries; i++) skipTrack[i]=0;
890 // 1st - first estimate of vtx using all tracks
891 // 2nd - apply cut on chi2 max per track
892 // 3rd - estimate of global chi2
893 for(step=0; step<3; step++) {
894 if(fDebug) printf(" step = %d\n",step);
898 TMatrixD sumWiri(3,1);
902 for(j=0; j<3; j++) sumWi(j,i) = 0.;
906 for(k=0; k<arrEntries; k++) {
907 if(skipTrack[k]) continue;
908 // get track from track array
909 t = (AliITStrackV2*)fTrkArray.At(k);
910 alpha = t->GetAlpha();
911 xlStart = initPos[0]*TMath::Cos(alpha)+initPos[1]*TMath::Sin(alpha);
912 t->PropagateTo(xlStart,0.,0.); // to vtxSeed
914 if(alpha<0.) rotAngle += 2.*TMath::Pi();
915 cosRot = TMath::Cos(rotAngle);
916 sinRot = TMath::Sin(rotAngle);
918 // vector of track global coordinates
920 ri(0,0) = t->GetX()*cosRot-t->GetY()*sinRot;
921 ri(1,0) = t->GetX()*sinRot+t->GetY()*cosRot;
924 // matrix to go from global (x,y,z) to local (y,z);
933 // covariance matrix of local (y,z) - inverted
935 t->GetExternalCovariance(cc);
941 // weights matrix: wWi = qQiT * uUiInv * qQi
942 if(uUi.Determinant() <= 0.) continue;
943 TMatrixD uUiInv(TMatrixD::kInverted,uUi);
944 TMatrixD uUiInvQi(uUiInv,TMatrixD::kMult,qQi);
945 TMatrixD wWi(qQi,TMatrixD::kTransposeMult,uUiInvQi);
948 TMatrixD deltar = rv; deltar -= ri;
949 TMatrixD wWideltar(wWi,TMatrixD::kMult,deltar);
950 chi2i = deltar(0,0)*wWideltar(0,0)+
951 deltar(1,0)*wWideltar(1,0)+
952 deltar(2,0)*wWideltar(2,0);
955 if(step==1 && chi2i > fMaxChi2PerTrack) {
963 TMatrixD wWiri(wWi,TMatrixD::kMult,ri);
969 } // end loop on tracks
971 if(nUsedTrks < fMinTracks) {
976 Double_t determinant = sumWi.Determinant();
977 //cerr<<" determinant: "<<determinant<<endl;
978 if(determinant < 100.) {
979 printf("det(V) = 0\n");
984 // inverted of weights matrix
985 TMatrixD invsumWi(TMatrixD::kInverted,sumWi);
988 // position of primary vertex
991 } // end loop on the 3 steps
1001 Double_t position[3];
1002 position[0] = rv(0,0);
1003 position[1] = rv(1,0);
1004 position[2] = rv(2,0);
1005 Double_t covmatrix[6];
1006 covmatrix[0] = vV(0,0);
1007 covmatrix[1] = vV(0,1);
1008 covmatrix[2] = vV(1,1);
1009 covmatrix[3] = vV(0,2);
1010 covmatrix[4] = vV(1,2);
1011 covmatrix[5] = vV(2,2);
1013 // store data in the vertex object
1014 fCurrentVertex = new AliESDVertex(position,covmatrix,chi2,nUsedTrks);
1017 printf(" VertexFitter(): finish\n");
1018 printf(" rv = ( %f , %f , %f )\n\n",rv(0,0),rv(1,0),rv(2,0));
1019 fCurrentVertex->PrintStatus();
1024 //----------------------------------------------------------------------------
1025 AliESDVertex *AliITSVertexerTracks::VertexOnTheFly(TTree &trkTree) {
1027 // Return vertex from tracks in trkTree
1029 if(fCurrentVertex) fCurrentVertex = 0;
1031 // get tracks and propagate them to initial vertex position
1032 Int_t nTrks = PrepareTracks(*(&trkTree));
1033 if(fDebug) printf(" tracks prepared: %d\n",nTrks);
1034 if(nTrks < fMinTracks) { TooFewTracks(); return fCurrentVertex; }
1040 ComputeMaxChi2PerTrack(nTrks);
1042 if(fDebug) printf(" vertex fit completed\n");
1044 return fCurrentVertex;
1046 //----------------------------------------------------------------------------