e0f4ddbd91869899183a42eef65f129e1f7605e8
[u/mrichter/AliRoot.git] / TRD / AliTRDtrigger.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 //                                                                           //
18 //  TRD trigger class                                                        //
19 //                                                                           //
20 //  Author:                                                                  //
21 //    Bogdan Vulpescu                                                        //
22 //                                                                           //
23 ///////////////////////////////////////////////////////////////////////////////
24
25 #include <TTree.h>
26 #include <TBranch.h>
27 #include <TMatrixD.h>
28 #include <TClonesArray.h>
29 #include <TObjArray.h>
30
31 #include "AliLog.h"
32 #include "AliRun.h"
33 #include "AliLoader.h"
34
35 #include "AliTRDdigitsManager.h"
36 #include "AliTRDgeometry.h"
37 #include "AliTRDdataArrayI.h"
38 #include "AliTRDcalibDB.h"
39 #include "AliTRDCommonParam.h"
40 #include "AliTRDrawData.h"
41 #include "AliTRDtrigger.h"
42 #include "AliTRDmodule.h"
43 #include "AliTRDmcmTracklet.h"
44 #include "AliTRDgtuTrack.h"
45 #include "AliTRDtrigParam.h"
46 #include "AliTRDmcm.h"
47 #include "AliTRDzmaps.h"
48 #include "AliTRDCalibraFillHisto.h"
49 #include "Cal/AliTRDCalPIDLQ.h"
50
51 ClassImp(AliTRDtrigger)
52
53 //_____________________________________________________________________________
54 AliTRDtrigger::AliTRDtrigger()
55   :TNamed()
56   ,fField(0)
57   ,fGeo(NULL)
58   ,fCalib(NULL)
59   ,fCParam(NULL)
60   ,fTrigParam(NULL)
61   ,fRunLoader(NULL)
62   ,fDigitsManager(NULL)
63   ,fTrackletTree(NULL)
64   ,fTracklets(NULL)
65   ,fNROB(0)
66   ,fMCM(NULL)
67   ,fTrk(NULL)
68   ,fTrkTest(NULL)
69   ,fModule(NULL)
70   ,fGTUtrk(NULL)
71   ,fNtracklets(0)
72   ,fDigits(NULL)
73   ,fTrack0(NULL)
74   ,fTrack1(NULL)
75   ,fTrack2(NULL)
76   ,fNPrimary(0)
77   ,fTracks(NULL)
78 {
79   //
80   // AliTRDtrigger default constructor
81   //
82
83 }
84
85 //_____________________________________________________________________________
86 AliTRDtrigger::AliTRDtrigger(const Text_t *name, const Text_t *title)
87   :TNamed(name,title)
88   ,fField(0)
89   ,fGeo(NULL)
90   ,fCalib(NULL)
91   ,fCParam(NULL)
92   ,fTrigParam(NULL)
93   ,fRunLoader(NULL)
94   ,fDigitsManager(new AliTRDdigitsManager())
95   ,fTrackletTree(NULL)
96   ,fTracklets(new TObjArray(400))
97   ,fNROB(0)
98   ,fMCM(NULL)
99   ,fTrk(NULL)
100   ,fTrkTest(NULL)
101   ,fModule(NULL)
102   ,fGTUtrk(NULL)
103   ,fNtracklets(0)
104   ,fDigits(NULL)
105   ,fTrack0(NULL)
106   ,fTrack1(NULL)
107   ,fTrack2(NULL)
108   ,fNPrimary(0)
109   ,fTracks(new TClonesArray("AliTRDgtuTrack",1000))
110 {
111   //
112   // AliTRDtrigger constructor
113   //
114
115 }
116
117 //_____________________________________________________________________________
118 AliTRDtrigger::AliTRDtrigger(const AliTRDtrigger &p)
119   :TNamed(p)
120   ,fField(p.fField)
121   ,fGeo(NULL)
122   ,fCalib(NULL)
123   ,fCParam(NULL)
124   ,fTrigParam(NULL)
125   ,fRunLoader(NULL)
126   ,fDigitsManager(NULL)
127   ,fTrackletTree(NULL)
128   ,fTracklets(NULL)
129   ,fNROB(p.fNROB)
130   ,fMCM(NULL)
131   ,fTrk(NULL)
132   ,fTrkTest(NULL)
133   ,fModule(NULL)
134   ,fGTUtrk(NULL)
135   ,fNtracklets(p.fNtracklets)
136   ,fDigits(NULL)
137   ,fTrack0(NULL)
138   ,fTrack1(NULL)
139   ,fTrack2(NULL)
140   ,fNPrimary(p.fNPrimary)
141   ,fTracks(NULL)
142 {
143   //
144   // AliTRDtrigger copy constructor
145   //
146
147 }
148
149 ///_____________________________________________________________________________
150 AliTRDtrigger::~AliTRDtrigger()
151 {
152   //
153   // AliTRDtrigger destructor
154   //
155
156   if (fTracklets) {
157     fTracklets->Delete();
158     delete fTracklets;
159   }
160
161   if (fTracks) {
162     fTracks->Delete();
163     delete fTracks;
164   }
165
166 }
167
168 //_____________________________________________________________________________
169 AliTRDtrigger &AliTRDtrigger::operator=(const AliTRDtrigger &p)
170 {
171   //
172   // Assignment operator
173   //
174
175   if (this != &p) ((AliTRDtrigger &) p).Copy(*this);
176   return *this;
177
178 }
179
180 //_____________________________________________________________________________
181 void AliTRDtrigger::Copy(TObject &) const
182 {
183   //
184   // Copy function
185   //
186
187   AliFatal("Not implemented");
188
189 }
190
191 //_____________________________________________________________________________
192 void AliTRDtrigger::Init()
193 {
194
195   fModule = new AliTRDmodule(fTrigParam); 
196   fTracks->Clear();
197
198   fField  = fTrigParam->GetField();
199   fGeo    = (AliTRDgeometry*)AliTRDgeometry::GetGeometry(fRunLoader);
200
201   fCalib  = AliTRDcalibDB::Instance();
202   if (!fCalib) {
203     AliError("No instance of AliTRDcalibDB.");
204     return;  
205   }
206
207   fCParam = AliTRDCommonParam::Instance();
208   if (!fCParam) {
209     AliError("No common parameters.");
210     return;
211   }
212
213 }
214
215 //_____________________________________________________________________________
216 Bool_t AliTRDtrigger::Open(const Char_t *name, Int_t nEvent)
217 {
218   //
219   // Opens the AliROOT file.
220   //
221
222   TString evfoldname = AliConfig::GetDefaultEventFolderName();
223   fRunLoader         = AliRunLoader::GetRunLoader(evfoldname);
224
225   if (!fRunLoader) {
226     fRunLoader = AliRunLoader::Open(name);
227   }
228   if (!fRunLoader) {
229     AliError(Form("Can not open session for file %s.",name));
230     return kFALSE;
231   }
232
233   // Import the Trees for the event nEvent in the file
234   fRunLoader->GetEvent(nEvent);
235
236   // Open output
237   TObjArray *ioArray = 0;
238   AliLoader* loader  = fRunLoader->GetLoader("TRDLoader");
239   loader->MakeTree("T");
240   fTrackletTree = loader->TreeT();
241   fTrackletTree->Branch("TRDmcmTracklet","TObjArray",&ioArray,32000,0);
242   Init();
243
244   return kTRUE;
245
246 }
247
248 //_____________________________________________________________________________
249 Bool_t AliTRDtrigger::ReadDigits() 
250 {
251   //
252   // Reads the digits arrays from the input aliroot file
253   //
254
255   if (!fRunLoader) {
256     AliError("Can not find the Run Loader");
257     return kFALSE;
258   }
259
260   AliLoader* loader = fRunLoader->GetLoader("TRDLoader");
261   if (!loader->TreeD()) {
262     loader->LoadDigits();
263   }
264   if (!loader->TreeD()) {
265      return kFALSE;
266   }
267
268   return (fDigitsManager->ReadDigits(loader->TreeD()));
269
270 }
271
272 //_____________________________________________________________________________
273 Bool_t AliTRDtrigger::ReadDigits(AliRawReader* rawReader)
274 {
275   //
276   // Reads the digits arrays from the ddl file
277   //
278
279   AliTRDrawData *raw = new AliTRDrawData();
280   fDigitsManager     = raw->Raw2Digits(rawReader);
281
282   return kTRUE;
283
284 }
285
286 //_____________________________________________________________________________
287 Bool_t AliTRDtrigger::ReadDigits(TTree *digitsTree) 
288 {
289   //
290   // Reads the digits arrays from the input tree
291   //
292
293   return (fDigitsManager->ReadDigits(digitsTree));
294
295 }
296
297 //_____________________________________________________________________________
298 Bool_t AliTRDtrigger::ReadTracklets(AliRunLoader *rl) 
299 {
300   //
301   // Reads the tracklets find the tracks
302   //
303
304   Int_t idet;
305
306   AliLoader *loader = rl->GetLoader("TRDLoader");
307   loader->LoadTracks();
308   fTrackletTree     = loader->TreeT();
309
310   TBranch *branch   = fTrackletTree->GetBranch("TRDmcmTracklet");
311   if (!branch) {
312     AliError("Can't get the branch !");
313     return kFALSE;
314   }
315   TObjArray *tracklets = new TObjArray(400);
316   branch->SetAddress(&tracklets);
317
318   Int_t nEntries   = (Int_t) fTrackletTree->GetEntries();
319   Int_t iEntry;
320   Int_t itrk;
321   Int_t iStack;
322   Int_t iStackPrev = -1;
323   
324   for (iEntry = 0; iEntry < nEntries; iEntry++) {    
325
326     fTrackletTree->GetEvent(iEntry);
327     
328     for (itrk = 0; itrk < tracklets->GetEntriesFast(); itrk++) {
329
330       fTrk   = (AliTRDmcmTracklet*)tracklets->UncheckedAt(itrk);
331       idet   = fTrk->GetDetector();
332       iStack = idet / (AliTRDgeometry::Nplan());
333
334       if (iStackPrev != iStack) {
335         if (iStackPrev == -1) {
336           iStackPrev = iStack;
337         } 
338         else {
339           MakeTracks(idet - AliTRDgeometry::Nplan());
340           ResetTracklets();
341           iStackPrev = iStack;
342         }
343       }
344       
345       Tracklets()->Add(fTrk);
346
347       if ((iEntry == (nEntries-1)) && 
348           (itrk   == (tracklets->GetEntriesFast() - 1))) {
349         idet++;
350         MakeTracks(idet-AliTRDgeometry::Nplan());
351         ResetTracklets();
352       }
353
354     }
355
356   }
357
358   loader->UnloadTracks();
359
360   return kTRUE;
361
362 }
363
364 //_____________________________________________________________________________
365 Bool_t AliTRDtrigger::MakeTracklets(Bool_t makeTracks)
366 {
367   //
368   // Create tracklets from digits
369   //
370
371   Int_t chamBeg = 0;
372   Int_t chamEnd = AliTRDgeometry::Ncham();
373   Int_t planBeg = 0;
374   Int_t planEnd = AliTRDgeometry::Nplan();
375   Int_t sectBeg = 0;
376   Int_t sectEnd = AliTRDgeometry::Nsect();
377
378   fTrkTest = new AliTRDmcmTracklet(0,0,0);
379   fMCM     = new AliTRDmcm(fTrigParam,0);
380
381   Int_t   time;
382   Int_t   col;
383   Int_t   row;
384   Int_t   col1;
385   Int_t   col2;
386   Int_t   idet       = -1;
387   Int_t   iStack     = -1;
388   Int_t   iStackPrev = -1;
389   Float_t amp;
390
391   for (Int_t isect = sectBeg; isect < sectEnd; isect++) {
392
393     for (Int_t icham = chamBeg; icham < chamEnd; icham++) {
394
395       // Number of ROBs in the chamber
396       if(icham == 2) {
397         fNROB = 6;
398       } 
399       else {
400         fNROB = 8;
401       }
402
403       for (Int_t iplan = planBeg; iplan < planEnd; iplan++) {
404
405         idet = fGeo->GetDetector(iplan,icham,isect);
406         ResetTracklets();
407         
408         if (makeTracks) {
409           iStack = idet / (AliTRDgeometry::Nplan());
410           if (iStackPrev != iStack) {
411             if (iStackPrev == -1) {
412               iStackPrev = iStack;
413             } 
414             else {
415               MakeTracks(idet-AliTRDgeometry::Nplan());
416               ResetTracklets();
417               iStackPrev = iStack;
418             }
419           }
420         }
421
422         Int_t nRowMax    = fCParam->GetRowMax(iplan,icham,isect);
423         Int_t nColMax    = fCParam->GetColMax(iplan);
424         Int_t nTimeTotal = fCalib->GetNumberOfTimeBins();
425
426         // Get the digits
427         fDigits = fDigitsManager->GetDigits(idet);
428         if (!fDigits) return kFALSE;
429         // This is to take care of switched off super modules
430         if (fDigits->GetNtime() == 0) {
431           continue;
432         }
433         fDigits->Expand();
434         fTrack0 = fDigitsManager->GetDictionary(idet,0);
435         if (!fTrack0) return kFALSE;
436         fTrack0->Expand();
437         fTrack1 = fDigitsManager->GetDictionary(idet,1);
438         if (!fTrack1) return kFALSE;
439         fTrack1->Expand();
440         fTrack2 = fDigitsManager->GetDictionary(idet,2); 
441         if (!fTrack2) return kFALSE;
442         fTrack2->Expand();
443
444         for (Int_t iRob = 0; iRob < fNROB; iRob++) {
445
446           for (Int_t iMcm = 0; iMcm < kNMCM; iMcm++) {
447
448             fMCM->Reset();
449             fMCM->SetRobId(iRob);
450             fMCM->SetChaId(idet);
451
452             SetMCMcoordinates(iMcm);
453
454             row = fMCM->GetRow();
455
456             if ((row < 0) || (row >= nRowMax)) {
457               AliError("MCM row number out of range.");
458               continue;
459             }
460
461             fMCM->GetColRange(col1,col2);
462             
463             for (time = 0; time < nTimeTotal; time++) {
464               for (col = col1; col < col2; col++) {
465                 if ((col >= 0) && (col < nColMax)) {
466                   amp = TMath::Abs(fDigits->GetDataUnchecked(row,col,time));
467                 } 
468                 else {
469                   amp = 0.0;
470                 }
471                 fMCM->SetADC(col-col1,time,amp);
472               }
473             }
474
475             if (fTrigParam->GetTailCancelation()) {
476               fMCM->Filter(fTrigParam->GetNexponential(),fTrigParam->GetFilterType());
477             }
478             
479             if (fMCM->Run()) {
480
481               for (Int_t iSeed = 0; iSeed < kMaxTrackletsPerMCM; iSeed++) {
482                 
483                 if (fMCM->GetSeedCol()[iSeed] < 0) {
484                   continue;
485                 }
486
487                 if (fTrigParam->GetDebugLevel()   > 1) { 
488                   AliInfo(Form("Add tracklet %d in col %02d \n",fNtracklets,fMCM->GetSeedCol()[iSeed]));
489                 }
490
491                 if (TestTracklet(idet,row,iSeed,0)) {
492                   AddTracklet(idet,row,iSeed,fNtracklets++);
493                 }
494
495               }
496
497             }
498
499           }
500
501       
502         }
503
504         // Compress the arrays
505         fDigits->Compress(1,0);
506         fTrack0->Compress(1,0);
507         fTrack1->Compress(1,0);
508         fTrack2->Compress(1,0);
509
510         WriteTracklets(idet);
511
512      }
513     }
514   }
515
516   if (makeTracks) {
517     idet++;
518     MakeTracks(idet - AliTRDgeometry::Nplan());
519     ResetTracklets();
520   }
521
522   return kTRUE;
523
524 }
525
526 //_____________________________________________________________________________
527 void AliTRDtrigger::SetMCMcoordinates(Int_t imcm)
528 {
529   //
530   // Configure MCM position in the pad plane
531   //
532
533   Int_t robid = fMCM->GetRobId();
534
535   // setting the Row and Col range
536
537   const Int_t kNcolRob = 2;  // number of ROBs per chamber in column direction
538   const Int_t kNmcmRob = 4;  // number of MCMs per ROB in column/row direction
539
540   Int_t mcmid = imcm%(kNmcmRob*kNmcmRob);
541
542   if (robid%kNcolRob == 0) {
543
544     if (mcmid%kNmcmRob == 0) {
545       fMCM->SetColRange(18*0-1,18*1-1+2+1);
546     }
547     if (mcmid%kNmcmRob == 1) {
548       fMCM->SetColRange(18*1-1,18*2-1+2+1);
549     }
550     if (mcmid%kNmcmRob == 2) {
551       fMCM->SetColRange(18*2-1,18*3-1+2+1);
552     }
553     if (mcmid%kNmcmRob == 3) {
554       fMCM->SetColRange(18*3-1,18*4-1+2+1);
555     }
556
557   } 
558   else {
559
560     if (mcmid%kNmcmRob == 0) {
561       fMCM->SetColRange(18*4-1,18*5-1+2+1);
562     }
563     if (mcmid%kNmcmRob == 1) {
564       fMCM->SetColRange(18*5-1,18*6-1+2+1);
565     }
566     if (mcmid%kNmcmRob == 2) {
567       fMCM->SetColRange(18*6-1,18*7-1+2+1);
568     }
569     if (mcmid%kNmcmRob == 3) {
570       fMCM->SetColRange(18*7-1,18*8-1+2+1);
571     }
572
573   } 
574
575   fMCM->SetRow(kNmcmRob*(robid/kNcolRob)+mcmid/kNmcmRob);
576
577 }
578
579 //_____________________________________________________________________________
580 Bool_t AliTRDtrigger::TestTracklet(Int_t det, Int_t row, Int_t seed, Int_t n)
581 {
582   //
583   // Check first the tracklet pt
584   //
585
586   Int_t nTimeTotal  = fCalib->GetNumberOfTimeBins();
587
588   // Calibration fill 2D
589   AliTRDCalibraFillHisto *calibra = AliTRDCalibraFillHisto::Instance();
590   if (!calibra) {
591     AliInfo("Could not get Calibra instance\n");
592   }
593
594   fTrkTest->Reset();
595
596   fTrkTest->SetDetector(det);
597   fTrkTest->SetRow(row);
598   fTrkTest->SetN(n);
599
600   Int_t iCol, iCol1, iCol2, track[3];
601   iCol = fMCM->GetSeedCol()[seed];  // 0....20 (MCM)
602   fMCM->GetColRange(iCol1,iCol2);   // range in the pad plane
603             
604   Float_t amp[3];
605   for (Int_t iTime = 0; iTime < nTimeTotal; iTime++) {
606
607     amp[0] = fMCM->GetADC(iCol-1,iTime);
608     amp[1] = fMCM->GetADC(iCol  ,iTime);
609     amp[2] = fMCM->GetADC(iCol+1,iTime);
610
611     // extract track contribution only from the central pad
612     track[0] = fTrack0->GetDataUnchecked(row,iCol+iCol1,iTime);
613     track[1] = fTrack1->GetDataUnchecked(row,iCol+iCol1,iTime);
614     track[2] = fTrack2->GetDataUnchecked(row,iCol+iCol1,iTime);
615
616     if      (fMCM->IsCluster(iCol,iTime)) {
617
618       fTrkTest->AddCluster(iCol+iCol1,iTime,amp,track);
619
620     } 
621     else if ((iCol+1+1) < kMcmCol) {
622
623       amp[0] = fMCM->GetADC(iCol-1+1,iTime);
624       amp[1] = fMCM->GetADC(iCol  +1,iTime);
625       amp[2] = fMCM->GetADC(iCol+1+1,iTime);
626
627       if (fMCM->IsCluster(iCol+1,iTime)) {
628
629         // extract track contribution only from the central pad
630         track[0] = fTrack0->GetDataUnchecked(row,iCol+1+iCol1,iTime);
631         track[1] = fTrack1->GetDataUnchecked(row,iCol+1+iCol1,iTime);
632         track[2] = fTrack2->GetDataUnchecked(row,iCol+1+iCol1,iTime);
633
634         fTrkTest->AddCluster(iCol+1+iCol1,iTime,amp,track);
635
636       }
637
638     } 
639
640   }
641
642   fTrkTest->CookLabel(0.8);  
643   /*
644   if (fTrkTest->GetLabel() >= fNPrimary) {
645     Info("AddTracklet","Only primaries are stored!");
646     return;
647   }
648   */
649   // LTU Pt cut
650   fTrkTest->MakeTrackletGraph(fGeo,fField);
651
652   // TRD Online calibration
653   if (calibra->GetMcmTracking()) {
654     calibra->UpdateHistogramcm(fTrkTest);
655   }
656
657   fTrkTest->MakeClusAmpGraph();
658
659   if (TMath::Abs(fTrkTest->GetPt()) < fTrigParam->GetLtuPtCut()) {
660     return kFALSE;
661   }
662   
663   return kTRUE;  
664
665 }
666
667 //_____________________________________________________________________________
668 void AliTRDtrigger::AddTracklet(Int_t det, Int_t row, Int_t seed, Int_t n)
669 {
670   //
671   // Add a found tracklet
672   //
673
674   Int_t nTimeTotal  = fCalib->GetNumberOfTimeBins();
675
676   fTrk = new AliTRDmcmTracklet(det,row,n);
677
678   Int_t iCol, iCol1, iCol2, track[3];
679   iCol = fMCM->GetSeedCol()[seed];  // 0....20 (MCM)
680   fMCM->GetColRange(iCol1,iCol2);   // range in the pad plane
681             
682   Float_t amp[3];
683   for (Int_t iTime = 0; iTime < nTimeTotal; iTime++) {
684
685     amp[0] = fMCM->GetADC(iCol-1,iTime);
686     amp[1] = fMCM->GetADC(iCol  ,iTime);
687     amp[2] = fMCM->GetADC(iCol+1,iTime);
688
689     // extract track contribution only from the central pad
690     track[0] = fTrack0->GetDataUnchecked(row,iCol+iCol1,iTime);
691     track[1] = fTrack1->GetDataUnchecked(row,iCol+iCol1,iTime);
692     track[2] = fTrack2->GetDataUnchecked(row,iCol+iCol1,iTime);
693
694     if      (fMCM->IsCluster(iCol,iTime)) {
695
696       fTrk->AddCluster(iCol+iCol1,iTime,amp,track);
697
698     } 
699     else if ((iCol+1+1) < kMcmCol) {
700
701       amp[0] = fMCM->GetADC(iCol-1+1,iTime);
702       amp[1] = fMCM->GetADC(iCol  +1,iTime);
703       amp[2] = fMCM->GetADC(iCol+1+1,iTime);
704
705       if (fMCM->IsCluster(iCol+1,iTime)) {
706
707         // extract track contribution only from the central pad
708         track[0] = fTrack0->GetDataUnchecked(row,iCol+1+iCol1,iTime);
709         track[1] = fTrack1->GetDataUnchecked(row,iCol+1+iCol1,iTime);
710         track[2] = fTrack2->GetDataUnchecked(row,iCol+1+iCol1,iTime);
711
712         fTrk->AddCluster(iCol+1+iCol1,iTime,amp,track);
713
714       }
715
716     }
717
718   }
719
720   fTrk->CookLabel(0.8);  
721   /*
722   if (fTrk->GetLabel() >= fNPrimary) {
723     Info("AddTracklet","Only primaries are stored!");
724     return;
725   }
726   */
727   // LTU Pt cut
728   fTrk->MakeTrackletGraph(fGeo,fField);
729   fTrk->MakeClusAmpGraph();
730   if (TMath::Abs(fTrk->GetPt()) < fTrigParam->GetLtuPtCut()) {
731     return;
732   }
733       
734   Tracklets()->Add(fTrk);
735
736 }
737
738 //_____________________________________________________________________________
739 Bool_t AliTRDtrigger::WriteTracklets(Int_t det) 
740 {
741   //
742   // Fills TRDmcmTracklet branch in the tree with the Tracklets 
743   // found in detector = det. For det=-1 writes the tree. 
744   //
745
746   if ((det < -1) || (det >= AliTRDgeometry::Ndet())) {
747     AliError(Form("Unexpected detector index %d.",det));
748     return kFALSE;
749   }
750
751   TBranch *branch = fTrackletTree->GetBranch("TRDmcmTracklet");
752   if (!branch) {
753     TObjArray *ioArray = 0;
754     branch = fTrackletTree->Branch("TRDmcmTracklet","TObjArray",&ioArray,32000,0);
755   }
756
757   if ((det >= 0) && (det < AliTRDgeometry::Ndet())) {
758
759     Int_t nTracklets = Tracklets()->GetEntriesFast();
760     TObjArray *detTracklets = new TObjArray(400);
761
762     for (Int_t i = 0; i < nTracklets; i++) {
763
764       AliTRDmcmTracklet *trk = (AliTRDmcmTracklet *) Tracklets()->UncheckedAt(i);
765       
766       if (det == trk->GetDetector()) {
767         detTracklets->AddLast(trk);
768       }
769
770     }
771
772     branch->SetAddress(&detTracklets);
773     fTrackletTree->Fill();
774
775     delete detTracklets;
776
777     return kTRUE;
778
779   }
780
781   if (det == -1) {
782
783     AliInfo(Form("Writing the Tracklet tree %s for event %d."
784                 ,fTrackletTree->GetName(),fRunLoader->GetEventNumber()));
785
786     AliLoader* loader = fRunLoader->GetLoader("TRDLoader");
787     loader->WriteTracks("OVERWRITE");
788     
789     return kTRUE;  
790
791   }
792
793   return kFALSE;
794
795 }
796
797 //_____________________________________________________________________________
798 void AliTRDtrigger::MakeTracks(Int_t det)
799 {
800   //
801   // Create GTU tracks per module (stack of 6 chambers)
802   //
803   
804   fModule->Reset();
805
806   Int_t nRowMax, iplan, icham, isect, row;
807
808   if ((det < 0) || (det >= AliTRDgeometry::Ndet())) {
809     AliError(Form("Unexpected detector index %d.",det));
810     return;
811   }
812   
813   Int_t nTracklets = Tracklets()->GetEntriesFast();
814   
815   AliTRDmcmTracklet *trk;
816   for (Int_t i = 0; i < nTracklets; i++) {
817     
818     trk = (AliTRDmcmTracklet *) Tracklets()->UncheckedAt(i);
819     
820     iplan = fGeo->GetPlane(trk->GetDetector());
821     icham = fGeo->GetChamber(trk->GetDetector());
822     isect = fGeo->GetSector(trk->GetDetector());
823
824     nRowMax = fCParam->GetRowMax(iplan,icham,isect);
825     row = trk->GetRow();
826
827     fModule->AddTracklet(trk->GetDetector(),
828                          row,
829                          trk->GetRowz(),
830                          trk->GetSlope(),
831                          trk->GetOffset(),
832                          trk->GetTime0(),
833                          trk->GetNclusters(),
834                          trk->GetLabel(),
835                          trk->GetdQdl());
836     
837   }
838
839   fModule->SortTracklets();
840   fModule->RemoveMultipleTracklets();
841   fModule->SortZ((Int_t)fGeo->GetChamber(det));
842   fModule->FindTracks();
843   fModule->SortTracks();
844   fModule->RemoveMultipleTracks();
845
846   Int_t nModTracks = fModule->GetNtracks();
847   AliTRDgtuTrack *gtutrk;
848   for (Int_t i = 0; i < nModTracks; i++) {
849     gtutrk = (AliTRDgtuTrack*)fModule->GetTrack(i);
850     if (TMath::Abs(gtutrk->GetPt()) < fTrigParam->GetGtuPtCut()) continue;
851     gtutrk->CookLabel();
852     gtutrk->MakePID();
853     AddTrack(gtutrk,det);
854   }
855   
856 }
857
858 //_____________________________________________________________________________
859 void AliTRDtrigger::AddTrack(const AliTRDgtuTrack *t, Int_t det)  
860
861   //
862   // Add a track to the list
863   //
864
865   AliTRDgtuTrack *track = new(fTracks->operator[](fTracks->GetEntriesFast())) 
866                           AliTRDgtuTrack(*t);
867   track->SetDetector(det); 
868
869 }
870
871 //_____________________________________________________________________________
872 TObjArray* AliTRDtrigger::Tracklets()
873
874   //
875   // Returns list of tracklets
876   //
877
878   if (!fTracklets) {
879     fTracklets = new TObjArray(400); 
880   }
881   return fTracklets;       
882
883 }
884
885 //_____________________________________________________________________________
886 void AliTRDtrigger::ResetTracklets()                              
887 {
888   //
889   // Resets the list of tracklets
890   //
891  
892   if (fTracklets) {
893     fTracklets->Delete();             
894   }
895
896 }
897
898 //_____________________________________________________________________________
899 Int_t AliTRDtrigger::GetNumberOfTracks() const                     
900
901   //
902   // Returns number of tracks
903   //
904
905   return fTracks->GetEntriesFast(); 
906                 
907 }
908
909 //_____________________________________________________________________________
910 AliTRDgtuTrack* AliTRDtrigger::GetTrack(Int_t i) const               
911
912   //
913   // Returns a given track from the list
914   //
915
916   return (AliTRDgtuTrack *) fTracks->UncheckedAt(i); 
917
918 }