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