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