]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TRD/AliTRDdigitizer.cxx
7dbc3adb18b9c7d1c66efd34a6f7ddf580cfbf08
[u/mrichter/AliRoot.git] / TRD / AliTRDdigitizer.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 //  Creates and handles digits from TRD hits                                 //
21 //  Author: C. Blume (C.Blume@gsi.de)                                        //
22 //                                                                           //
23 //  The following effects are included:                                      //
24 //      - Diffusion                                                          //
25 //      - ExB effects                                                        //
26 //      - Gas gain including fluctuations                                    //
27 //      - Pad-response (simple Gaussian approximation)                       //
28 //      - Time-response                                                      //
29 //      - Electronics noise                                                  //
30 //      - Electronics gain                                                   //
31 //      - Digitization                                                       //
32 //      - ADC threshold                                                      //
33 //  The corresponding parameter can be adjusted via the various              //
34 //  Set-functions. If these parameters are not explicitly set, default       //
35 //  values are used (see Init-function).                                     //
36 //  As an example on how to use this class to produce digits from hits       //
37 //  have a look at the macro hits2digits.C                                   //
38 //  The production of summable digits is demonstrated in hits2sdigits.C      //
39 //  and the subsequent conversion of the s-digits into normal digits is      //
40 //  explained in sdigits2digits.C.                                           //
41 //                                                                           //
42 ///////////////////////////////////////////////////////////////////////////////
43
44 #include <stdlib.h>
45
46 #include <TMath.h>
47 #include <TVector.h>
48 #include <TRandom.h>
49 #include <TROOT.h>
50 #include <TTree.h>
51 #include <TFile.h>
52 #include <TF1.h>
53 #include <TList.h>
54 #include <TTask.h>
55
56 #include "AliRun.h"
57 #include "AliRunLoader.h"
58 #include "AliLoader.h"
59 #include "AliConfig.h"
60 #include "AliMagF.h"
61 #include "AliRunDigitizer.h"
62 #include "AliRunLoader.h"
63 #include "AliLoader.h"
64
65 #include "AliTRD.h"
66 #include "AliTRDhit.h"
67 #include "AliTRDdigitizer.h"
68 #include "AliTRDdataArrayI.h"
69 #include "AliTRDdataArrayF.h"
70 #include "AliTRDsegmentArray.h"
71 #include "AliTRDdigitsManager.h"
72 #include "AliTRDgeometry.h"
73 #include "AliTRDparameter.h"
74
75 ClassImp(AliTRDdigitizer)
76
77 //_____________________________________________________________________________
78 AliTRDdigitizer::AliTRDdigitizer()
79 {
80   //
81   // AliTRDdigitizer default constructor
82   //
83
84   fRunLoader          = 0;
85   fDigitsManager      = 0;
86   fSDigitsManager     = 0;
87   fSDigitsManagerList = 0;
88   fTRD                = 0;
89   fGeo                = 0;
90   fPar                = 0;
91   fEvent              = 0;
92   fMasks              = 0;
93   fCompress           = kTRUE;
94   fDebug              = 0;
95   fSDigits            = kFALSE;
96   fSDigitsScale       = 0.0;
97   fMergeSignalOnly    = kFALSE;
98   fSimpleSim          = kFALSE;
99   fSimpleDet          = 0;
100  
101 }
102
103 //_____________________________________________________________________________
104 AliTRDdigitizer::AliTRDdigitizer(const Text_t *name, const Text_t *title)
105                 :AliDigitizer(name,title)
106 {
107   //
108   // AliTRDdigitizer constructor
109   //
110
111   fRunLoader          = 0;
112
113   //NewIO: These data members probably are not needed anymore
114   fDigitsManager      = 0;
115   fSDigitsManager     = 0;
116   fSDigitsManagerList = 0;
117   fTRD                = 0;
118   fGeo                = 0;
119   fPar                = 0;
120   //End NewIO comment
121   fEvent              = 0;
122   fMasks              = 0;
123   fCompress           = kTRUE;
124   fDebug              = 0;
125   fSDigits            = kFALSE;
126   fSDigitsScale       = 100.; // For the summable digits
127   fMergeSignalOnly    = kFALSE;
128   fSimpleSim          = kFALSE;
129   fSimpleDet          = 0;
130  
131
132 }
133
134 //_____________________________________________________________________________
135 AliTRDdigitizer::AliTRDdigitizer(AliRunDigitizer *manager
136                                 , const Text_t *name, const Text_t *title)
137                 :AliDigitizer(manager,name,title)
138 {
139   //
140   // AliTRDdigitizer constructor
141   //
142
143   fRunLoader          = 0;
144   fDigitsManager      = 0;
145   fSDigitsManager     = 0;
146   fSDigitsManagerList = 0;
147   fTRD                = 0;
148   fGeo                = 0;
149   fPar                = 0;
150   fEvent              = 0;
151   fMasks              = 0;
152   fCompress           = kTRUE;
153   fDebug              = 0;
154   fSDigits            = kFALSE;
155   fSDigitsScale       = 100.; // For the summable digits
156   fMergeSignalOnly    = kFALSE;
157   fSimpleSim          = kFALSE;
158   fSimpleDet          = 0;
159  
160
161 }
162
163 //_____________________________________________________________________________
164 AliTRDdigitizer::AliTRDdigitizer(AliRunDigitizer *manager)
165                 :AliDigitizer(manager,"AliTRDdigitizer","TRD digitizer")
166 {
167   //
168   // AliTRDdigitizer constructor
169   //
170
171
172   fRunLoader          = 0;
173   fDigitsManager      = 0;
174   fSDigitsManager     = 0;
175   fSDigitsManagerList = 0;
176   fTRD                = 0;
177   fGeo                = 0;
178   fPar                = 0;
179   fEvent              = 0;
180   fMasks              = 0;
181   fCompress           = kTRUE;
182   fDebug              = 0;
183   fSDigits            = kFALSE;
184   fSDigitsScale       = 100.;  // For the summable digits
185   fMergeSignalOnly    = kFALSE;
186   fSimpleSim          = kFALSE;
187   fSimpleDet          = 0;
188
189
190 }
191
192 //_____________________________________________________________________________
193 AliTRDdigitizer::AliTRDdigitizer(const AliTRDdigitizer &d):AliDigitizer(d)
194 {
195   //
196   // AliTRDdigitizer copy constructor
197   //
198
199   ((AliTRDdigitizer &) d).Copy(*this);
200
201 }
202
203 //_____________________________________________________________________________
204 AliTRDdigitizer::~AliTRDdigitizer()
205 {
206   //
207   // AliTRDdigitizer destructor
208   //
209
210
211   if (fDigitsManager) {
212     delete fDigitsManager;
213     fDigitsManager = 0;
214   }
215
216   if (fSDigitsManager) {
217     delete fSDigitsManager;
218     fSDigitsManager = 0;
219   }
220
221   if (fSDigitsManagerList) {
222     delete fSDigitsManagerList;
223     fSDigitsManagerList = 0;
224   }
225
226   if (fMasks) {
227     delete [] fMasks;
228     fMasks = 0;
229   }
230
231 }
232
233 //_____________________________________________________________________________
234 AliTRDdigitizer &AliTRDdigitizer::operator=(const AliTRDdigitizer &d)
235 {
236   //
237   // Assignment operator
238   //
239
240   if (this != &d) ((AliTRDdigitizer &) d).Copy(*this);
241   return *this;
242
243 }
244
245 //_____________________________________________________________________________
246 void AliTRDdigitizer::Copy(TObject &d)
247 {
248   //
249   // Copy function
250   //
251
252   ((AliTRDdigitizer &) d).fRunLoader          = 0;
253   ((AliTRDdigitizer &) d).fDigitsManager      = 0;
254   ((AliTRDdigitizer &) d).fSDigitsManager     = 0;
255   ((AliTRDdigitizer &) d).fSDigitsManagerList = 0;
256   ((AliTRDdigitizer &) d).fTRD                = 0;
257   ((AliTRDdigitizer &) d).fGeo                = 0;
258   ((AliTRDdigitizer &) d).fPar                = 0;
259   ((AliTRDdigitizer &) d).fEvent              = 0;
260   ((AliTRDdigitizer &) d).fMasks              = 0;
261   ((AliTRDdigitizer &) d).fCompress           = fCompress;
262   ((AliTRDdigitizer &) d).fDebug              = fDebug  ;
263   ((AliTRDdigitizer &) d).fSDigits            = fSDigits;
264   ((AliTRDdigitizer &) d).fSDigitsScale       = fSDigitsScale;
265   ((AliTRDdigitizer &) d).fMergeSignalOnly    = fMergeSignalOnly;
266   ((AliTRDdigitizer &) d).fSimpleSim          = fSimpleSim;
267   ((AliTRDdigitizer &) d).fSimpleDet          = fSimpleDet;
268                                        
269 }
270
271 //_____________________________________________________________________________
272 void AliTRDdigitizer::Exec(Option_t* option)
273 {
274   //
275   // Executes the merging
276   //
277
278   Int_t iInput;
279
280   AliTRDdigitsManager *sdigitsManager;
281
282   TString optionString = option;
283   if (optionString.Contains("deb")) {
284     fDebug = 1;
285     if (optionString.Contains("2")) {
286       fDebug = 2;
287     }
288     printf("<AliTRDdigitizer::Exec> ");
289     printf("Called with debug option %d\n",fDebug);
290   }
291
292   // The AliRoot file is already connected by the manager
293   AliRunLoader* inrl;
294   
295   if (gAlice) 
296    {
297     if (fDebug > 0) {
298       printf("<AliTRDdigitizer::Exec> ");
299       printf("AliRun object found on file.\n");
300     }
301    }
302   else {
303     inrl = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(0));
304     inrl->LoadgAlice();
305     gAlice = inrl->GetAliRun();
306     if (!gAlice)
307      {
308        printf("<AliTRDdigitizer::Exec> ");
309        printf("Could not find AliRun object.\n");
310        return;
311      }
312   }
313                                                                            
314   Int_t nInput = fManager->GetNinputs();
315   fMasks = new Int_t[nInput];
316   for (iInput = 0; iInput < nInput; iInput++) {
317     fMasks[iInput] = fManager->GetMask(iInput);
318   }
319
320   // Initialization
321   InitDetector();
322
323   for (iInput = 0; iInput < nInput; iInput++) {
324
325     if (fDebug > 0) {
326       printf("<AliTRDdigitizer::Exec> ");
327       printf("Add input stream %d\n",iInput);
328     }
329
330     // check if the input tree exists
331     inrl = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(iInput));
332     AliLoader* gime = inrl->GetLoader("TRDLoader");
333
334     TTree * treees =  gime->TreeS();
335     if (treees == 0x0) 
336      {
337       if (gime->LoadSDigits())
338        {
339          Error("Exec","Error Occured while loading S. Digits for input %d.",iInput);
340          return;
341        }
342       treees =  gime->TreeS();
343      }
344     
345     if (treees == 0x0) {
346       printf("<AliTRDdigitizer::Exec> ");
347       printf("Input stream %d does not exist\n",iInput);
348       return;
349     } 
350
351     // Read the s-digits via digits manager
352     sdigitsManager = new AliTRDdigitsManager();
353     sdigitsManager->SetDebug(fDebug);
354     sdigitsManager->SetSDigits(kTRUE);
355     
356     AliRunLoader* rl = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(iInput));
357     AliLoader* gimme = rl->GetLoader("TRDLoader");
358     if (!gimme->TreeS()) gimme->LoadSDigits();
359     sdigitsManager->ReadDigits(gimme->TreeS());
360
361     // Add the s-digits to the input list 
362     AddSDigitsManager(sdigitsManager);
363
364   }
365
366   // Convert the s-digits to normal digits
367   if (fDebug > 0) {
368     printf("<AliTRDdigitizer::Exec> ");
369     printf("Do the conversion\n");
370   }
371   SDigits2Digits();
372
373   // Store the digits
374   if (fDebug > 0) {
375     printf("<AliTRDdigitizer::Exec> ");
376     printf("Write the digits\n");
377   }
378   
379   AliRunLoader* orl = AliRunLoader::GetRunLoader(fManager->GetOutputFolderName());
380   AliLoader* ogime = orl->GetLoader("TRDLoader");
381
382   fDigitsManager->MakeBranch(ogime->TreeD());
383
384   fDigitsManager->WriteDigits();
385
386   if (fDebug > 0) {
387     printf("<AliTRDdigitizer::Exec> ");
388     printf("Done\n");
389   }
390
391   DeleteSDigitsManager();
392
393 }
394
395 //_____________________________________________________________________________
396 Bool_t AliTRDdigitizer::Open(const Char_t *file, Int_t nEvent)
397 {
398   //
399   // Opens a ROOT-file with TRD-hits and reads in the hit-tree
400   //
401
402   // Connect the AliRoot file containing Geometry, Kine, and Hits
403   
404   fRunLoader = AliRunLoader::Open(file,AliConfig::fgkDefaultEventFolderName,
405                                   "UPDATE");
406   
407   if (!fRunLoader)
408    {
409      Error("Open","Can not open session for file %s.",file);
410      return kFALSE;
411    }
412    
413   fRunLoader->LoadgAlice();
414   gAlice = fRunLoader->GetAliRun();
415   
416   if (gAlice) {
417     if (fDebug > 0) {
418       printf("<AliTRDdigitizer::Open> ");
419       printf("AliRun object found on file.\n");
420     }
421   }
422   else {
423     printf("<AliTRDdigitizer::Open> ");
424     printf("Could not find AliRun object.\n");
425     return kFALSE;
426   }
427
428   fEvent = nEvent;
429
430   // Import the Trees for the event nEvent in the file
431   fRunLoader->GetEvent(fEvent);
432   
433   AliLoader* loader = fRunLoader->GetLoader("TRDLoader");
434   if (!loader)
435    {
436      Error("Open","Can not get TRD loader from Run Loader");
437      return kFALSE;
438    }
439   
440   if (InitDetector()) {
441     TTree* tree = 0;
442     if (fSDigits)
443      { 
444      //if we produce SDigits
445        tree = loader->TreeS();
446        if (!tree)
447         {
448          loader->MakeTree("S");
449          tree = loader->TreeS();
450         }
451      }
452     else
453      {//if we produce Digits
454        tree = loader->TreeD();
455        if (!tree)
456         {
457          loader->MakeTree("D");
458          tree = loader->TreeD();
459         }
460      }
461     return MakeBranch(tree);
462   }
463   else {
464     return kFALSE;
465   }
466
467 }
468
469 //_____________________________________________________________________________
470 Bool_t AliTRDdigitizer::InitDetector()
471 {
472   //
473   // Sets the pointer to the TRD detector and the geometry
474   //
475
476   // Get the pointer to the detector class and check for version 1
477   fTRD = (AliTRD *) gAlice->GetDetector("TRD");
478   if (!fTRD) {
479     printf("<AliTRDdigitizer::InitDetector> ");
480     printf("No TRD module found\n");
481     exit(1);
482   }
483   if (fTRD->IsVersion() != 1) {
484     printf("<AliTRDdigitizer::InitDetector> ");
485     printf("TRD must be version 1 (slow simulator).\n");
486     exit(1);
487   }
488
489   // Get the geometry
490   fGeo = fTRD->GetGeometry();
491   if (fDebug > 0) {
492     printf("<AliTRDdigitizer::InitDetector> ");
493     printf("Geometry version %d\n",fGeo->IsVersion());
494   }
495
496   // Create a digits manager
497   fDigitsManager = new AliTRDdigitsManager();
498   fDigitsManager->SetSDigits(fSDigits);
499   fDigitsManager->CreateArrays();
500   fDigitsManager->SetEvent(fEvent);
501   fDigitsManager->SetDebug(fDebug);
502
503   // The list for the input s-digits manager to be merged
504   fSDigitsManagerList = new TList();
505
506   return kTRUE;
507
508 }
509
510 //_____________________________________________________________________________
511 Bool_t AliTRDdigitizer::MakeBranch(TTree* tree) const
512 {
513   // 
514   // Create the branches for the digits array
515   //
516
517   return fDigitsManager->MakeBranch(tree);
518
519 }
520
521 //_____________________________________________________________________________
522 Bool_t AliTRDdigitizer::MakeDigits()
523 {
524   //
525   // Creates digits.
526   //
527
528   ///////////////////////////////////////////////////////////////
529   // Parameter 
530   ///////////////////////////////////////////////////////////////
531
532   // Converts number of electrons to fC
533   const Double_t kEl2fC  = 1.602E-19 * 1.0E15; 
534
535   ///////////////////////////////////////////////////////////////
536
537   // Number of pads included in the pad response
538   const Int_t kNpad  = 3;
539
540   // Number of track dictionary arrays
541   const Int_t kNDict = AliTRDdigitsManager::kNDict;
542
543   // Half the width of the amplification region
544   const Float_t kAmWidth = AliTRDgeometry::AmThick() / 2.;
545
546   Int_t   iRow, iCol, iTime, iPad;
547   Int_t   iDict  = 0;
548   Int_t   nBytes = 0;
549
550   Int_t   totalSizeDigits = 0;
551   Int_t   totalSizeDict0  = 0;
552   Int_t   totalSizeDict1  = 0;
553   Int_t   totalSizeDict2  = 0;
554
555   Int_t   timeTRDbeg = 0;
556   Int_t   timeTRDend = 1;
557
558   Float_t pos[3];
559   Float_t rot[3];
560   Float_t xyz[3];
561   Float_t padSignal[kNpad];
562   Float_t signalOld[kNpad];
563
564   AliTRDdataArrayF *signals = 0;
565   AliTRDdataArrayI *digits  = 0;
566   AliTRDdataArrayI *dictionary[kNDict];
567
568   // Create a default parameter class if none is defined
569   if (!fPar) {
570     fPar = new AliTRDparameter("TRDparameter","Standard TRD parameter");
571     if (fDebug > 0) {
572       printf("<AliTRDdigitizer::MakeDigits> ");
573       printf("Create the default parameter object\n");
574     }
575   }
576
577   // Create a container for the amplitudes
578   AliTRDsegmentArray *signalsArray 
579                      = new AliTRDsegmentArray("AliTRDdataArrayF"
580                                              ,AliTRDgeometry::Ndet());
581
582   if (fPar->TRFOn()) {
583     timeTRDbeg = ((Int_t) (-fPar->GetTRFlo() / fPar->GetTimeBinSize())) - 1;
584     timeTRDend = ((Int_t) ( fPar->GetTRFhi() / fPar->GetTimeBinSize())) - 1;
585     if (fDebug > 0) {
586       printf("<AliTRDdigitizer::MakeDigits> ");
587       printf("Sample the TRF between -%d and %d\n",timeTRDbeg,timeTRDend);
588     }
589   }
590
591   Float_t elAttachProp = fPar->GetElAttachProp() / 100.; 
592
593   if (!fGeo) {
594     printf("<AliTRDdigitizer::MakeDigits> ");
595     printf("No geometry defined\n");
596     return kFALSE;
597   }
598
599   if (fDebug > 0) {
600     printf("<AliTRDdigitizer::MakeDigits> ");
601     printf("Start creating digits.\n");
602   }
603
604   AliLoader* gimme = fRunLoader->GetLoader("TRDLoader");
605   if (!gimme->TreeH()) gimme->LoadHits();
606   TTree* hitTree = gimme->TreeH();
607   if (hitTree == 0x0)
608     {
609       Error("MakeDigits","Can not get TreeH");
610       return kFALSE;
611     }
612   fTRD->SetTreeAddress();
613   
614   // Get the number of entries in the hit tree
615   // (Number of primary particles creating a hit somewhere)
616   Int_t nTrack = 1;
617   if (!fSimpleSim) {
618     nTrack = (Int_t) hitTree->GetEntries();
619     if (fDebug > 0) {
620       printf("<AliTRDdigitizer::MakeDigits> ");
621       printf("Found %d primary particles\n",nTrack);
622     } 
623   }
624
625   Int_t detectorOld = -1;
626   Int_t countHits   =  0; 
627
628   // Loop through all entries in the tree
629   for (Int_t iTrack = 0; iTrack < nTrack; iTrack++) {
630
631     if (!fSimpleSim) {   
632       gAlice->ResetHits();
633       nBytes += hitTree->GetEvent(iTrack);
634     }
635
636     // Loop through the TRD hits
637     Int_t iHit = 0;
638     AliTRDhit *hit = (AliTRDhit *) fTRD->FirstHit(-1);
639     while (hit) {
640  
641       countHits++;
642       iHit++;
643
644               pos[0]      = hit->X();
645               pos[1]      = hit->Y();
646               pos[2]      = hit->Z();
647       Float_t q           = hit->GetCharge();
648       Int_t   track       = hit->Track();
649       Int_t   detector    = hit->GetDetector();
650       Int_t   plane       = fGeo->GetPlane(detector);
651       Int_t   sector      = fGeo->GetSector(detector);
652       Int_t   chamber     = fGeo->GetChamber(detector);
653       Int_t   nRowMax     = fPar->GetRowMax(plane,chamber,sector);
654       Int_t   nColMax     = fPar->GetColMax(plane);
655       Int_t   nTimeMax    = fPar->GetTimeMax();
656       Int_t   nTimeBefore = fPar->GetTimeBefore();
657       Int_t   nTimeAfter  = fPar->GetTimeAfter();
658       Int_t   nTimeTotal  = fPar->GetTimeTotal();
659       Float_t row0        = fPar->GetRow0(plane,chamber,sector);
660       Float_t col0        = fPar->GetCol0(plane);
661       Float_t time0       = fPar->GetTime0(plane);
662       Float_t rowPadSize  = fPar->GetRowPadSize(plane,chamber,sector);
663       Float_t colPadSize  = fPar->GetColPadSize(plane);
664       Float_t timeBinSize = fPar->GetTimeBinSize();
665       Float_t divideRow   = 1.0 / rowPadSize;
666       Float_t divideCol   = 1.0 / colPadSize;
667       Float_t divideTime  = 1.0 / timeBinSize;
668
669       if (fDebug > 1) {
670         printf("Analyze hit no. %d ",iHit);
671         printf("-----------------------------------------------------------\n");
672         hit->Dump();
673         printf("plane = %d, sector = %d, chamber = %d\n"
674               ,plane,sector,chamber);
675         printf("nRowMax = %d, nColMax = %d, nTimeMax = %d\n" 
676               ,nRowMax,nColMax,nTimeMax);
677         printf("nTimeBefore = %d, nTimeAfter = %d, nTimeTotal = %d\n"
678               ,nTimeBefore,nTimeAfter,nTimeTotal);
679         printf("row0 = %f, col0 = %f, time0 = %f\n"
680               ,row0,col0,time0);
681         printf("rowPadSize = %f, colPadSize = %f, timeBinSize = %f\n"
682                ,rowPadSize,colPadSize,timeBinSize); 
683       }
684        
685       // Don't analyze test hits and switched off detectors
686       if ((CheckDetector(plane,chamber,sector)) &&
687           (((Int_t) q) != 0)) {
688
689         if (detector != detectorOld) {
690
691           if (fDebug > 1) {
692             printf("<AliTRDdigitizer::MakeDigits> ");
693             printf("Get new container. New det = %d, Old det = %d\n"
694                   ,detector,detectorOld);
695           }
696           // Compress the old one if enabled
697           if ((fCompress) && (detectorOld > -1)) {
698             if (fDebug > 1) {
699               printf("<AliTRDdigitizer::MakeDigits> ");
700               printf("Compress the old container ...");
701             }
702             signals->Compress(1,0);
703             for (iDict = 0; iDict < kNDict; iDict++) {
704               dictionary[iDict]->Compress(1,0);
705             }
706             if (fDebug > 1) printf("done\n");
707           }
708           // Get the new container
709           signals = (AliTRDdataArrayF *) signalsArray->At(detector);
710           if (signals->GetNtime() == 0) {
711             // Allocate a new one if not yet existing
712             if (fDebug > 1) {
713               printf("<AliTRDdigitizer::MakeDigits> ");
714               printf("Allocate a new container ... ");
715             }
716             signals->Allocate(nRowMax,nColMax,nTimeTotal);
717           }
718           else if (fSimpleSim) {
719             // Clear an old one for the simple simulation
720             if (fDebug > 1) {
721               printf("<AliTRDdigitizer::MakeDigits> ");
722               printf("Clear a old container ... ");
723             }
724             signals->Clear();
725           }
726           else {
727             // Expand an existing one
728             if (fCompress) {
729               if (fDebug > 1) {
730                 printf("<AliTRDdigitizer::MakeDigits> ");
731                 printf("Expand an existing container ... ");
732               }
733               signals->Expand();
734             }
735           }
736           // The same for the dictionary
737           if (!fSimpleSim) {       
738             for (iDict = 0; iDict < kNDict; iDict++) {       
739               dictionary[iDict] = fDigitsManager->GetDictionary(detector,iDict);
740               if (dictionary[iDict]->GetNtime() == 0) {
741                 dictionary[iDict]->Allocate(nRowMax,nColMax,nTimeTotal);
742               }
743               else {
744                 if (fCompress) dictionary[iDict]->Expand();
745               }
746             }
747           }      
748           if (fDebug > 1) printf("done\n");
749           detectorOld = detector;
750         }
751
752         // Rotate the sectors on top of each other
753         if (fSimpleSim) {
754           rot[0] = pos[0];
755           rot[1] = pos[1];
756           rot[2] = pos[2];
757         }
758         else {
759           fGeo->Rotate(detector,pos,rot);
760         }
761
762         // The driftlength. It is negative if the hit is in the 
763         // amplification region.
764         Float_t driftlength = time0 - rot[0];
765
766         // Take also the drift in the amplification region into account
767         // The drift length is at the moment still the same, regardless of
768         // the position relativ to the wire. This non-isochronity needs still
769         // to be implemented.
770         Float_t driftlengthL = TMath::Abs(driftlength + kAmWidth);
771         if (fPar->ExBOn()) driftlengthL /= TMath::Sqrt(fPar->GetLorentzFactor());
772
773         // Loop over all electrons of this hit
774         // TR photons produce hits with negative charge
775         Int_t nEl = ((Int_t) TMath::Abs(q));
776         for (Int_t iEl = 0; iEl < nEl; iEl++) {
777
778           xyz[0] = rot[0];
779           xyz[1] = rot[1];
780           xyz[2] = rot[2];
781
782           // Electron attachment
783           if (fPar->ElAttachOn()) {
784             if (gRandom->Rndm() < (driftlengthL * elAttachProp)) 
785               continue;
786           }
787
788           // Apply the diffusion smearing
789           if (fPar->DiffusionOn()) {
790             if (!(fPar->Diffusion(driftlengthL,xyz))) continue;
791           }
792
793           // Apply E x B effects (depends on drift direction)
794           if (fPar->ExBOn()) { 
795             if (!(fPar->ExB(driftlength+kAmWidth,xyz))) continue;   
796           }
797
798           // The electron position after diffusion and ExB in pad coordinates 
799           // The pad row (z-direction)
800           Float_t rowDist   = xyz[2] - row0;
801           Int_t   rowE      = ((Int_t) (rowDist * divideRow));
802           if ((rowE < 0) || (rowE >= nRowMax)) continue;   
803           Float_t rowOffset = ((((Float_t) rowE) + 0.5) * rowPadSize) - rowDist;
804
805           // The pad column (rphi-direction)
806           Float_t col0tilt  = fPar->Col0Tilted(col0,rowOffset,plane);
807           Float_t colDist   = xyz[1] - col0tilt;
808           Int_t   colE      = ((Int_t) (colDist * divideCol));
809           if ((colE < 0) || (colE >= nColMax)) continue;   
810           Float_t colOffset = ((((Float_t) colE) + 0.5) * colPadSize) - colDist;    
811
812           // The time bin (negative for hits in the amplification region)
813           // In the amplification region the electrons drift from both sides
814           // to the middle (anode wire plane)
815           Float_t timeDist   = time0 - xyz[0];
816           Float_t timeOffset = 0;
817           Int_t   timeE      = 0;
818           if (timeDist > 0) {
819             // The time bin
820             timeE      = ((Int_t) (timeDist * divideTime));
821             // The distance of the position to the middle of the timebin
822             timeOffset = ((((Float_t) timeE) + 0.5) * timeBinSize) - timeDist;
823           }
824           else {
825             // Difference between half of the amplification gap width and
826             // the distance to the anode wire
827             Float_t anodeDist = kAmWidth - TMath::Abs(timeDist + kAmWidth);
828             // The time bin
829             timeE      = -1 * (((Int_t ) (anodeDist * divideTime)) + 1);
830             // The distance of the position to the middle of the timebin
831             timeOffset = ((((Float_t) timeE) + 0.5) * timeBinSize) + anodeDist;
832           }
833  
834           // Apply the gas gain including fluctuations
835           Float_t ggRndm = 0.0;
836           do {
837             ggRndm = gRandom->Rndm();
838           } while (ggRndm <= 0);
839           Int_t signal = (Int_t) (-fPar->GetGasGain() * TMath::Log(ggRndm));
840
841           // Apply the pad response 
842           if (fPar->PRFOn()) {
843             // The distance of the electron to the center of the pad 
844             // in units of pad width
845             Float_t dist = - colOffset * divideCol;
846             if (!(fPar->PadResponse(signal,dist,plane,padSignal))) continue;
847           }
848           else {
849             padSignal[0] = 0.0;
850             padSignal[1] = signal;
851             padSignal[2] = 0.0;
852           }
853
854           // Sample the time response inside the drift region
855           // + additional time bins before and after.
856           // The sampling is done always in the middle of the time bin
857           for (Int_t iTimeBin = TMath::Max(timeE-timeTRDbeg,        -nTimeBefore) 
858                     ;iTimeBin < TMath::Min(timeE+timeTRDend,nTimeMax+nTimeAfter ) 
859                     ;iTimeBin++) {
860
861             // Apply the time response
862             Float_t timeResponse = 1.0;
863             Float_t crossTalk    = 0.0;
864             Float_t time         = (iTimeBin - timeE) * timeBinSize + timeOffset;
865             if (fPar->TRFOn()) {
866               timeResponse = fPar->TimeResponse(time);
867             }
868             if (fPar->CTOn()) {
869               crossTalk    = fPar->CrossTalk(time);
870             }
871
872             signalOld[0] = 0.0;
873             signalOld[1] = 0.0;
874             signalOld[2] = 0.0;
875
876             for (iPad = 0; iPad < kNpad; iPad++) {
877
878               Int_t colPos = colE + iPad - 1;
879               if (colPos <        0) continue;
880               if (colPos >= nColMax) break;
881
882               // Add the signals
883               // Note: The time bin number is shifted by nTimeBefore to avoid negative
884               // time bins. This has to be subtracted later.
885               Int_t iCurrentTimeBin = iTimeBin + nTimeBefore;
886               signalOld[iPad]  = signals->GetDataUnchecked(rowE,colPos,iCurrentTimeBin);
887               if( colPos != colE ) {
888                 signalOld[iPad] += padSignal[iPad] * (timeResponse + crossTalk);
889               } 
890               else {
891                 signalOld[iPad] += padSignal[iPad] * timeResponse;
892               }
893               signals->SetDataUnchecked(rowE,colPos,iCurrentTimeBin,signalOld[iPad]);
894
895               // Store the track index in the dictionary
896               // Note: We store index+1 in order to allow the array to be compressed
897               if ((signalOld[iPad] > 0) && (!fSimpleSim)) { 
898                 for (iDict = 0; iDict < kNDict; iDict++) {
899                   Int_t oldTrack = dictionary[iDict]->GetDataUnchecked(rowE
900                                                                       ,colPos
901                                                                       ,iCurrentTimeBin);
902                   if (oldTrack == track+1) break;
903                   if (oldTrack ==       0) {
904                     dictionary[iDict]->SetDataUnchecked(rowE,colPos,iCurrentTimeBin,track+1);
905                     break;
906                   }
907                 }
908               }
909
910             } // Loop: pads
911
912           } // Loop: time bins
913
914         } // Loop: electrons of a single hit
915
916       } // If: detector and test hit
917
918       hit = (AliTRDhit *) fTRD->NextHit();   
919
920     } // Loop: hits of one primary track
921
922   } // Loop: primary tracks
923
924   if (fDebug > 0) {
925     printf("<AliTRDdigitizer::MakeDigits> ");
926     printf("Finished analyzing %d hits\n",countHits);
927   }
928
929   // The coupling factor
930   Float_t coupling = fPar->GetPadCoupling() 
931                    * fPar->GetTimeCoupling();
932
933   // The conversion factor
934   Float_t convert  = kEl2fC
935                    * fPar->GetChipGain();
936
937   // Loop through all chambers to finalize the digits
938   Int_t iDetBeg = 0;
939   Int_t iDetEnd = AliTRDgeometry::Ndet();
940   if (fSimpleSim) {
941     iDetBeg = fSimpleDet;
942     iDetEnd = iDetBeg + 1;
943   }
944   for (Int_t iDet = iDetBeg; iDet < iDetEnd; iDet++) {
945
946     Int_t plane       = fGeo->GetPlane(iDet);
947     Int_t sector      = fGeo->GetSector(iDet);
948     Int_t chamber     = fGeo->GetChamber(iDet);
949     Int_t nRowMax     = fPar->GetRowMax(plane,chamber,sector);
950     Int_t nColMax     = fPar->GetColMax(plane);
951     Int_t nTimeMax    = fPar->GetTimeMax();
952     Int_t nTimeTotal  = fPar->GetTimeTotal();
953
954     Double_t *inADC  = new Double_t[nTimeTotal];
955     Double_t *outADC = new Double_t[nTimeTotal];
956
957     if (fDebug > 0) {
958       printf("<AliTRDdigitizer::MakeDigits> ");
959       printf("Digitization for chamber %d\n",iDet);
960     }
961
962     // Add a container for the digits of this detector
963     digits = fDigitsManager->GetDigits(iDet);        
964     // Allocate memory space for the digits buffer
965     if (digits->GetNtime() == 0) {
966       digits->Allocate(nRowMax,nColMax,nTimeTotal);
967     }
968     else if (fSimpleSim) {
969       digits->Clear();
970     }
971  
972     // Get the signal container
973     signals = (AliTRDdataArrayF *) signalsArray->At(iDet);
974     if (signals->GetNtime() == 0) {
975       // Create missing containers
976       signals->Allocate(nRowMax,nColMax,nTimeTotal);      
977     }
978     else {
979       // Expand the container if neccessary
980       if (fCompress) signals->Expand();
981     }
982     // Create the missing dictionary containers
983     if (!fSimpleSim) {    
984       for (iDict = 0; iDict < kNDict; iDict++) {       
985         dictionary[iDict] = fDigitsManager->GetDictionary(iDet,iDict);
986         if (dictionary[iDict]->GetNtime() == 0) {
987           dictionary[iDict]->Allocate(nRowMax,nColMax,nTimeTotal);
988         }
989       } 
990     }
991
992     Int_t nDigits = 0;
993
994     // Don't create noise in detectors that are switched off
995     if (CheckDetector(plane,chamber,sector)) {
996
997       // Create the digits for this chamber
998       for (iRow  = 0; iRow  <  nRowMax;   iRow++ ) {
999         for (iCol  = 0; iCol  <  nColMax;   iCol++ ) {
1000
1001           // Create summable digits
1002           if (fSDigits) {
1003
1004             for (iTime = 0; iTime < nTimeTotal; iTime++) {         
1005               Float_t signalAmp = signals->GetDataUnchecked(iRow,iCol,iTime);
1006               signalAmp *= fSDigitsScale;
1007               signalAmp  = TMath::Min(signalAmp,(Float_t) 1.0e9);
1008               Int_t adc  = (Int_t) signalAmp;
1009               if (adc > 0) nDigits++;
1010               digits->SetDataUnchecked(iRow,iCol,iTime,adc);
1011             }
1012
1013           }
1014           // Create normal digits
1015           else {
1016
1017             for (iTime = 0; iTime < nTimeTotal; iTime++) {         
1018               Float_t signalAmp = signals->GetDataUnchecked(iRow,iCol,iTime);
1019               // Pad and time coupling
1020               signalAmp *= coupling;
1021               // Add the noise, starting from minus ADC baseline in electrons
1022               Double_t baselineEl = fPar->GetADCbaseline() * (fPar->GetADCinRange()
1023                                                            / fPar->GetADCoutRange()) 
1024                                                            / convert;
1025               signalAmp  = TMath::Max((Double_t) gRandom->Gaus(signalAmp,fPar->GetNoise())
1026                                      ,-baselineEl);
1027               // Convert to mV
1028               signalAmp *= convert;
1029               // Add ADC baseline in mV
1030               signalAmp += fPar->GetADCbaseline() * (fPar->GetADCinRange()
1031                                                    / fPar->GetADCoutRange());
1032               // Convert to ADC counts. Set the overflow-bit fADCoutRange if the 
1033               // signal is larger than fADCinRange
1034               Int_t adc  = 0;
1035               if (signalAmp >= fPar->GetADCinRange()) {
1036                 adc = ((Int_t) fPar->GetADCoutRange());
1037               }
1038               else {
1039                 adc = ((Int_t) (signalAmp * (fPar->GetADCoutRange() 
1040                                            / fPar->GetADCinRange())));
1041               }
1042               inADC[iTime]  = adc;
1043               outADC[iTime] = adc;
1044             }
1045
1046             // Apply the tail cancelation via the digital filter
1047             if (fPar->TCOn()) {
1048               DeConvExp(inADC,outADC,nTimeTotal,fPar->GetTCnexp());
1049             }
1050
1051             for (iTime = 0; iTime < nTimeTotal; iTime++) {   
1052               // Store the amplitude of the digit if above threshold
1053               if (outADC[iTime] > fPar->GetADCthreshold()) {
1054                 if (fDebug > 2) {
1055                   printf("  iRow = %d, iCol = %d, iTime = %d, adc = %f\n"
1056                         ,iRow,iCol,iTime,outADC[iTime]);
1057                 }
1058                 nDigits++;
1059                 digits->SetDataUnchecked(iRow,iCol,iTime,((Int_t) outADC[iTime]));
1060               }
1061             }
1062
1063           }
1064
1065         }
1066       }
1067
1068     }
1069
1070     // Compress the arrays
1071     if (!fSimpleSim) {  
1072       digits->Compress(1,0);
1073       for (iDict = 0; iDict < kNDict; iDict++) {
1074         dictionary[iDict]->Compress(1,0);
1075       }
1076
1077       totalSizeDigits += digits->GetSize();
1078       totalSizeDict0  += dictionary[0]->GetSize();
1079       totalSizeDict1  += dictionary[1]->GetSize();
1080       totalSizeDict2  += dictionary[2]->GetSize();
1081
1082       Float_t nPixel = nRowMax * nColMax * nTimeMax;
1083       if (fDebug > 0) {
1084         printf("<AliTRDdigitizer::MakeDigits> ");
1085         printf("Found %d digits in detector %d (%3.0f).\n"
1086               ,nDigits,iDet
1087               ,100.0 * ((Float_t) nDigits) / nPixel);
1088       } 
1089
1090       if (fCompress) signals->Compress(1,0);
1091
1092     }
1093
1094     delete [] inADC;
1095     delete [] outADC;
1096
1097   }
1098
1099   if (signalsArray) {
1100     delete signalsArray;
1101     signalsArray = 0;
1102   }
1103
1104   if (fDebug > 0) {
1105     printf("<AliTRDdigitizer::MakeDigits> ");
1106     printf("Total number of analyzed hits = %d\n",countHits);
1107     if (!fSimpleSim) {    
1108       printf("<AliTRDdigitizer::MakeDigits> ");
1109       printf("Total digits data size = %d, %d, %d, %d\n",totalSizeDigits
1110                                                         ,totalSizeDict0
1111                                                         ,totalSizeDict1
1112                                                         ,totalSizeDict2);        
1113     }
1114   }
1115
1116   return kTRUE;
1117
1118 }
1119
1120 //_____________________________________________________________________________
1121 void AliTRDdigitizer::AddSDigitsManager(AliTRDdigitsManager *man)
1122 {
1123   //
1124   // Add a digits manager for s-digits to the input list.
1125   //
1126
1127   fSDigitsManagerList->Add(man);
1128
1129 }
1130
1131 //_____________________________________________________________________________
1132 void AliTRDdigitizer::DeleteSDigitsManager()
1133 {
1134   //
1135   // Removes digits manager from the input list.
1136   //
1137
1138   fSDigitsManagerList->Delete();
1139
1140 }
1141
1142 //_____________________________________________________________________________
1143 Bool_t AliTRDdigitizer::ConvertSDigits()
1144 {
1145   //
1146   // Converts s-digits to normal digits
1147   //
1148
1149   // Number of track dictionary arrays
1150   const Int_t    kNDict = AliTRDdigitsManager::kNDict;
1151
1152   // Converts number of electrons to fC
1153   const Double_t kEl2fC = 1.602E-19 * 1.0E15; 
1154
1155   Int_t iDict = 0;
1156   Int_t iRow;
1157   Int_t iCol;
1158   Int_t iTime;
1159
1160   if (!fPar) {    
1161     fPar = new AliTRDparameter("TRDparameter","Standard parameter");
1162     if (fDebug > 0) {
1163       printf("<AliTRDdigitizer::ConvertSDigits> ");
1164       printf("Create the default parameter object\n");
1165     }
1166   }
1167
1168   Double_t sDigitsScale = 1.0 / GetSDigitsScale();
1169   Double_t noise        = fPar->GetNoise();
1170   Double_t padCoupling  = fPar->GetPadCoupling();
1171   Double_t timeCoupling = fPar->GetTimeCoupling();
1172   Double_t chipGain     = fPar->GetChipGain();
1173   Double_t coupling     = padCoupling * timeCoupling;
1174   Double_t convert      = kEl2fC * chipGain;
1175   Double_t adcInRange   = fPar->GetADCinRange();
1176   Double_t adcOutRange  = fPar->GetADCoutRange();
1177   Int_t    adcThreshold = fPar->GetADCthreshold();
1178   Int_t    adcBaseline  = fPar->GetADCbaseline();   
1179
1180   AliTRDdataArrayI *digitsIn;
1181   AliTRDdataArrayI *digitsOut;
1182   AliTRDdataArrayI *dictionaryIn[kNDict];
1183   AliTRDdataArrayI *dictionaryOut[kNDict];
1184
1185   // Loop through the detectors
1186   for (Int_t iDet = 0; iDet < AliTRDgeometry::Ndet(); iDet++) {
1187
1188     if (fDebug > 0) {
1189       printf("<AliTRDdigitizer::ConvertSDigits> ");
1190       printf("Convert detector %d to digits.\n",iDet);
1191     }
1192
1193     Int_t plane      = fGeo->GetPlane(iDet);
1194     Int_t sector     = fGeo->GetSector(iDet);
1195     Int_t chamber    = fGeo->GetChamber(iDet);
1196     Int_t nRowMax    = fPar->GetRowMax(plane,chamber,sector);
1197     Int_t nColMax    = fPar->GetColMax(plane);
1198     Int_t nTimeTotal = fPar->GetTimeTotal();
1199
1200     Double_t *inADC  = new Double_t[nTimeTotal];
1201     Double_t *outADC = new Double_t[nTimeTotal];
1202
1203     digitsIn  = fSDigitsManager->GetDigits(iDet);
1204     digitsIn->Expand();
1205     digitsOut = fDigitsManager->GetDigits(iDet);
1206     digitsOut->Allocate(nRowMax,nColMax,nTimeTotal);
1207     for (iDict = 0; iDict < kNDict; iDict++) {
1208       dictionaryIn[iDict]  = fSDigitsManager->GetDictionary(iDet,iDict);
1209       dictionaryIn[iDict]->Expand();
1210       dictionaryOut[iDict] = fDigitsManager->GetDictionary(iDet,iDict);
1211       dictionaryOut[iDict]->Allocate(nRowMax,nColMax,nTimeTotal);
1212     }
1213
1214     for (iRow  = 0; iRow  <  nRowMax;   iRow++ ) {
1215       for (iCol  = 0; iCol  <  nColMax;   iCol++ ) {
1216
1217         for (iTime = 0; iTime < nTimeTotal; iTime++) {         
1218           Double_t signal = (Double_t) digitsIn->GetDataUnchecked(iRow,iCol,iTime);
1219           signal *= sDigitsScale;
1220           // Pad and time coupling
1221           signal *= coupling;
1222           // Add the noise, starting from minus ADC baseline in electrons
1223           Double_t baselineEl = adcBaseline * (adcInRange / adcOutRange) / convert;
1224           signal  = TMath::Max((Double_t) gRandom->Gaus(signal,noise),-baselineEl);
1225           // Convert to mV
1226           signal *= convert;
1227           // add ADC baseline in mV
1228           signal += adcBaseline * (adcInRange / adcOutRange);
1229           // Convert to ADC counts. Set the overflow-bit adcOutRange if the 
1230           // signal is larger than adcInRange
1231           Int_t adc  = 0;
1232           if (signal >= adcInRange) {
1233             adc = ((Int_t) adcOutRange);
1234           }
1235           else {
1236             adc = ((Int_t) (signal * (adcOutRange / adcInRange)));
1237           }
1238           inADC[iTime]  = adc;
1239           outADC[iTime] = adc;
1240         }
1241
1242         // Apply the tail cancelation via the digital filter
1243         if (fPar->TCOn()) {
1244           DeConvExp(inADC,outADC,nTimeTotal,fPar->GetTCnexp());
1245         }
1246
1247         for (iTime = 0; iTime < nTimeTotal; iTime++) {   
1248           // Store the amplitude of the digit if above threshold
1249           if (outADC[iTime] > adcThreshold) {
1250             digitsOut->SetDataUnchecked(iRow,iCol,iTime,((Int_t) outADC[iTime]));
1251             // Copy the dictionary
1252             for (iDict = 0; iDict < kNDict; iDict++) { 
1253               Int_t track = dictionaryIn[iDict]->GetDataUnchecked(iRow,iCol,iTime);
1254               dictionaryOut[iDict]->SetDataUnchecked(iRow,iCol,iTime,track);
1255             }
1256           }
1257         }
1258
1259       }
1260     }
1261
1262     if (fCompress) {
1263       digitsIn->Compress(1,0);
1264       digitsOut->Compress(1,0);
1265       for (iDict = 0; iDict < kNDict; iDict++) {
1266         dictionaryIn[iDict]->Compress(1,0);
1267         dictionaryOut[iDict]->Compress(1,0);
1268       }
1269     }
1270
1271     delete [] inADC;
1272     delete [] outADC;
1273
1274   }    
1275
1276   return kTRUE;
1277
1278 }
1279
1280 //_____________________________________________________________________________
1281 Bool_t AliTRDdigitizer::MergeSDigits()
1282 {
1283   //
1284   // Merges the input s-digits:
1285   //   - The amplitude of the different inputs are summed up.
1286   //   - Of the track IDs from the input dictionaries only one is
1287   //     kept for each input. This works for maximal 3 different merged inputs.
1288   //
1289
1290   // Number of track dictionary arrays
1291   const Int_t kNDict = AliTRDdigitsManager::kNDict;
1292
1293   if (!fPar) {
1294     fPar = new AliTRDparameter("TRDparameter","Standard parameter");
1295     if (fDebug > 0) {
1296       printf("<AliTRDdigitizer::MergeSDigits> ");
1297       printf("Create the default parameter object\n");
1298     }
1299   }
1300
1301   Int_t iDict = 0;
1302   Int_t jDict = 0;
1303
1304   AliTRDdataArrayI *digitsA;
1305   AliTRDdataArrayI *digitsB;
1306   AliTRDdataArrayI *dictionaryA[kNDict];
1307   AliTRDdataArrayI *dictionaryB[kNDict];
1308
1309   // Get the first s-digits
1310   fSDigitsManager = (AliTRDdigitsManager *) fSDigitsManagerList->First();
1311   if (!fSDigitsManager) return kFALSE;
1312
1313   // Loop through the other sets of s-digits
1314   AliTRDdigitsManager *mergeSDigitsManager;
1315   mergeSDigitsManager = (AliTRDdigitsManager *) 
1316                         fSDigitsManagerList->After(fSDigitsManager);
1317
1318   if (fDebug > 0) {
1319     if (mergeSDigitsManager) {
1320       printf("<AliTRDdigitizer::MergeSDigits> ");
1321       printf("Merge %d input files.\n",fSDigitsManagerList->GetSize());
1322     }
1323     else {
1324       printf("<AliTRDdigitizer::MergeSDigits> ");
1325       printf("Only one input file.\n");
1326     }
1327   }
1328
1329   Int_t iMerge = 0;
1330   while (mergeSDigitsManager) {
1331
1332     iMerge++;
1333
1334     // Loop through the detectors
1335     for (Int_t iDet = 0; iDet < AliTRDgeometry::Ndet(); iDet++) {
1336
1337       Int_t plane      = fGeo->GetPlane(iDet);
1338       Int_t sector     = fGeo->GetSector(iDet);
1339       Int_t chamber    = fGeo->GetChamber(iDet);
1340       Int_t nRowMax    = fPar->GetRowMax(plane,chamber,sector);
1341       Int_t nColMax    = fPar->GetColMax(plane);
1342       Int_t nTimeTotal = fPar->GetTimeTotal();
1343
1344       // Loop through the pixels of one detector and add the signals
1345       digitsA = fSDigitsManager->GetDigits(iDet);
1346       digitsB = mergeSDigitsManager->GetDigits(iDet);
1347       digitsA->Expand();
1348       digitsB->Expand();
1349       for (iDict = 0; iDict < kNDict; iDict++) {
1350         dictionaryA[iDict] = fSDigitsManager->GetDictionary(iDet,iDict);
1351         dictionaryB[iDict] = mergeSDigitsManager->GetDictionary(iDet,iDict);
1352         dictionaryA[iDict]->Expand();
1353         dictionaryB[iDict]->Expand();
1354       }
1355
1356       // Merge only detectors that contain a signal
1357       Bool_t doMerge = kTRUE;
1358       if (fMergeSignalOnly) {
1359         if (digitsA->GetOverThreshold(0) == 0) {
1360           doMerge = kFALSE;
1361         }
1362       }
1363
1364       if (doMerge) {
1365
1366         if (fDebug > 0) {
1367           printf("<AliTRDdigitizer::MergeSDigits> ");
1368           printf("Merge detector %d of input no.%d\n",iDet,iMerge+1);
1369         }
1370
1371         for (Int_t iRow  = 0; iRow  <  nRowMax;   iRow++ ) {
1372           for (Int_t iCol  = 0; iCol  <  nColMax;   iCol++ ) {
1373             for (Int_t iTime = 0; iTime < nTimeTotal; iTime++) {         
1374
1375               // Add the amplitudes of the summable digits 
1376               Int_t ampA = digitsA->GetDataUnchecked(iRow,iCol,iTime);
1377               Int_t ampB = digitsB->GetDataUnchecked(iRow,iCol,iTime);
1378               ampA += ampB;
1379               digitsA->SetDataUnchecked(iRow,iCol,iTime,ampA);
1380
1381              // Add the mask to the track id if defined.
1382               for (iDict = 0; iDict < kNDict; iDict++) {
1383                 Int_t trackB = dictionaryB[iDict]->GetDataUnchecked(iRow,iCol,iTime);
1384                 if ((fMasks) && (trackB > 0)) {
1385                   for (jDict = 0; jDict < kNDict; jDict++) { 
1386                     Int_t trackA = dictionaryA[iDict]->GetDataUnchecked(iRow,iCol,iTime);
1387                     if (trackA == 0) {
1388                       trackA = trackB + fMasks[iMerge];
1389                       dictionaryA[iDict]->SetDataUnchecked(iRow,iCol,iTime,trackA);
1390                     }
1391                   }
1392                 }
1393               }
1394
1395             }
1396           }
1397         }
1398
1399       }
1400
1401       if (fCompress) {
1402         digitsA->Compress(1,0);
1403         digitsB->Compress(1,0);
1404         for (iDict = 0; iDict < kNDict; iDict++) {
1405           dictionaryA[iDict]->Compress(1,0);
1406           dictionaryB[iDict]->Compress(1,0);
1407         }
1408       }
1409
1410     }    
1411
1412     // The next set of s-digits
1413     mergeSDigitsManager = (AliTRDdigitsManager *) 
1414                           fSDigitsManagerList->After(mergeSDigitsManager);
1415
1416   }
1417
1418   return kTRUE;
1419
1420 }
1421
1422 //_____________________________________________________________________________
1423 Bool_t AliTRDdigitizer::SDigits2Digits()
1424 {
1425   //
1426   // Merges the input s-digits and converts them to normal digits
1427   //
1428
1429   if (!MergeSDigits()) return kFALSE;
1430
1431   return ConvertSDigits();
1432
1433 }
1434
1435 //_____________________________________________________________________________
1436 Bool_t AliTRDdigitizer::CheckDetector(Int_t plane, Int_t chamber, Int_t sector)
1437 {
1438   //
1439   // Checks whether a detector is enabled
1440   //
1441
1442   if (fSimpleSim) return kTRUE; 
1443
1444   if ((fTRD->GetSensChamber() >=       0) &&
1445       (fTRD->GetSensChamber() != chamber)) return kFALSE;
1446   if ((fTRD->GetSensPlane()   >=       0) &&
1447       (fTRD->GetSensPlane()   !=   plane)) return kFALSE;
1448   if ( fTRD->GetSensSector()  >=       0) {
1449     Int_t sens1 = fTRD->GetSensSector();
1450     Int_t sens2 = sens1 + fTRD->GetSensSectorRange();
1451     sens2 -= ((Int_t) (sens2 / AliTRDgeometry::Nsect())) 
1452            * AliTRDgeometry::Nsect();
1453     if (sens1 < sens2) {
1454       if ((sector < sens1) || (sector >= sens2)) return kFALSE;
1455     }
1456     else {
1457       if ((sector < sens1) && (sector >= sens2)) return kFALSE;
1458     }
1459   }
1460
1461   return kTRUE;
1462
1463 }
1464
1465 //_____________________________________________________________________________
1466 Bool_t AliTRDdigitizer::WriteDigits() const
1467 {
1468   //
1469   // Writes out the TRD-digits and the dictionaries
1470   //
1471
1472   // Store the digits and the dictionary in the tree
1473   return fDigitsManager->WriteDigits();
1474
1475 }
1476
1477 //_____________________________________________________________________________
1478 void AliTRDdigitizer::DeConvExp(Double_t *source, Double_t *target
1479                               , Int_t n, Int_t nexp) 
1480 {
1481   //
1482   // Does the deconvolution by the digital filter.
1483   //
1484   // Author:        Marcus Gutfleisch, KIP Heidelberg
1485   // Optimized for: New TRF from Venelin Angelov, simulated with CADENCE
1486   //                Pad-ground capacitance = 25 pF
1487   //                Pad-pad cross talk capacitance = 6 pF
1488   //                For 10 MHz digitization, corresponding to 20 time bins
1489   //                in the drift region
1490   //
1491
1492   Double_t rates[2];
1493   Double_t coefficients[2];
1494
1495   /* initialize (coefficient = alpha, rates = lambda) */
1496   
1497   if( nexp == 1 ) {
1498     rates[0] = 0.466998;
1499     /* no rescaling */
1500     coefficients[0] = 1.0;
1501   }
1502   if( nexp == 2 ) {
1503     rates[0] = 0.8988162;
1504     coefficients[0] = 0.11392069;
1505     rates[1] = 0.3745688;
1506     coefficients[1] = 0.8860793;
1507     /* no rescaling */
1508     Float_t sumc = coefficients[0]+coefficients[1];
1509     coefficients[0] /= sumc;
1510     coefficients[1] /= sumc;
1511   }
1512       
1513   Int_t i, k;
1514   Double_t reminder[2];
1515   Double_t correction, result;
1516
1517   /* attention: computation order is important */
1518   correction=0.0;
1519   for ( k = 0; k < nexp; k++ ) reminder[k]=0.0;
1520     
1521   for ( i = 0; i < n; i++ ) {
1522     result = ( source[i] - correction );    /* no rescaling */
1523     target[i] = result;
1524     
1525     for ( k = 0; k < nexp; k++ ) reminder[k] = rates[k] 
1526                              * ( reminder[k] + coefficients[k] * result);
1527       
1528     correction=0.0;
1529     for ( k = 0; k < nexp; k++ ) correction += reminder[k];
1530   }
1531   
1532 }
1533
1534 //_____________________________________________________________________________
1535 void AliTRDdigitizer::InitOutput(Int_t iEvent)
1536 {
1537   //
1538   // Initializes the output branches
1539   //
1540
1541   fEvent = iEvent;
1542    
1543   if (!fRunLoader)
1544    {
1545      Error("InitOutput","Run Loader is NULL");
1546      return;  
1547    }
1548   AliLoader* loader = fRunLoader->GetLoader("TRDLoader");
1549   if (!loader)
1550    {
1551      Error("Open","Can not get TRD loader from Run Loader");
1552      return;
1553    }
1554
1555   TTree* tree = 0;
1556   
1557   if (fSDigits)
1558    { 
1559    //if we produce SDigits
1560     tree = loader->TreeS();
1561     if (!tree)
1562      {
1563       loader->MakeTree("S");
1564       tree = loader->TreeS();
1565      }
1566    }
1567   else
1568    {//if we produce Digits
1569      tree = loader->TreeD();
1570      if (!tree)
1571       {
1572        loader->MakeTree("D");
1573        tree = loader->TreeD();
1574       }
1575    }
1576   fDigitsManager->SetEvent(iEvent);
1577   fDigitsManager->MakeBranch(tree);
1578
1579 }