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