]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITStrackerSA.cxx
AliHMPIDDigitN no longer needed
[u/mrichter/AliRoot.git] / ITS / AliITStrackerSA.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /* $Id$ */
17
18 ////////////////////////////////////////////////////
19 //  Stand alone tracker class                     //
20 //  Origin:  Elisabetta Crescio                   //
21 //  e-mail:  crescio@to.infn.it                   //
22 //  tracks are saved as AliITStrackV2 objects     //
23 ////////////////////////////////////////////////////
24
25 #include <stdlib.h>
26
27 #include <TArrayI.h>
28 #include <TBranch.h>
29 #include <TObjArray.h>
30 #include <TTree.h>
31
32 #include "AliESD.h"
33 #include "AliESDVertex.h"
34 #include "AliESDtrack.h"
35 #include "AliITSVertexer.h"
36 #include "AliITSclusterTable.h"
37 #include "AliITSRecPoint.h"
38 #include "AliITSgeom.h"
39 #include "AliITStrackSA.h"
40 #include "AliITStrackerSA.h"
41 #include "AliRun.h"
42
43 ClassImp(AliITStrackerSA)
44
45 //____________________________________________________________________________
46 AliITStrackerSA::AliITStrackerSA():AliITStrackerMI(),
47 fPhiEstimate(0),
48 fLambdac(0),
49 fPhic(0),
50 fCoef1(0),
51 fCoef2(0),
52 fCoef3(0),
53 fNloop(0),
54 fPhiWin(0),
55 fLambdaWin(0),
56 fVert(0),
57 fVertexer(0),
58 fGeom(0),
59 fListOfTracks(0),
60 fITSclusters(0),
61 fSixPoints(0),
62 fCluLayer(0),
63 fCluCoord(0){
64   // Default constructor
65   Init();
66  
67 }
68 //____________________________________________________________________________
69 AliITStrackerSA::AliITStrackerSA(AliITSgeom *geom):AliITStrackerMI(geom),
70 fPhiEstimate(0),
71 fLambdac(0),
72 fPhic(0),
73 fCoef1(0),
74 fCoef2(0),
75 fCoef3(0),
76 fNloop(0),
77 fPhiWin(0),
78 fLambdaWin(0),
79 fVert(0),
80 fVertexer(0),
81 fGeom(0),
82 fListOfTracks(0),
83 fITSclusters(0),
84 fSixPoints(0),
85 fCluLayer(0),
86 fCluCoord(0) 
87 {
88   // Standard constructor (Vertex is known and passed to this obj.)
89   Init();
90   fVert = 0;
91   fGeom = geom;
92  
93 }
94
95 //____________________________________________________________________________
96 AliITStrackerSA::AliITStrackerSA(AliITSgeom *geom, AliESDVertex *vert):AliITStrackerMI(geom),
97 fPhiEstimate(0),
98 fLambdac(0),
99 fPhic(0),
100 fCoef1(0),
101 fCoef2(0),
102 fCoef3(0),
103 fNloop(0),
104 fPhiWin(0),
105 fLambdaWin(0),
106 fVert(vert),
107 fVertexer(0),
108 fGeom(0),
109 fListOfTracks(0),
110 fITSclusters(0),
111 fSixPoints(0),
112 fCluLayer(0),
113 fCluCoord(0) 
114 {
115   // Standard constructor (Vertex is known and passed to this obj.)
116   Init();
117   fGeom = geom;
118  
119 }
120
121 //____________________________________________________________________________
122 AliITStrackerSA::AliITStrackerSA(AliITSgeom *geom, AliITSVertexer *vertexer):AliITStrackerMI(geom),
123 fPhiEstimate(0),
124 fLambdac(0),
125 fPhic(0),
126 fCoef1(0),
127 fCoef2(0),
128 fCoef3(0),
129 fNloop(0),
130 fPhiWin(0),
131 fLambdaWin(0),
132 fVert(),
133 fVertexer(vertexer),
134 fGeom(0),
135 fListOfTracks(0),
136 fITSclusters(0),
137 fSixPoints(0),
138 fCluLayer(0),
139 fCluCoord(0)  
140 {
141   // Standard constructor (Vertex is unknown - vertexer is passed to this obj)
142   Init();
143   fVertexer = vertexer;
144   fGeom = geom;
145  
146 }
147
148 //____________________________________________________________________________
149 AliITStrackerSA::AliITStrackerSA(const AliITStrackerSA& tracker):AliITStrackerMI(),
150 fPhiEstimate(tracker.fPhiEstimate),
151 fLambdac(tracker.fLambdac),
152 fPhic(tracker.fPhic),
153 fCoef1(tracker.fCoef1),
154 fCoef2(tracker.fCoef2),
155 fCoef3(tracker.fCoef3),
156 fNloop(tracker.fNloop),
157 fPhiWin(tracker.fPhiWin),
158 fLambdaWin(tracker.fLambdaWin),
159 fVert(tracker.fVert),
160 fVertexer(tracker.fVertexer),
161 fGeom(tracker.fGeom),
162 fListOfTracks(tracker.fListOfTracks),
163 fITSclusters(tracker.fITSclusters),
164 fSixPoints(tracker.fSixPoints),
165 fCluLayer(tracker.fCluLayer),
166 fCluCoord(tracker.fCluCoord) {
167   // Copy constructor
168   for(Int_t i=0;i<2;i++){
169     fPoint1[i]=tracker.fPoint1[i];
170     fPoint2[i]=tracker.fPoint2[i];
171     fPoint3[i]=tracker.fPoint3[i];
172     fPointc[i]=tracker.fPointc[i];
173   }
174   if(tracker.fVertexer && tracker.fVert){
175     fVert = new AliESDVertex(*tracker.fVert);
176   }
177   else {
178     fVert = tracker.fVert;
179   }
180   for(Int_t i=0;i<fGeom->GetNlayers();i++){
181     fCluLayer[i] = tracker.fCluLayer[i];
182     fCluCoord[i] = tracker.fCluCoord[i];
183   } 
184 }
185 //______________________________________________________________________
186 AliITStrackerSA& AliITStrackerSA::operator=(const AliITStrackerSA& source){
187     // Assignment operator. 
188   this->~AliITStrackerSA();
189   new(this) AliITStrackerSA(source);
190   return *this;
191  
192 }
193
194 //____________________________________________________________________________
195 AliITStrackerSA::~AliITStrackerSA(){
196   // destructor
197   // if fVertexer is not null, the AliESDVertex obj. is owned by this class
198   // and is deleted here
199   if(fVertexer){
200     if(fVert)delete fVert;
201   }
202   fVert = 0;
203   fVertexer = 0;
204  
205   if(fPhiWin)delete []fPhiWin;
206   if(fLambdaWin)delete []fLambdaWin;
207   fListOfTracks->Delete();
208   if(fCluLayer){
209     for(Int_t i=0;i<fGeom->GetNlayers();i++){
210       if(fCluLayer[i]){
211         fCluLayer[i]->Delete();
212         delete fCluLayer[i];
213       }
214     }
215     delete [] fCluLayer;
216   }
217   if(fCluCoord){
218     for(Int_t i=0;i<fGeom->GetNlayers();i++){
219       if(fCluCoord[i]){
220         fCluCoord[i]->Delete();
221         delete fCluCoord[i];
222       }
223     }
224     delete [] fCluCoord;
225   }
226   
227   fGeom = 0; 
228 }
229
230 //____________________________________________________________________________
231 void AliITStrackerSA::Init(){
232   //  Reset all data members
233     fPhiEstimate=0;
234     for(Int_t i=0;i<3;i++){fPoint1[i]=0;fPoint2[i]=0;fPoint3[i]=0;}
235     fLambdac=0;
236     fPhic=0;
237     fCoef1=0;
238     fCoef2=0;
239     fCoef3=0;
240     fPointc[0]=0;
241     fPointc[1]=0;
242     fVert = 0;
243     fVertexer = 0;
244     fGeom = 0;
245     SetWindowSizes();
246     fITSclusters = 0;
247     SetSixPoints();
248     fListOfTracks=new TObjArray(0,0);
249     fCluLayer = 0;
250     fCluCoord = 0;
251  }
252 //_______________________________________________________________________
253 void AliITStrackerSA::ResetForFinding(){
254   //  Reset data members used in all loops during track finding
255     fPhiEstimate=0;
256     for(Int_t i=0;i<3;i++){fPoint1[i]=0;fPoint2[i]=0;fPoint3[i]=0;}
257     fLambdac=0;
258     fPhic=0;
259     fCoef1=0;
260     fCoef2=0;
261     fCoef3=0;
262     fPointc[0]=0;
263     fPointc[1]=0;
264     fListOfTracks->Delete();
265 }
266
267  
268
269 //______________________________________________________________________
270 Int_t AliITStrackerSA::FindTracks(AliESD* event){
271
272 // Track finder using the ESD object
273
274
275   //controllare numero cluster sui layer1 e 2 (morti?)
276   //non trova tracce...controllare..
277
278   if(!fITSclusters){
279     Fatal("FindTracks","ITS cluster tree is not accessed - Abort!!!\n Please use method SetClusterTree to pass the pointer to the tree\n");
280     return -1;
281   }
282   
283    
284   //Reads event and mark clusters of traks already found, with flag kITSin
285    Int_t nentr=event->GetNumberOfTracks();
286    while (nentr--) {
287      AliESDtrack *track=event->GetTrack(nentr);
288      if (track->GetStatus()&AliESDtrack::kITSin==AliESDtrack::kITSin){
289        Int_t idx[12];
290        Int_t ncl = track->GetITSclusters(idx);
291        for(Int_t k=0;k<ncl;k++){
292          AliITSRecPoint* cll = (AliITSRecPoint*)GetCluster(idx[k]);
293          cll->SetBit(kSAflag);
294        }
295      }
296    }
297
298    Double_t primaryVertex[3];
299    event->GetVertex()->GetXYZ(primaryVertex);
300    //Creates TClonesArray with clusters for each layer. The clusters already used
301    //by AliITStrackerMI are not considered
302    
303    Int_t nclusters[6]={0,0,0,0,0,0};
304    Int_t dmar[6]={0,0,0,0,0,0};
305    fCluLayer = new TClonesArray*[fGeom->GetNlayers()];
306    fCluCoord = new TClonesArray*[fGeom->GetNlayers()];
307
308    for(Int_t i=0;i<fGeom->GetNlayers();i++){
309      AliITSlayer &layer=fgLayers[i];
310      for(Int_t cli=0;cli<layer.GetNumberOfClusters();cli++){
311        AliITSRecPoint* cls = (AliITSRecPoint*)layer.GetCluster(cli);
312        if(cls->TestBit(kSAflag)==kTRUE) continue; //clusters used by TPC prol.
313        if(cls->GetQ()==0) continue; //fake clusters dead zones
314        nclusters[i]++;
315      }
316      dmar[i]=0;
317      fCluLayer[i] = new TClonesArray("AliITSRecPoint",nclusters[i]);
318      fCluCoord[i] = new TClonesArray("AliITSclusterTable",nclusters[i]);
319    }
320
321    
322    Int_t * firstmod = new Int_t[fGeom->GetNlayers()];
323    for(Int_t i=0;i<fGeom->GetNlayers();i++){
324      firstmod[i]=fGeom->GetModuleIndex(i+1,1,1);
325    }
326    
327    for(Int_t ilay=0;ilay<fGeom->GetNlayers();ilay++){
328      TClonesArray &clulay = *fCluLayer[ilay];
329      TClonesArray &clucoo = *fCluCoord[ilay];
330      AliITSlayer &layer=fgLayers[ilay];
331      for(Int_t cli=0;cli<layer.GetNumberOfClusters();cli++){
332        AliITSRecPoint* cls = (AliITSRecPoint*)layer.GetCluster(cli);
333        if(cls->TestBit(kSAflag)==kTRUE) continue;
334        if(cls->GetQ()==0) continue;
335        Double_t phi=0;Double_t lambda=0;
336        Float_t x=0;Float_t y=0;Float_t z=0;
337        Float_t sx=0;Float_t sy=0;Float_t sz=0;
338        Int_t module = cls->GetDetectorIndex()+firstmod[ilay];
339        GetCoorAngles(cls,module,phi,lambda,x,y,z,primaryVertex);
340        GetCoorErrors(cls,module,sx,sy,sz);
341        new (clulay[dmar[ilay]]) AliITSRecPoint(*cls);
342        new (clucoo[dmar[ilay]]) AliITSclusterTable(x,y,z,sx,sy,sz,phi,lambda,cli);
343        dmar[ilay]++;
344      }
345    }
346    
347  
348   //Get primary vertex
349
350    Int_t ntrack=0;
351    //loop on the different windows
352    for(Int_t nloop=0;nloop<fNloop;nloop++){
353      for(Int_t ncl=0;ncl<fCluLayer[0]->GetEntries();ncl++){ //loop starting from layer 0
354        
355        ResetForFinding();
356        Int_t pflag=0;
357        
358        AliITSRecPoint* cl = (AliITSRecPoint*)fCluLayer[0]->At(ncl);
359
360        if(!cl) continue;
361
362
363        if (cl->GetQ()<=0) continue;
364        
365        AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(0,ncl); 
366        fPhic = arr->GetPhi();
367        fLambdac = arr->GetLambda();
368        if (TMath::Abs(fLambdac)>0.26*TMath::Pi()) continue;
369        fPhiEstimate = fPhic;
370        AliITStrackSA* trs = new AliITStrackSA(); 
371        fPoint1[0]=primaryVertex[0];
372        fPoint1[1]=primaryVertex[1];
373
374
375        fPoint2[0]=arr->GetX();
376        fPoint2[1]=arr->GetY();
377        Int_t * nn = new Int_t[fGeom->GetNlayers()];//counter for clusters on each layer
378        for(Int_t i=0;i<fGeom->GetNlayers();i++){ nn[i]=0;}
379        nn[0] = SearchClusters(0,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
380        
381        nn[1] = SearchClusters(1,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
382       if(nn[1]>0){
383         pflag=1;
384         fPoint3[0] = fPointc[0];
385         fPoint3[1] = fPointc[1];
386       }
387       nn[2] = SearchClusters(2,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
388       if(nn[1]==0 && nn[2]==0) pflag=0;
389       if(nn[2]!=0 && nn[1]!=0){ pflag=1; UpdatePoints();}
390       if(nn[2]!=0 && nn[1]==0){
391         pflag=1;
392         fPoint3[0]=fPointc[0];
393         fPoint3[1]=fPointc[1];
394       }
395
396       nn[3] = SearchClusters(3,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag);
397       pflag=1;
398       if(nn[3]!=0) UpdatePoints();
399       nn[4] = SearchClusters(4,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag); 
400       pflag=1;
401       if(nn[4]!=0) UpdatePoints();
402       nn[5] = SearchClusters(5,fPhiWin[nloop],fLambdaWin[nloop],trs,primaryVertex[2],pflag); 
403           
404
405       Int_t layOK=0;
406       Int_t numberofpoints;
407       if(fSixPoints) numberofpoints=6;  //check of the candidate track
408       else numberofpoints=5;           //if track is good (with the required number        
409       for(Int_t nnp=0;nnp<fGeom->GetNlayers();nnp++){    //of points) it is written on file
410         if(nn[nnp]!=0) layOK+=1;
411       }
412       if(layOK>=numberofpoints){
413
414         AliITStrackV2* tr2 = FitTrack(trs,primaryVertex);
415         
416         if(tr2==0) continue;
417
418         AliESDtrack outtrack;
419         outtrack.UpdateTrackParams(tr2,AliESDtrack::kITSin);
420         event->AddTrack(&outtrack);
421         ntrack++;
422         
423       }
424         
425
426       delete trs;
427       delete[] nn;
428       
429      }//end loop on clusters of layer1
430     
431      //end loop2
432    }
433    
434    //if 5/6 points are required, second loop starting 
435    //from second layer, to find tracks with point of 
436    //layer 1 missing
437    
438    if(!fSixPoints){
439      //   counter for clusters on each layer  
440      Int_t * nn = new Int_t[fGeom->GetNlayers()-1];      
441      for(Int_t nloop=0;nloop<fNloop;nloop++){
442        Int_t ncl2=fCluLayer[1]->GetEntries();
443        while(ncl2--){ //loop starting from layer 2
444          ResetForFinding();
445          Int_t pflag=0;
446          AliITSRecPoint* cl = (AliITSRecPoint*)fCluLayer[1]->At(ncl2);
447          
448          if(!cl) continue;
449          AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(1,ncl2);
450          fPhic = arr->GetPhi();
451          fLambdac = arr->GetLambda();
452          fPhiEstimate = fPhic;
453          
454          AliITStrackSA* trs = new AliITStrackSA(); 
455          fPoint1[0]=primaryVertex[0];
456          fPoint1[1]=primaryVertex[1];
457          
458          fPoint2[0]=arr->GetX();
459          fPoint2[1]=arr->GetY();
460          for(Int_t kk=0;kk<fGeom->GetNlayers()-1;kk++)nn[kk] = 0;
461          nn[0] = SearchClusters(1,fPhiWin[nloop],fLambdaWin[nloop],
462                                    trs,primaryVertex[2],pflag);
463          nn[1] = SearchClusters(2,fPhiWin[nloop],fLambdaWin[nloop],
464                                    trs,primaryVertex[2],pflag);
465          if(nn[1]!=0){
466            pflag=1;
467            fPoint3[0]=fPointc[0];
468            fPoint3[1]=fPointc[1];
469          }
470          nn[2]= SearchClusters(3,fPhiWin[nloop],fLambdaWin[nloop],
471                                    trs,primaryVertex[2],pflag);
472          if(nn[2]!=0){
473            pflag=1;
474            UpdatePoints();
475          }
476          nn[3]= SearchClusters(4,fPhiWin[nloop],fLambdaWin[nloop],
477                                    trs,primaryVertex[2],pflag);
478          if(nn[3]!=0){
479            pflag=1;
480            UpdatePoints();
481          }
482          nn[4]=SearchClusters(5,fPhiWin[nloop],fLambdaWin[nloop],
483                                    trs,primaryVertex[2],pflag);
484
485          Int_t fl=0;
486          for(Int_t nnp=0;nnp<fGeom->GetNlayers()-1;nnp++){
487            if(nn[nnp]!=0) fl+=1;
488          }
489          if(fl>=5){  // 5/6       
490            AliITStrackV2* tr2 = FitTrack(trs,primaryVertex);
491            if(tr2==0){
492              continue;
493            }
494            
495            AliESDtrack outtrack;
496            outtrack.UpdateTrackParams(tr2,AliESDtrack::kITSin);
497            event->AddTrack(&outtrack);
498            ntrack++;
499
500          }   
501         
502        
503         delete trs;
504       }//end loop on clusters of layer2
505      }
506    
507     delete [] nn;
508   }  //end opt="5/6"  
509    
510   delete [] firstmod;
511   Info("FindTracks","Number of found tracks: %d",event->GetNumberOfTracks());
512   return 0;
513
514 }
515  
516
517
518
519
520 //________________________________________________________________________
521
522 AliITStrackV2* AliITStrackerSA::FitTrack(AliITStrackSA* tr,Double_t *primaryVertex){
523   //fit of the found track
524
525   
526   Int_t * firstmod = new Int_t[fGeom->GetNlayers()];
527   for(Int_t i=0;i<fGeom->GetNlayers();i++){
528     firstmod[i]=fGeom->GetModuleIndex(i+1,1,1);
529   }  
530
531   Int_t nclusters = tr->GetNumberOfClustersSA();
532   TObjArray** listlayer = new TObjArray*[fGeom->GetNlayers()];
533   for(Int_t i=0;i<fGeom->GetNlayers();i++){
534     listlayer[i] = new TObjArray(0,0);
535   }
536
537   TArrayI clind0(20);
538   TArrayI clind1(20);
539   TArrayI clind2(20);
540   TArrayI clind3(20);
541   TArrayI clind4(20);
542   TArrayI clind5(20);
543
544   TArrayI mark0(20);
545   TArrayI mark1(20);
546   TArrayI mark2(20);
547   TArrayI mark3(20);
548   TArrayI mark4(20);
549   TArrayI mark5(20);
550
551
552   Int_t * nnn = new Int_t[fGeom->GetNlayers()];
553   Int_t * kkk = new Int_t[fGeom->GetNlayers()];
554   for(Int_t i=0;i<fGeom->GetNlayers();i++) {nnn[i]=0;kkk[i]=0;}
555   
556   for(Int_t ncl=0;ncl<nclusters;ncl++){
557     Int_t index = tr->GetClusterIndexSA(ncl); 
558     AliITSRecPoint* cl = (AliITSRecPoint*)GetCluster(index);
559     if(cl->TestBit(kSAflag)==kTRUE) cl->ResetBit(kSAflag);
560     Int_t lay = (index & 0xf0000000) >> 28;
561     if(lay==0) { listlayer[0]->AddLast(cl); clind0[nnn[0]]=index;nnn[0]++;}
562     if(lay==1) { listlayer[1]->AddLast(cl); clind1[nnn[1]]=index;nnn[1]++;}
563     if(lay==2) { listlayer[2]->AddLast(cl); clind2[nnn[2]]=index;nnn[2]++;}
564     if(lay==3) { listlayer[3]->AddLast(cl); clind3[nnn[3]]=index;nnn[3]++;}
565     if(lay==4) { listlayer[4]->AddLast(cl); clind4[nnn[4]]=index;nnn[4]++;}
566     if(lay==5) { listlayer[5]->AddLast(cl); clind5[nnn[5]]=index;nnn[5]++;}    
567   }
568   delete [] nnn;
569
570   for(Int_t nlay=0;nlay<fGeom->GetNlayers();nlay++){
571     for(Int_t ncl=0;ncl<tr->GetNumberOfMarked(nlay);ncl++){
572       Int_t mark = tr->GetClusterMark(nlay,ncl);
573       if(nlay==0) { mark0[kkk[0]]=mark;kkk[0]++;}
574       if(nlay==1) { mark1[kkk[1]]=mark;kkk[1]++;}
575       if(nlay==2) { mark2[kkk[2]]=mark;kkk[2]++;}
576       if(nlay==3) { mark3[kkk[3]]=mark;kkk[3]++;}
577       if(nlay==4) { mark4[kkk[4]]=mark;kkk[4]++;}
578       if(nlay==5) { mark5[kkk[5]]=mark;kkk[5]++;}
579
580     }
581   }
582
583   delete [] kkk;
584
585  
586   Int_t * end = new Int_t[fGeom->GetNlayers()];
587   for(Int_t i=0;i<fGeom->GetNlayers();i++){
588     if(listlayer[i]->GetEntries()==0) end[i]=1;
589     else end[i]=listlayer[i]->GetEntries();
590   }
591
592   TClonesArray* listSA = new TClonesArray("AliITStrackSA");
593   TClonesArray &tri = *listSA;
594   Int_t nlist=0;
595
596   if(end[0]==0) end[0]=1; //for tracks with cluster on layer 0 missing
597   for(Int_t l1=0;l1<end[0];l1++){//loop on layer 1
598     AliITSRecPoint* cl0 = (AliITSRecPoint*)listlayer[0]->At(l1); 
599     Double_t x1,y1,z1,sx1,sy1,sz1;
600     Double_t x2,y2,z2,sx2,sy2,sz2;
601     AliITSRecPoint* p1=0;
602     AliITSRecPoint* p2=0;
603     Int_t index1=clind0[l1];
604     Int_t index2=0;
605     Int_t mrk1 = mark0[l1];
606     Int_t mrk2 = 0;
607     Int_t lay1=0;
608     Int_t lay2=1;
609     Int_t module1=-1;
610     for(Int_t l2=0;l2<end[1];l2++){//loop on layer 2
611       AliITSRecPoint* cl1 = (AliITSRecPoint*)listlayer[1]->At(l2); 
612       index2=clind1[l2];
613       mrk2 = mark1[l2];
614       for(Int_t l3=0;l3<end[2];l3++){  //loop on layer 3
615         AliITSRecPoint* cl2 = (AliITSRecPoint*)listlayer[2]->At(l3);
616
617         if(cl0==0 && cl1!=0) {
618           p2 = cl2;index1=clind2[l3];mrk1=mark2[l3];lay1=2;
619           p1=cl1;
620           module1 = p1->GetDetectorIndex()+firstmod[1]; 
621         }
622         if(cl0!=0 && cl1==0){
623           p1=cl0;
624           p2=cl2;index2=clind2[l3];mrk2=mark2[l3];lay2=2;
625           module1 = p1->GetDetectorIndex()+firstmod[0];
626         }
627         if(cl0!=0 && cl1!=0){
628           p1=cl0;
629           p2=cl1;
630           module1 = p1->GetDetectorIndex()+firstmod[0];
631         }
632         
633         Int_t cln1=mrk1;
634         Int_t cln2=mrk2;
635         AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(lay1,cln1);
636         AliITSclusterTable* arr1= (AliITSclusterTable*)GetClusterCoord(lay2,cln2);
637         x1 = arr->GetX();
638         x2 = arr1->GetX();
639         y1 = arr->GetY();
640         y2 = arr1->GetY();
641         z1 = arr->GetZ();
642         z2 = arr1->GetZ();
643         sx1 = arr->GetSx();
644         sx2 = arr1->GetSx();
645         sy1 = arr->GetSy();
646         sy2 = arr1->GetSy();
647         sz1 = arr->GetSz();
648         sz2 = arr1->GetSz();
649         
650         Int_t layer,ladder,detector;
651         fGeom->GetModuleId(module1,layer,ladder,detector);
652         Float_t yclu1 = p1->GetY();
653         Float_t zclu1 = p1->GetZ();
654         Double_t cv=Curvature(primaryVertex[0],primaryVertex[1],x1,y1,x2,y2);
655         
656         Double_t tgl2 = (z2-z1)/TMath::Sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
657         Double_t phi2 = TMath::ATan2((y2-y1),(x2-x1));
658
659         for(Int_t l4=0;l4<end[3];l4++){ //loop on layer 4   
660           AliITSRecPoint* cl3 = (AliITSRecPoint*)listlayer[3]->At(l4);
661           for(Int_t l5=0;l5<end[4];l5++){ //loop on layer 5
662             AliITSRecPoint* cl4 = (AliITSRecPoint*)listlayer[4]->At(l5);
663             for(Int_t l6=0;l6<end[5];l6++){ //loop on layer 6  
664               AliITSRecPoint* cl5 = (AliITSRecPoint*)listlayer[5]->At(l6);
665               AliITStrackSA* trac = new AliITStrackSA(fGeom,layer,ladder,detector,yclu1,zclu1,phi2,tgl2,cv,1);
666                               
667               if(cl5!=0) {
668                 trac->AddClusterV2(5,(clind5[l6] & 0x0fffffff)>>0);
669                 trac->AddClusterMark(5,mark5[l6]);
670               }
671               if(cl4!=0){
672                 trac->AddClusterV2(4,(clind4[l5] & 0x0fffffff)>>0);
673                 trac->AddClusterMark(4,mark4[l5]);
674               }
675               if(cl3!=0){
676                 trac->AddClusterV2(3,(clind3[l4] & 0x0fffffff)>>0);
677                 trac->AddClusterMark(3,mark3[l4]);
678               }
679               if(cl2!=0){
680                 trac->AddClusterV2(2,(clind2[l3] & 0x0fffffff)>>0);
681                 trac->AddClusterMark(2,mark2[l3]);
682               }
683               if(cl1!=0){
684                 trac->AddClusterV2(1,(clind1[l2] & 0x0fffffff)>>0);
685                 trac->AddClusterMark(1,mark1[l2]);
686               }
687               if(cl0!=0){
688                 trac->AddClusterV2(0,(clind0[l1] & 0x0fffffff)>>0);
689                 trac->AddClusterMark(0,mark0[l1]);
690               }
691               //fit with Kalman filter using AliITStrackerMI::RefitAt()
692           
693
694               AliITStrackMI* ot = new AliITStrackSA(*trac);
695               
696               ot->ResetCovariance(10.);
697               ot->ResetClusters();
698               
699               if(RefitAt(49.,ot,trac)){ //fit from layer 1 to layer 6
700                 AliITStrackMI *otrack2 = new AliITStrackMI(*ot);
701                 otrack2->ResetCovariance(10.); 
702                 otrack2->ResetClusters();
703                 //fit from layer 6 to layer 1
704                 if(RefitAt(3.7,otrack2,ot)) {
705                   fListOfTracks->AddLast(otrack2);
706                   new (tri[nlist]) AliITStrackSA(*trac);
707                   nlist++;
708                 } else {
709                   delete otrack2;
710                 }
711                               
712               }       
713           
714               delete ot;
715               delete trac;
716             }//end loop layer 6
717           }//end loop layer 5
718         }//end loop layer 4
719         
720       }//end loop layer 3
721     }//end loop layer 2 
722   }//end loop layer 1
723
724   delete [] end;
725
726  
727
728   Int_t dim=fListOfTracks->GetEntries();
729   if(dim==0){
730     for(Int_t i=0;i<fGeom->GetNlayers();i++){
731       delete listlayer[i];
732     }
733     delete [] listlayer;
734     listSA->Delete();
735     delete listSA;
736     delete [] firstmod;
737     return 0;
738   }
739
740   Int_t lowchi2 = FindTrackLowChiSquare(fListOfTracks,dim);
741   AliITStrackV2* otrack =(AliITStrackV2*)fListOfTracks->At(lowchi2);
742   AliITStrackSA* trsa = (AliITStrackSA*)listSA->At(lowchi2);
743  
744   if(otrack==0) {
745     for(Int_t i=0;i<fGeom->GetNlayers();i++){
746       delete listlayer[i];
747     }
748     delete [] listlayer; 
749     listSA->Delete();
750     delete listSA;
751     delete [] firstmod;
752     return 0;
753   }
754   Int_t * indexc = new Int_t[fGeom->GetNlayers()];
755   for(Int_t i=0;i<fGeom->GetNlayers();i++) indexc[i]=0;
756   for(Int_t nind=0;nind<otrack->GetNumberOfClusters();nind++){
757     indexc[nind] = otrack->GetClusterIndex(nind);
758   }      
759   AliITSRecPoint* cl0 = (AliITSRecPoint*)GetCluster(indexc[0]);
760   AliITSRecPoint* cl1 = (AliITSRecPoint*)GetCluster(indexc[1]);     
761   AliITSRecPoint* cl2 = (AliITSRecPoint*)GetCluster(indexc[2]);     
762   AliITSRecPoint* cl3 = (AliITSRecPoint*)GetCluster(indexc[3]);
763   AliITSRecPoint* cl4 = (AliITSRecPoint*)GetCluster(indexc[4]);
764   Int_t labl[3]={-1,-1,-1};
765   if(otrack->GetNumberOfClusters()==fGeom->GetNlayers()){
766     AliITSRecPoint* cl5 = (AliITSRecPoint*)GetCluster(indexc[5]);
767     labl[0]=cl5->GetLabel(0);
768     labl[1]=cl5->GetLabel(1);
769     labl[2]=cl5->GetLabel(2);
770   }
771   delete [] indexc;
772   if(otrack->GetNumberOfClusters()==(fGeom->GetNlayers()-1)){
773     labl[0]=-1;
774     labl[1]=-1;
775     labl[2]=-1;
776   }
777   Int_t numberofpoints;
778   if(fSixPoints) numberofpoints=6;
779   else numberofpoints=5;
780   CookLabel(otrack,0.); //MI change - to see fake ratio
781   Int_t label =  Label(cl0->GetLabel(0),cl1->GetLabel(0), 
782                        cl2->GetLabel(0),cl3->GetLabel(0),
783                        cl4->GetLabel(0),labl[0],
784                        cl0->GetLabel(1),cl1->GetLabel(1),
785                        cl2->GetLabel(1),cl3->GetLabel(1),
786                        cl4->GetLabel(1),labl[1],
787                        cl0->GetLabel(2),cl1->GetLabel(2),
788                        cl2->GetLabel(2),cl3->GetLabel(2),
789                        cl4->GetLabel(2),labl[2],numberofpoints);
790   
791   otrack->SetLabel(label);  
792   //remove clusters of found track
793
794   for(Int_t nlay=0;nlay<fGeom->GetNlayers();nlay++){
795     for(Int_t cln=0;cln<trsa->GetNumberOfMarked(nlay);cln++){
796       Int_t index = trsa->GetClusterMark(nlay,cln);
797       fCluLayer[nlay]->RemoveAt(index);
798       RemoveClusterCoord(nlay,index);
799       fCluLayer[nlay]->Compress();
800     }    
801   }
802   listSA->Delete();
803   delete listSA;
804
805   for(Int_t i=0;i<fGeom->GetNlayers();i++){
806     delete listlayer[i];
807   }
808   delete [] listlayer; 
809   delete [] firstmod;
810   return otrack;
811
812 }
813
814
815
816 //_______________________________________________________
817 Int_t AliITStrackerSA::SearchClusters(Int_t layer,Double_t phiwindow,Double_t lambdawindow, AliITStrackSA* trs,Double_t /*zvertex*/,Int_t pflag){
818   //function used to to find the clusters associated to the track
819   Int_t nc=0;
820   AliITSlayer &lay = fgLayers[layer];
821   Double_t r=lay.GetR();
822    if(pflag==1){      
823     Float_t cx1,cx2,cy1,cy2;
824     FindEquation(fPoint1[0],fPoint1[1],fPoint2[0],fPoint2[1],fPoint3[0],fPoint3[1],fCoef1,fCoef2,fCoef3);
825     if (FindIntersection(fCoef1,fCoef2,fCoef3,-r*r,cx1,cy1,cx2,cy2)==0)
826        return 0;
827     Double_t fi1=TMath::ATan2(cy1,cx1);
828     Double_t fi2=TMath::ATan2(cy2,cx2);
829     fPhiEstimate=ChoosePoint(fi1,fi2,fPhic);
830   }
831
832  
833   Int_t ncl = fCluLayer[layer]->GetEntries();
834   for (Int_t index=0; index<ncl; index++) {
835     AliITSRecPoint *c = (AliITSRecPoint*)fCluLayer[layer]->At(index);
836     if (!c) continue;
837     if (c->GetQ()<=0) continue;
838     
839      AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(layer,index);
840      Double_t phi = arr->GetPhi();
841      if (TMath::Abs(phi-fPhiEstimate)>phiwindow) continue;
842
843      Double_t lambda = arr->GetLambda();
844      if (TMath::Abs(lambda-fLambdac)>lambdawindow) continue;
845
846      if(trs->GetNumberOfClustersSA()==trs->GetMaxNumberOfClusters()) return 0;
847      if(trs->GetNumberOfMarked(layer)==trs->GetMaxNMarkedPerLayer()) return 0;
848      Int_t orind = arr->GetOrInd();
849      trs->AddClusterSA(layer,orind);
850      trs->AddClusterMark(layer,index);
851        
852      nc++;
853      fLambdac=lambda;
854      fPhiEstimate=phi;
855
856      fPointc[0]=arr->GetX();
857      fPointc[1]=arr->GetY();
858
859   }
860   return nc;
861 }
862
863 //________________________________________________________________
864 void AliITStrackerSA::UpdatePoints(){
865   //update of points for the estimation of the curvature  
866
867   fPoint2[0]=fPoint3[0];
868   fPoint2[1]=fPoint3[1];
869   fPoint3[0]=fPointc[0];
870   fPoint3[1]=fPointc[1];
871
872   
873 }
874
875 //___________________________________________________________________
876 Int_t AliITStrackerSA::FindEquation(Float_t x1, Float_t y1, Float_t x2, Float_t y2, Float_t x3, Float_t y3,Float_t& a, Float_t& b, Float_t& c){
877
878    //given (x,y) of three recpoints (in global coordinates) 
879    //returns the parameters a,b,c of circonference x*x + y*y +a*x + b*y +c
880
881    Float_t den = (x3-x1)*(y2-y1)-(x2-x1)*(y3-y1);
882    if(den==0) return 0;
883    a = ((y3-y1)*(x2*x2+y2*y2-x1*x1-y1*y1)-(y2-y1)*(x3*x3+y3*y3-x1*x1-y1*y1))/den;
884    b = -(x2*x2-x1*x1+y2*y2-y1*y1+a*(x2-x1))/(y2-y1);
885    c = -x1*x1-y1*y1-a*x1-b*y1;
886    return 1;
887  }
888 //__________________________________________________________________________
889  Int_t AliITStrackerSA::FindIntersection(Float_t a1, Float_t b1, Float_t c1, Float_t c2,Float_t& x1,Float_t& y1, Float_t& x2, Float_t& y2){
890  
891  //Finds the intersection between the circonference of the track and the circonference centered in (0,0) represented by one layer
892  //c2 is -rlayer*rlayer
893
894   if(a1==0) return 0;
895  Double_t m = c2-c1; 
896  Double_t aA = (b1*b1)/(a1*a1)+1;
897  Double_t bB = (-2*m*b1/(a1*a1));
898  Double_t cC = c2+(m*m)/(a1*a1);
899  Double_t dD = bB*bB-4*aA*cC;
900  if(dD<0) return 0;
901  
902  y1 = (-bB+TMath::Sqrt(dD))/(2*aA); 
903  y2 = (-bB-TMath::Sqrt(dD))/(2*aA); 
904  x1 = (c2-c1-b1*y1)/a1;
905  x2 = (c2-c1-b1*y2)/a1;
906
907  return 1; 
908 }
909 //____________________________________________________________________
910 Double_t AliITStrackerSA::Curvature(Double_t x1,Double_t y1,Double_t 
911 x2,Double_t y2,Double_t x3,Double_t y3){
912
913   //calculates the curvature of track  
914   Double_t den = (x3-x1)*(y2-y1)-(x2-x1)*(y3-y1);
915   if(den==0) return 0;
916   Double_t a = ((y3-y1)*(x2*x2+y2*y2-x1*x1-y1*y1)-(y2-y1)*(x3*x3+y3*y3-x1*x1-y1*y1))/den;
917   Double_t b = -(x2*x2-x1*x1+y2*y2-y1*y1+a*(x2-x1))/(y2-y1);
918   Double_t c = -x1*x1-y1*y1-a*x1-b*y1;
919   Double_t xc=-a/2.;
920
921   if((a*a+b*b-4*c)<0) return 0;
922   Double_t rad = TMath::Sqrt(a*a+b*b-4*c)/2.;
923   if(rad==0) return 0;
924   
925   if((x1>0 && y1>0 && x1<xc)) rad*=-1;
926   if((x1<0 && y1>0 && x1<xc)) rad*=-1;
927   //  if((x1<0 && y1<0 && x1<xc)) rad*=-1;
928   // if((x1>0 && y1<0 && x1<xc)) rad*=-1;
929   
930   return 1/rad;
931  
932 }
933
934
935 //____________________________________________________________________
936 Double_t AliITStrackerSA::ChoosePoint(Double_t p1, Double_t p2, Double_t pp){
937
938   //Returns the point closest to pp
939
940   Double_t diff1 = p1-pp;
941   Double_t diff2 = p2-pp;
942   
943   if(TMath::Abs(diff1)<TMath::Abs(diff2)) fPhiEstimate=p1;
944   else fPhiEstimate=p2;  
945   return fPhiEstimate;
946   
947 }
948
949
950 //_________________________________________________________________
951 Int_t AliITStrackerSA::FindTrackLowChiSquare(TObjArray* tracklist, Int_t dim) const {
952   // returns track with lowes chi square  
953   if(dim==1){
954     //AliITStrackV2* trk = (AliITStrackV2*)tracklist->At(0);
955     //return trk;
956     return 0;
957   }
958   //if(dim==0) return 0;
959   Double_t * chi2 = new Double_t[dim];
960   Int_t * index = new Int_t[dim];
961   for(Int_t i=0;i<dim;i++){
962     AliITStrackV2* trk = (AliITStrackV2*)tracklist->At(i);
963     chi2[i]=trk->GetChi2();
964     index[i]=i;
965   }
966
967   Int_t w=0;Double_t value;
968   Int_t lp;
969   while(w<dim){
970     for(Int_t j=w+1;j<dim;j++){
971       if(chi2[w]<chi2[j]){
972         value=chi2[w];
973         chi2[w]=chi2[j];
974         chi2[j]=value;
975         lp=index[w];
976         index[w]=index[j];
977         index[j]=lp;
978       }
979     }
980     w++;
981   }
982
983   delete [] chi2;
984   delete [] index;
985   return index[dim-1];
986 }
987
988 //__________________________________________________________
989 Int_t AliITStrackerSA::FindLabel(Int_t l1, Int_t l2, Int_t l3, Int_t l4, Int_t l5, Int_t l6){
990
991   //function used to determine the track label
992   
993   Int_t lb[6] = {l1,l2,l3,l4,l5,l6};
994   Int_t aa[6]={1,1,1,1,1,1};
995   Int_t ff=0; 
996   Int_t ll=0;
997   Int_t k=0;Int_t w=0;Int_t num=6;
998   if(lb[5]==-1) num=5;
999   
1000   while(k<num){
1001   
1002     for(Int_t i=k+1;i<num;i++){
1003     
1004       if(lb[k]==lb[i] && aa[k]!=0){
1005       
1006         aa[k]+=1;
1007         aa[i]=0;
1008       }
1009     }
1010   k++;
1011   }
1012
1013   while(w<num){
1014   
1015     for(Int_t j=0;j<6;j++){
1016       if(aa[w]<aa[j]){
1017       ff=aa[w];
1018       aa[w]=aa[j];
1019       aa[j]=ff;
1020       ll=lb[w];
1021       lb[w]=lb[j];
1022       lb[j]=ll;
1023      }
1024     }
1025   w++;
1026   }
1027   if(num==6)  return lb[5];
1028   else return lb[4];
1029 }
1030
1031 //_____________________________________________________________________________
1032 Int_t AliITStrackerSA::Label(Int_t gl1, Int_t gl2, Int_t gl3, Int_t gl4, Int_t gl5, Int_t gl6,Int_t gl7, Int_t gl8, Int_t gl9, Int_t gl10,Int_t gl11,
1033 Int_t gl12, Int_t gl13, Int_t gl14,Int_t gl15, Int_t gl16, Int_t gl17, Int_t gl18, Int_t numberofpoints){
1034
1035  
1036   //function used to assign label to the found track. If track is fake, the label is negative
1037
1038   Int_t lb0[6] = {gl1,gl2,gl3,gl4,gl5,gl6};
1039   Int_t lb1[6] = {gl7,gl8,gl9,gl10,gl11,gl12};
1040   Int_t lb2[6] = {gl13,gl14,gl15,gl16,gl17,gl18};
1041   Int_t ll=FindLabel(lb0[0],lb0[1],lb0[2],lb0[3],lb0[4],lb0[5]);
1042   Int_t lflag=0;Int_t num=6;
1043   if(lb0[5]==-1 && lb1[5]==-1 && lb2[5]==-1) num=5;
1044
1045   for(Int_t i=0;i<num;i++){
1046     if(lb0[i]==ll || lb1[i]==ll || lb2[i]==ll) lflag+=1;
1047   }
1048
1049   if(lflag>=numberofpoints) return ll;
1050   else return -ll;
1051
1052   
1053 }
1054
1055 //_____________________________________________________________________________
1056 void AliITStrackerSA::SetWindowSizes(Int_t n, Double_t *phi, Double_t *lam){
1057   // Set sizes of the phi and lambda windows used for track finding
1058   fNloop = n;
1059   if(phi){ // user defined values
1060     fPhiWin = new Double_t[fNloop];
1061     fLambdaWin = new Double_t[fNloop];
1062     for(Int_t k=0;k<fNloop;k++){
1063       fPhiWin[k]=phi[k];
1064       fLambdaWin[k]=lam[k];
1065     }
1066   }
1067   else {  // default values
1068             
1069     Double_t phid[33]   = {0.002,0.003,0.004,0.0045,0.0047,
1070                            0.005,0.0053,0.0055,
1071                            0.006,0.0063,0.0065,0.007,0.0073,0.0075,0.0077,
1072                            0.008,0.0083,0.0085,0.0087,0.009,0.0095,0.0097,
1073                            0.01,0.0105,0.011,0.0115,0.012,0.0125,0.013,0.0135,0.0140,0.0145};
1074     Double_t lambdad[33] = {0.003,0.004,0.005,0.005,0.005,
1075                             0.005,0.005,0.006,
1076                             0.006,0.006,0.006,0.007,0.007,0.007,0.007,
1077                             0.007,0.007,0.007,0.007,0.007,0.007,0.007,
1078                             0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008};
1079     
1080     if(fNloop!=33){
1081       fNloop = 33;
1082     }
1083     
1084     
1085     fPhiWin = new Double_t[fNloop];
1086     fLambdaWin = new Double_t[fNloop];
1087    
1088     for(Int_t k=0;k<fNloop;k++){
1089       fPhiWin[k]=phid[k];
1090       fLambdaWin[k]=lambdad[k];
1091     }
1092   
1093   }
1094
1095 }
1096 //_______________________________________________________________________
1097 void AliITStrackerSA::GetCoorAngles(AliITSRecPoint* cl,Int_t module,Double_t &phi,Double_t &lambda, Float_t &x, Float_t &y,Float_t &z,Double_t* vertex){
1098   //Returns values of phi (azimuthal) and lambda angles for a given cluster
1099   
1100   Double_t rot[9];     fGeom->GetRotMatrix(module,rot);
1101   Int_t lay,lad,det; fGeom->GetModuleId(module,lay,lad,det);
1102   Float_t tx,ty,tz;  fGeom->GetTrans(lay,lad,det,tx,ty,tz);     
1103
1104   Double_t alpha=TMath::ATan2(rot[1],rot[0])+TMath::Pi();
1105   Double_t phi1=TMath::Pi()/2+alpha;
1106   if (lay==1) phi1+=TMath::Pi();
1107
1108   Float_t cp=TMath::Cos(phi1), sp=TMath::Sin(phi1);
1109   Float_t r=tx*cp+ty*sp;
1110
1111   x= r*cp - cl->GetY()*sp;
1112   y= r*sp + cl->GetY()*cp;
1113   z=cl->GetZ();
1114   
1115   phi=TMath::ATan2(y,x);
1116   lambda=TMath::ATan2(z-vertex[2],TMath::Sqrt((x-vertex[0])*(x-vertex[0])+(y-vertex[1])*(y-vertex[1])));
1117 }
1118
1119 //________________________________________________________________________
1120 void AliITStrackerSA::GetCoorErrors(AliITSRecPoint* cl, Int_t module,Float_t &sx,Float_t &sy, Float_t &sz){
1121
1122   //returns x,y,z of cluster in global coordinates
1123
1124   Double_t rot[9];     fGeom->GetRotMatrix(module,rot);
1125   Int_t lay,lad,det; fGeom->GetModuleId(module,lay,lad,det);
1126  
1127   Double_t alpha=TMath::ATan2(rot[1],rot[0])+TMath::Pi();
1128   Double_t phi=TMath::Pi()/2+alpha;
1129   if (lay==1) phi+=TMath::Pi();
1130
1131   Float_t cp=TMath::Cos(phi), sp=TMath::Sin(phi);
1132
1133   sx = TMath::Sqrt(sp*sp*cl->GetSigmaY2());
1134   sy = TMath::Sqrt(cp*cp*cl->GetSigmaY2());
1135   sz = TMath::Sqrt(cl->GetSigmaZ2());
1136
1137 }