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