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