]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TRD/AliTRDtracker.cxx
Bug fix (Yu.Belikov)
[u/mrichter/AliRoot.git] / TRD / AliTRDtracker.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, 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 //                                                                           //
20 //  The standard TRD tracker                                                 //
21 //                                                                           //
22 ///////////////////////////////////////////////////////////////////////////////
23
24 #include <Riostream.h>
25 #include <TFile.h>
26 #include <TBranch.h>
27 #include <TTree.h>  
28 #include <TObjArray.h> 
29
30 #include "AliTRDgeometry.h"
31 #include "AliTRDparameter.h"
32 #include "AliTRDgeometryHole.h"
33 #include "AliTRDcluster.h" 
34 #include "AliTRDtrack.h"
35 #include "AliESD.h"
36
37 #include "AliTRDtracker.h"
38
39 ClassImp(AliTRDtracker) 
40
41   const  Float_t     AliTRDtracker::fgkSeedDepth          = 0.5; 
42   const  Float_t     AliTRDtracker::fgkSeedStep           = 0.10;   
43   const  Float_t     AliTRDtracker::fgkSeedGap            = 0.25;  
44
45   const  Float_t     AliTRDtracker::fgkMaxSeedDeltaZ12    = 40.;  
46   const  Float_t     AliTRDtracker::fgkMaxSeedDeltaZ      = 25.;  
47   const  Float_t     AliTRDtracker::fgkMaxSeedC           = 0.0052; 
48   const  Float_t     AliTRDtracker::fgkMaxSeedTan         = 1.2;  
49   const  Float_t     AliTRDtracker::fgkMaxSeedVertexZ     = 150.; 
50
51   const  Double_t    AliTRDtracker::fgkSeedErrorSY        = 0.2;
52   const  Double_t    AliTRDtracker::fgkSeedErrorSY3       = 2.5;
53   const  Double_t    AliTRDtracker::fgkSeedErrorSZ        = 0.1;
54
55   const  Float_t     AliTRDtracker::fgkMinClustersInSeed  = 0.7;  
56
57   const  Float_t     AliTRDtracker::fgkMinClustersInTrack = 0.5;  
58   const  Float_t     AliTRDtracker::fgkMinFractionOfFoundClusters = 0.8;  
59
60   const  Float_t     AliTRDtracker::fgkSkipDepth          = 0.3;
61   const  Float_t     AliTRDtracker::fgkLabelFraction      = 0.8;  
62   const  Float_t     AliTRDtracker::fgkWideRoad           = 20.;
63
64   const  Double_t    AliTRDtracker::fgkMaxChi2            = 12.; 
65
66 const Int_t AliTRDtracker::fgkFirstPlane = 5;
67 const Int_t AliTRDtracker::fgkLastPlane = 17;
68
69
70 //____________________________________________________________________
71 AliTRDtracker::AliTRDtracker():AliTracker(),
72                                fGeom(0),
73                                fPar(0),
74                                fNclusters(0),
75                                fClusters(0),
76                                fNseeds(0),
77                                fSeeds(0),
78                                fNtracks(0),
79                                fTracks(0),
80                                fSY2corr(0),
81                                fSZ2corr(0),
82                                fTimeBinsPerPlane(0),
83                                fMaxGap(0),
84                                fVocal(kFALSE),
85                                fAddTRDseeds(kFALSE),
86                                fNoTilt(kFALSE)
87 {
88   // Default constructor
89
90   for(Int_t i=0;i<kTrackingSectors;i++) fTrSec[i]=0;
91   for(Int_t j=0;j<5;j++)
92     for(Int_t k=0;k<18;k++) fHoles[j][k]=kFALSE;
93
94 //____________________________________________________________________
95 AliTRDtracker::AliTRDtracker(const TFile *geomfile):AliTracker()
96 {
97   // 
98   //  Main constructor
99   //  
100
101   //Float_t fTzero = 0;
102    
103   fAddTRDseeds = kFALSE;
104   fGeom = NULL;
105   fNoTilt = kFALSE;
106   
107   TDirectory *savedir=gDirectory; 
108   TFile *in=(TFile*)geomfile;  
109   if (!in->IsOpen()) {
110     printf("AliTRDtracker::AliTRDtracker(): geometry file is not open!\n");
111     printf("    DETAIL TRD geometry and DEFAULT TRD parameter will be used\n");
112   }
113   else {
114     in->cd();  
115 //    in->ls();
116     fGeom = (AliTRDgeometry*) in->Get("TRDgeometry");
117     fPar  = (AliTRDparameter*) in->Get("TRDparameter");
118 //    fGeom->Dump();
119   }
120
121   if(fGeom) {
122     //    fTzero = geo->GetT0();
123     printf("Found geometry version %d on file \n", fGeom->IsVersion());
124   }
125   else { 
126     printf("AliTRDtracker::AliTRDtracker(): can't find TRD geometry!\n");
127     //printf("The DETAIL TRD geometry will be used\n");
128     //fGeom = new AliTRDgeometryDetail();
129     fGeom = new AliTRDgeometryHole();
130     fGeom->SetPHOShole();
131     fGeom->SetRICHhole();    
132   } 
133
134   if (!fPar) {  
135     printf("AliTRDtracker::AliTRDtracker(): can't find TRD parameter!\n");
136     printf("The DEFAULT TRD parameter will be used\n");
137     fPar = new AliTRDparameter();
138   }
139   fPar->ReInit();
140
141   savedir->cd();  
142
143
144   //  fGeom->SetT0(fTzero);
145
146   fNclusters = 0;
147   fClusters  = new TObjArray(2000); 
148   fNseeds    = 0;
149   fSeeds     = new TObjArray(2000);
150   fNtracks   = 0;
151   fTracks    = new TObjArray(1000);
152
153   for(Int_t geomS = 0; geomS < kTrackingSectors; geomS++) {
154     Int_t trS = CookSectorIndex(geomS);
155     fTrSec[trS] = new AliTRDtrackingSector(fGeom, geomS, fPar);
156     for (Int_t icham=0;icham<AliTRDgeometry::kNcham; icham++){
157       fHoles[icham][trS]=fGeom->IsHole(0,icham,geomS);
158     }
159   }
160
161   Float_t tiltAngle = TMath::Abs(fPar->GetTiltingAngle()); 
162   if(tiltAngle < 0.1) {
163     fNoTilt = kTRUE;
164   }
165
166   fSY2corr = 0.2;
167   fSZ2corr = 120.;      
168
169   if(fNoTilt && (tiltAngle > 0.1)) fSY2corr = fSY2corr + tiltAngle * 0.05; 
170
171
172   // calculate max gap on track
173
174   Double_t dxAmp = (Double_t) fGeom->CamHght();   // Amplification region
175   Double_t dxDrift = (Double_t) fGeom->CdrHght(); // Drift region
176
177   Double_t dx = (Double_t) fPar->GetTimeBinSize();   
178   Int_t tbAmp = fPar->GetTimeBefore();
179   Int_t maxAmp = (Int_t) ((dxAmp+0.000001)/dx);
180   if(kTRUE) maxAmp = 0;  // intentional until we change the parameter class 
181   Int_t tbDrift = fPar->GetTimeMax();
182   Int_t maxDrift = (Int_t) ((dxDrift+0.000001)/dx);
183
184   tbDrift = TMath::Min(tbDrift,maxDrift);
185   tbAmp = TMath::Min(tbAmp,maxAmp);
186
187   fTimeBinsPerPlane = tbAmp + tbDrift;
188   fMaxGap = (Int_t) (fTimeBinsPerPlane * fGeom->Nplan() * fgkSkipDepth);
189
190   fVocal = kFALSE;
191
192   savedir->cd();
193 }   
194
195 //___________________________________________________________________
196 AliTRDtracker::~AliTRDtracker()
197 {
198   //
199   // Destructor of AliTRDtracker 
200   //
201
202   if (fClusters) {
203     fClusters->Delete();
204     delete fClusters;
205   }
206   if (fTracks) {
207     fTracks->Delete();
208     delete fTracks;
209   }
210   if (fSeeds) {
211     fSeeds->Delete();
212     delete fSeeds;
213   }
214   delete fGeom;  
215   delete fPar;  
216
217   for(Int_t geomS = 0; geomS < kTrackingSectors; geomS++) {
218     delete fTrSec[geomS];
219   }
220 }   
221
222 //_____________________________________________________________________
223
224 Bool_t AliTRDtracker::AdjustSector(AliTRDtrack *track) {
225   //
226   // Rotates the track when necessary
227   //
228
229   Double_t alpha = AliTRDgeometry::GetAlpha(); 
230   Double_t y = track->GetY();
231   Double_t ymax = track->GetX()*TMath::Tan(0.5*alpha);
232
233   //Int_t ns = AliTRDgeometry::kNsect;
234   //Int_t s=Int_t(track->GetAlpha()/alpha)%ns; 
235
236   if (y > ymax) {
237     //s = (s+1) % ns;
238     if (!track->Rotate(alpha)) return kFALSE;
239   } else if (y <-ymax) {
240     //s = (s-1+ns) % ns;                           
241     if (!track->Rotate(-alpha)) return kFALSE;   
242   } 
243
244   return kTRUE;
245 }
246
247 //_____________________________________________________________________
248 inline Double_t f1trd(Double_t x1,Double_t y1,
249                       Double_t x2,Double_t y2,
250                       Double_t x3,Double_t y3)
251 {
252   //
253   // Initial approximation of the track curvature
254   //
255   Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
256   Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
257                   (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
258   Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
259                   (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
260
261   Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
262
263   return -xr*yr/sqrt(xr*xr+yr*yr);
264 }          
265
266 //_____________________________________________________________________
267 inline Double_t f2trd(Double_t x1,Double_t y1,
268                       Double_t x2,Double_t y2,
269                       Double_t x3,Double_t y3)
270 {
271   //
272   // Initial approximation of the track curvature times X coordinate
273   // of the center of curvature
274   //
275
276   Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
277   Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
278                   (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
279   Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
280                   (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
281
282   Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
283
284   return -a/(d*y1-b)*xr/sqrt(xr*xr+yr*yr);
285 }          
286
287 //_____________________________________________________________________
288 inline Double_t f3trd(Double_t x1,Double_t y1,
289                       Double_t x2,Double_t y2,
290                       Double_t z1,Double_t z2)
291 {
292   //
293   // Initial approximation of the tangent of the track dip angle
294   //
295
296   return (z1 - z2)/sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
297 }            
298
299
300 AliTRDcluster * AliTRDtracker::GetCluster(AliTRDtrack * track, Int_t plane, Int_t timebin){
301   //
302   //try to find cluster in the backup list
303   //
304   AliTRDcluster * cl =0;
305   UInt_t *indexes = track->GetBackupIndexes();
306   for (UInt_t i=0;i<kMaxTimeBinIndex;i++){
307     if (indexes[i]==0) break;  
308     AliTRDcluster * cli = (AliTRDcluster*)fClusters->UncheckedAt(indexes[i]);
309     if (!cli) break;
310     if (cli->GetLocalTimeBin()!=timebin) continue;
311     Int_t iplane = fGeom->GetPlane(cli->GetDetector());
312     if (iplane==plane) {
313       cl = cli;
314       break;
315     }
316   }
317   return cl;
318 }
319
320
321 Int_t  AliTRDtracker::GetLastPlane(AliTRDtrack * track){
322   //
323   //return last updated plane
324   Int_t lastplane=0;
325   UInt_t *indexes = track->GetBackupIndexes();
326   for (UInt_t i=0;i<kMaxTimeBinIndex;i++){
327     AliTRDcluster * cli = (AliTRDcluster*)fClusters->UncheckedAt(indexes[i]);
328     if (!cli) break;
329     Int_t iplane = fGeom->GetPlane(cli->GetDetector());
330     if (iplane>lastplane) {
331       lastplane = iplane;
332     }
333   }
334   return lastplane;
335 }
336 //___________________________________________________________________
337 Int_t AliTRDtracker::Clusters2Tracks(AliESD* event)
338 {
339   //
340   // Finds tracks within the TRD. The ESD event is expected to contain seeds 
341   // at the outer part of the TRD. The seeds
342   // are found within the TRD if fAddTRDseeds is TRUE. 
343   // The tracks are propagated to the innermost time bin 
344   // of the TRD and the ESD event is updated
345   //
346
347   Int_t timeBins = fTrSec[0]->GetNumberOfTimeBins();
348   Float_t foundMin = fgkMinClustersInTrack * timeBins; 
349   Int_t nseed = 0;
350   Int_t found = 0;
351   Int_t innerTB = fTrSec[0]->GetInnerTimeBin();
352
353   Int_t n = event->GetNumberOfTracks();
354   for (Int_t i=0; i<n; i++) {
355     AliESDtrack* seed=event->GetTrack(i);
356     ULong_t status=seed->GetStatus();
357     if ( (status & AliESDtrack::kTRDout ) == 0 ) continue;
358     if ( (status & AliESDtrack::kTRDin) != 0 ) continue;
359     nseed++;
360
361     AliTRDtrack* seed2 = new AliTRDtrack(*seed);
362     //seed2->ResetCovariance(); 
363     AliTRDtrack *pt = new AliTRDtrack(*seed2,seed2->GetAlpha());
364     AliTRDtrack &t=*pt; 
365     FollowProlongation(t, innerTB); 
366     if (t.GetNumberOfClusters() >= foundMin) {
367       UseClusters(&t);
368       CookLabel(pt, 1-fgkLabelFraction);
369       //      t.CookdEdx();
370     }
371     found++;
372 //    cout<<found<<'\r';     
373
374     if(PropagateToTPC(t)) {
375       seed->UpdateTrackParams(pt, AliESDtrack::kTRDin);
376     }  
377     delete seed2;
378     delete pt;
379   }     
380
381   cout<<"Number of loaded seeds: "<<nseed<<endl;  
382   cout<<"Number of found tracks from loaded seeds: "<<found<<endl;
383
384   // after tracks from loaded seeds are found and the corresponding 
385   // clusters are used, look for additional seeds from TRD
386
387   if(fAddTRDseeds) { 
388     // Find tracks for the seeds in the TRD
389     Int_t timeBins = fTrSec[0]->GetNumberOfTimeBins();
390   
391     Int_t nSteps = (Int_t) (fgkSeedDepth / fgkSeedStep);
392     Int_t gap = (Int_t) (timeBins * fgkSeedGap);
393     Int_t step = (Int_t) (timeBins * fgkSeedStep);
394   
395     // make a first turn with tight cut on initial curvature
396     for(Int_t turn = 1; turn <= 2; turn++) {
397       if(turn == 2) {
398         nSteps = (Int_t) (fgkSeedDepth / (3*fgkSeedStep));
399         step = (Int_t) (timeBins * (3*fgkSeedStep));
400       }
401       for(Int_t i=0; i<nSteps; i++) {
402         Int_t outer=timeBins-1-i*step; 
403         Int_t inner=outer-gap;
404
405         nseed=fSeeds->GetEntriesFast();
406       
407         MakeSeeds(inner, outer, turn);
408       
409         nseed=fSeeds->GetEntriesFast();
410         //        printf("\n turn %d, step %d: number of seeds for TRD inward %d\n", 
411         //               turn, i, nseed); 
412               
413         for (Int_t i=0; i<nseed; i++) {   
414           AliTRDtrack *pt=(AliTRDtrack*)fSeeds->UncheckedAt(i), &t=*pt; 
415           FollowProlongation(t,innerTB); 
416           if (t.GetNumberOfClusters() >= foundMin) {
417             UseClusters(&t);
418             CookLabel(pt, 1-fgkLabelFraction);
419             t.CookdEdx();
420             found++;
421 //            cout<<found<<'\r';     
422             if(PropagateToTPC(t)) {
423               AliESDtrack track;
424               track.UpdateTrackParams(pt,AliESDtrack::kTRDin);
425               event->AddTrack(&track);
426               //              track.SetTRDtrack(new AliTRDtrack(*pt));
427             }        
428           }
429           delete fSeeds->RemoveAt(i);
430           fNseeds--;
431         }
432       }
433     }
434   }
435   
436   cout<<"Total number of found tracks: "<<found<<endl;
437     
438   return 0;    
439 }     
440      
441   
442
443 //_____________________________________________________________________________
444 Int_t AliTRDtracker::PropagateBack(AliESD* event) {
445   //
446   // Gets seeds from ESD event. The seeds are AliTPCtrack's found and
447   // backpropagated by the TPC tracker. Each seed is first propagated 
448   // to the TRD, and then its prolongation is searched in the TRD.
449   // If sufficiently long continuation of the track is found in the TRD
450   // the track is updated, otherwise it's stored as originaly defined 
451   // by the TPC tracker.   
452   //  
453
454   Int_t found=0;  
455   Float_t foundMin = 20;
456
457   Int_t n = event->GetNumberOfTracks();
458   for (Int_t i=0; i<n; i++) {
459     AliESDtrack* seed=event->GetTrack(i);
460     ULong_t status=seed->GetStatus();
461     if ( (status & AliESDtrack::kTPCout ) == 0 ) continue;
462     if ( (status & AliESDtrack::kTRDout) != 0 ) continue;
463
464     Int_t lbl = seed->GetLabel();
465     AliTRDtrack *track = new AliTRDtrack(*seed);
466     track->SetSeedLabel(lbl);
467     seed->UpdateTrackParams(track, AliESDtrack::kTRDbackup); //make backup
468     fNseeds++;
469     Float_t p4 = track->GetC();
470     //
471     Int_t expectedClr = FollowBackProlongation(*track);
472     /*
473       // only debug purpose
474     if (track->GetNumberOfClusters()<expectedClr/3){
475       AliTRDtrack *track1 = new AliTRDtrack(*seed);
476       track1->SetSeedLabel(lbl);
477       FollowBackProlongation(*track1);
478       AliTRDtrack *track2= new AliTRDtrack(*seed);
479       track->SetSeedLabel(lbl);
480       FollowBackProlongation(*track2);      
481       delete track1;
482       delete track2;
483     }
484     */
485      if (TMath::Abs(track->GetC()-p4)/TMath::Abs(p4)>0.2) {
486       delete track;
487       continue; //too big change of curvature - to be checked
488     }
489
490     Int_t foundClr = track->GetNumberOfClusters();
491     if (foundClr >= foundMin) {
492       track->CookdEdx(0.,1.);
493       CookdEdxTimBin(*track);
494  
495       CookLabel(track, 1-fgkLabelFraction);
496       if(track->GetChi2()/track->GetNumberOfClusters()<6) {   // sign only gold tracks
497         UseClusters(track);
498       }
499       Bool_t isGold = kFALSE;
500      
501       if (track->GetChi2()/track->GetNumberOfClusters()<5) {  //full gold track
502         seed->UpdateTrackParams(track, AliESDtrack::kTRDbackup);
503         isGold = kTRUE;
504       }
505       if (!isGold && track->GetNCross()==0&&track->GetChi2()/track->GetNumberOfClusters()<7){ //almost gold track
506         seed->UpdateTrackParams(track, AliESDtrack::kTRDbackup);
507         isGold = kTRUE;
508       }
509       if (!isGold && track->GetBackupTrack()){
510         if (track->GetBackupTrack()->GetNumberOfClusters()>foundMin&&
511             (track->GetBackupTrack()->GetChi2()/(track->GetBackupTrack()->GetNumberOfClusters()+1))<7){   
512           seed->UpdateTrackParams(track->GetBackupTrack(), AliESDtrack::kTRDbackup);
513           isGold = kTRUE;
514         }
515       }
516     }
517     else{
518       delete track;
519       continue;
520     }
521
522     
523     if (track->GetStop()==kFALSE){
524
525       Double_t xtof=371.;
526       Double_t c2=track->GetC()*xtof - track->GetEta();
527       if (TMath::Abs(c2)>=0.85) {
528         delete track;
529         continue;
530       }
531       Double_t xTOF0 = 371. ;          
532       PropagateToOuterPlane(*track,xTOF0); 
533       //      
534       Double_t ymax=xtof*TMath::Tan(0.5*AliTRDgeometry::GetAlpha());
535       Double_t y=track->GetYat(xtof);
536       if (y > ymax) {
537         if (!track->Rotate(AliTRDgeometry::GetAlpha())) {
538           delete track;
539           continue;
540         }
541       } else if (y <-ymax) {
542         if (!track->Rotate(-AliTRDgeometry::GetAlpha())) {
543           delete track;
544           continue;
545         }
546       }
547       
548       if (track->PropagateTo(xtof)) {
549         seed->UpdateTrackParams(track, AliESDtrack::kTRDout);
550         for (Int_t i=0;i<kNPlane;i++) {
551            seed->SetTRDsignals(track->GetPIDsignals(i),i);
552            seed->SetTRDTimBin(track->GetPIDTimBin(i),i);
553         }
554         seed->SetTRDtrack(new AliTRDtrack(*track));
555         if (track->GetNumberOfClusters()>foundMin) found++;
556       }
557     }else{
558       if (track->GetNumberOfClusters()>15&&track->GetNumberOfClusters()>0.5*expectedClr){
559         seed->UpdateTrackParams(track, AliESDtrack::kTRDout);
560         //seed->SetStatus(AliESDtrack::kTRDStop);    
561         for (Int_t i=0;i<kNPlane;i++) {
562            seed->SetTRDsignals(track->GetPIDsignals(i),i);
563            seed->SetTRDTimBin(track->GetPIDTimBin(i),i);
564         }
565         seed->SetTRDtrack(new AliTRDtrack(*track));
566         found++;
567       }
568     }
569
570     delete track;
571     
572     //End of propagation to the TOF
573     //if (foundClr>foundMin)
574     //  seed->UpdateTrackParams(track, AliESDtrack::kTRDout);
575     
576
577   }
578   
579   cerr<<"Number of seeds: "<<fNseeds<<endl;  
580   cerr<<"Number of back propagated TRD tracks: "<<found<<endl;
581
582   fSeeds->Clear(); fNseeds=0;
583
584   return 0;
585
586 }
587
588 //_____________________________________________________________________________
589 Int_t AliTRDtracker::RefitInward(AliESD* event)
590 {
591   //
592   // Refits tracks within the TRD. The ESD event is expected to contain seeds 
593   // at the outer part of the TRD. 
594   // The tracks are propagated to the innermost time bin 
595   // of the TRD and the ESD event is updated
596   // Origin: Thomas KUHR (Thomas.Kuhr@cern.ch)
597   //
598
599   Int_t timeBins = fTrSec[0]->GetNumberOfTimeBins();
600   Float_t foundMin = fgkMinClustersInTrack * timeBins; 
601   Int_t nseed = 0;
602   Int_t found = 0;
603   Int_t innerTB = fTrSec[0]->GetInnerTimeBin();
604
605   Int_t n = event->GetNumberOfTracks();
606   for (Int_t i=0; i<n; i++) {
607     AliESDtrack* seed=event->GetTrack(i);
608     AliTRDtrack* seed2 = new AliTRDtrack(*seed);
609     if (seed2->GetX()<270){
610       seed->UpdateTrackParams(seed2, AliESDtrack::kTRDbackup); // backup TPC track - only update
611       delete seed2;
612       continue;
613     }
614
615     ULong_t status=seed->GetStatus();
616     if ( (status & AliESDtrack::kTRDout ) == 0 ) {
617       delete seed2;
618       continue;
619     }
620     if ( (status & AliESDtrack::kTRDin) != 0 ) {
621       delete seed2;
622       continue;
623     }
624     nseed++;    
625     seed2->ResetCovariance(5.); 
626     AliTRDtrack *pt = new AliTRDtrack(*seed2,seed2->GetAlpha());
627     for (Int_t i=0;i<kNPlane;i++) {
628         pt->SetPIDsignals(seed2->GetPIDsignals(i),i);
629         pt->SetPIDTimBin(seed2->GetPIDTimBin(i),i);
630     }
631
632     UInt_t * indexes2 = seed2->GetIndexes();
633     UInt_t * indexes3 = pt->GetBackupIndexes();
634     for (Int_t i=0;i<200;i++) {
635       if (indexes2[i]==0) break;
636       indexes3[i] = indexes2[i];
637     }          
638     //AliTRDtrack *pt = seed2;
639     AliTRDtrack &t=*pt; 
640     FollowProlongation(t, innerTB); 
641     /*
642     if (t.GetNumberOfClusters()<seed->GetTRDclusters(indexes3)*0.5){
643       // debug  - why we dont go back?
644       AliTRDtrack *pt2 = new AliTRDtrack(*seed2,seed2->GetAlpha());
645       UInt_t * indexes2 = seed2->GetIndexes();
646       UInt_t * indexes3 = pt2->GetBackupIndexes();
647       for (Int_t i=0;i<200;i++) {
648         if (indexes2[i]==0) break;
649         indexes3[i] = indexes2[i];
650       }  
651       FollowProlongation(*pt2, innerTB);
652       delete pt2;
653     }
654     */
655     if (t.GetNumberOfClusters() >= foundMin) {
656       //      UseClusters(&t);
657       //CookLabel(pt, 1-fgkLabelFraction);
658       //      t.CookdEdx();
659     }
660     found++;
661 //    cout<<found<<'\r';     
662
663     if(PropagateToTPC(t)) {
664       seed->UpdateTrackParams(pt, AliESDtrack::kTRDrefit);
665       for (Int_t i=0;i<kNPlane;i++) {
666         seed->SetTRDsignals(pt->GetPIDsignals(i),i);
667         seed->SetTRDTimBin(pt->GetPIDTimBin(i),i);
668       }
669     }else{
670       //if not prolongation to TPC - propagate without update
671       AliTRDtrack* seed2 = new AliTRDtrack(*seed);
672       seed2->ResetCovariance(5.); 
673       AliTRDtrack *pt2 = new AliTRDtrack(*seed2,seed2->GetAlpha());
674       delete seed2;
675       if (PropagateToTPC(*pt2)) { 
676         pt2->CookdEdx(0.,1.);
677         CookdEdxTimBin(*pt2);
678         seed->UpdateTrackParams(pt2, AliESDtrack::kTRDrefit);
679         for (Int_t i=0;i<kNPlane;i++) {
680           seed->SetTRDsignals(pt2->GetPIDsignals(i),i);
681           seed->SetTRDTimBin(pt2->GetPIDTimBin(i),i);
682         }
683       }
684       delete pt2;
685     }  
686
687     delete seed2;
688     delete pt;
689   }   
690
691   cout<<"Number of loaded seeds: "<<nseed<<endl;  
692   cout<<"Number of found tracks from loaded seeds: "<<found<<endl;
693
694   return 0;
695
696 }
697
698
699 //---------------------------------------------------------------------------
700 Int_t AliTRDtracker::FollowProlongation(AliTRDtrack& t, Int_t rf)
701 {
702   // Starting from current position on track=t this function tries
703   // to extrapolate the track up to timeBin=0 and to confirm prolongation
704   // if a close cluster is found. Returns the number of clusters
705   // expected to be found in sensitive layers
706
707   Float_t  wIndex, wTB, wChi2;
708   Float_t  wYrt, wYclosest, wYcorrect, wYwindow;
709   Float_t  wZrt, wZclosest, wZcorrect, wZwindow;
710   Float_t  wPx, wPy, wPz, wC;
711   Double_t px, py, pz;
712   Float_t  wSigmaC2, wSigmaTgl2, wSigmaY2, wSigmaZ2;
713   Int_t lastplane = GetLastPlane(&t);
714
715   Int_t trackIndex = t.GetLabel();  
716
717   Int_t ns=Int_t(2*TMath::Pi()/AliTRDgeometry::GetAlpha()+0.5);     
718
719   Int_t tryAgain=fMaxGap;
720
721   Double_t alpha=t.GetAlpha();
722   alpha = TVector2::Phi_0_2pi(alpha);
723
724   Int_t s=Int_t(alpha/AliTRDgeometry::GetAlpha())%AliTRDgeometry::kNsect;  
725   Double_t radLength, rho, x, dx, y, ymax, z;
726
727   Int_t expectedNumberOfClusters = 0;
728   Bool_t lookForCluster;
729
730   alpha=AliTRDgeometry::GetAlpha();  // note: change in meaning
731
732  
733   for (Int_t nr=fTrSec[0]->GetLayerNumber(t.GetX()); nr>rf; nr--) { 
734
735     y = t.GetY(); z = t.GetZ();
736
737     // first propagate to the inner surface of the current time bin 
738     fTrSec[s]->GetLayer(nr)->GetPropagationParameters(y,z,dx,rho,radLength,lookForCluster);
739     x = fTrSec[s]->GetLayer(nr)->GetX()-dx/2; y = t.GetY(); z = t.GetZ();
740     if(!t.PropagateTo(x,radLength,rho)) break;
741     y = t.GetY();
742     ymax = x*TMath::Tan(0.5*alpha);
743     if (y > ymax) {
744       s = (s+1) % ns;
745       if (!t.Rotate(alpha)) break;
746       if(!t.PropagateTo(x,radLength,rho)) break;
747     } else if (y <-ymax) {
748       s = (s-1+ns) % ns;                           
749       if (!t.Rotate(-alpha)) break;   
750       if(!t.PropagateTo(x,radLength,rho)) break;
751     } 
752
753     y = t.GetY(); z = t.GetZ();
754
755     // now propagate to the middle plane of the next time bin 
756     fTrSec[s]->GetLayer(nr-1)->GetPropagationParameters(y,z,dx,rho,radLength,lookForCluster);
757     x = fTrSec[s]->GetLayer(nr-1)->GetX(); y = t.GetY(); z = t.GetZ();
758     if(!t.PropagateTo(x,radLength,rho)) break;
759     y = t.GetY();
760     ymax = x*TMath::Tan(0.5*alpha);
761     if (y > ymax) {
762       s = (s+1) % ns;
763       if (!t.Rotate(alpha)) break;
764       if(!t.PropagateTo(x,radLength,rho)) break;
765     } else if (y <-ymax) {
766       s = (s-1+ns) % ns;                           
767       if (!t.Rotate(-alpha)) break;   
768       if(!t.PropagateTo(x,radLength,rho)) break;
769     } 
770
771
772     if(lookForCluster) {
773
774       expectedNumberOfClusters++;       
775       wIndex = (Float_t) t.GetLabel();
776       wTB = nr;
777
778       AliTRDpropagationLayer& timeBin=*(fTrSec[s]->GetLayer(nr-1));
779
780       Double_t sy2=ExpectedSigmaY2(x,t.GetTgl(),t.GetPt());
781       Double_t sz2=ExpectedSigmaZ2(x,t.GetTgl());
782
783       Double_t road;
784       if((t.GetSigmaY2() + sy2) > 0) road=10.*sqrt(t.GetSigmaY2() + sy2);
785       else return expectedNumberOfClusters;
786       
787       wYrt = (Float_t) y;
788       wZrt = (Float_t) z;
789       wYwindow = (Float_t) road;
790       t.GetPxPyPz(px,py,pz);
791       wPx = (Float_t) px;
792       wPy = (Float_t) py;
793       wPz = (Float_t) pz;
794       wC  = (Float_t) t.GetC();
795       wSigmaC2 = (Float_t) t.GetSigmaC2();
796       wSigmaTgl2    = (Float_t) t.GetSigmaTgl2();
797       wSigmaY2 = (Float_t) t.GetSigmaY2();
798       wSigmaZ2 = (Float_t) t.GetSigmaZ2();
799       wChi2 = -1;            
800       
801
802       AliTRDcluster *cl=0;
803       UInt_t index=0;
804
805       Double_t maxChi2=fgkMaxChi2;
806
807       wYclosest = 12345678;
808       wYcorrect = 12345678;
809       wZclosest = 12345678;
810       wZcorrect = 12345678;
811       wZwindow  = TMath::Sqrt(2.25 * 12 * sz2);   
812
813       // Find the closest correct cluster for debugging purposes
814       if (timeBin) {
815         Float_t minDY = 1000000;
816         for (Int_t i=0; i<timeBin; i++) {
817           AliTRDcluster* c=(AliTRDcluster*)(timeBin[i]);
818           if((c->GetLabel(0) != trackIndex) &&
819              (c->GetLabel(1) != trackIndex) &&
820              (c->GetLabel(2) != trackIndex)) continue;
821           if(TMath::Abs(c->GetY() - y) > minDY) continue;
822           minDY = TMath::Abs(c->GetY() - y);
823           wYcorrect = c->GetY();
824           wZcorrect = c->GetZ();
825
826           Double_t h01 = GetTiltFactor(c);
827           wChi2 = t.GetPredictedChi2(c, h01);
828         }
829       }                    
830
831       // Now go for the real cluster search
832
833       if (timeBin) {
834         //
835         //find cluster in history
836         cl =0;
837         
838         AliTRDcluster * cl0 = timeBin[0];
839         if (!cl0) {
840           continue;
841         }
842         Int_t plane = fGeom->GetPlane(cl0->GetDetector());
843         if (plane>lastplane) continue;
844         Int_t timebin = cl0->GetLocalTimeBin();
845         AliTRDcluster * cl2= GetCluster(&t,plane, timebin);
846         if (cl2) {
847           cl =cl2;      
848           Double_t h01 = GetTiltFactor(cl);
849           maxChi2=t.GetPredictedChi2(cl,h01);
850         }
851         if ((!cl) && road>fgkWideRoad) {
852           //if (t.GetNumberOfClusters()>4)
853           //  cerr<<t.GetNumberOfClusters()
854           //    <<"FindProlongation warning: Too broad road !\n";
855           continue;
856         }             
857
858
859         if(!cl){
860
861           for (Int_t i=timeBin.Find(y-road); i<timeBin; i++) {
862             AliTRDcluster* c=(AliTRDcluster*)(timeBin[i]);
863             if (c->GetY() > y+road) break;
864             if (c->IsUsed() > 0) continue;
865             if((c->GetZ()-z)*(c->GetZ()-z) > 3 * sz2) continue;
866             
867             Double_t h01 = GetTiltFactor(c);
868             Double_t chi2=t.GetPredictedChi2(c,h01);
869             
870             if (chi2 > maxChi2) continue;
871             maxChi2=chi2;
872             cl=c;
873             index=timeBin.GetIndex(i);
874           }               
875         }
876
877         if(!cl) {
878
879           for (Int_t i=timeBin.Find(y-road); i<timeBin; i++) {
880             AliTRDcluster* c=(AliTRDcluster*)(timeBin[i]);
881             
882             if (c->GetY() > y+road) break;
883             if (c->IsUsed() > 0) continue;
884             if((c->GetZ()-z)*(c->GetZ()-z) > 12 * sz2) continue;
885             
886             Double_t h01 = GetTiltFactor(c);
887             Double_t chi2=t.GetPredictedChi2(c, h01);
888             
889             if (chi2 > maxChi2) continue;
890             maxChi2=chi2;
891             cl=c;
892             index=timeBin.GetIndex(i);
893           }
894         }        
895         if (cl) {
896           wYclosest = cl->GetY();
897           wZclosest = cl->GetZ();
898           Double_t h01 = GetTiltFactor(cl);
899
900           t.SetSampledEdx(cl->GetQ()/dx,t.GetNumberOfClusters()); 
901           //printf("Track   position\t%f\t%f\t%f\n",t.GetX(),t.GetY(),t.GetZ());
902           //printf("Cluster position\t%d\t%f\t%f\n",cl->GetLocalTimeBin(),cl->GetY(),cl->GetZ());
903           Int_t det = cl->GetDetector();    
904           Int_t plane = fGeom->GetPlane(det);
905
906           if(!t.UpdateMI(cl,maxChi2,index,h01,plane)) {
907             //if(!t.Update(cl,maxChi2,index,h01)) {
908             //if(!tryAgain--) return 0;
909           }  
910           else tryAgain=fMaxGap;
911         }
912         else {
913           //if (tryAgain==0) break; 
914           tryAgain--;
915         }
916
917         /*
918         if((((Int_t) wTB)%15 == 0) || (((Int_t) wTB)%15 == 14)) {
919           
920           printf(" %f", wIndex);       //1
921           printf(" %f", wTB);          //2
922           printf(" %f", wYrt);         //3
923           printf(" %f", wYclosest);    //4
924           printf(" %f", wYcorrect);    //5
925           printf(" %f", wYwindow);     //6
926           printf(" %f", wZrt);         //7
927           printf(" %f", wZclosest);    //8
928           printf(" %f", wZcorrect);    //9
929           printf(" %f", wZwindow);     //10
930           printf(" %f", wPx);          //11
931           printf(" %f", wPy);          //12
932           printf(" %f", wPz);          //13
933           printf(" %f", wSigmaC2*1000000);  //14
934           printf(" %f", wSigmaTgl2*1000);   //15
935           printf(" %f", wSigmaY2);     //16
936           //      printf(" %f", wSigmaZ2);     //17
937           printf(" %f", wChi2);     //17
938           printf(" %f", wC);           //18
939           printf("\n");
940         } 
941         */                        
942       }
943     }  
944   }
945   return expectedNumberOfClusters;
946   
947   
948 }                
949
950 //___________________________________________________________________
951
952 Int_t AliTRDtracker::FollowBackProlongation(AliTRDtrack& t)
953 {
954   // Starting from current radial position of track <t> this function
955   // extrapolates the track up to outer timebin and in the sensitive
956   // layers confirms prolongation if a close cluster is found. 
957   // Returns the number of clusters expected to be found in sensitive layers
958
959
960   Float_t  wIndex, wTB, wChi2;
961   Float_t  wYrt, wYclosest, wYcorrect, wYwindow;
962   Float_t  wZrt, wZclosest, wZcorrect, wZwindow;
963   Float_t  wPx, wPy, wPz, wC;
964   Double_t px, py, pz;
965   Float_t  wSigmaC2, wSigmaTgl2, wSigmaY2, wSigmaZ2;
966
967   Int_t trackIndex = t.GetLabel();  
968   Int_t tryAgain=fMaxGap;
969
970   Double_t alpha=t.GetAlpha();
971   TVector2::Phi_0_2pi(alpha);
972
973   Int_t s;
974
975   Int_t outerTB = fTrSec[0]->GetOuterTimeBin();
976   Double_t radLength, rho, x, dx, y, ymax = 0, z;
977   Bool_t lookForCluster;
978
979   Int_t expectedNumberOfClusters = 0;
980   x = t.GetX();
981
982   alpha=AliTRDgeometry::GetAlpha();  // note: change in meaning
983
984   Int_t nRefPlane = fgkFirstPlane;
985   Bool_t isNewLayer = kFALSE; 
986
987   Double_t chi2;
988   Double_t minDY;
989   Int_t zone =-10;
990   Int_t nr;
991   for (nr=fTrSec[0]->GetLayerNumber(t.GetX()); nr<outerTB+1; nr++) { 
992     
993     y = t.GetY(); 
994     z = t.GetZ();
995
996     // first propagate to the outer surface of the current time bin 
997
998     s = t.GetSector();
999     fTrSec[s]->GetLayer(nr)->GetPropagationParameters(y,z,dx,rho,radLength,lookForCluster);
1000     x = fTrSec[s]->GetLayer(nr)->GetX()+dx/2; 
1001     y = t.GetY(); 
1002     z = t.GetZ();
1003
1004     if(!t.PropagateTo(x,radLength,rho)) break;
1005     //    if (!AdjustSector(&t)) break;
1006     //
1007     // MI -fix untill correct material desription will be implemented
1008     //
1009     Float_t angle =  t.GetAlpha();  // MI - if rotation - we go through the material 
1010     if (!AdjustSector(&t)) break;
1011     Int_t cross = kFALSE;
1012     
1013     if (TMath::Abs(angle -  t.GetAlpha())>0.000001) cross = kTRUE; //better to stop track
1014     Int_t currentzone = fTrSec[s]->GetLayer(nr)->GetZone(z);
1015     if (currentzone==-10) cross = kTRUE;  // we are in the frame
1016     if (currentzone>-10){   // layer knows where we are
1017       if (zone==-10) zone = currentzone;
1018       if (zone!=currentzone) cross=kTRUE;  
1019     }
1020     if (cross) {
1021       t.IncCross();
1022       if (t.GetNCross()==1) t.MakeBackupTrack();
1023       if (t.GetNCross()>2) break;
1024     }
1025     
1026     //
1027     //
1028     s = t.GetSector();
1029     if (!t.PropagateTo(x,radLength,rho)) break;
1030
1031     y = t.GetY();
1032     z = t.GetZ();
1033
1034     // Barrel Tracks [SR, 04.04.2003]
1035
1036     s = t.GetSector();
1037     if (fTrSec[s]->GetLayer(nr)->IsSensitive() != 
1038         fTrSec[s]->GetLayer(nr+1)->IsSensitive() ) {
1039
1040 //      if (IsStoringBarrel()) StoreBarrelTrack(&t, nRefPlane++, kTrackBack);
1041     }
1042
1043     if (fTrSec[s]->GetLayer(nr-1)->IsSensitive() && 
1044           ! fTrSec[s]->GetLayer(nr)->IsSensitive()) {
1045       isNewLayer = kTRUE;
1046     } else {isNewLayer = kFALSE;}
1047
1048     y = t.GetY();
1049     z = t.GetZ();
1050
1051     // now propagate to the middle plane of the next time bin 
1052     fTrSec[s]->GetLayer(nr+1)->GetPropagationParameters(y,z,dx,rho,radLength,lookForCluster);
1053
1054     x = fTrSec[s]->GetLayer(nr+1)->GetX(); 
1055       if(!t.PropagateTo(x,radLength,rho)) break;
1056     if (!AdjustSector(&t)) break;
1057     s = t.GetSector();
1058       if(!t.PropagateTo(x,radLength,rho)) break;
1059
1060     y = t.GetY();
1061     z = t.GetZ();
1062
1063     if(fVocal) printf("nr+1=%d, x %f, z %f, y %f, ymax %f\n",nr+1,x,z,y,ymax);
1064     //    printf("label %d, pl %d, lookForCluster %d \n",
1065     //     trackIndex, nr+1, lookForCluster);
1066
1067     if(lookForCluster) {
1068       expectedNumberOfClusters++;       
1069
1070       wIndex = (Float_t) t.GetLabel();
1071       wTB = fTrSec[s]->GetLayer(nr+1)->GetTimeBinIndex();
1072
1073       AliTRDpropagationLayer& timeBin=*(fTrSec[s]->GetLayer(nr+1));
1074       Double_t sy2=ExpectedSigmaY2(t.GetX(),t.GetTgl(),t.GetPt());
1075       Double_t sz2=ExpectedSigmaZ2(t.GetX(),t.GetTgl());
1076       if((t.GetSigmaY2() + sy2) < 0) break;
1077       Double_t road = 10.*sqrt(t.GetSigmaY2() + sy2); 
1078       Double_t y=t.GetY(), z=t.GetZ();
1079
1080       wYrt = (Float_t) y;
1081       wZrt = (Float_t) z;
1082       wYwindow = (Float_t) road;
1083       t.GetPxPyPz(px,py,pz);
1084       wPx = (Float_t) px;
1085       wPy = (Float_t) py;
1086       wPz = (Float_t) pz;
1087       wC  = (Float_t) t.GetC();
1088       wSigmaC2 = (Float_t) t.GetSigmaC2();
1089       wSigmaTgl2    = (Float_t) t.GetSigmaTgl2();
1090       wSigmaY2 = (Float_t) t.GetSigmaY2();
1091       wSigmaZ2 = (Float_t) t.GetSigmaZ2();
1092       wChi2 = -1;            
1093       
1094       if (road>fgkWideRoad) {
1095         if (t.GetNumberOfClusters()>4)
1096           cerr<<t.GetNumberOfClusters()
1097               <<"FindProlongation warning: Too broad road !\n";
1098         return 0;
1099       }      
1100
1101       AliTRDcluster *cl=0;
1102       UInt_t index=0;
1103
1104       Double_t maxChi2=fgkMaxChi2;
1105
1106       if (isNewLayer) { 
1107         road = 3 * road;
1108         //sz2 = 3 * sz2;
1109         maxChi2 = 10 * fgkMaxChi2;
1110       }
1111       
1112       if (nRefPlane == fgkFirstPlane) maxChi2 = 20 * fgkMaxChi2; 
1113       if (nRefPlane == fgkFirstPlane+2) maxChi2 = 15 * fgkMaxChi2;
1114       if (t.GetNRotate() > 0) maxChi2 = 3 * maxChi2;
1115       
1116
1117       wYclosest = 12345678;
1118       wYcorrect = 12345678;
1119       wZclosest = 12345678;
1120       wZcorrect = 12345678;
1121       wZwindow  = TMath::Sqrt(2.25 * 12 * sz2);   
1122
1123       // Find the closest correct cluster for debugging purposes
1124       if (timeBin) {
1125         minDY = 1000000;
1126         for (Int_t i=0; i<timeBin; i++) {
1127           AliTRDcluster* c=(AliTRDcluster*)(timeBin[i]);
1128           if((c->GetLabel(0) != trackIndex) &&
1129              (c->GetLabel(1) != trackIndex) &&
1130              (c->GetLabel(2) != trackIndex)) continue;
1131           if(TMath::Abs(c->GetY() - y) > minDY) continue;
1132           //minDY = TMath::Abs(c->GetY() - y);
1133           minDY = c->GetY() - y;
1134           wYcorrect = c->GetY();
1135           wZcorrect = c->GetZ();
1136
1137           Double_t h01 = GetTiltFactor(c);
1138           wChi2 = t.GetPredictedChi2(c, h01);
1139         }
1140       }                    
1141
1142       // Now go for the real cluster search
1143
1144       if (timeBin) {
1145
1146         for (Int_t i=timeBin.Find(y-road); i<timeBin; i++) {
1147           AliTRDcluster* c=(AliTRDcluster*)(timeBin[i]);
1148           if (c->GetY() > y+road) break;
1149           if (c->IsUsed() > 0) continue;
1150           if((c->GetZ()-z)*(c->GetZ()-z) > 3 * sz2) continue;
1151
1152           Double_t h01 = GetTiltFactor(c);
1153           chi2=t.GetPredictedChi2(c,h01);
1154           
1155           if (chi2 > maxChi2) continue;
1156           maxChi2=chi2;
1157           cl=c;
1158           index=timeBin.GetIndex(i);
1159
1160           //check is correct
1161           if((c->GetLabel(0) != trackIndex) &&
1162              (c->GetLabel(1) != trackIndex) &&
1163              (c->GetLabel(2) != trackIndex)) t.AddNWrong();
1164         }               
1165         
1166         if(!cl) {
1167
1168           for (Int_t i=timeBin.Find(y-road); i<timeBin; i++) {
1169             AliTRDcluster* c=(AliTRDcluster*)(timeBin[i]);
1170             
1171             if (c->GetY() > y+road) break;
1172             if (c->IsUsed() > 0) continue;
1173             if((c->GetZ()-z)*(c->GetZ()-z) > 2.25 * 12 * sz2) continue;
1174             
1175             Double_t h01 = GetTiltFactor(c);
1176             chi2=t.GetPredictedChi2(c,h01);
1177             
1178             if (chi2 > maxChi2) continue;
1179             maxChi2=chi2;
1180             cl=c;
1181             index=timeBin.GetIndex(i);
1182           }
1183         }        
1184         
1185         if (cl) {
1186           wYclosest = cl->GetY();
1187           wZclosest = cl->GetZ();
1188
1189           t.SetSampledEdx(cl->GetQ()/dx,t.GetNumberOfClusters()); 
1190           Double_t h01 = GetTiltFactor(cl);
1191           Int_t det = cl->GetDetector();    
1192           Int_t plane = fGeom->GetPlane(det);
1193
1194           if(!t.UpdateMI(cl,maxChi2,index,h01,plane)) {
1195           //if(!t.Update(cl,maxChi2,index,h01)) {
1196             if(!tryAgain--) return 0;
1197           }  
1198           else tryAgain=fMaxGap;
1199         }
1200         else {
1201           if (tryAgain==0) break; 
1202           tryAgain--;
1203           
1204           //if (minDY < 1000000 && isNewLayer) 
1205             //cout << "\t" << nRefPlane << "\t" << "\t" << t.GetNRotate() <<  "\t" << 
1206             //  road << "\t" << minDY << "\t" << chi2 << "\t" << wChi2 << "\t" << maxChi2 << endl;
1207                                                                      
1208         }
1209
1210         isNewLayer = kFALSE;
1211
1212         /*
1213         if((((Int_t) wTB)%15 == 0) || (((Int_t) wTB)%15 == 14)) {
1214           
1215           printf(" %f", wIndex);       //1
1216           printf(" %f", wTB);          //2
1217           printf(" %f", wYrt);         //3
1218           printf(" %f", wYclosest);    //4
1219           printf(" %f", wYcorrect);    //5
1220           printf(" %f", wYwindow);     //6
1221           printf(" %f", wZrt);         //7
1222           printf(" %f", wZclosest);    //8
1223           printf(" %f", wZcorrect);    //9
1224           printf(" %f", wZwindow);     //10
1225           printf(" %f", wPx);          //11
1226           printf(" %f", wPy);          //12
1227           printf(" %f", wPz);          //13
1228           printf(" %f", wSigmaC2*1000000);  //14
1229           printf(" %f", wSigmaTgl2*1000);   //15
1230           printf(" %f", wSigmaY2);     //16
1231           //      printf(" %f", wSigmaZ2);     //17
1232           printf(" %f", wChi2);     //17
1233           printf(" %f", wC);           //18
1234           printf("\n");
1235         } 
1236         */                        
1237       }
1238     }  
1239   }
1240   if (nr<outerTB) 
1241     t.SetStop(kTRUE);
1242   else
1243     t.SetStop(kFALSE);
1244   return expectedNumberOfClusters;
1245
1246
1247 }         
1248
1249 //---------------------------------------------------------------------------
1250 Int_t AliTRDtracker::Refit(AliTRDtrack& t, Int_t rf)
1251 {
1252   // Starting from current position on track=t this function tries
1253   // to extrapolate the track up to timeBin=0 and to reuse already
1254   // assigned clusters. Returns the number of clusters
1255   // expected to be found in sensitive layers
1256   // get indices of assigned clusters for each layer
1257   // Origin: Thomas KUHR (Thomas.Kuhr@cern.ch)
1258
1259   Int_t iCluster[90];
1260   for (Int_t i = 0; i < 90; i++) iCluster[i] = 0;
1261   for (Int_t i = 0; i < t.GetNumberOfClusters(); i++) {
1262     Int_t index = t.GetClusterIndex(i);
1263     AliTRDcluster *cl=(AliTRDcluster*) GetCluster(index);
1264     if (!cl) continue;
1265     Int_t detector=cl->GetDetector();
1266     Int_t localTimeBin=cl->GetLocalTimeBin();
1267     Int_t sector=fGeom->GetSector(detector);
1268     Int_t plane=fGeom->GetPlane(detector);
1269
1270     Int_t trackingSector = CookSectorIndex(sector);
1271
1272     Int_t gtb = fTrSec[trackingSector]->CookTimeBinIndex(plane,localTimeBin);
1273     if(gtb < 0) continue; 
1274     Int_t layer = fTrSec[trackingSector]->GetLayerNumber(gtb);
1275     iCluster[layer] = index;
1276   }
1277   t.ResetClusters();
1278
1279   Int_t ns=Int_t(2*TMath::Pi()/AliTRDgeometry::GetAlpha()+0.5);     
1280
1281   Double_t alpha=t.GetAlpha();
1282   alpha = TVector2::Phi_0_2pi(alpha);
1283
1284   Int_t s=Int_t(alpha/AliTRDgeometry::GetAlpha())%AliTRDgeometry::kNsect;  
1285   Double_t radLength, rho, x, dx, y, ymax, z;
1286
1287   Int_t expectedNumberOfClusters = 0;
1288   Bool_t lookForCluster;
1289
1290   alpha=AliTRDgeometry::GetAlpha();  // note: change in meaning
1291
1292  
1293   for (Int_t nr=fTrSec[0]->GetLayerNumber(t.GetX()); nr>rf; nr--) { 
1294
1295     y = t.GetY(); z = t.GetZ();
1296
1297     // first propagate to the inner surface of the current time bin 
1298     fTrSec[s]->GetLayer(nr)->GetPropagationParameters(y,z,dx,rho,radLength,lookForCluster);
1299     x = fTrSec[s]->GetLayer(nr)->GetX()-dx/2; y = t.GetY(); z = t.GetZ();
1300     if(!t.PropagateTo(x,radLength,rho)) break;
1301     y = t.GetY();
1302     ymax = x*TMath::Tan(0.5*alpha);
1303     if (y > ymax) {
1304       s = (s+1) % ns;
1305       if (!t.Rotate(alpha)) break;
1306       if(!t.PropagateTo(x,radLength,rho)) break;
1307     } else if (y <-ymax) {
1308       s = (s-1+ns) % ns;                           
1309       if (!t.Rotate(-alpha)) break;   
1310       if(!t.PropagateTo(x,radLength,rho)) break;
1311     } 
1312
1313     y = t.GetY(); z = t.GetZ();
1314
1315     // now propagate to the middle plane of the next time bin 
1316     fTrSec[s]->GetLayer(nr-1)->GetPropagationParameters(y,z,dx,rho,radLength,lookForCluster);
1317     x = fTrSec[s]->GetLayer(nr-1)->GetX(); y = t.GetY(); z = t.GetZ();
1318     if(!t.PropagateTo(x,radLength,rho)) break;
1319     y = t.GetY();
1320     ymax = x*TMath::Tan(0.5*alpha);
1321     if (y > ymax) {
1322       s = (s+1) % ns;
1323       if (!t.Rotate(alpha)) break;
1324       if(!t.PropagateTo(x,radLength,rho)) break;
1325     } else if (y <-ymax) {
1326       s = (s-1+ns) % ns;                           
1327       if (!t.Rotate(-alpha)) break;   
1328       if(!t.PropagateTo(x,radLength,rho)) break;
1329     } 
1330
1331     if(lookForCluster) expectedNumberOfClusters++;       
1332
1333     // use assigned cluster
1334     if (!iCluster[nr-1]) continue;
1335     AliTRDcluster *cl=(AliTRDcluster*)GetCluster(iCluster[nr-1]);
1336     Double_t h01 = GetTiltFactor(cl);
1337     Double_t chi2=t.GetPredictedChi2(cl, h01);
1338     t.SetSampledEdx(cl->GetQ()/dx,t.GetNumberOfClusters()); 
1339     t.Update(cl,chi2,iCluster[nr-1],h01);
1340   }
1341
1342   return expectedNumberOfClusters;
1343 }                
1344
1345 //___________________________________________________________________
1346
1347 Int_t AliTRDtracker::PropagateToOuterPlane(AliTRDtrack& t, Double_t xToGo)
1348 {
1349   // Starting from current radial position of track <t> this function
1350   // extrapolates the track up to radial position <xToGo>. 
1351   // Returns 1 if track reaches the plane, and 0 otherwise 
1352
1353   Int_t ns=Int_t(2*TMath::Pi()/AliTRDgeometry::GetAlpha()+0.5);     
1354
1355   Double_t alpha=t.GetAlpha();
1356
1357   if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
1358   if (alpha < 0.            ) alpha += 2.*TMath::Pi();
1359
1360   Int_t s=Int_t(alpha/AliTRDgeometry::GetAlpha())%AliTRDgeometry::kNsect;  
1361
1362   Bool_t lookForCluster;
1363   Double_t radLength, rho, x, dx, y, ymax, z;
1364
1365   x = t.GetX();
1366
1367   alpha=AliTRDgeometry::GetAlpha();  // note: change in meaning
1368
1369   Int_t plToGo = fTrSec[0]->GetLayerNumber(xToGo);
1370
1371   for (Int_t nr=fTrSec[0]->GetLayerNumber(x); nr<plToGo; nr++) { 
1372
1373     y = t.GetY(); z = t.GetZ();
1374
1375     // first propagate to the outer surface of the current time bin 
1376     fTrSec[s]->GetLayer(nr)->GetPropagationParameters(y,z,dx,rho,radLength,lookForCluster);
1377     x = fTrSec[s]->GetLayer(nr)->GetX()+dx/2; y = t.GetY(); z = t.GetZ();
1378     if(!t.PropagateTo(x,radLength,rho)) return 0;
1379     y = t.GetY();
1380     ymax = x*TMath::Tan(0.5*alpha);
1381     if (y > ymax) {
1382       s = (s+1) % ns;
1383       if (!t.Rotate(alpha)) return 0;
1384     } else if (y <-ymax) {
1385       s = (s-1+ns) % ns;                           
1386       if (!t.Rotate(-alpha)) return 0;   
1387     } 
1388     if(!t.PropagateTo(x,radLength,rho)) return 0;
1389
1390     y = t.GetY(); z = t.GetZ();
1391
1392     // now propagate to the middle plane of the next time bin 
1393     fTrSec[s]->GetLayer(nr+1)->GetPropagationParameters(y,z,dx,rho,radLength,lookForCluster);
1394     x = fTrSec[s]->GetLayer(nr+1)->GetX(); y = t.GetY(); z = t.GetZ();
1395     if(!t.PropagateTo(x,radLength,rho)) return 0;
1396     y = t.GetY();
1397     ymax = x*TMath::Tan(0.5*alpha);
1398     if (y > ymax) {
1399       s = (s+1) % ns;
1400       if (!t.Rotate(alpha)) return 0;
1401     } else if (y <-ymax) {
1402       s = (s-1+ns) % ns;                           
1403       if (!t.Rotate(-alpha)) return 0;   
1404     } 
1405     if(!t.PropagateTo(x,radLength,rho)) return 0;
1406   }
1407   return 1;
1408 }         
1409
1410 //___________________________________________________________________
1411
1412 Int_t AliTRDtracker::PropagateToTPC(AliTRDtrack& t)
1413 {
1414   // Starting from current radial position of track <t> this function
1415   // extrapolates the track up to radial position of the outermost
1416   // padrow of the TPC. 
1417   // Returns 1 if track reaches the TPC, and 0 otherwise 
1418
1419   //Int_t ns=Int_t(2*TMath::Pi()/AliTRDgeometry::GetAlpha()+0.5);     
1420
1421   Double_t alpha=t.GetAlpha();
1422   alpha = TVector2::Phi_0_2pi(alpha);
1423
1424   Int_t s=Int_t(alpha/AliTRDgeometry::GetAlpha())%AliTRDgeometry::kNsect;  
1425
1426   Bool_t lookForCluster;
1427   Double_t radLength, rho, x, dx, y, /*ymax,*/ z;
1428
1429   x = t.GetX();
1430
1431   alpha=AliTRDgeometry::GetAlpha();  // note: change in meaning
1432   Int_t plTPC = fTrSec[0]->GetLayerNumber(246.055);
1433
1434   for (Int_t nr=fTrSec[0]->GetLayerNumber(x); nr>plTPC; nr--) { 
1435
1436     y = t.GetY(); 
1437     z = t.GetZ();
1438
1439     // first propagate to the outer surface of the current time bin 
1440     fTrSec[s]->GetLayer(nr)->GetPropagationParameters(y,z,dx,rho,radLength,lookForCluster);
1441     x = fTrSec[s]->GetLayer(nr)->GetX()-dx/2; 
1442     
1443     if(!t.PropagateTo(x,radLength,rho)) return 0;
1444     AdjustSector(&t);
1445     if(!t.PropagateTo(x,radLength,rho)) return 0;
1446
1447     y = t.GetY(); 
1448     z = t.GetZ();
1449
1450     // now propagate to the middle plane of the next time bin 
1451     fTrSec[s]->GetLayer(nr-1)->GetPropagationParameters(y,z,dx,rho,radLength,lookForCluster);
1452     x = fTrSec[s]->GetLayer(nr-1)->GetX(); 
1453     
1454     if(!t.PropagateTo(x,radLength,rho)) return 0;
1455     AdjustSector(&t);
1456     if(!t.PropagateTo(x,radLength,rho)) return 0;
1457   } 
1458   return 1;
1459 }         
1460
1461 //_____________________________________________________________________________
1462 Int_t AliTRDtracker::LoadClusters(TTree *cTree)
1463 {
1464   // Fills clusters into TRD tracking_sectors 
1465   // Note that the numbering scheme for the TRD tracking_sectors 
1466   // differs from that of TRD sectors
1467
1468   if (ReadClusters(fClusters,cTree)) {
1469      Error("LoadClusters","Problem with reading the clusters !");
1470      return 1;
1471   }
1472   Int_t ncl=fClusters->GetEntriesFast();
1473   fNclusters=ncl;
1474   cout<<"\n LoadSectors: sorting "<<ncl<<" clusters"<<endl;
1475               
1476   UInt_t index;
1477   for (Int_t ichamber=0;ichamber<5;ichamber++)
1478     for (Int_t isector=0;isector<18;isector++){
1479       fHoles[ichamber][isector]=kTRUE;
1480     }
1481
1482
1483   while (ncl--) {
1484 //    printf("\r %d left  ",ncl); 
1485     AliTRDcluster *c=(AliTRDcluster*)fClusters->UncheckedAt(ncl);
1486     Int_t detector=c->GetDetector();
1487     Int_t localTimeBin=c->GetLocalTimeBin();
1488     Int_t sector=fGeom->GetSector(detector);
1489     Int_t plane=fGeom->GetPlane(detector);
1490       
1491     Int_t trackingSector = CookSectorIndex(sector);
1492     if (c->GetLabel(0)>0){
1493       Int_t chamber = fGeom->GetChamber(detector);
1494       fHoles[chamber][trackingSector]=kFALSE;
1495     }
1496
1497     Int_t gtb = fTrSec[trackingSector]->CookTimeBinIndex(plane,localTimeBin);
1498     if(gtb < 0) continue; 
1499     Int_t layer = fTrSec[trackingSector]->GetLayerNumber(gtb);
1500
1501     index=ncl;
1502     fTrSec[trackingSector]->GetLayer(layer)->InsertCluster(c,index);
1503   }    
1504   //  printf("\r\n");
1505   //
1506   //
1507   /*
1508   for (Int_t isector=0;isector<18;isector++){
1509     for (Int_t ichamber=0;ichamber<5;ichamber++)      
1510       if (fHoles[ichamber][isector]!=fGeom->IsHole(0,ichamber,17-isector)) 
1511         printf("Problem \t%d\t%d\t%d\t%d\n",isector,ichamber,fHoles[ichamber][isector],
1512              fGeom->IsHole(0,ichamber,17-isector));
1513   }
1514   */
1515   return 0;
1516 }
1517
1518 //_____________________________________________________________________________
1519 void AliTRDtracker::UnloadClusters() 
1520
1521   //
1522   // Clears the arrays of clusters and tracks. Resets sectors and timebins 
1523   //
1524
1525   Int_t i, nentr;
1526
1527   nentr = fClusters->GetEntriesFast();
1528   for (i = 0; i < nentr; i++) delete fClusters->RemoveAt(i);
1529   fNclusters = 0;
1530
1531   nentr = fSeeds->GetEntriesFast();
1532   for (i = 0; i < nentr; i++) delete fSeeds->RemoveAt(i);
1533
1534   nentr = fTracks->GetEntriesFast();
1535   for (i = 0; i < nentr; i++) delete fTracks->RemoveAt(i);
1536
1537   Int_t nsec = AliTRDgeometry::kNsect;
1538
1539   for (i = 0; i < nsec; i++) {    
1540     for(Int_t pl = 0; pl < fTrSec[i]->GetNumberOfLayers(); pl++) {
1541       fTrSec[i]->GetLayer(pl)->Clear();
1542     }
1543   }
1544
1545 }
1546
1547 //__________________________________________________________________________
1548 void AliTRDtracker::MakeSeeds(Int_t inner, Int_t outer, Int_t turn)
1549 {
1550   // Creates track seeds using clusters in timeBins=i1,i2
1551
1552   if(turn > 2) {
1553     cerr<<"MakeSeeds: turn "<<turn<<" exceeds the limit of 2"<<endl;
1554     return;
1555   }
1556
1557   Double_t x[5], c[15];
1558   Int_t maxSec=AliTRDgeometry::kNsect;
1559   
1560   Double_t alpha=AliTRDgeometry::GetAlpha();
1561   Double_t shift=AliTRDgeometry::GetAlpha()/2.;
1562   Double_t cs=cos(alpha), sn=sin(alpha);
1563   Double_t cs2=cos(2.*alpha), sn2=sin(2.*alpha);
1564     
1565       
1566   Int_t i2 = fTrSec[0]->GetLayerNumber(inner);
1567   Int_t i1 = fTrSec[0]->GetLayerNumber(outer);
1568       
1569   Double_t x1 =fTrSec[0]->GetX(i1);
1570   Double_t xx2=fTrSec[0]->GetX(i2);
1571       
1572   for (Int_t ns=0; ns<maxSec; ns++) {
1573     
1574     Int_t nl2 = *(fTrSec[(ns-2+maxSec)%maxSec]->GetLayer(i2));
1575     Int_t nl=(*fTrSec[(ns-1+maxSec)%maxSec]->GetLayer(i2));
1576     Int_t nm=(*fTrSec[ns]->GetLayer(i2));
1577     Int_t nu=(*fTrSec[(ns+1)%maxSec]->GetLayer(i2));
1578     Int_t nu2=(*fTrSec[(ns+2)%maxSec]->GetLayer(i2));
1579     
1580     AliTRDpropagationLayer& r1=*(fTrSec[ns]->GetLayer(i1));
1581     
1582     for (Int_t is=0; is < r1; is++) {
1583       Double_t y1=r1[is]->GetY(), z1=r1[is]->GetZ();
1584       
1585       for (Int_t js=0; js < nl2+nl+nm+nu+nu2; js++) {
1586         
1587         const AliTRDcluster *cl;
1588         Double_t x2,   y2,   z2;
1589         Double_t x3=0., y3=0.;   
1590         
1591         if (js<nl2) {
1592           if(turn != 2) continue;
1593           AliTRDpropagationLayer& r2=*(fTrSec[(ns-2+maxSec)%maxSec]->GetLayer(i2));
1594           cl=r2[js];
1595           y2=cl->GetY(); z2=cl->GetZ();
1596           
1597           x2= xx2*cs2+y2*sn2;
1598           y2=-xx2*sn2+y2*cs2;
1599         }
1600         else if (js<nl2+nl) {
1601           if(turn != 1) continue;
1602           AliTRDpropagationLayer& r2=*(fTrSec[(ns-1+maxSec)%maxSec]->GetLayer(i2));
1603           cl=r2[js-nl2];
1604           y2=cl->GetY(); z2=cl->GetZ();
1605           
1606           x2= xx2*cs+y2*sn;
1607           y2=-xx2*sn+y2*cs;
1608         }                                
1609         else if (js<nl2+nl+nm) {
1610           if(turn != 1) continue;
1611           AliTRDpropagationLayer& r2=*(fTrSec[ns]->GetLayer(i2));
1612           cl=r2[js-nl2-nl];
1613           x2=xx2; y2=cl->GetY(); z2=cl->GetZ();
1614         }
1615         else if (js<nl2+nl+nm+nu) {
1616           if(turn != 1) continue;
1617           AliTRDpropagationLayer& r2=*(fTrSec[(ns+1)%maxSec]->GetLayer(i2));
1618           cl=r2[js-nl2-nl-nm];
1619           y2=cl->GetY(); z2=cl->GetZ();
1620           
1621           x2=xx2*cs-y2*sn;
1622           y2=xx2*sn+y2*cs;
1623         }              
1624         else {
1625           if(turn != 2) continue;
1626           AliTRDpropagationLayer& r2=*(fTrSec[(ns+2)%maxSec]->GetLayer(i2));
1627           cl=r2[js-nl2-nl-nm-nu];
1628           y2=cl->GetY(); z2=cl->GetZ();
1629           
1630           x2=xx2*cs2-y2*sn2;
1631           y2=xx2*sn2+y2*cs2;
1632         }
1633         
1634         if(TMath::Abs(z1-z2) > fgkMaxSeedDeltaZ12) continue;
1635         
1636         Double_t zz=z1 - z1/x1*(x1-x2);
1637         
1638         if (TMath::Abs(zz-z2)>fgkMaxSeedDeltaZ) continue;
1639         
1640         Double_t d=(x2-x1)*(0.-y2)-(0.-x2)*(y2-y1);
1641         if (d==0.) {cerr<<"TRD MakeSeeds: Straight seed !\n"; continue;}
1642         
1643         x[0]=y1;
1644         x[1]=z1;
1645         x[4]=f1trd(x1,y1,x2,y2,x3,y3);
1646         
1647         if (TMath::Abs(x[4]) > fgkMaxSeedC) continue;      
1648         
1649         x[2]=f2trd(x1,y1,x2,y2,x3,y3);
1650         
1651         if (TMath::Abs(x[4]*x1-x[2]) >= 0.99999) continue;
1652         
1653         x[3]=f3trd(x1,y1,x2,y2,z1,z2);
1654         
1655         if (TMath::Abs(x[3]) > fgkMaxSeedTan) continue;
1656         
1657         Double_t a=asin(x[2]);
1658         Double_t zv=z1 - x[3]/x[4]*(a+asin(x[4]*x1-x[2]));
1659         
1660         if (TMath::Abs(zv)>fgkMaxSeedVertexZ) continue;
1661         
1662         Double_t sy1=r1[is]->GetSigmaY2(), sz1=r1[is]->GetSigmaZ2();
1663         Double_t sy2=cl->GetSigmaY2(),     sz2=cl->GetSigmaZ2();
1664         Double_t sy3=fgkSeedErrorSY3, sy=fgkSeedErrorSY, sz=fgkSeedErrorSZ;  
1665
1666         // Tilt changes
1667         Double_t h01 = GetTiltFactor(r1[is]);
1668         Double_t xuFactor = 100.;
1669         if(fNoTilt) { 
1670           h01 = 0;
1671           xuFactor = 1;
1672         }
1673
1674         sy1=sy1+sz1*h01*h01;
1675         Double_t syz=sz1*(-h01);
1676         // end of tilt changes
1677         
1678         Double_t f40=(f1trd(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
1679         Double_t f42=(f1trd(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
1680         Double_t f43=(f1trd(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
1681         Double_t f20=(f2trd(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
1682         Double_t f22=(f2trd(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
1683         Double_t f23=(f2trd(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
1684         Double_t f30=(f3trd(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
1685         Double_t f31=(f3trd(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
1686         Double_t f32=(f3trd(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
1687         Double_t f34=(f3trd(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;    
1688
1689         
1690         c[0]=sy1;
1691         //        c[1]=0.;       c[2]=sz1;
1692         c[1]=syz;       c[2]=sz1*xuFactor;
1693         c[3]=f20*sy1;  c[4]=0.;       c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
1694         c[6]=f30*sy1;  c[7]=f31*sz1;  c[8]=f30*sy1*f20+f32*sy2*f22;
1695                        c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
1696         c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
1697         c[13]=f30*sy1*f40+f32*sy2*f42;
1698         c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;      
1699         
1700         UInt_t index=r1.GetIndex(is);
1701         
1702         AliTRDtrack *track=new AliTRDtrack(r1[is],index,x,c,x1,ns*alpha+shift);
1703
1704         Int_t rc=FollowProlongation(*track, i2);     
1705         
1706         if ((rc < 1) ||
1707             (track->GetNumberOfClusters() < 
1708              (outer-inner)*fgkMinClustersInSeed)) delete track;
1709         else {
1710           fSeeds->AddLast(track); fNseeds++;
1711 //          cerr<<"\r found seed "<<fNseeds;
1712         }
1713       }
1714     }
1715   }
1716 }            
1717
1718 //_____________________________________________________________________________
1719 Int_t AliTRDtracker::ReadClusters(TObjArray *array, TTree *ClusterTree) const
1720 {
1721   //
1722   // Reads AliTRDclusters (option >= 0) or AliTRDrecPoints (option < 0) 
1723   // from the file. The names of the cluster tree and branches 
1724   // should match the ones used in AliTRDclusterizer::WriteClusters()
1725   //
1726   TObjArray *clusterArray = new TObjArray(400); 
1727   
1728   TBranch *branch=ClusterTree->GetBranch("TRDcluster");
1729   if (!branch) {
1730     Error("ReadClusters","Can't get the branch !");
1731     return 1;
1732   }
1733   branch->SetAddress(&clusterArray); 
1734   
1735   Int_t nEntries = (Int_t) ClusterTree->GetEntries();
1736   //  printf("found %d entries in %s.\n",nEntries,ClusterTree->GetName());
1737   
1738   // Loop through all entries in the tree
1739   Int_t nbytes = 0;
1740   AliTRDcluster *c = 0;
1741   //  printf("\n");
1742
1743   for (Int_t iEntry = 0; iEntry < nEntries; iEntry++) {    
1744     
1745     // Import the tree
1746     nbytes += ClusterTree->GetEvent(iEntry);  
1747     
1748     // Get the number of points in the detector
1749     Int_t nCluster = clusterArray->GetEntriesFast();  
1750 //    printf("\r Read %d clusters from entry %d", nCluster, iEntry);
1751     
1752     // Loop through all TRD digits
1753     for (Int_t iCluster = 0; iCluster < nCluster; iCluster++) { 
1754       c = (AliTRDcluster*)clusterArray->UncheckedAt(iCluster);
1755       AliTRDcluster *co = new AliTRDcluster(*c);
1756       co->SetSigmaY2(c->GetSigmaY2() * fSY2corr);
1757       Int_t ltb = co->GetLocalTimeBin();
1758       if(ltb == 19) co->SetSigmaZ2(c->GetSigmaZ2());
1759       else if(fNoTilt) co->SetSigmaZ2(c->GetSigmaZ2() * fSZ2corr);
1760       array->AddLast(co);
1761       delete clusterArray->RemoveAt(iCluster); 
1762     }
1763   }
1764
1765   delete clusterArray;
1766
1767   return 0;
1768 }
1769
1770 //__________________________________________________________________
1771 void AliTRDtracker::CookLabel(AliKalmanTrack* pt, Float_t wrong) const 
1772 {
1773   //
1774   // This cooks a label. Mmmmh, smells good...
1775   //
1776
1777   Int_t label=123456789, index, i, j;
1778   Int_t ncl=pt->GetNumberOfClusters();
1779   const Int_t kRange = fTrSec[0]->GetOuterTimeBin()+1;
1780
1781   Bool_t labelAdded;
1782
1783   //  Int_t s[kRange][2];
1784   Int_t **s = new Int_t* [kRange];
1785   for (i=0; i<kRange; i++) {
1786     s[i] = new Int_t[2];
1787   }
1788   for (i=0; i<kRange; i++) {
1789     s[i][0]=-1;
1790     s[i][1]=0;
1791   }
1792
1793   Int_t t0,t1,t2;
1794   for (i=0; i<ncl; i++) {
1795     index=pt->GetClusterIndex(i);
1796     AliTRDcluster *c=(AliTRDcluster*)fClusters->UncheckedAt(index);
1797     t0=c->GetLabel(0);
1798     t1=c->GetLabel(1);
1799     t2=c->GetLabel(2);
1800   }
1801
1802   for (i=0; i<ncl; i++) {
1803     index=pt->GetClusterIndex(i);
1804     AliTRDcluster *c=(AliTRDcluster*)fClusters->UncheckedAt(index);
1805     for (Int_t k=0; k<3; k++) { 
1806       label=c->GetLabel(k);
1807       labelAdded=kFALSE; j=0;
1808       if (label >= 0) {
1809         while ( (!labelAdded) && ( j < kRange ) ) {
1810           if (s[j][0]==label || s[j][1]==0) {
1811             s[j][0]=label; 
1812             s[j][1]=s[j][1]+1; 
1813             labelAdded=kTRUE;
1814           }
1815           j++;
1816         }
1817       }
1818     }
1819   }
1820
1821   Int_t max=0;
1822   label = -123456789;
1823
1824   for (i=0; i<kRange; i++) {
1825     if (s[i][1]>max) {
1826       max=s[i][1]; label=s[i][0];
1827     }
1828   }
1829
1830   for (i=0; i<kRange; i++) {
1831     delete []s[i];
1832   }        
1833
1834   delete []s;
1835
1836   if ((1.- Float_t(max)/ncl) > wrong) label=-label;   
1837
1838   pt->SetLabel(label); 
1839
1840 }
1841
1842
1843 //__________________________________________________________________
1844 void AliTRDtracker::UseClusters(const AliKalmanTrack* t, Int_t from) const 
1845 {
1846   //
1847   // Use clusters, but don't abuse them!
1848   //
1849
1850   Int_t ncl=t->GetNumberOfClusters();
1851   for (Int_t i=from; i<ncl; i++) {
1852     Int_t index = t->GetClusterIndex(i);
1853     AliTRDcluster *c=(AliTRDcluster*)fClusters->UncheckedAt(index);
1854     c->Use();
1855   }
1856 }
1857
1858
1859 //_____________________________________________________________________
1860 Double_t AliTRDtracker::ExpectedSigmaY2(Double_t , Double_t , Double_t ) const
1861 {
1862   // Parametrised "expected" error of the cluster reconstruction in Y 
1863
1864   Double_t s = 0.08 * 0.08;    
1865   return s;
1866 }
1867
1868 //_____________________________________________________________________
1869 Double_t AliTRDtracker::ExpectedSigmaZ2(Double_t , Double_t ) const
1870 {
1871   // Parametrised "expected" error of the cluster reconstruction in Z 
1872
1873   Double_t s = 9 * 9 /12.;  
1874   return s;
1875 }                  
1876
1877 //_____________________________________________________________________
1878 Double_t AliTRDtracker::GetX(Int_t sector, Int_t plane, Int_t localTB) const 
1879 {
1880   //
1881   // Returns radial position which corresponds to time bin <localTB>
1882   // in tracking sector <sector> and plane <plane>
1883   //
1884
1885   Int_t index = fTrSec[sector]->CookTimeBinIndex(plane, localTB); 
1886   Int_t pl = fTrSec[sector]->GetLayerNumber(index);
1887   return fTrSec[sector]->GetLayer(pl)->GetX();
1888
1889 }
1890
1891
1892 //_______________________________________________________
1893 AliTRDtracker::AliTRDpropagationLayer::AliTRDpropagationLayer(Double_t x, 
1894                Double_t dx, Double_t rho, Double_t radLength, Int_t tbIndex)
1895
1896   //
1897   // AliTRDpropagationLayer constructor
1898   //
1899
1900   fN = 0; fX = x; fdX = dx; fRho = rho; fX0 = radLength;
1901   fClusters = NULL; fIndex = NULL; fTimeBinIndex = tbIndex;
1902
1903
1904   for(Int_t i=0; i < (Int_t) kZones; i++) {
1905     fZc[i]=0; fZmax[i] = 0;
1906   }
1907
1908   fYmax = 0;
1909
1910   if(fTimeBinIndex >= 0) { 
1911     fClusters = new AliTRDcluster*[kMaxClusterPerTimeBin];
1912     fIndex = new UInt_t[kMaxClusterPerTimeBin];
1913   }
1914
1915   for (Int_t i=0;i<5;i++) fIsHole[i] = kFALSE;
1916   fHole = kFALSE;
1917   fHoleZc = 0;
1918   fHoleZmax = 0;
1919   fHoleYc = 0;
1920   fHoleYmax = 0;
1921   fHoleRho = 0;
1922   fHoleX0 = 0;
1923
1924 }
1925
1926 //_______________________________________________________
1927 void AliTRDtracker::AliTRDpropagationLayer::SetHole(
1928           Double_t Zmax, Double_t Ymax, Double_t rho, 
1929           Double_t radLength, Double_t Yc, Double_t Zc) 
1930 {
1931   //
1932   // Sets hole in the layer 
1933   //
1934   fHole = kTRUE;
1935   fHoleZc = Zc;
1936   fHoleZmax = Zmax;
1937   fHoleYc = Yc;
1938   fHoleYmax = Ymax;
1939   fHoleRho = rho;
1940   fHoleX0 = radLength;
1941 }
1942   
1943
1944 //_______________________________________________________
1945 AliTRDtracker::AliTRDtrackingSector::AliTRDtrackingSector(AliTRDgeometry* geo, Int_t gs, AliTRDparameter* par)
1946 {
1947   //
1948   // AliTRDtrackingSector Constructor
1949   //
1950
1951   fGeom = geo;
1952   fPar = par;
1953   fGeomSector = gs;
1954   fTzeroShift = 0.13;
1955   fN = 0;
1956   //
1957   // get holes description from geometry
1958   Bool_t holes[AliTRDgeometry::kNcham];
1959   //printf("sector\t%d\t",gs);
1960   for (Int_t icham=0; icham<AliTRDgeometry::kNcham;icham++){
1961     holes[icham] = fGeom->IsHole(0,icham,gs);
1962     //printf("%d",holes[icham]);
1963   } 
1964   //printf("\n");
1965   
1966   for(UInt_t i=0; i < kMaxTimeBinIndex; i++) fTimeBinIndex[i] = -1;
1967
1968
1969   AliTRDpropagationLayer* ppl;
1970
1971   Double_t x, xin, xout, dx, rho, radLength;
1972   Int_t    steps;
1973
1974   // set time bins in the gas of the TPC
1975
1976   xin = 246.055; xout = 254.055; steps = 20; dx = (xout-xin)/steps;
1977   rho = 0.9e-3;  radLength = 28.94;
1978
1979   for(Int_t i=0; i<steps; i++) {
1980     x = xin + i*dx + dx/2;
1981     ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,-1);
1982     InsertLayer(ppl);
1983   }
1984
1985   // set time bins in the outer field cage vessel
1986
1987   dx = 50e-4; xin = xout; xout = xin + dx; rho = 1.71; radLength = 44.77; // Tedlar
1988   ppl = new AliTRDpropagationLayer(xin+dx/2,dx,rho,radLength,-1);
1989   InsertLayer(ppl);
1990
1991   dx = 0.02; xin = xout; xout = xin + dx; rho = 1.45; radLength = 44.86; // prepreg
1992   ppl = new AliTRDpropagationLayer(xin+dx/2,dx,rho,radLength,-1);
1993   InsertLayer(ppl);
1994
1995   dx = 2.; xin = xout; xout = xin + dx; rho = 1.45*0.02; radLength = 41.28; // Nomex
1996   steps = 5; dx = (xout - xin)/steps;
1997   for(Int_t i=0; i<steps; i++) {
1998     x = xin + i*dx + dx/2;
1999     ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,-1);
2000     InsertLayer(ppl);
2001   }
2002
2003   dx = 0.02; xin = xout; xout = xin + dx; rho = 1.45; radLength = 44.86; // prepreg
2004   ppl = new AliTRDpropagationLayer(xin+dx/2,dx,rho,radLength,-1);
2005   InsertLayer(ppl);
2006
2007   dx = 50e-4; xin = xout; xout = xin + dx; rho = 1.71; radLength = 44.77; // Tedlar
2008   ppl = new AliTRDpropagationLayer(xin+dx/2,dx,rho,radLength,-1);
2009   InsertLayer(ppl);
2010
2011
2012   // set time bins in CO2
2013
2014   xin = xout; xout = 275.0; 
2015   steps = 50; dx = (xout - xin)/steps;
2016   rho = 1.977e-3;  radLength = 36.2;
2017   
2018   for(Int_t i=0; i<steps; i++) {
2019     x = xin + i*dx + dx/2;
2020     ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,-1);
2021     InsertLayer(ppl);
2022   }
2023
2024   // set time bins in the outer containment vessel
2025
2026   dx = 50e-4; xin = xout; xout = xin + dx; rho = 2.7; radLength = 24.01; // Al
2027   ppl = new AliTRDpropagationLayer(xin+dx/2,dx,rho,radLength,-1);
2028   InsertLayer(ppl);
2029
2030   dx = 50e-4; xin = xout; xout = xin + dx; rho = 1.71; radLength = 44.77; // Tedlar
2031   ppl = new AliTRDpropagationLayer(xin+dx/2,dx,rho,radLength,-1);
2032   InsertLayer(ppl);
2033
2034   dx = 0.06; xin = xout; xout = xin + dx; rho = 1.45; radLength = 44.86; // prepreg
2035   ppl = new AliTRDpropagationLayer(xin+dx/2,dx,rho,radLength,-1);
2036   InsertLayer(ppl);
2037
2038   dx = 3.; xin = xout; xout = xin + dx; rho = 1.45*0.02; radLength = 41.28; // Nomex
2039   steps = 10; dx = (xout - xin)/steps;
2040   for(Int_t i=0; i<steps; i++) {
2041     x = xin + i*dx + dx/2;
2042     ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,-1);
2043     InsertLayer(ppl);
2044   }
2045
2046   dx = 0.06; xin = xout; xout = xin + dx; rho = 1.45; radLength = 44.86; // prepreg
2047   ppl = new AliTRDpropagationLayer(xin+dx/2,dx,rho,radLength,-1);
2048   InsertLayer(ppl);
2049
2050   dx = 50e-4; xin = xout; xout = xin + dx; rho = 1.71; radLength = 44.77; // Tedlar
2051   ppl = new AliTRDpropagationLayer(xin+dx/2,dx,rho,radLength,-1);
2052   InsertLayer(ppl);
2053   
2054   dx = 50e-4; xin = xout; xout = xin + dx; rho = 2.7; radLength = 24.01; // Al
2055   ppl = new AliTRDpropagationLayer(xin+dx/2,dx,rho,radLength,-1);
2056   InsertLayer(ppl);
2057
2058   Double_t xtrd = (Double_t) fGeom->Rmin();  
2059
2060   // add layers between TPC and TRD (Air temporarily)
2061   xin = xout; xout = xtrd;
2062   steps = 50; dx = (xout - xin)/steps;
2063   rho = 1.2e-3;  radLength = 36.66;
2064   
2065   for(Int_t i=0; i<steps; i++) {
2066     x = xin + i*dx + dx/2;
2067     ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,-1);
2068     InsertLayer(ppl);
2069   }
2070
2071
2072   //  Double_t alpha=AliTRDgeometry::GetAlpha();
2073
2074   // add layers for each of the planes
2075
2076   Double_t dxRo = (Double_t) fGeom->CroHght();    // Rohacell 
2077   Double_t dxSpace = (Double_t) fGeom->Cspace();  // Spacing between planes
2078   Double_t dxAmp = (Double_t) fGeom->CamHght();   // Amplification region
2079   Double_t dxDrift = (Double_t) fGeom->CdrHght(); // Drift region  
2080   Double_t dxRad = (Double_t) fGeom->CraHght();   // Radiator
2081   Double_t dxTEC = dxRad + dxDrift + dxAmp + dxRo; 
2082   Double_t dxPlane = dxTEC + dxSpace; 
2083
2084   Int_t tb, tbIndex;
2085   const Int_t  kNchambers = AliTRDgeometry::Ncham();
2086   Double_t  ymax = 0;
2087   //, holeYmax = 0;
2088   Double_t ymaxsensitive=0;
2089   Double_t *zc = new Double_t[kNchambers];
2090   Double_t *zmax = new Double_t[kNchambers];
2091   Double_t *zmaxsensitive = new Double_t[kNchambers];  
2092   //  Double_t  holeZmax = 1000.;   // the whole sector is missing
2093
2094   for(Int_t plane = 0; plane < AliTRDgeometry::Nplan(); plane++) {
2095     //
2096     // Radiator 
2097     xin = xtrd + plane * dxPlane; xout = xin + dxRad;
2098     steps = 12; dx = (xout - xin)/steps; rho = 0.074; radLength = 40.6; 
2099     for(Int_t i=0; i<steps; i++) {
2100       x = xin + i*dx + dx/2;
2101       ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,-1);      
2102       InsertLayer(ppl);
2103     }
2104
2105     ymax          = fGeom->GetChamberWidth(plane)/2.;
2106     ymaxsensitive = (fPar->GetColPadSize(plane)*fPar->GetColMax(plane)-4)/2.;
2107     
2108     for(Int_t ch = 0; ch < kNchambers; ch++) {
2109       zmax[ch] = fGeom->GetChamberLength(plane,ch)/2;
2110       Float_t pad = fPar->GetRowPadSize(plane,ch,0);
2111       Float_t row0 = fPar->GetRow0(plane,ch,0);
2112       Int_t nPads = fPar->GetRowMax(plane,ch,0);
2113       zmaxsensitive[ch] = Float_t(nPads)*pad/2.;      
2114       //      zc[ch] = (pad * nPads)/2 + row0 - pad/2;
2115       zc[ch] = (pad * nPads)/2 + row0;
2116       //zc[ch] = row0+zmax[ch]-AliTRDgeometry::RpadW();
2117
2118     }
2119
2120     dx = fPar->GetTimeBinSize(); 
2121     rho = 0.00295 * 0.85; radLength = 11.0;  
2122
2123     Double_t x0 = (Double_t) fPar->GetTime0(plane);
2124     Double_t xbottom = x0 - dxDrift;
2125     Double_t xtop = x0 + dxAmp;
2126     //
2127     // Amplification region
2128     steps = (Int_t) (dxAmp/dx);
2129
2130     for(tb = 0; tb < steps; tb++) {
2131       x = x0 + tb * dx + dx/2;
2132       tbIndex = CookTimeBinIndex(plane, -tb-1);
2133       ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,tbIndex);
2134       ppl->SetYmax(ymax,ymaxsensitive);
2135       ppl->SetZ(zc, zmax, zmaxsensitive);
2136       ppl->SetHoles(holes);
2137       InsertLayer(ppl);
2138     }
2139     tbIndex = CookTimeBinIndex(plane, -steps);
2140     x = (x + dx/2 + xtop)/2;
2141     dx = 2*(xtop-x);
2142     ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,tbIndex);
2143     ppl->SetYmax(ymax,ymaxsensitive);
2144     ppl->SetZ(zc, zmax,zmaxsensitive);
2145     ppl->SetHoles(holes);
2146     InsertLayer(ppl);
2147
2148     // Drift region
2149     dx = fPar->GetTimeBinSize();
2150     steps = (Int_t) (dxDrift/dx);
2151
2152     for(tb = 0; tb < steps; tb++) {
2153       x = x0 - tb * dx - dx/2;
2154       tbIndex = CookTimeBinIndex(plane, tb);
2155
2156       ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,tbIndex);
2157       ppl->SetYmax(ymax,ymaxsensitive);
2158       ppl->SetZ(zc, zmax, zmaxsensitive);
2159       ppl->SetHoles(holes);
2160       InsertLayer(ppl);
2161     }
2162     tbIndex = CookTimeBinIndex(plane, steps);
2163     x = (x - dx/2 + xbottom)/2;
2164     dx = 2*(x-xbottom);
2165     ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,tbIndex);
2166     ppl->SetYmax(ymax,ymaxsensitive);
2167     ppl->SetZ(zc, zmax, zmaxsensitive);
2168     ppl->SetHoles(holes);    
2169     InsertLayer(ppl);
2170
2171     // Pad Plane
2172     xin = xtop; dx = 0.025; xout = xin + dx; rho = 1.7; radLength = 33.0;
2173     ppl = new AliTRDpropagationLayer(xin+dx/2,dx,rho,radLength,-1);
2174     ppl->SetYmax(ymax,ymaxsensitive);
2175     ppl->SetZ(zc, zmax,zmax);
2176     ppl->SetHoles(holes);         
2177     InsertLayer(ppl);
2178
2179     // Rohacell
2180     xin = xout; xout = xtrd + (plane + 1) * dxPlane - dxSpace;
2181     steps = 5; dx = (xout - xin)/steps; rho = 0.074; radLength = 40.6; 
2182     for(Int_t i=0; i<steps; i++) {
2183       x = xin + i*dx + dx/2;
2184       ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,-1);
2185       ppl->SetYmax(ymax,ymaxsensitive);
2186       ppl->SetZ(zc, zmax,zmax);
2187       ppl->SetHoles(holes);
2188       InsertLayer(ppl);
2189     }
2190
2191     // Space between the chambers, air
2192     xin = xout; xout = xtrd + (plane + 1) * dxPlane;
2193     steps = 5; dx = (xout - xin)/steps; rho = 1.29e-3; radLength = 36.66; 
2194     for(Int_t i=0; i<steps; i++) {
2195       x = xin + i*dx + dx/2;
2196       ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,-1);
2197       InsertLayer(ppl);
2198     }
2199   }    
2200
2201   // Space between the TRD and RICH
2202   Double_t xRICH = 500.;
2203   xin = xout; xout = xRICH;
2204   steps = 200; dx = (xout - xin)/steps; rho = 1.29e-3; radLength = 36.66; 
2205   for(Int_t i=0; i<steps; i++) {
2206     x = xin + i*dx + dx/2;
2207     ppl = new AliTRDpropagationLayer(x,dx,rho,radLength,-1);
2208     InsertLayer(ppl);
2209   }
2210
2211   MapTimeBinLayers();
2212   delete [] zc;
2213   delete [] zmax;
2214
2215 }
2216
2217 //______________________________________________________
2218
2219 Int_t  AliTRDtracker::AliTRDtrackingSector::CookTimeBinIndex(Int_t plane, Int_t localTB) const
2220 {
2221   //
2222   // depending on the digitization parameters calculates "global"
2223   // time bin index for timebin <localTB> in plane <plane>
2224   //
2225
2226   Double_t dxAmp = (Double_t) fGeom->CamHght();   // Amplification region
2227   Double_t dxDrift = (Double_t) fGeom->CdrHght(); // Drift region  
2228   Double_t dx = (Double_t) fPar->GetTimeBinSize();  
2229
2230   Int_t tbAmp = fPar->GetTimeBefore();
2231   Int_t maxAmp = (Int_t) ((dxAmp+0.000001)/dx);
2232   if(kTRUE) maxAmp = 0;   // intentional until we change parameter class 
2233   Int_t tbDrift = fPar->GetTimeMax();
2234   Int_t maxDrift = (Int_t) ((dxDrift+0.000001)/dx);
2235
2236   Int_t tbPerPlane = TMath::Min(tbAmp,maxAmp) + TMath::Min(tbDrift,maxDrift);
2237
2238   Int_t gtb = (plane+1) * tbPerPlane - localTB - 1 - TMath::Min(tbAmp,maxAmp);
2239
2240   if((localTB < 0) && 
2241      (TMath::Abs(localTB) > TMath::Min(tbAmp,maxAmp))) return -1;
2242   if(localTB >= TMath::Min(tbDrift,maxDrift)) return -1;
2243
2244   return gtb;
2245
2246
2247 }
2248
2249 //______________________________________________________
2250
2251 void AliTRDtracker::AliTRDtrackingSector::MapTimeBinLayers() 
2252 {
2253   //
2254   // For all sensitive time bins sets corresponding layer index
2255   // in the array fTimeBins 
2256   //
2257
2258   Int_t index;
2259
2260   for(Int_t i = 0; i < fN; i++) {
2261     index = fLayers[i]->GetTimeBinIndex();
2262     
2263     //    printf("gtb %d -> pl %d -> x %f \n", index, i, fLayers[i]->GetX());
2264
2265     if(index < 0) continue;
2266     if(index >= (Int_t) kMaxTimeBinIndex) {
2267       printf("*** AliTRDtracker::MapTimeBinLayers: \n");
2268       printf("    index %d exceeds allowed maximum of %d!\n",
2269              index, kMaxTimeBinIndex-1);
2270       continue;
2271     }
2272     fTimeBinIndex[index] = i;
2273   }
2274
2275   Double_t x1, dx1, x2, dx2, gap;
2276
2277   for(Int_t i = 0; i < fN-1; i++) {
2278     x1 = fLayers[i]->GetX();
2279     dx1 = fLayers[i]->GetdX();
2280     x2 = fLayers[i+1]->GetX();
2281     dx2 = fLayers[i+1]->GetdX();
2282     gap = (x2 - dx2/2) - (x1 + dx1/2);
2283     if(gap < -0.01) {
2284       printf("*** warning: layers %d and %d are overlayed:\n",i,i+1);
2285       printf("             %f + %f + %f > %f\n", x1, dx1/2, dx2/2, x2);
2286     }
2287     if(gap > 0.01) { 
2288       printf("*** warning: layers %d and %d have a large gap:\n",i,i+1);
2289       printf("             (%f - %f) - (%f + %f) = %f\n", 
2290              x2, dx2/2, x1, dx1, gap);
2291     }
2292   }
2293 }
2294   
2295
2296 //______________________________________________________
2297
2298
2299 Int_t AliTRDtracker::AliTRDtrackingSector::GetLayerNumber(Double_t x) const
2300 {
2301   // 
2302   // Returns the number of time bin which in radial position is closest to <x>
2303   //
2304
2305   if(x >= fLayers[fN-1]->GetX()) return fN-1; 
2306   if(x <= fLayers[0]->GetX()) return 0; 
2307
2308   Int_t b=0, e=fN-1, m=(b+e)/2;
2309   for (; b<e; m=(b+e)/2) {
2310     if (x > fLayers[m]->GetX()) b=m+1;
2311     else e=m;
2312   }
2313   if(TMath::Abs(x - fLayers[m]->GetX()) > 
2314      TMath::Abs(x - fLayers[m+1]->GetX())) return m+1;
2315   else return m;
2316
2317 }
2318
2319 //______________________________________________________
2320
2321 Int_t AliTRDtracker::AliTRDtrackingSector::GetInnerTimeBin() const 
2322 {
2323   // 
2324   // Returns number of the innermost SENSITIVE propagation layer
2325   //
2326
2327   return GetLayerNumber(0);
2328 }
2329
2330 //______________________________________________________
2331
2332 Int_t AliTRDtracker::AliTRDtrackingSector::GetOuterTimeBin() const 
2333 {
2334   // 
2335   // Returns number of the outermost SENSITIVE time bin
2336   //
2337
2338   return GetLayerNumber(GetNumberOfTimeBins() - 1);
2339 }
2340
2341 //______________________________________________________
2342
2343 Int_t AliTRDtracker::AliTRDtrackingSector::GetNumberOfTimeBins() const 
2344 {
2345   // 
2346   // Returns number of SENSITIVE time bins
2347   //
2348
2349   Int_t tb, layer;
2350   for(tb = kMaxTimeBinIndex-1; tb >=0; tb--) {
2351     layer = GetLayerNumber(tb);
2352     if(layer>=0) break;
2353   }
2354   return tb+1;
2355 }
2356
2357 //______________________________________________________
2358
2359 void AliTRDtracker::AliTRDtrackingSector::InsertLayer(AliTRDpropagationLayer* pl)
2360
2361   //
2362   // Insert layer <pl> in fLayers array.
2363   // Layers are sorted according to X coordinate.
2364
2365   if ( fN == ((Int_t) kMaxLayersPerSector)) {
2366     printf("AliTRDtrackingSector::InsertLayer(): Too many layers !\n");
2367     return;
2368   }
2369   if (fN==0) {fLayers[fN++] = pl; return;}
2370   Int_t i=Find(pl->GetX());
2371
2372   memmove(fLayers+i+1 ,fLayers+i,(fN-i)*sizeof(AliTRDpropagationLayer*));
2373   fLayers[i]=pl; fN++;
2374
2375 }              
2376
2377 //______________________________________________________
2378
2379 Int_t AliTRDtracker::AliTRDtrackingSector::Find(Double_t x) const 
2380 {
2381   //
2382   // Returns index of the propagation layer nearest to X 
2383   //
2384
2385   if (x <= fLayers[0]->GetX()) return 0;
2386   if (x > fLayers[fN-1]->GetX()) return fN;
2387   Int_t b=0, e=fN-1, m=(b+e)/2;
2388   for (; b<e; m=(b+e)/2) {
2389     if (x > fLayers[m]->GetX()) b=m+1;
2390     else e=m;
2391   }
2392   return m;
2393 }             
2394
2395 //______________________________________________________
2396 void AliTRDtracker::AliTRDpropagationLayer::SetZ(Double_t* center, Double_t *w, Double_t *wsensitive )
2397 {
2398   //
2399   // set centers and the width of sectors
2400   for (Int_t icham=0;icham< AliTRDgeometry::kNcham;icham++){
2401     fZc[icham] = center[icham];  
2402     fZmax[icham] = w[icham];
2403     fZmaxSensitive[icham] = wsensitive[icham];
2404     //   printf("chamber\t%d\tzc\t%f\tzmax\t%f\tzsens\t%f\n",icham,fZc[icham],fZmax[icham],fZmaxSensitive[icham]);
2405   }  
2406 }
2407 //______________________________________________________
2408
2409 void AliTRDtracker::AliTRDpropagationLayer::SetHoles(Bool_t *holes)
2410 {
2411   //
2412   // set centers and the width of sectors
2413   fHole = kFALSE;
2414   for (Int_t icham=0;icham< AliTRDgeometry::kNcham;icham++){
2415     fIsHole[icham] = holes[icham]; 
2416     if (holes[icham]) fHole = kTRUE;
2417   }  
2418 }
2419
2420
2421
2422 void AliTRDtracker::AliTRDpropagationLayer::GetPropagationParameters(
2423         Double_t y, Double_t z, Double_t &dx, Double_t &rho, Double_t &radLength, 
2424         Bool_t &lookForCluster) const
2425 {
2426   //
2427   // Returns radial step <dx>, density <rho>, rad. length <radLength>,
2428   // and sensitivity <lookForCluster> in point <y,z>  
2429   //
2430
2431   dx  = fdX;
2432   rho = fRho;
2433   radLength  = fX0;
2434   lookForCluster = kFALSE;
2435   //
2436   // check dead regions in sensitive volume 
2437   if(fTimeBinIndex >= 0) {
2438     //
2439     Int_t zone=-1;
2440     for(Int_t ch = 0; ch < (Int_t) kZones; ch++) {
2441       if  (TMath::Abs(z - fZc[ch]) < fZmaxSensitive[ch]){ 
2442         zone = ch;
2443         lookForCluster = !(fIsHole[zone]);
2444         if(TMath::Abs(y) > fYmaxSensitive){  
2445           lookForCluster = kFALSE;
2446         }
2447         if (fIsHole[zone]) {
2448           //if hole
2449           rho = 1.29e-3;
2450           radLength = 36.66;
2451         }
2452       }    
2453     }
2454     return;
2455   }
2456   //
2457   //
2458   // check hole
2459   if (fHole==kFALSE) return;
2460   //
2461   for(Int_t ch = 0; ch < (Int_t) kZones; ch++) {
2462     if  (TMath::Abs(z - fZc[ch]) < fZmax[ch]){ 
2463       if (fIsHole[ch]) {
2464         //if hole
2465         rho = 1.29e-3;
2466         radLength = 36.66;
2467       }
2468     }
2469   }
2470   return;
2471 }
2472
2473 Int_t  AliTRDtracker::AliTRDpropagationLayer::GetZone( Double_t z) const
2474 {
2475   //
2476   //
2477   if (fTimeBinIndex < 0) return -20;  //unknown 
2478   Int_t zone=-10;   // dead zone
2479   for(Int_t ch = 0; ch < (Int_t) kZones; ch++) {
2480     if(TMath::Abs(z - fZc[ch]) < fZmax[ch]) 
2481       zone = ch;
2482   }
2483   return zone;
2484 }
2485
2486
2487 //______________________________________________________
2488
2489 void AliTRDtracker::AliTRDpropagationLayer::InsertCluster(AliTRDcluster* c, 
2490                                                           UInt_t index) {
2491
2492 // Insert cluster in cluster array.
2493 // Clusters are sorted according to Y coordinate.  
2494
2495   if(fTimeBinIndex < 0) { 
2496     printf("*** attempt to insert cluster into non-sensitive time bin!\n");
2497     return;
2498   }
2499
2500   if (fN== (Int_t) kMaxClusterPerTimeBin) {
2501     printf("AliTRDpropagationLayer::InsertCluster(): Too many clusters !\n"); 
2502     return;
2503   }
2504   if (fN==0) {fIndex[0]=index; fClusters[fN++]=c; return;}
2505   Int_t i=Find(c->GetY());
2506   memmove(fClusters+i+1 ,fClusters+i,(fN-i)*sizeof(AliTRDcluster*));
2507   memmove(fIndex   +i+1 ,fIndex   +i,(fN-i)*sizeof(UInt_t)); 
2508   fIndex[i]=index; fClusters[i]=c; fN++;
2509 }  
2510
2511 //______________________________________________________
2512
2513 Int_t AliTRDtracker::AliTRDpropagationLayer::Find(Double_t y) const {
2514
2515 // Returns index of the cluster nearest in Y    
2516
2517   if (y <= fClusters[0]->GetY()) return 0;
2518   if (y > fClusters[fN-1]->GetY()) return fN;
2519   Int_t b=0, e=fN-1, m=(b+e)/2;
2520   for (; b<e; m=(b+e)/2) {
2521     if (y > fClusters[m]->GetY()) b=m+1;
2522     else e=m;
2523   }
2524   return m;
2525 }    
2526
2527 //---------------------------------------------------------
2528
2529 Double_t AliTRDtracker::GetTiltFactor(const AliTRDcluster* c) {
2530 //
2531 //  Returns correction factor for tilted pads geometry 
2532 //
2533
2534   Double_t h01 = sin(TMath::Pi() / 180.0 * fPar->GetTiltingAngle());
2535   Int_t det = c->GetDetector();    
2536   Int_t plane = fGeom->GetPlane(det);
2537
2538   //if((plane == 1) || (plane == 3) || (plane == 5)) h01=-h01;
2539   if((plane == 0) || (plane == 2) || (plane == 4)) h01=-h01;
2540
2541   if(fNoTilt) h01 = 0;
2542   
2543   return h01;
2544 }
2545
2546
2547 void AliTRDtracker::CookdEdxTimBin(AliTRDtrack& TRDtrack)
2548 {
2549   // *** ADDED TO GET MORE INFORMATION FOR TRD PID  ---- PS
2550   // This is setting fdEdxPlane and fTimBinPlane
2551   // Sums up the charge in each plane for track TRDtrack and also get the 
2552   // Time bin for Max. Cluster
2553   // Prashant Shukla (shukla@physi.uni-heidelberg.de)
2554
2555   //  const Int_t kNPlane = AliTRDgeometry::Nplan();
2556   //  const Int_t kNPlane = 6;
2557   Double_t  clscharge[kNPlane], maxclscharge[kNPlane];
2558   Int_t  nCluster[kNPlane], timebin[kNPlane];
2559
2560   //Initialization of cluster charge per plane.  
2561   for (Int_t iPlane = 0; iPlane < kNPlane; iPlane++) {
2562     clscharge[iPlane] = 0.0;
2563     nCluster[iPlane] = 0;
2564     timebin[iPlane] = -1;
2565     maxclscharge[iPlane] = 0.0;
2566   }
2567
2568   // Loop through all clusters associated to track TRDtrack
2569   Int_t nClus = TRDtrack.GetNumberOfClusters();  // from Kalmantrack
2570   for (Int_t iClus = 0; iClus < nClus; iClus++) {
2571     Double_t charge = TRDtrack.GetClusterdQdl(iClus);
2572     Int_t index = TRDtrack.GetClusterIndex(iClus);
2573     AliTRDcluster *TRDcluster = (AliTRDcluster *) GetCluster(index); 
2574     if (!TRDcluster) continue;
2575     Int_t tb = TRDcluster->GetLocalTimeBin();
2576     if (!tb) continue;
2577     Int_t detector = TRDcluster->GetDetector();
2578     Int_t iPlane   = fGeom->GetPlane(detector);
2579     clscharge[iPlane] = clscharge[iPlane]+charge;
2580     if(charge > maxclscharge[iPlane]) {
2581       maxclscharge[iPlane] = charge;
2582       timebin[iPlane] = tb;
2583     }
2584     nCluster[iPlane]++;
2585   } // end of loop over cluster
2586
2587   // Setting the fdEdxPlane and fTimBinPlane variabales 
2588   Double_t Total_ch = 0;
2589   for (Int_t iPlane = 0; iPlane < kNPlane; iPlane++) {
2590     if (nCluster[iPlane]) clscharge[iPlane] /= nCluster[iPlane];
2591     TRDtrack.SetPIDsignals(clscharge[iPlane], iPlane);
2592     TRDtrack.SetPIDTimBin(timebin[iPlane], iPlane);
2593     Total_ch= Total_ch+clscharge[iPlane];
2594   }
2595   //  Int_t i;
2596   //  Int_t nc=TRDtrack.GetNumberOfClusters(); 
2597   //  Float_t dedx=0;
2598   //  for (i=0; i<nc; i++) dedx += TRDtrack.GetClusterdQdl(i);
2599   //  dedx /= nc;
2600   //  for (Int_t iPlane = 0; iPlane < kNPlane; iPlane++) {
2601   //    TRDtrack.SetPIDsignals(dedx, iPlane);
2602   //    TRDtrack.SetPIDTimBin(timbin[iPlane], iPlane);
2603   //  }
2604
2605 } // end of function
2606
2607
2608
2609
2610