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