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