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