]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITStrackerSA.cxx
837708d5819bc11a6fd76bcd72e830caac2a1b51
[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     if(!fCluLayer[i]){
391       fCluLayer[i] = new TClonesArray("AliITSRecPoint",nclusters[i]);
392     }else{
393       fCluLayer[i]->Delete();
394       fCluLayer[i]->Expand(nclusters[i]);
395     }
396     if(!fCluCoord[i]){
397       fCluCoord[i] = new TClonesArray("AliITSclusterTable",nclusters[i]);
398     }else{
399       fCluCoord[i]->Delete();
400       fCluCoord[i]->Expand(nclusters[i]);
401     }
402   }
403
404   for(Int_t ilay=0;ilay<AliITSgeomTGeo::GetNLayers();ilay++){
405     TClonesArray &clulay = *fCluLayer[ilay];
406     TClonesArray &clucoo = *fCluCoord[ilay];
407     AliITSlayer &layer=fgLayers[ilay];
408     if (!ForceSkippingOfLayer(ilay)) {
409       for(Int_t cli=0;cli<layer.GetNumberOfClusters();cli++){
410         AliITSRecPoint* cls = (AliITSRecPoint*)layer.GetCluster(cli);
411         if(cls->TestBit(kSAflag)==kTRUE) continue;
412         if(cls->GetQ()==0) continue;
413         if(ilay>1 && cls->GetQ()<=fMinQ) continue; 
414         Double_t phi=0;Double_t lambda=0;
415         Float_t x=0;Float_t y=0;Float_t z=0;
416         Float_t sx=0;Float_t sy=0;Float_t sz=0;
417         GetCoorAngles(cls,phi,lambda,x,y,z,primaryVertex);
418         GetCoorErrors(cls,sx,sy,sz);
419         new (clulay[dmar[ilay]]) AliITSRecPoint(*cls);
420         new (clucoo[dmar[ilay]]) AliITSclusterTable(x,y,z,sx,sy,sz,phi,lambda,cli);
421         dmar[ilay]++;
422       }
423     }
424   }
425    
426   // track counter
427   Int_t ntrack=0;
428
429   static Int_t nClusLay[AliITSgeomTGeo::kNLayers];//counter for clusters on each layer
430
431   // loop on minimum number of points
432   for(Int_t iMinNPoints=AliITSgeomTGeo::GetNLayers(); iMinNPoints>=fMinNPoints; iMinNPoints--) {
433
434     if(!fInwardFlag){ // Tracking outwards from the inner layers
435       // loop on starting layer for track finding 
436       for(Int_t innLay=0; innLay<=fOuterStartLayer; innLay++) {
437         if(ForceSkippingOfLayer(innLay)) continue; 
438         Int_t minNPoints=iMinNPoints-innLay;
439         for(Int_t i=innLay+1;i<AliITSgeomTGeo::GetNLayers();i++)
440           if(ForceSkippingOfLayer(i)) 
441             minNPoints--;
442         if(minNPoints<fMinNPoints) continue;
443
444         // loop on phi and lambda window size
445         for(Int_t nloop=0;nloop<fNloop;nloop++){
446           Int_t nclInnLay=fCluLayer[innLay]->GetEntries();
447           while(nclInnLay--){ 
448             ResetForFinding();
449             Bool_t useRP=SetFirstPoint(innLay,nclInnLay,primaryVertex);
450             if(!useRP) continue;            
451             AliITStrackSA* trs = new AliITStrackSA(); 
452             
453             Int_t pflag=0;          
454             Int_t kk;
455             for(kk=0;kk<AliITSgeomTGeo::GetNLayers();kk++) nClusLay[kk] = 0;
456             
457             kk=0;
458             nClusLay[kk] = SearchClusters(innLay,fPhiWin[nloop],fLambdaWin[nloop],
459                                           trs,primaryVertex[2],pflag);
460             for(Int_t nextLay=innLay+1; nextLay<AliITSgeomTGeo::GetNLayers(); nextLay++) {
461               kk++;
462               nClusLay[kk] = SearchClusters(nextLay,fPhiWin[nloop],fLambdaWin[nloop],
463                                             trs,primaryVertex[2],pflag);
464               if(nClusLay[kk]!=0){
465                 pflag=1;
466                 if(kk==1) {
467                   fPoint3[0]=fPointc[0];
468                   fPoint3[1]=fPointc[1];
469                 } else {
470                   UpdatePoints();
471                 }
472               }
473             }
474             
475             Int_t layOK=0;
476             for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers()-innLay;nnp++){
477               if(nClusLay[nnp]!=0) layOK+=1;
478             }
479             if(layOK>=minNPoints){ 
480               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]));
481               AliITStrackV2* tr2 = 0;
482               tr2 = FitTrack(trs,primaryVertex);
483               if(!tr2) continue;
484               AliDebug(2,Form("---NPOINTS fit: %d\n",tr2->GetNumberOfClusters()));
485               
486               StoreTrack(tr2,event);
487               ntrack++;
488               
489             }   
490             
491             delete trs;
492           }//end loop on clusters of innLay
493         } //end loop on window sizes
494       } //end loop on innLay
495     }else{// Tracking inwards from the outer layers
496     // loop on starting layer for track finding 
497       for(Int_t outLay=AliITSgeomTGeo::GetNLayers()-1; outLay>=fInnerStartLayer; outLay--) {
498
499         if(ForceSkippingOfLayer(outLay)) continue;
500         Int_t minNPoints=iMinNPoints-(AliITSgeomTGeo::GetNLayers()-1-outLay);
501         for(Int_t i=0;i<outLay-1;i++)
502           if(ForceSkippingOfLayer(i)) 
503             minNPoints--;
504         if(minNPoints<fMinNPoints) continue;
505         
506         // loop on phi and lambda window size
507         for(Int_t nloop=0;nloop<fNloop;nloop++){
508           Int_t nclOutLay=fCluLayer[outLay]->GetEntries();
509           while(nclOutLay--){ 
510             ResetForFinding();
511             Bool_t useRP=SetFirstPoint(outLay,nclOutLay,primaryVertex);
512             if(!useRP) continue;            
513             AliITStrackSA* trs = new AliITStrackSA(); 
514             
515             Int_t pflag=0;          
516             Int_t kk;
517             for(kk=0;kk<AliITSgeomTGeo::GetNLayers();kk++) nClusLay[kk] = 0;
518             
519             kk=0;
520             nClusLay[kk] = SearchClusters(outLay,fPhiWin[nloop],fLambdaWin[nloop],
521                                   trs,primaryVertex[2],pflag);
522             for(Int_t nextLay=outLay-1; nextLay>=0; nextLay--) {
523               kk++;
524               nClusLay[kk] = SearchClusters(nextLay,fPhiWin[nloop],fLambdaWin[nloop],
525                                             trs,primaryVertex[2],pflag);
526               if(nClusLay[kk]!=0){
527                 pflag=1;
528                 if(kk==1) {
529                   fPoint3[0]=fPointc[0];
530                   fPoint3[1]=fPointc[1];
531                 } else {
532                   UpdatePoints();
533                 }
534               }
535             }
536           
537             Int_t layOK=0;
538             for(Int_t nnp=outLay; nnp>=0; nnp--){
539               if(nClusLay[nnp]!=0) layOK+=1;
540             }
541             if(layOK>=minNPoints){ 
542               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]));
543               AliITStrackV2* tr2 = 0;
544               tr2 = FitTrack(trs,primaryVertex);
545               if(!tr2) continue;
546               AliDebug(2,Form("---NPOINTS fit: %d\n",tr2->GetNumberOfClusters()));
547               
548               StoreTrack(tr2,event);
549               ntrack++;
550               
551             }   
552             
553             delete trs;
554         }//end loop on clusters of innLay
555         } //end loop on window sizes
556       } //end loop on innLay
557     } // end if (fInwardFlag)
558   }//end loop on min points
559
560   // search for 1-point tracks in SPD, only for cosmics
561   // (A.Dainese 21.03.08)
562   if(AliITSReconstructor::GetRecoParam()->GetSAOnePointTracks() && 
563      TMath::Abs(event->GetMagneticField())<0.01) {
564     Int_t outerLayer=1; // only SPD
565     for(Int_t innLay=0; innLay<=TMath::Min(1,fOuterStartLayer); innLay++) {
566       //   counter for clusters on each layer  
567
568       for(Int_t nloop=0;nloop<fNloop;nloop++){
569         Int_t nclInnLay=fCluLayer[innLay]->GetEntries();
570         while(nclInnLay--){ //loop starting from layer innLay
571           ResetForFinding();
572           Bool_t useRP=SetFirstPoint(innLay,nclInnLay,primaryVertex);
573           if(!useRP) continue;
574           AliITStrackSA* trs = new AliITStrackSA(); 
575             
576           Int_t pflag=0;            
577           Int_t kk;
578           for(kk=0;kk<AliITSgeomTGeo::GetNLayers();kk++) nClusLay[kk] = 0;
579           
580           kk=0;
581           nClusLay[kk] = SearchClusters(innLay,fPhiWin[nloop],fLambdaWin[nloop],
582                                   trs,primaryVertex[2],pflag);
583           for(Int_t nextLay=innLay+1; nextLay<=outerLayer; nextLay++) {
584             kk++;
585             nClusLay[kk] = SearchClusters(nextLay,fPhiWin[nloop],fLambdaWin[nloop],
586                                     trs,primaryVertex[2],pflag);
587             if(nClusLay[kk]!=0){
588               pflag=1;
589               if(kk==1) {
590                 fPoint3[0]=fPointc[0];
591                 fPoint3[1]=fPointc[1];
592               } else {
593                 UpdatePoints();
594               }
595             }
596           }
597           
598           Int_t layOK=0;
599           for(Int_t nnp=0;nnp<AliITSgeomTGeo::GetNLayers()-innLay;nnp++){
600             if(nClusLay[nnp]!=0) layOK+=1;
601           }
602           if(layOK==1) {
603             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]));
604             AliITStrackV2* tr2 = 0;
605             Bool_t onePoint = kTRUE;
606             tr2 = FitTrack(trs,primaryVertex,onePoint);
607             if(!tr2) continue;
608             AliDebug(2,Form("----NPOINTS fit: %d\n",tr2->GetNumberOfClusters()));
609             
610             StoreTrack(tr2,event);
611             ntrack++;
612             
613           }   
614           
615           delete trs;
616         }//end loop on clusters of innLay
617       } //end loop on window sizes
618       
619     } //end loop on innLay
620   } // end search 1-point tracks
621   
622   AliInfo(Form("Number of found tracks: %d",event->GetNumberOfTracks()));
623   ResetForFinding();
624   return 0;
625
626 }
627  
628 //________________________________________________________________________
629
630 AliITStrackV2* AliITStrackerSA::FitTrack(AliITStrackSA* tr,Double_t *primaryVertex,Bool_t onePoint) {
631   //fit of the found track (most general case, also <6 points, layers missing)
632   // A.Dainese 16.11.07 
633
634   
635   const Int_t kMaxClu=AliITStrackSA::kMaxNumberOfClusters;
636
637   static Int_t firstmod[AliITSgeomTGeo::kNLayers];
638   
639   static Int_t clind[AliITSgeomTGeo::kNLayers][kMaxClu];
640   static Int_t clmark[AliITSgeomTGeo::kNLayers][kMaxClu];
641   static Int_t end[AliITSgeomTGeo::kNLayers];
642   static AliITSRecPoint *listlayer[AliITSgeomTGeo::kNLayers][kMaxClu];
643
644   for(Int_t i=0;i<AliITSgeomTGeo::GetNLayers();i++) {
645     firstmod[i]=AliITSgeomTGeo::GetModuleIndex(i+1,1,1);
646     end[i]=0;
647     for(Int_t j=0;j<kMaxClu; j++){
648       clind[i][j]=0;
649       clmark[i][j]=0;
650       listlayer[i][j]=0;
651    }
652   }
653   
654
655   Int_t nclusters = tr->GetNumberOfClustersSA();
656   for(Int_t ncl=0;ncl<nclusters;ncl++){
657     Int_t index = tr->GetClusterIndexSA(ncl); 
658     AliITSRecPoint* cl = (AliITSRecPoint*)GetCluster(index);
659     if(cl->TestBit(kSAflag)==kTRUE) cl->ResetBit(kSAflag);
660     Int_t lay = (index & 0xf0000000) >> 28;
661     Int_t nInLay=end[lay];
662     listlayer[lay][nInLay]=cl;
663     clind[lay][nInLay]=index;
664     end[lay]++;
665   }
666
667   for(Int_t nlay=0;nlay<AliITSgeomTGeo::GetNLayers();nlay++){
668     for(Int_t ncl=0;ncl<tr->GetNumberOfMarked(nlay);ncl++){
669       Int_t mark = tr->GetClusterMark(nlay,ncl);
670       clmark[nlay][ncl]=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 }