Skipping layers corresponding to ITS subdetectors that are not in the TriggerCluster...
[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 "AliESDEvent.h"
33 #include "AliESDVertex.h"
34 #include "AliESDtrack.h"
35 #include "AliITSVertexer.h"
36 #include "AliITSclusterTable.h"
37 #include "AliITSRecPoint.h"
38 #include "AliITSgeomTGeo.h"
39 #include "AliITStrackSA.h"
40 #include "AliITStrackerSA.h"
41 #include "AliITSReconstructor.h"
42 #include "AliLog.h"
43 #include "AliRun.h"
44
45 ClassImp(AliITStrackerSA)
46
47 //____________________________________________________________________________
48 AliITStrackerSA::AliITStrackerSA():AliITStrackerMI(),
49 fPhiEstimate(0),
50 fITSStandAlone(0),
51 fLambdac(0),
52 fPhic(0),
53 fCoef1(0),
54 fCoef2(0),
55 fCoef3(0),
56 fNloop(0),
57 fPhiWin(0),
58 fLambdaWin(0),
59 fVert(0),
60 fVertexer(0),
61 fListOfTracks(0),
62 fListOfSATracks(0),
63 fITSclusters(0),
64 fInwardFlag(0),
65 fOuterStartLayer(0),
66 fInnerStartLayer(5),
67 fMinNPoints(0),
68 fMinQ(0.),
69 fCluLayer(0),
70 fCluCoord(0){
71   // Default constructor
72   Init();
73  
74 }
75 //____________________________________________________________________________
76 AliITStrackerSA::AliITStrackerSA(const Char_t *geom):AliITStrackerMI(0),
77 fPhiEstimate(0),
78 fITSStandAlone(0),
79 fLambdac(0),
80 fPhic(0),
81 fCoef1(0),
82 fCoef2(0),
83 fCoef3(0),
84 fNloop(0),
85 fPhiWin(0),
86 fLambdaWin(0),
87 fVert(0),
88 fVertexer(0),
89 fListOfTracks(0),
90 fListOfSATracks(0),
91 fITSclusters(0),
92 fInwardFlag(0),
93 fOuterStartLayer(0),
94 fInnerStartLayer(5),
95 fMinNPoints(0),
96 fMinQ(0.),
97 fCluLayer(0),
98 fCluCoord(0) 
99 {
100   // Standard constructor (Vertex is known and passed to this obj.)
101   if (geom) {
102     AliWarning("\"geom\" is actually a dummy argument !");
103   }
104
105   Init();
106   fVert = 0;
107  
108 }
109
110 //____________________________________________________________________________
111 AliITStrackerSA::AliITStrackerSA(const Char_t *geom, AliESDVertex *vert):AliITStrackerMI(0),
112 fPhiEstimate(0),
113 fITSStandAlone(0),
114 fLambdac(0),
115 fPhic(0),
116 fCoef1(0),
117 fCoef2(0),
118 fCoef3(0),
119 fNloop(0),
120 fPhiWin(0),
121 fLambdaWin(0),
122 fVert(vert),
123 fVertexer(0),
124 fListOfTracks(0),
125 fListOfSATracks(0),
126 fITSclusters(0),
127 fInwardFlag(0),
128 fOuterStartLayer(0),
129 fInnerStartLayer(5),
130 fMinNPoints(0),
131 fMinQ(0.),
132 fCluLayer(0),
133 fCluCoord(0)
134 {
135   // Standard constructor (Vertex is known and passed to this obj.)
136   if (geom) {
137     AliWarning("\"geom\" is actually a dummy argument !");
138   }
139   Init();
140  
141 }
142
143 //____________________________________________________________________________
144 AliITStrackerSA::AliITStrackerSA(const Char_t *geom, AliITSVertexer *vertexer):AliITStrackerMI(0),
145 fPhiEstimate(0),
146 fITSStandAlone(0),
147 fLambdac(0),
148 fPhic(0),
149 fCoef1(0),
150 fCoef2(0),
151 fCoef3(0),
152 fNloop(0),
153 fPhiWin(0),
154 fLambdaWin(0),
155 fVert(),
156 fVertexer(vertexer),
157 fListOfTracks(0),
158 fListOfSATracks(0),
159 fITSclusters(0),
160 fInwardFlag(0),
161 fOuterStartLayer(0),
162 fInnerStartLayer(5),
163 fMinNPoints(0),
164 fMinQ(0.),
165 fCluLayer(0),
166 fCluCoord(0)
167 {
168   // Standard constructor (Vertex is unknown - vertexer is passed to this obj)
169   if (geom) {
170     AliWarning("\"geom\" is actually a dummy argument !");
171   }
172   Init();
173   fVertexer = vertexer;
174  
175 }
176
177 //____________________________________________________________________________
178 AliITStrackerSA::AliITStrackerSA(const AliITStrackerSA& tracker):AliITStrackerMI(),
179 fPhiEstimate(tracker.fPhiEstimate),
180 fITSStandAlone(tracker.fITSStandAlone),
181 fLambdac(tracker.fLambdac),
182 fPhic(tracker.fPhic),
183 fCoef1(tracker.fCoef1),
184 fCoef2(tracker.fCoef2),
185 fCoef3(tracker.fCoef3),
186 fNloop(tracker.fNloop),
187 fPhiWin(tracker.fPhiWin),
188 fLambdaWin(tracker.fLambdaWin),
189 fVert(tracker.fVert),
190 fVertexer(tracker.fVertexer),
191 fListOfTracks(tracker.fListOfTracks),
192 fListOfSATracks(tracker.fListOfSATracks),
193 fITSclusters(tracker.fITSclusters),
194 fInwardFlag(tracker.fInwardFlag),
195 fOuterStartLayer(tracker.fOuterStartLayer),
196 fInnerStartLayer(tracker.fInnerStartLayer),
197 fMinNPoints(tracker.fMinNPoints),
198 fMinQ(tracker.fMinQ),
199 fCluLayer(tracker.fCluLayer),
200 fCluCoord(tracker.fCluCoord) {
201   // Copy constructor
202   for(Int_t i=0;i<2;i++){
203     fPoint1[i]=tracker.fPoint1[i];
204     fPoint2[i]=tracker.fPoint2[i];
205     fPoint3[i]=tracker.fPoint3[i];
206     fPointc[i]=tracker.fPointc[i];
207   }
208   if(tracker.fVertexer && tracker.fVert){
209     fVert = new AliESDVertex(*tracker.fVert);
210   }
211   else {
212     fVert = tracker.fVert;
213   }
214   for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
215     fCluLayer[i] = tracker.fCluLayer[i];
216     fCluCoord[i] = tracker.fCluCoord[i];
217   } 
218 }
219 //______________________________________________________________________
220 AliITStrackerSA& AliITStrackerSA::operator=(const AliITStrackerSA& source){
221     // Assignment operator. 
222   this->~AliITStrackerSA();
223   new(this) AliITStrackerSA(source);
224   return *this;
225  
226 }
227
228 //____________________________________________________________________________
229 AliITStrackerSA::~AliITStrackerSA(){
230   // destructor
231   // if fVertexer is not null, the AliESDVertex obj. is owned by this class
232   // and is deleted here
233   if(fVertexer){
234     if(fVert)delete fVert;
235   }
236   fVert = 0;
237   fVertexer = 0;
238  
239   if(fPhiWin)delete []fPhiWin;
240   if(fLambdaWin)delete []fLambdaWin;
241   fListOfTracks->Delete();
242   delete fListOfTracks;
243   fListOfSATracks->Delete();
244   delete fListOfSATracks;
245   if(fCluLayer){
246     for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
247       if(fCluLayer[i]){
248         fCluLayer[i]->Delete();
249         delete fCluLayer[i];
250       }
251     }
252     delete [] fCluLayer;
253   }
254   if(fCluCoord){
255     for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
256       if(fCluCoord[i]){
257         fCluCoord[i]->Delete();
258         delete fCluCoord[i];
259       }
260     }
261     delete [] fCluCoord;
262   }
263   
264 }
265
266 //____________________________________________________________________________
267 Int_t AliITStrackerSA::Clusters2Tracks(AliESDEvent *event){
268 // This method is used to find and fit the tracks. By default the corresponding
269 // method in the parent class is invoked. In this way a combined tracking
270 // TPC+ITS is performed. If the flag fITSStandAlone is true, the tracking
271 // is done in the ITS only. In the standard reconstruction chain this option
272 // can be set via AliReconstruction::SetOption("ITS","onlyITS")
273   Int_t rc=0;
274   if(!fITSStandAlone){
275     rc=AliITStrackerMI::Clusters2Tracks(event);
276   }
277   else {
278     AliDebug(1,"Stand Alone flag set: doing tracking in ITS alone\n");
279   }
280   if(!rc) rc=FindTracks(event);
281   return rc;
282 }
283
284 //____________________________________________________________________________
285 void AliITStrackerSA::Init(){
286   //  Reset all data members
287     fPhiEstimate=0;
288     for(Int_t i=0;i<3;i++){fPoint1[i]=0;fPoint2[i]=0;fPoint3[i]=0;}
289     fLambdac=0;
290     fPhic=0;
291     fCoef1=0;
292     fCoef2=0;
293     fCoef3=0;
294     fPointc[0]=0;
295     fPointc[1]=0;
296     fVert = 0;
297     fVertexer = 0;
298     Int_t nLoops=AliITSReconstructor::GetRecoParam()->GetNLoopsSA();
299     if(nLoops==33){
300       SetFixedWindowSizes();
301     }else{
302       Double_t phimin=AliITSReconstructor::GetRecoParam()->GetMinPhiSA();
303       Double_t phimax=AliITSReconstructor::GetRecoParam()->GetMaxPhiSA();
304       Double_t lambmin=AliITSReconstructor::GetRecoParam()->GetMinLambdaSA();
305       Double_t lambmax=AliITSReconstructor::GetRecoParam()->GetMaxLambdaSA();
306       SetCalculatedWindowSizes(nLoops,phimin,phimax,lambmin,lambmax);
307     }
308     fMinQ=AliITSReconstructor::GetRecoParam()->GetSAMinClusterCharge();
309     fITSclusters = 0;
310     SetOuterStartLayer(1);
311     SetSAFlag(kFALSE);
312     fListOfTracks=new TObjArray(0,0);
313     fListOfSATracks=new TObjArray(0,0);
314     fCluLayer = 0;
315     fCluCoord = 0;
316     fMinNPoints = 3;
317  }
318 //_______________________________________________________________________
319 void AliITStrackerSA::ResetForFinding(){
320   //  Reset data members used in all loops during track finding
321     fPhiEstimate=0;
322     for(Int_t i=0;i<3;i++){fPoint1[i]=0;fPoint2[i]=0;fPoint3[i]=0;}
323     fLambdac=0;
324     fPhic=0;
325     fCoef1=0;
326     fCoef2=0;
327     fCoef3=0;
328     fPointc[0]=0;
329     fPointc[1]=0;
330     fListOfTracks->Delete();
331     fListOfSATracks->Delete();
332 }
333
334  
335
336 //______________________________________________________________________
337 Int_t AliITStrackerSA::FindTracks(AliESDEvent* event){
338
339 // Track finder using the ESD object
340
341   AliDebug(2,Form(" field is %f",event->GetMagneticField()));
342   AliDebug(2,Form("SKIPPING %d %d %d %d %d %d",ForceSkippingOfLayer(0),ForceSkippingOfLayer(1),ForceSkippingOfLayer(2),ForceSkippingOfLayer(3),ForceSkippingOfLayer(4),ForceSkippingOfLayer(5)));
343
344   if(!fITSclusters){
345     Fatal("FindTracks","ITS cluster tree is not accessed - Abort!!!\n Please use method SetClusterTree to pass the pointer to the tree\n");
346     return -1;
347   }
348   //Reads event and mark clusters of traks already found, with flag kITSin
349   Int_t nentr=event->GetNumberOfTracks();
350   if(AliITSReconstructor::GetRecoParam()->GetSAUseAllClusters()==kFALSE) {
351     while (nentr--) {
352       AliESDtrack *track=event->GetTrack(nentr);
353       if ((track->GetStatus()&AliESDtrack::kITSin) == AliESDtrack::kITSin){
354         Int_t idx[12];
355         Int_t ncl = track->GetITSclusters(idx);
356         for(Int_t k=0;k<ncl;k++){
357           AliITSRecPoint* cll = (AliITSRecPoint*)GetCluster(idx[k]);
358           cll->SetBit(kSAflag);
359         }
360       }
361     }
362   }
363   //Get primary vertex
364   Double_t primaryVertex[3];
365   event->GetVertex()->GetXYZ(primaryVertex);
366   //Creates TClonesArray with clusters for each layer. The clusters already used
367   //by AliITStrackerMI are not considered
368   Int_t nclusters[AliITSgeomTGeo::kNLayers]={0,0,0,0,0,0};
369   Int_t dmar[AliITSgeomTGeo::kNLayers]={0,0,0,0,0,0};
370   if (fCluLayer == 0) {
371     fCluLayer = new TClonesArray*[AliITSgeomTGeo::kNLayers];
372     fCluCoord = new TClonesArray*[AliITSgeomTGeo::kNLayers];
373     for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
374       fCluLayer[i]=0;
375       fCluCoord[i]=0;
376     }
377   }
378   for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++){
379     AliITSlayer &layer=fgLayers[i];
380     if (!ForceSkippingOfLayer(i)) {
381       for(Int_t cli=0;cli<layer.GetNumberOfClusters();cli++){
382         AliITSRecPoint* cls = (AliITSRecPoint*)layer.GetCluster(cli);
383         if(cls->TestBit(kSAflag)==kTRUE) continue; //clusters used by TPC prol.
384         if(cls->GetQ()==0) continue; //fake clusters dead zones
385         if(i>1 && cls->GetQ()<=fMinQ) continue; // cut on SDD and SSD cluster charge
386         nclusters[i]++;
387       }
388     }
389     dmar[i]=0;
390     delete fCluLayer[i];
391     fCluLayer[i] = new TClonesArray("AliITSRecPoint",nclusters[i]);
392     delete fCluCoord[i];
393     fCluCoord[i] = new TClonesArray("AliITSclusterTable",nclusters[i]);
394   }
395
396   for(Int_t ilay=0;ilay<AliITSgeomTGeo::GetNLayers();ilay++){
397     TClonesArray &clulay = *fCluLayer[ilay];
398     TClonesArray &clucoo = *fCluCoord[ilay];
399     AliITSlayer &layer=fgLayers[ilay];
400     if (!ForceSkippingOfLayer(ilay)) {
401       for(Int_t cli=0;cli<layer.GetNumberOfClusters();cli++){
402         AliITSRecPoint* cls = (AliITSRecPoint*)layer.GetCluster(cli);
403         if(cls->TestBit(kSAflag)==kTRUE) continue;
404         if(cls->GetQ()==0) continue;
405         if(ilay>1 && cls->GetQ()<=fMinQ) continue; 
406         Double_t phi=0;Double_t lambda=0;
407         Float_t x=0;Float_t y=0;Float_t z=0;
408         Float_t sx=0;Float_t sy=0;Float_t sz=0;
409         GetCoorAngles(cls,phi,lambda,x,y,z,primaryVertex);
410         GetCoorErrors(cls,sx,sy,sz);
411         new (clulay[dmar[ilay]]) AliITSRecPoint(*cls);
412         new (clucoo[dmar[ilay]]) AliITSclusterTable(x,y,z,sx,sy,sz,phi,lambda,cli);
413         dmar[ilay]++;
414       }
415     }
416   }
417    
418   // track counter
419   Int_t ntrack=0;
420
421   static Int_t nClusLay[AliITSgeomTGeo::kNLayers];//counter for clusters on each layer
422
423   if(AliITSReconstructor::GetRecoParam()->GetAllowProlongationWithEmptyRoad()) fMinNPoints=2;
424
425  
426   // loop on minimum number of points
427   for(Int_t iMinNPoints=AliITSgeomTGeo::GetNLayers(); iMinNPoints>=fMinNPoints; iMinNPoints--) {
428
429     if(!fInwardFlag){ // Tracking outwards from the inner layers
430       // loop on starting layer for track finding 
431       for(Int_t innLay=0; innLay<=fOuterStartLayer; innLay++) {
432         if(ForceSkippingOfLayer(innLay)) continue; 
433         Int_t minNPoints=iMinNPoints-innLay;
434         for(Int_t i=innLay+1;i<AliITSgeomTGeo::GetNLayers();i++)
435           if(ForceSkippingOfLayer(i)) 
436             minNPoints--;
437         if(minNPoints<fMinNPoints) continue;
438
439         // loop on phi and lambda window size
440         for(Int_t nloop=0;nloop<fNloop;nloop++){
441           Int_t nclInnLay=fCluLayer[innLay]->GetEntries();
442           while(nclInnLay--){ 
443             ResetForFinding();
444             Bool_t useRP=SetFirstPoint(innLay,nclInnLay,primaryVertex);
445             if(!useRP) continue;            
446             AliITStrackSA* trs = new AliITStrackSA(); 
447             
448             Int_t pflag=0;          
449             Int_t kk;
450             for(kk=0;kk<AliITSgeomTGeo::GetNLayers();kk++) nClusLay[kk] = 0;
451             
452             kk=0;
453             nClusLay[kk] = SearchClusters(innLay,fPhiWin[nloop],fLambdaWin[nloop],
454                                           trs,primaryVertex[2],pflag);
455             for(Int_t nextLay=innLay+1; nextLay<AliITSgeomTGeo::GetNLayers(); nextLay++) {
456               kk++;
457               nClusLay[kk] = SearchClusters(nextLay,fPhiWin[nloop],fLambdaWin[nloop],
458                                             trs,primaryVertex[2],pflag);
459               if(nClusLay[kk]!=0){
460                 pflag=1;
461                 if(kk==1) {
462                   fPoint3[0]=fPointc[0];
463                   fPoint3[1]=fPointc[1];
464                 } else {
465                   UpdatePoints();
466                 }
467               }
468             }
469             
470             Int_t layOK=0;
471             for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers()-innLay;nnp++){
472               if(nClusLay[nnp]!=0) layOK+=1;
473             }
474             if(layOK>=minNPoints){ 
475               AliDebug(2,Form("---NPOINTS: %d; MAP: %d %d %d %d %d %d\n",layOK,nClusLay[0],nClusLay[1],nClusLay[2],nClusLay[3],nClusLay[4],nClusLay[5]));
476               AliITStrackV2* tr2 = 0;
477               tr2 = FitTrack(trs,primaryVertex);
478               if(!tr2) continue;
479               AliDebug(2,Form("---NPOINTS fit: %d\n",tr2->GetNumberOfClusters()));
480               
481               StoreTrack(tr2,event);
482               ntrack++;
483               
484             }   
485             
486             delete trs;
487           }//end loop on clusters of innLay
488         } //end loop on window sizes
489       } //end loop on innLay
490     }else{// Tracking inwards from the outer layers
491     // loop on starting layer for track finding 
492       for(Int_t outLay=AliITSgeomTGeo::GetNLayers()-1; outLay>=fInnerStartLayer; outLay--) {
493
494         if(ForceSkippingOfLayer(outLay)) continue;
495         Int_t minNPoints=iMinNPoints-(AliITSgeomTGeo::GetNLayers()-1-outLay);
496         for(Int_t i=0;i<outLay-1;i++)
497           if(ForceSkippingOfLayer(i)) 
498             minNPoints--;
499         if(minNPoints<fMinNPoints) continue;
500         
501         // loop on phi and lambda window size
502         for(Int_t nloop=0;nloop<fNloop;nloop++){
503           Int_t nclOutLay=fCluLayer[outLay]->GetEntries();
504           while(nclOutLay--){ 
505             ResetForFinding();
506             Bool_t useRP=SetFirstPoint(outLay,nclOutLay,primaryVertex);
507             if(!useRP) continue;            
508             AliITStrackSA* trs = new AliITStrackSA(); 
509             
510             Int_t pflag=0;          
511             Int_t kk;
512             for(kk=0;kk<AliITSgeomTGeo::GetNLayers();kk++) nClusLay[kk] = 0;
513             
514             kk=0;
515             nClusLay[kk] = SearchClusters(outLay,fPhiWin[nloop],fLambdaWin[nloop],
516                                   trs,primaryVertex[2],pflag);
517             for(Int_t nextLay=outLay-1; nextLay>=0; nextLay--) {
518               kk++;
519               nClusLay[kk] = SearchClusters(nextLay,fPhiWin[nloop],fLambdaWin[nloop],
520                                             trs,primaryVertex[2],pflag);
521               if(nClusLay[kk]!=0){
522                 pflag=1;
523                 if(kk==1) {
524                   fPoint3[0]=fPointc[0];
525                   fPoint3[1]=fPointc[1];
526                 } else {
527                   UpdatePoints();
528                 }
529               }
530             }
531           
532             Int_t layOK=0;
533             for(Int_t nnp=outLay; nnp>=0; nnp--){
534               if(nClusLay[nnp]!=0) layOK+=1;
535             }
536             if(layOK>=minNPoints){ 
537               AliDebug(2,Form("---NPOINTS: %d; MAP: %d %d %d %d %d %d\n",layOK,nClusLay[0],nClusLay[1],nClusLay[2],nClusLay[3],nClusLay[4],nClusLay[5]));
538               AliITStrackV2* tr2 = 0;
539               tr2 = FitTrack(trs,primaryVertex);
540               if(!tr2) continue;
541               AliDebug(2,Form("---NPOINTS fit: %d\n",tr2->GetNumberOfClusters()));
542               
543               StoreTrack(tr2,event);
544               ntrack++;
545               
546             }   
547             
548             delete trs;
549         }//end loop on clusters of innLay
550         } //end loop on window sizes
551       } //end loop on innLay
552     } // end if (fInwardFlag)
553   }//end loop on min points
554
555   // search for 1-point tracks in SPD, only for cosmics
556   // (A.Dainese 21.03.08)
557   if(AliITSReconstructor::GetRecoParam()->GetSAOnePointTracks() && 
558      TMath::Abs(event->GetMagneticField())<0.01) {
559     Int_t outerLayer=1; // only SPD
560     for(Int_t innLay=0; innLay<=TMath::Min(1,fOuterStartLayer); innLay++) {
561       //   counter for clusters on each layer  
562
563       for(Int_t nloop=0;nloop<fNloop;nloop++){
564         Int_t nclInnLay=fCluLayer[innLay]->GetEntries();
565         while(nclInnLay--){ //loop starting from layer innLay
566           ResetForFinding();
567           Bool_t useRP=SetFirstPoint(innLay,nclInnLay,primaryVertex);
568           if(!useRP) continue;
569           AliITStrackSA* trs = new AliITStrackSA(); 
570             
571           Int_t pflag=0;            
572           Int_t kk;
573           for(kk=0;kk<AliITSgeomTGeo::GetNLayers();kk++) nClusLay[kk] = 0;
574           
575           kk=0;
576           nClusLay[kk] = SearchClusters(innLay,fPhiWin[nloop],fLambdaWin[nloop],
577                                   trs,primaryVertex[2],pflag);
578           for(Int_t nextLay=innLay+1; nextLay<=outerLayer; nextLay++) {
579             kk++;
580             nClusLay[kk] = SearchClusters(nextLay,fPhiWin[nloop],fLambdaWin[nloop],
581                                     trs,primaryVertex[2],pflag);
582             if(nClusLay[kk]!=0){
583               pflag=1;
584               if(kk==1) {
585                 fPoint3[0]=fPointc[0];
586                 fPoint3[1]=fPointc[1];
587               } else {
588                 UpdatePoints();
589               }
590             }
591           }
592           
593           Int_t layOK=0;
594           for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers()-innLay;nnp++){
595             if(nClusLay[nnp]!=0) layOK+=1;
596           }
597           if(layOK==1) {
598             AliDebug(2,Form("----NPOINTS: %d; MAP: %d %d %d %d %d %d\n",layOK,nClusLay[0],nClusLay[1],nClusLay[2],nClusLay[3],nClusLay[4],nClusLay[5]));
599             AliITStrackV2* tr2 = 0;
600             Bool_t onePoint = kTRUE;
601             tr2 = FitTrack(trs,primaryVertex,onePoint);
602             if(!tr2) continue;
603             AliDebug(2,Form("----NPOINTS fit: %d\n",tr2->GetNumberOfClusters()));
604             
605             StoreTrack(tr2,event);
606             ntrack++;
607             
608           }   
609           
610           delete trs;
611         }//end loop on clusters of innLay
612       } //end loop on window sizes
613       
614     } //end loop on innLay
615   } // end search 1-point tracks
616   
617   Info("FindTracks","Number of found tracks: %d",event->GetNumberOfTracks());
618   return 0;
619
620 }
621  
622 //________________________________________________________________________
623
624 AliITStrackV2* AliITStrackerSA::FitTrack(AliITStrackSA* tr,Double_t *primaryVertex,Bool_t onePoint) {
625   //fit of the found track (most general case, also <6 points, layers missing)
626   // A.Dainese 16.11.07 
627
628   
629   const Int_t kMaxClu=AliITStrackSA::kMaxNumberOfClusters;
630
631   static Int_t firstmod[AliITSgeomTGeo::kNLayers];
632   
633   static Int_t clind[AliITSgeomTGeo::kNLayers][kMaxClu];
634   static Int_t clmark[AliITSgeomTGeo::kNLayers][kMaxClu];
635   static Int_t nnn[AliITSgeomTGeo::kNLayers];
636   static Int_t kkk[AliITSgeomTGeo::kNLayers];
637   static Int_t end[AliITSgeomTGeo::kNLayers];
638   static AliITSRecPoint *listlayer[AliITSgeomTGeo::kNLayers][kMaxClu];
639
640   for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
641     firstmod[i]=AliITSgeomTGeo::GetModuleIndex(i+1,1,1);
642     nnn[i]=0;
643     kkk[i]=0;
644     end[i]=0;
645     for(Int_t j=0;j<kMaxClu; j++){
646       clind[i][j]=0;
647       clmark[i][j]=0;
648       listlayer[i][j]=0;
649    }
650   }
651   
652
653   Int_t nclusters = tr->GetNumberOfClustersSA();
654   for(Int_t ncl=0;ncl<nclusters;ncl++){
655     Int_t index = tr->GetClusterIndexSA(ncl); 
656     AliITSRecPoint* cl = (AliITSRecPoint*)GetCluster(index);
657     if(cl->TestBit(kSAflag)==kTRUE) cl->ResetBit(kSAflag);
658     Int_t lay = (index & 0xf0000000) >> 28;
659     Int_t nInLay=end[lay];
660     listlayer[lay][nInLay]=cl;
661     Int_t ind=nnn[lay];
662     clind[lay][ind]=index;
663     end[lay]++;
664   }
665
666   for(Int_t nlay=0;nlay<AliITSgeomTGeo::GetNLayers();nlay++){
667     for(Int_t ncl=0;ncl<tr->GetNumberOfMarked(nlay);ncl++){
668       Int_t mark = tr->GetClusterMark(nlay,ncl);
669       Int_t ind=kkk[nlay];
670       clmark[nlay][ind]=mark;
671     }
672   }
673
674
675   Int_t firstLay=-1,secondLay=-1;
676   for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
677     if(end[i]==0) {
678       end[i]=1;
679     }else{
680       if(firstLay==-1) {
681         firstLay=i;
682       } else if(secondLay==-1) {
683         secondLay=i;
684       }
685     }
686   }
687
688   if(firstLay==-1 || (secondLay==-1 && !onePoint)) return 0;
689   
690   for(Int_t l0=0;l0<end[0];l0++){ //loop on layer 1
691     AliITSRecPoint* cl0 = (AliITSRecPoint*)listlayer[0][l0];
692     for(Int_t l1=0;l1<end[1];l1++){ //loop on layer 2
693       AliITSRecPoint* cl1 = (AliITSRecPoint*)listlayer[1][l1];
694       for(Int_t l2=0;l2<end[2];l2++){  //loop on layer 3
695         AliITSRecPoint* cl2 = (AliITSRecPoint*)listlayer[2][l2];
696         for(Int_t l3=0;l3<end[3];l3++){ //loop on layer 4   
697           AliITSRecPoint* cl3 = (AliITSRecPoint*)listlayer[3][l3];
698           for(Int_t l4=0;l4<end[4];l4++){ //loop on layer 5
699             AliITSRecPoint* cl4 = (AliITSRecPoint*)listlayer[4][l4];
700             for(Int_t l5=0;l5<end[5];l5++){ //loop on layer 6  
701               AliITSRecPoint* cl5 = (AliITSRecPoint*)listlayer[5][l5];
702
703
704               Double_t x1,y1,z1,sx1,sy1,sz1;
705               Double_t x2,y2,z2,sx2,sy2,sz2;
706               AliITSRecPoint* p1=0;
707               AliITSRecPoint* p2=0;
708               Int_t index1=0,index2=0;
709               Int_t mrk1=0,mrk2=0;
710
711               switch(firstLay) {
712               case 0:
713                 p1=cl0;
714                 index1=clind[0][l0];mrk1=clmark[0][l0];
715                 break;
716               case 1:
717                 p1=cl1;
718                 index1=clind[1][l1];mrk1=clmark[1][l1];
719                 break;
720               case 2:
721                 p1=cl2;
722                 index1=clind[2][l2];mrk1=clmark[2][l2];
723                 break;
724               case 3:
725                 p1=cl3;
726                 index1=clind[3][l3];mrk1=clmark[3][l3];
727                 break;
728               case 4:
729                 p1=cl4;
730                 index1=clind[4][l4];mrk1=clmark[4][l4];
731                 break;
732               }
733
734               switch(secondLay) {
735               case 1:
736                 p2=cl1;
737                 index2=clind[1][l1];mrk2=clmark[1][l1];
738                 break;
739               case 2:
740                 p2=cl2;
741                 index2=clind[2][l2];mrk2=clmark[2][l2];
742                 break;
743               case 3:
744                 p2=cl3;
745                 index2=clind[3][l3];mrk2=clmark[3][l3];
746                 break;
747               case 4:
748                 p2=cl4;
749                 index2=clind[4][l4];mrk2=clmark[4][l4];
750                 break;
751               case 5:
752                 p2=cl5;
753                 index2=clind[5][l5];mrk2=clmark[5][l5];
754                 break;
755               default:
756                 p2=0;
757                 index2=-1;mrk2=-1;
758                 break;
759               }
760
761               Int_t module1 = p1->GetDetectorIndex()+firstmod[firstLay]; 
762               Int_t layer,ladder,detector;
763               AliITSgeomTGeo::GetModuleId(module1,layer,ladder,detector);
764               Float_t yclu1 = p1->GetY();
765               Float_t zclu1 = p1->GetZ();
766               Double_t cv=0,tgl2=0,phi2=0;
767               
768               Int_t cln1=mrk1;
769               AliITSclusterTable* arr1 = (AliITSclusterTable*)GetClusterCoord(firstLay,cln1);
770               x1 = arr1->GetX();
771               y1 = arr1->GetY();
772               z1 = arr1->GetZ();
773               sx1 = arr1->GetSx();
774               sy1 = arr1->GetSy();
775               sz1 = arr1->GetSz();
776
777               if(secondLay>0) {
778                 Int_t cln2=mrk2;
779                 AliITSclusterTable* arr2 = (AliITSclusterTable*)GetClusterCoord(secondLay,cln2);
780                 x2 = arr2->GetX();
781                 y2 = arr2->GetY();
782                 z2 = arr2->GetZ();
783                 sx2 = arr2->GetSx();
784                 sy2 = arr2->GetSy();
785                 sz2 = arr2->GetSz();
786                 cv = Curvature(primaryVertex[0],primaryVertex[1],x1,y1,x2,y2);
787                 tgl2 = (z2-z1)/TMath::Sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
788                 phi2 = TMath::ATan2((y2-y1),(x2-x1));
789               } else { // special case of 1-point tracks, only for cosmics (B=0)
790                 x2 = primaryVertex[0];
791                 y2 = primaryVertex[1];
792                 z2 = primaryVertex[2];
793                 cv = 0;
794                 tgl2 = (z1-z2)/TMath::Sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
795                 phi2 = TMath::ATan2((y1-y2),(x1-x2));
796               }
797
798
799               AliITStrackSA* trac = new AliITStrackSA(layer,ladder,detector,yclu1,zclu1,phi2,tgl2,cv,1);
800
801
802               if(cl5!=0) {
803                 trac->AddClusterV2(5,(clind[5][l5] & 0x0fffffff)>>0);
804                 trac->AddClusterMark(5,clmark[5][l5]);
805               }
806               if(cl4!=0){
807                 trac->AddClusterV2(4,(clind[4][l4] & 0x0fffffff)>>0);
808                 trac->AddClusterMark(4,clmark[4][l4]);
809               }
810               if(cl3!=0){
811                 trac->AddClusterV2(3,(clind[3][l3] & 0x0fffffff)>>0);
812                 trac->AddClusterMark(3,clmark[3][l3]);
813               }
814               if(cl2!=0){
815                 trac->AddClusterV2(2,(clind[2][l2] & 0x0fffffff)>>0);
816                 trac->AddClusterMark(2,clmark[2][l2]);
817               }
818               if(cl1!=0){
819                 trac->AddClusterV2(1,(clind[1][l1] & 0x0fffffff)>>0);
820                 trac->AddClusterMark(1,clmark[1][l1]);
821               }
822               if(cl0!=0){
823                 trac->AddClusterV2(0,(clind[0][l0] & 0x0fffffff)>>0);
824                 trac->AddClusterMark(0,clmark[0][l0]);
825               }
826
827               //fit with Kalman filter using AliITStrackerMI::RefitAt()
828               AliITStrackMI* ot = new AliITStrackSA(*trac);
829               
830               ot->ResetCovariance(10.);
831               ot->ResetClusters();
832               
833               // Propagate inside the innermost layer with a cluster 
834               if(ot->Propagate(ot->GetX()-0.1*ot->GetX())) {
835
836                 if(RefitAt(AliITSRecoParam::GetrInsideITSscreen(),ot,trac)){ //fit from layer 1 to layer 6
837                   AliITStrackMI *otrack2 = new AliITStrackMI(*ot);
838                   otrack2->ResetCovariance(10.); 
839                   otrack2->ResetClusters();
840                   //fit from layer 6 to layer 1
841                   if(RefitAt(AliITSRecoParam::GetrInsideSPD1(),otrack2,ot)) {
842                     fListOfTracks->AddLast(otrack2);
843                     fListOfSATracks->AddLast(trac);
844                   } else {
845                     delete otrack2;
846                     delete trac;
847                   }
848                               
849                 }       
850               }
851               delete ot;
852             }//end loop layer 6
853           }//end loop layer 5
854         }//end loop layer 4        
855       }//end loop layer 3
856     }//end loop layer 2 
857   }//end loop layer 1
858
859
860
861
862   if(fListOfTracks->GetEntries()==0) return 0;
863
864   Int_t lowchi2 = FindTrackLowChiSquare();
865   AliITStrackV2* otrack =(AliITStrackV2*)fListOfTracks->At(lowchi2);
866   AliITStrackSA* trsa = (AliITStrackSA*)fListOfSATracks->At(lowchi2);
867  
868   if(otrack==0) return 0;
869
870   Int_t indexc[AliITSgeomTGeo::kNLayers];
871   for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) indexc[i]=0;
872   for(Int_t nind=0;nind<otrack->GetNumberOfClusters();nind++){
873     indexc[nind] = otrack->GetClusterIndex(nind);
874   }      
875   Int_t labl[6][3];
876   for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
877     if(i<otrack->GetNumberOfClusters()) {
878       AliITSRecPoint* cl = (AliITSRecPoint*)GetCluster(indexc[i]);
879       labl[i][0]=cl->GetLabel(0);
880       labl[i][1]=cl->GetLabel(1);
881       labl[i][2]=cl->GetLabel(2);
882     } else {
883       labl[i][0]=-1;
884       labl[i][1]=-1;
885       labl[i][2]=-1;
886     }
887   }
888
889   CookLabel(otrack,0.); //MI change - to see fake ratio
890  
891   Int_t label=FindLabel(labl[0][0],labl[1][0],labl[2][0],labl[3][0],labl[4][0],labl[5][0]);
892   Int_t lflag=0;
893   for(Int_t i=0;i<otrack->GetNumberOfClusters();i++)
894     if(labl[i][0]==label || labl[i][1]==label || labl[i][2]==label) lflag++;
895   
896   if(lflag<otrack->GetNumberOfClusters()) label = -label;
897   otrack->SetLabel(label);  
898
899   //remove clusters of found track
900   for(Int_t nlay=0;nlay<AliITSgeomTGeo::GetNLayers();nlay++){
901     for(Int_t cln=0;cln<trsa->GetNumberOfMarked(nlay);cln++){
902       Int_t index = trsa->GetClusterMark(nlay,cln);
903       fCluLayer[nlay]->RemoveAt(index);
904       RemoveClusterCoord(nlay,index);
905       fCluLayer[nlay]->Compress();
906     }    
907   }
908
909   return otrack;
910
911 }
912
913 //_______________________________________________________
914 void AliITStrackerSA::StoreTrack(AliITStrackV2 *t,AliESDEvent *event) const 
915 {
916   //
917   // Add new track to the ESD
918   //
919   AliESDtrack outtrack;
920   outtrack.UpdateTrackParams(t,AliESDtrack::kITSin);
921   for(Int_t i=0;i<12;i++) {
922     outtrack.SetITSModuleIndex(i,t->GetModuleIndex(i));
923   }
924   Double_t sdedx[4]={0.,0.,0.,0.};
925   for(Int_t i=0; i<4; i++) sdedx[i]=t->GetSampledEdx(i);
926   outtrack.SetITSdEdxSamples(sdedx);
927   event->AddTrack(&outtrack);
928
929   return;
930 }
931
932
933 //_______________________________________________________
934 Int_t AliITStrackerSA::SearchClusters(Int_t layer,Double_t phiwindow,Double_t lambdawindow, AliITStrackSA* trs,Double_t /*zvertex*/,Int_t pflag){
935   //function used to to find the clusters associated to the track
936
937   if(ForceSkippingOfLayer(layer)) return 0;
938
939   Int_t nc=0;
940   AliITSlayer &lay = fgLayers[layer];
941   Double_t r=lay.GetR();
942   if(pflag==1){      
943     Float_t cx1,cx2,cy1,cy2;
944     FindEquation(fPoint1[0],fPoint1[1],fPoint2[0],fPoint2[1],fPoint3[0],fPoint3[1],fCoef1,fCoef2,fCoef3);
945     if (FindIntersection(fCoef1,fCoef2,fCoef3,-r*r,cx1,cy1,cx2,cy2)==0)
946        return 0;
947     Double_t fi1=TMath::ATan2(cy1-fPoint1[1],cx1-fPoint1[0]);
948     Double_t fi2=TMath::ATan2(cy2-fPoint1[1],cx2-fPoint1[0]);
949     fPhiEstimate=ChoosePoint(fi1,fi2,fPhic);
950   }
951
952  
953   Int_t ncl = fCluLayer[layer]->GetEntries();
954   for (Int_t index=0; index<ncl; index++) {
955     AliITSRecPoint *c = (AliITSRecPoint*)fCluLayer[layer]->At(index);
956     if (!c) continue;
957     if (c->GetQ()<=0) continue;
958     if(layer>1 && c->GetQ()<=fMinQ) continue;
959     
960      AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(layer,index);
961      Double_t phi = arr->GetPhi();
962      if (TMath::Abs(phi-fPhiEstimate)>phiwindow) continue;
963
964      Double_t lambda = arr->GetLambda();
965      if (TMath::Abs(lambda-fLambdac)>lambdawindow) continue;
966
967      if(trs->GetNumberOfClustersSA()==trs->GetMaxNumberOfClusters()) return 0;
968      if(trs->GetNumberOfMarked(layer)==trs->GetMaxNMarkedPerLayer()) return 0;
969      Int_t orind = arr->GetOrInd();
970      trs->AddClusterSA(layer,orind);
971      trs->AddClusterMark(layer,index);
972        
973      nc++;
974      fLambdac=lambda;
975      fPhiEstimate=phi;
976
977      fPointc[0]=arr->GetX();
978      fPointc[1]=arr->GetY();
979
980   }
981   return nc;
982 }
983
984 //________________________________________________________________
985 Bool_t AliITStrackerSA::SetFirstPoint(Int_t lay, Int_t clu, Double_t* primaryVertex){
986   // Sets the first point (seed) for tracking
987
988   AliITSRecPoint* cl = (AliITSRecPoint*)fCluLayer[lay]->At(clu);
989   if(!cl) return kFALSE;
990   if (cl->GetQ()<=0) return kFALSE;
991   if(lay>1 && cl->GetQ()<=fMinQ) return kFALSE;
992
993   AliITSclusterTable* arr = (AliITSclusterTable*)GetClusterCoord(lay,clu);
994   fPhic = arr->GetPhi();
995   fLambdac = arr->GetLambda();
996   fPhiEstimate = fPhic;
997   fPoint1[0]=primaryVertex[0];
998   fPoint1[1]=primaryVertex[1];
999   fPoint2[0]=arr->GetX();
1000   fPoint2[1]=arr->GetY();
1001   return kTRUE; 
1002 }
1003
1004 //________________________________________________________________
1005 void AliITStrackerSA::UpdatePoints(){
1006   //update of points for the estimation of the curvature  
1007
1008   fPoint2[0]=fPoint3[0];
1009   fPoint2[1]=fPoint3[1];
1010   fPoint3[0]=fPointc[0];
1011   fPoint3[1]=fPointc[1];
1012
1013   
1014 }
1015
1016 //___________________________________________________________________
1017 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){
1018
1019    //given (x,y) of three recpoints (in global coordinates) 
1020    //returns the parameters a,b,c of circonference x*x + y*y +a*x + b*y +c
1021
1022    Float_t den = (x3-x1)*(y2-y1)-(x2-x1)*(y3-y1);
1023    if(den==0) return 0;
1024    a = ((y3-y1)*(x2*x2+y2*y2-x1*x1-y1*y1)-(y2-y1)*(x3*x3+y3*y3-x1*x1-y1*y1))/den;
1025    b = -(x2*x2-x1*x1+y2*y2-y1*y1+a*(x2-x1))/(y2-y1);
1026    c = -x1*x1-y1*y1-a*x1-b*y1;
1027    return 1;
1028  }
1029 //__________________________________________________________________________
1030  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){
1031  
1032  //Finds the intersection between the circonference of the track and the circonference centered in (0,0) represented by one layer
1033  //c2 is -rlayer*rlayer
1034
1035   if(a1==0) return 0;
1036  Double_t m = c2-c1; 
1037  Double_t aA = (b1*b1)/(a1*a1)+1;
1038  Double_t bB = (-2*m*b1/(a1*a1));
1039  Double_t cC = c2+(m*m)/(a1*a1);
1040  Double_t dD = bB*bB-4*aA*cC;
1041  if(dD<0) return 0;
1042  
1043  y1 = (-bB+TMath::Sqrt(dD))/(2*aA); 
1044  y2 = (-bB-TMath::Sqrt(dD))/(2*aA); 
1045  x1 = (c2-c1-b1*y1)/a1;
1046  x2 = (c2-c1-b1*y2)/a1;
1047
1048  return 1; 
1049 }
1050 //____________________________________________________________________
1051 Double_t AliITStrackerSA::Curvature(Double_t x1,Double_t y1,Double_t 
1052 x2,Double_t y2,Double_t x3,Double_t y3){
1053
1054   //calculates the curvature of track  
1055   Double_t den = (x3-x1)*(y2-y1)-(x2-x1)*(y3-y1);
1056   if(den==0) return 0;
1057   Double_t a = ((y3-y1)*(x2*x2+y2*y2-x1*x1-y1*y1)-(y2-y1)*(x3*x3+y3*y3-x1*x1-y1*y1))/den;
1058   Double_t b = -(x2*x2-x1*x1+y2*y2-y1*y1+a*(x2-x1))/(y2-y1);
1059   Double_t c = -x1*x1-y1*y1-a*x1-b*y1;
1060   Double_t xc=-a/2.;
1061
1062   if((a*a+b*b-4*c)<0) return 0;
1063   Double_t rad = TMath::Sqrt(a*a+b*b-4*c)/2.;
1064   if(rad==0) return 0;
1065   
1066   if((x1>0 && y1>0 && x1<xc)) rad*=-1;
1067   if((x1<0 && y1>0 && x1<xc)) rad*=-1;
1068   //  if((x1<0 && y1<0 && x1<xc)) rad*=-1;
1069   // if((x1>0 && y1<0 && x1<xc)) rad*=-1;
1070   
1071   return 1/rad;
1072  
1073 }
1074
1075
1076 //____________________________________________________________________
1077 Double_t AliITStrackerSA::ChoosePoint(Double_t p1, Double_t p2, Double_t pp){
1078
1079   //Returns the point closest to pp
1080
1081   Double_t diff1 = p1-pp;
1082   Double_t diff2 = p2-pp;
1083   
1084   if(TMath::Abs(diff1)<TMath::Abs(diff2)) fPhiEstimate=p1;
1085   else fPhiEstimate=p2;  
1086   return fPhiEstimate;
1087   
1088 }
1089
1090
1091 //_________________________________________________________________
1092 Int_t AliITStrackerSA::FindTrackLowChiSquare() const {
1093   // returns track with lowest chi square  
1094   Int_t dim=fListOfTracks->GetEntries();
1095   if(dim<=1) return 0;
1096   AliITStrackV2* trk = (AliITStrackV2*)fListOfTracks->At(0);
1097   Double_t minChi2=trk->GetChi2();
1098   Int_t index=0;
1099   for(Int_t i=1;i<dim;i++){
1100     trk = (AliITStrackV2*)fListOfTracks->At(i);
1101     Double_t chi2=trk->GetChi2();
1102     if(chi2<minChi2){
1103       minChi2=chi2;
1104       index=i;
1105     }
1106   }
1107   return index;
1108 }
1109
1110 //__________________________________________________________
1111 Int_t AliITStrackerSA::FindLabel(Int_t l0, Int_t l1, Int_t l2, Int_t l3, Int_t l4, Int_t l5){
1112
1113   //function used to determine the track label
1114   
1115   Int_t lb[6] = {l0,l1,l2,l3,l4,l5};
1116   Int_t aa[6]={1,1,1,1,1,1};
1117   Int_t ff=0; 
1118   Int_t ll=0;
1119   Int_t k=0;Int_t w=0;Int_t num=6;
1120   for(Int_t i=5;i>=0;i--) if(lb[i]==-1) num=i;
1121   
1122   while(k<num){
1123   
1124     for(Int_t i=k+1;i<num;i++){
1125     
1126       if(lb[k]==lb[i] && aa[k]!=0){
1127       
1128         aa[k]+=1;
1129         aa[i]=0;
1130       }
1131     }
1132     k++;
1133   }
1134
1135   while(w<num){
1136  
1137     for(Int_t j=0;j<6;j++){
1138       if(aa[w]<aa[j]){
1139       ff=aa[w];
1140       aa[w]=aa[j];
1141       aa[j]=ff;
1142       ll=lb[w];
1143       lb[w]=lb[j];
1144       lb[j]=ll;
1145      }
1146     }
1147     w++;
1148   }
1149   
1150   if(num<1) return -1; 
1151   return lb[num-1];
1152 }
1153
1154 //_____________________________________________________________________________
1155 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,
1156 Int_t gl12, Int_t gl13, Int_t gl14,Int_t gl15, Int_t gl16, Int_t gl17, Int_t gl18, Int_t minNPoints){
1157
1158  
1159   //function used to assign label to the found track. If track is fake, the label is negative
1160
1161   Int_t lb0[6] = {gl1,gl2,gl3,gl4,gl5,gl6};
1162   Int_t lb1[6] = {gl7,gl8,gl9,gl10,gl11,gl12};
1163   Int_t lb2[6] = {gl13,gl14,gl15,gl16,gl17,gl18};
1164   Int_t ll=FindLabel(lb0[0],lb0[1],lb0[2],lb0[3],lb0[4],lb0[5]);
1165   Int_t lflag=0;Int_t num=6;
1166   if(lb0[5]==-1 && lb1[5]==-1 && lb2[5]==-1) num=5;
1167
1168   for(Int_t i=0;i<num;i++){
1169     if(lb0[i]==ll || lb1[i]==ll || lb2[i]==ll) lflag+=1;
1170   }
1171
1172   if(lflag>=minNPoints) return ll;
1173   else return -ll;
1174
1175   
1176 }
1177 //_____________________________________________________________________________
1178 void AliITStrackerSA::SetCalculatedWindowSizes(Int_t n, Float_t phimin, Float_t phimax, Float_t lambdamin, Float_t lambdamax){
1179   // Set sizes of the phi and lambda windows used for track finding
1180   fNloop = n;
1181   if(fPhiWin) delete [] fPhiWin;
1182   if(fLambdaWin) delete [] fLambdaWin;
1183   fPhiWin = new Double_t[fNloop];
1184   fLambdaWin = new Double_t[fNloop];
1185   Float_t stepPhi=(phimax-phimin)/(Float_t)(fNloop-1);
1186   Float_t stepLambda=(lambdamax-lambdamin)/(Float_t)(fNloop-1);
1187   for(Int_t k=0;k<fNloop;k++){
1188     Float_t phi=phimin+k*stepPhi;
1189     Float_t lam=lambdamin+k*stepLambda;
1190     fPhiWin[k]=phi;
1191     fLambdaWin[k]=lam;
1192   }
1193 }
1194 //_____________________________________________________________________________
1195 void AliITStrackerSA::SetFixedWindowSizes(Int_t n, Double_t *phi, Double_t *lam){
1196   // Set sizes of the phi and lambda windows used for track finding
1197   fNloop = n;
1198   if(phi){ // user defined values
1199     fPhiWin = new Double_t[fNloop];
1200     fLambdaWin = new Double_t[fNloop];
1201     for(Int_t k=0;k<fNloop;k++){
1202       fPhiWin[k]=phi[k];
1203       fLambdaWin[k]=lam[k];
1204     }
1205   }
1206   else {  // default values
1207             
1208     Double_t phid[33]   = {0.002,0.003,0.004,0.0045,0.0047,
1209                            0.005,0.0053,0.0055,
1210                            0.006,0.0063,0.0065,0.007,0.0073,0.0075,0.0077,
1211                            0.008,0.0083,0.0085,0.0087,0.009,0.0095,0.0097,
1212                            0.01,0.0105,0.011,0.0115,0.012,0.0125,0.013,0.0135,0.0140,0.0145};
1213     Double_t lambdad[33] = {0.003,0.004,0.005,0.005,0.005,
1214                             0.005,0.005,0.006,
1215                             0.006,0.006,0.006,0.007,0.007,0.007,0.007,
1216                             0.007,0.007,0.007,0.007,0.007,0.007,0.007,
1217                             0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008,0.008};
1218     
1219     if(fNloop!=33){
1220       fNloop = 33;
1221     }
1222     
1223     
1224     fPhiWin = new Double_t[fNloop];
1225     fLambdaWin = new Double_t[fNloop];
1226
1227     Double_t factor=AliITSReconstructor::GetRecoParam()->GetFactorSAWindowSizes(); // possibility to enlarge windows for cosmics reco with large misalignments (A.Dainese)
1228   
1229     for(Int_t k=0;k<fNloop;k++){
1230       fPhiWin[k]=phid[k]*factor;
1231       fLambdaWin[k]=lambdad[k]*factor;
1232     }
1233   
1234   }
1235
1236 }
1237 //_______________________________________________________________________
1238 void AliITStrackerSA::GetCoorAngles(AliITSRecPoint* cl,Double_t &phi,Double_t &lambda, Float_t &x, Float_t &y,Float_t &z,Double_t* vertex){
1239   //Returns values of phi (azimuthal) and lambda angles for a given cluster
1240 /*  
1241   Double_t rot[9];     fGeom->GetRotMatrix(module,rot);
1242   Int_t lay,lad,det; fGeom->GetModuleId(module,lay,lad,det);
1243   Float_t tx,ty,tz;  fGeom->GetTrans(lay,lad,det,tx,ty,tz);     
1244
1245   Double_t alpha=TMath::ATan2(rot[1],rot[0])+TMath::Pi();
1246   Double_t phi1=TMath::Pi()/2+alpha;
1247   if (lay==1) phi1+=TMath::Pi();
1248
1249   Float_t cp=TMath::Cos(phi1), sp=TMath::Sin(phi1);
1250   Float_t r=tx*cp+ty*sp;
1251
1252   xyz= r*cp - cl->GetY()*sp;
1253   y= r*sp + cl->GetY()*cp;
1254   z=cl->GetZ();
1255 */
1256   Float_t xyz[3];
1257   cl->GetGlobalXYZ(xyz);
1258   x=xyz[0];
1259   y=xyz[1];
1260   z=xyz[2];
1261  
1262   phi=TMath::ATan2(y-vertex[1],x-vertex[0]);
1263   lambda=TMath::ATan2(z-vertex[2],TMath::Sqrt((x-vertex[0])*(x-vertex[0])+(y-vertex[1])*(y-vertex[1])));
1264 }
1265
1266 //________________________________________________________________________
1267 void AliITStrackerSA::GetCoorErrors(AliITSRecPoint* cl,Float_t &sx,Float_t &sy, Float_t &sz){
1268
1269   //returns sigmax, y, z of cluster in global coordinates
1270 /*
1271   Double_t rot[9];     fGeom->GetRotMatrix(module,rot);
1272   Int_t lay,lad,det; 
1273   AliITSgeomTGeo::GetModuleId(module,lay,lad,det);
1274  
1275   Double_t alpha=TMath::ATan2(rot[1],rot[0])+TMath::Pi();
1276   Double_t phi=TMath::Pi()/2+alpha;
1277   if (lay==1) phi+=TMath::Pi();
1278
1279   Float_t cp=TMath::Cos(phi), sp=TMath::Sin(phi);
1280 */
1281   Float_t covm[6];
1282   cl->GetGlobalCov(covm);
1283   sx=TMath::Sqrt(covm[0]);
1284   sy=TMath::Sqrt(covm[3]);
1285   sz=TMath::Sqrt(covm[5]);
1286 /*
1287   sx = TMath::Sqrt(sp*sp*cl->GetSigmaY2());
1288   sy = TMath::Sqrt(cp*cp*cl->GetSigmaY2());
1289   sz = TMath::Sqrt(cl->GetSigmaZ2());
1290 */
1291 }
1292