]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EMCAL/AliEMCALDigitizer.cxx
2820bb4cd7361e947aa2b66ad71c045200334492
[u/mrichter/AliRoot.git] / EMCAL / AliEMCALDigitizer.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 //////////////////////////////////////////////////////////////////////////////
21 // Class performs digitization of Summable digits 
22 //  
23 // In addition it performs mixing of summable digits from different events.
24 //
25 // For each event two branches are created in TreeD:
26 //   "EMCAL" - list of digits
27 //   "AliEMCALDigitizer" - AliEMCALDigitizer with all parameters used in digitization
28 //
29 // Note, that one cset title for new digits branch, and repeat digitization with
30 // another set of parameters.
31 //
32 // Examples of use:
33 // root[0] AliEMCALDigitizer * d = new AliEMCALDigitizer() ;
34 // root[1] d->ExecuteTask()             
35 // Warning in <TDatabasePDG::TDatabasePDG>: object already instantiated
36 //                       //Digitizes SDigitis in all events found in file galice.root 
37 //
38 // root[2] AliEMCALDigitizer * d1 = new AliEMCALDigitizer("galice1.root") ;  
39 //                       // Will read sdigits from galice1.root
40 // root[3] d1->MixWith("galice2.root")       
41 // Warning in <TDatabasePDG::TDatabasePDG>: object already instantiated
42 //                       // Reads another portion of sdigits from galice2.root
43 // root[3] d1->MixWith("galice3.root")       
44 //                       // Reads another portion of sdigits from galice3.root
45 // root[4] d->ExecuteTask("deb timing")    
46 //                       // Reads SDigits from files galice1.root, galice2.root ....
47 //                       // mixes them and stores produced Digits in file galice1.root          
48 //                       // deb - prints number of produced digits
49 //                       // deb all - prints list of produced digits
50 //                       // timing  - prints time used for digitization
51 ////////////////////////////////////////////////////////////////////////////////////
52 //
53 //*-- Author: Sahal Yacoob (LBL)
54 // based on : AliEMCALDigitizer
55 //_________________________________________________________________________________
56
57 // --- ROOT system ---
58 #include "TFile.h"
59 #include "TTree.h"
60 #include "TSystem.h"
61 #include "TROOT.h"
62 #include "TFolder.h"
63 #include "TObjString.h"
64 #include "TGeometry.h"
65 #include "TBenchmark.h"
66 // --- Standard library ---
67 #include <iomanip.h>
68
69 // --- AliRoot header files ---
70
71 #include "AliRun.h"
72 #include "AliHeader.h"
73 #include "AliStream.h"
74 #include "AliRunDigitizer.h"
75 #include "AliEMCALDigit.h"
76 #include "AliEMCALHit.h"
77 #include "AliEMCALTick.h"
78 #include "AliEMCALv1.h"
79 #include "AliEMCALDigitizer.h"
80 #include "AliEMCALSDigitizer.h"
81 #include "AliEMCALGeometry.h"
82 #include "AliEMCALGetter.h"
83 ClassImp(AliEMCALDigitizer)
84
85
86 //____________________________________________________________________________ 
87   AliEMCALDigitizer::AliEMCALDigitizer()
88 {
89   // ctor
90
91   InitParameters() ; 
92   fDefaultInit = kTRUE ; 
93
94 }
95
96 //____________________________________________________________________________ 
97 AliEMCALDigitizer::AliEMCALDigitizer(const char *headerFile,const char *name)
98 {
99   SetName(name) ;
100   SetTitle(headerFile) ;
101   fManager = 0 ;                     // We work in the standalong mode
102   fSplitFile= 0 ; 
103   InitParameters() ; 
104   Init() ;
105   fDefaultInit = kFALSE ; 
106
107 }
108
109 //____________________________________________________________________________ 
110 AliEMCALDigitizer::AliEMCALDigitizer(AliRunDigitizer * ard):AliDigitizer(ard)
111 {
112   // ctor
113   SetName("Default");    
114   SetTitle("aliroot") ;  
115   fDefaultInit = kFALSE ; 
116 }
117
118 //____________________________________________________________________________ 
119   AliEMCALDigitizer::~AliEMCALDigitizer()
120 {
121   // dtor
122   // fDefaultInit = kTRUE if Digitizer created by default ctor (to get just the parameters)
123   
124   if (!fDefaultInit) {
125     AliEMCALGetter * gime = AliEMCALGetter::GetInstance() ; 
126     
127     // remove the task from the folder list
128     gime->RemoveTask("S",GetName()) ;
129     gime->RemoveTask("D",GetName()) ;
130     
131     // remove the Digits from the folder list
132     gime->RemoveObjects("D", GetName()) ;
133     
134     // remove the SDigits from the folder list
135     gime->RemoveSDigits() ;
136     
137     // Delete gAlice
138     gime->CloseFile() ; 
139     
140     fSplitFile = 0 ; 
141   }
142 }
143
144 //____________________________________________________________________________ 
145 void AliEMCALDigitizer::InitParameters()
146 {
147   fSDigitizer = 0 ;
148   fNinputs = 1 ;
149   fPinNoise = 0.00001 ;
150   fTowerDigitThreshold = 0.001 ;
151   fTimeResolution     = 0.5e-9 ;
152   fTimeSignalLength   = 1.0e-9 ;
153   fPreShowerDigitThreshold = fTowerDigitThreshold/25. ;
154   fInitialized = kFALSE ;
155   fADCchannelTower = 0.000220;       // width of one ADC channel in GeV
156   fADCpedestalTower = 0.005 ;      // GeV
157   fNADCTower = (Int_t) TMath::Power(2,16) ;  // number of channels in Tower ADC
158
159   fADCchannelPreSho = 0.0000300;          // width of one ADC channel in Pre Shower
160   fADCpedestalPreSho = 0.005 ;         // 
161   fNADCPreSho = (Int_t) TMath::Power(2,12);      // number of channels in Pre ShowerADC
162
163   fTimeThreshold = 0.001*10000000 ; //Means 1 MeV in terms of SDigits amplitude
164  
165 }
166
167 //____________________________________________________________________________ 
168 Bool_t AliEMCALDigitizer::Init()
169 {
170   // Makes all memory allocations
171
172   AliEMCALGetter * gime = AliEMCALGetter::GetInstance(GetTitle(), GetName(), "update") ; 
173   if ( gime == 0 ) {
174     cerr << "ERROR: AliEMCALDigitizer::Init -> Could not obtain the Getter object !" << endl ; 
175     return kFALSE;
176   } 
177   
178   //const AliEMCALGeometry * geom = gime->EMCALGeometry() ;
179   //fEmcCrystals = geom->GetNModules() *  geom->GetNCristalsInModule() ;
180   
181   // Post Digits to the white board
182   gime->PostDigits(GetName() ) ;   
183   
184   // Post Digitizer to the white board
185   gime->PostDigitizer(this) ;
186   
187   //Mark that we will use current header file
188   if(!fManager){
189     gime->PostSDigits(GetName(),GetTitle()) ;
190     gime->PostSDigitizer(GetName(),GetTitle()) ;
191   }
192   return kTRUE ;
193     
194 }
195
196 //____________________________________________________________________________
197 void AliEMCALDigitizer::Reset() { 
198   //sets current event number to the first simulated event
199 if( strcmp(GetName(), "") == 0 )
200   Init() ;
201
202       // Int_t inputs ;
203       // for(inputs = 0; inputs < fNinputs ;inputs++)
204       //  fIevent->AddAt(-1, inputs ) ;
205   
206 }
207
208 //____________________________________________________________________________
209 void AliEMCALDigitizer::Digitize(const Int_t event) { 
210
211   // Makes the digitization of the collected summable digits
212   // for this it first creates the array of all EMCAL modules
213   // filled with noise (different for EMC, CPV and PPSD) and
214   // after that adds contributions from SDigits. This design 
215   // helps to avoid scanning over the list of digits to add 
216   // contribution of any new SDigit.
217
218   AliEMCALGetter * gime = AliEMCALGetter::GetInstance() ; 
219   TClonesArray * digits = gime->Digits(GetName()) ; 
220   
221   digits->Clear() ;
222
223     const AliEMCALGeometry *geom = gime->EMCALGeometry() ; 
224
225
226   //Making digits with noise, first EMC
227   Int_t nEMC = 2*geom->GetNPhi()*geom->GetNZ();
228   Int_t absID ;
229   TString name      =  geom->GetName() ;
230
231  // get first the sdigitizer from the tasks list (must have same name as the digitizer)
232   const AliEMCALSDigitizer * sDigitizer = gime->SDigitizer(GetName()); 
233   if ( !sDigitizer) {
234     cerr << "ERROR: AliEMCALDigitizer::Digitize -> SDigitizer with name " << GetName() << " not found " << endl ; 
235     abort() ; 
236   }
237 // loop through the sdigits posted to the White Board and add them to the noise
238   TCollection * folderslist = gime->SDigitsFolder()->GetListOfFolders() ; 
239   TIter next(folderslist) ; 
240   TFolder * folder = 0 ; 
241   TClonesArray * sdigits = 0 ;
242   Int_t input = 0 ;
243   TObjArray * sdigArray = new TObjArray(2) ;
244   while ( (folder = (TFolder*)next()) ) {
245     if ( (sdigits = (TClonesArray*)folder->FindObject(GetName()) ) ) {
246       TString fileName(folder->GetName()) ;
247       fileName.ReplaceAll("_","/") ;
248       cout << "INFO: AliEMCALDigitizer::Digitize -> Adding SDigits " 
249            << GetName() << " from " << fileName << endl ; 
250       sdigArray->AddAt(sdigits, input) ;
251       input++ ;
252     }
253   }
254
255   //Find the first tower with signal
256   Int_t nextSig = 200000 ; 
257   Int_t i;
258   for(i=0; i<input; i++){
259     sdigits = (TClonesArray *)sdigArray->At(i) ;
260     if ( !sdigits->GetEntriesFast() )
261       continue ; 
262     Int_t curNext = ((AliEMCALDigit *)sdigits->At(0))->GetId() ;
263      if(curNext < nextSig) 
264        nextSig = curNext ;
265   }
266
267   TArrayI index(input) ;
268   index.Reset() ;  //Set all indexes to zero
269
270   AliEMCALDigit * digit = 0 ;
271   AliEMCALDigit * curSDigit = 0 ;
272
273   TClonesArray * ticks = new TClonesArray("AliEMCALTick",1000) ;
274
275   //Put Noise contribution
276   for(absID = 1; absID <= nEMC; absID++){
277     Float_t noise = gRandom->Gaus(0., fPinNoise); 
278     new((*digits)[absID-1]) AliEMCALDigit( -1, -1, absID,sDigitizer->Digitize(noise), TimeOfNoise() ) ;
279     //look if we have to add signal?
280     digit = (AliEMCALDigit *) digits->At(absID-1) ;
281     if(absID==nextSig){
282       //Add SDigits from all inputs    
283       ticks->Clear() ;
284       Int_t contrib = 0 ;
285       Float_t a = digit->GetAmp() ;
286       Float_t b = TMath::Abs( a /fTimeSignalLength) ;
287       //Mark the beginnign of the signal
288       new((*ticks)[contrib++]) AliEMCALTick(digit->GetTime(),0, b);  
289       //Mark the end of the ignal     
290       new((*ticks)[contrib++]) AliEMCALTick(digit->GetTime()+fTimeSignalLength, -a, -b);
291       
292  // loop over input
293   
294       for(i = 0; i< input ; i++){  //loop over (possible) merge sources
295         if(((TClonesArray *)sdigArray->At(i))->GetEntriesFast() > index[i] )
296           curSDigit = (AliEMCALDigit*)((TClonesArray *)sdigArray->At(i))->At(index[i]) ;        
297         else
298           curSDigit = 0 ;
299         //May be several digits will contribute from the same input
300         while(curSDigit && curSDigit->GetId() == absID){           
301           //Shift primary to separate primaries belonging different inputs
302           Int_t primaryoffset ;
303           if(fManager)
304             primaryoffset = fManager->GetMask(i) ; 
305           else
306             primaryoffset = i ;
307           curSDigit->ShiftPrimary(primaryoffset) ;
308           
309           a = curSDigit->GetAmp() ;
310           b = a /fTimeSignalLength ;
311           new((*ticks)[contrib++]) AliEMCALTick(curSDigit->GetTime(),0, b);  
312           new((*ticks)[contrib++]) AliEMCALTick(curSDigit->GetTime()+fTimeSignalLength, -a, -b); 
313
314           *digit = *digit + *curSDigit ;  //add energies
315
316           index[i]++ ;
317           if(((TClonesArray *)sdigArray->At(i))->GetEntriesFast() > index[i] )
318             curSDigit = (AliEMCALDigit*)((TClonesArray *)sdigArray->At(i))->At(index[i]) ;      
319           else
320             curSDigit = 0 ;
321         }
322       }
323
324 //calculate and set time
325       Float_t time = FrontEdgeTime(ticks) ;
326       digit->SetTime(time) ;
327
328       //Find next signal module
329       nextSig = 200000 ;
330       for(i=0; i<input; i++){
331         sdigits = ((TClonesArray *)sdigArray->At(i)) ;
332         Int_t curNext = nextSig ;
333         if(sdigits->GetEntriesFast() > index[i] ){
334           curNext = ((AliEMCALDigit *) sdigits->At(index[i]))->GetId() ;
335           
336         }
337         if(curNext < nextSig) nextSig = curNext ;
338       }
339     }
340   }
341   
342   ticks->Delete() ;
343   delete ticks ;
344
345
346
347
348   //remove digits below thresholds
349  
350   for(absID = 0; absID < nEMC/2 ; absID++){
351    if(sDigitizer->Calibrate(((AliEMCALDigit*)digits->At(absID))->GetAmp()) < fTowerDigitThreshold)
352       digits->RemoveAt(absID) ;
353     else
354       digit->SetTime(gRandom->Gaus(digit->GetTime(),fTimeResolution) ) ;
355   }
356   
357   for(absID = nEMC/2; absID < nEMC ; absID++){
358
359     if(sDigitizer->Calibrate(((AliEMCALDigit*)digits->At(absID))->GetAmp()) < fPreShowerDigitThreshold)
360       digits->RemoveAt(absID) ;
361     else
362       digit->SetTime(gRandom->Gaus(digit->GetTime(),fTimeResolution) ) ;
363   }
364   
365   digits->Compress() ;  
366   
367   Int_t ndigits = digits->GetEntriesFast() ;
368   
369   digits->Expand(ndigits) ;
370   
371   
372   //Set indexes in list of digits
373   //Int_t i ;
374  for (i = 0 ; i < ndigits ; i++) { 
375     AliEMCALDigit * digit = (AliEMCALDigit *) digits->At(i) ; 
376     digit->SetIndexInList(i) ; 
377     Float_t energy = sDigitizer->Calibrate(digit->GetAmp()) ;
378     digit->SetAmp(DigitizeEnergy(energy,digit->GetId()) ) ;
379   }
380 }
381
382 //____________________________________________________________________________
383
384 Int_t AliEMCALDigitizer::DigitizeEnergy(Float_t energy, Int_t absId)
385
386   Int_t channel = -999;
387   Int_t nphi = AliEMCALGetter::GetInstance()->EMCALGeometry()->GetNPhi() ; 
388   Int_t nz   = AliEMCALGetter::GetInstance()->EMCALGeometry()->GetNZ() ;
389   
390   if(absId <= nphi*nz){  //digitize as tower
391     channel = static_cast<Int_t> (TMath::Ceil( (energy + fADCpedestalTower)/fADCchannelTower ))  ;
392   if(channel > fNADCTower ) 
393     channel =  fNADCTower ;
394   } else {
395     channel =  static_cast<Int_t>(TMath::Ceil( (energy + fADCpedestalPreSho)/fADCchannelPreSho ))  ;
396   if(channel > fNADCPreSho ) 
397     channel =  fNADCPreSho ;
398   }
399   
400   return channel ;
401 }
402
403 //____________________________________________________________________________
404 void AliEMCALDigitizer::Exec(Option_t *option) { 
405   // Managing method
406 if(strcmp(GetName(), "") == 0 )   
407     Init() ;
408   
409   if (strstr(option,"print")) {
410     Print("");
411     return ; 
412   }
413   
414   if(strstr(option,"tim"))
415     gBenchmark->Start("EMCALDigitizer");
416
417   AliEMCALGetter * gime = AliEMCALGetter::GetInstance() ;
418   
419   Int_t nevents ;
420   
421   TTree * treeD ;
422   
423   if(fManager){
424     treeD = fManager->GetTreeD() ;
425     nevents = 1 ;    // Will process only one event
426   }
427   else {
428     gAlice->GetEvent(0) ;
429     nevents = (Int_t) gAlice->TreeE()->GetEntries() ;
430     treeD=gAlice->TreeD() ;
431   }
432  
433
434   //Check, if this branch already exits
435   if (treeD) {
436     TObjArray * lob = (TObjArray*)treeD->GetListOfBranches() ;
437     TIter next(lob) ; 
438     TBranch * branch = 0 ;  
439     Bool_t emcalfound = kFALSE, digitizerfound = kFALSE ; 
440     
441     while ( (branch = (TBranch*)next()) && (!emcalfound || !digitizerfound) ) {
442       if ( (strcmp(branch->GetName(), "EMCAL")==0) && 
443            (strcmp(branch->GetTitle(), GetName())==0) ) 
444         emcalfound = kTRUE ;
445       
446       else if ( (strcmp(branch->GetName(), "AliEMCALDigitizer")==0) && 
447                 (strcmp(branch->GetTitle(), GetName())==0) ) 
448         digitizerfound = kTRUE ; 
449     }
450     
451     if ( emcalfound ) {
452       cerr << "WARNING: AliEMCALDigitizer -> Digits branch with name " << GetName() 
453            << " already exits" << endl ;
454       return ; 
455     }   
456     if ( digitizerfound ) {
457       cerr << "WARNING: AliEMCALDigitizer -> Digitizer branch with name " << GetName() 
458            << " already exits" << endl ;
459       return ; 
460     }   
461   }
462   Int_t ievent ;
463
464   for(ievent = 0; ievent < nevents; ievent++){
465     
466     if(fManager){
467       Int_t input ;
468       for(input = 0 ; input < fManager->GetNinputs(); input ++){
469         TTree * treeS = fManager->GetInputTreeS(input) ;
470         if(!treeS){
471           cerr << "AliEMCALDigitizer -> No Input " << endl ;
472           return ;
473         }
474         gime->ReadTreeS(treeS,input) ;
475       }
476     }
477     else 
478       gime->Event(ievent,"S") ; 
479     
480     Digitize(ievent) ; //Add prepared SDigits to digits and add the noise
481     
482     WriteDigits(ievent) ;
483     
484     if(strstr(option,"deb"))
485       PrintDigits(option);
486     
487     //increment the total number of Digits per run 
488     fDigitsInRun += gime->Digits()->GetEntriesFast() ;  
489   }
490   
491   if(strstr(option,"tim")){
492     gBenchmark->Stop("EMCALDigitizer");
493     cout << "AliEMCALDigitizer:" << endl ;
494     cout << "  took " << gBenchmark->GetCpuTime("EMCALDigitizer") << " seconds for Digitizing " 
495          <<  gBenchmark->GetCpuTime("EMCALDigitizer")/nevents << " seconds per event " << endl ;
496     cout << endl ;
497   }
498   
499 }
500
501
502
503 //__________________________________________________________________
504 void AliEMCALDigitizer::MixWith(char* headerFile){
505   // Alows produce digits by superimposing background and signal event.
506   // It is assumed, that headers file with SIGNAL events is opened in 
507   // constructor, and now we set the BACKGROUND event, with which we 
508   // will mix. Thus we avoid writing (changing) huge and expencive 
509   // backgound files: all output will be writen into SIGNAL, i.e. 
510   // opened in constructor file. 
511   //
512   // One can open as many files to mix with as one wants.
513
514 if( strcmp(GetName(), "") == 0 )
515     Init() ;
516   
517  if(fManager){
518     cout << "Can not use this method under AliRunDigitizer " << endl ;
519     return ;
520   } // check if the specified SDigits do not already exist on the White Board:
521   // //Folders/RunMC/Event/Data/EMCAL/SDigits/headerFile/sdigitsname
522
523   TString path = "Folders/RunMC/Event/Data/EMCAL/SDigits" ; 
524   path += headerFile ; 
525   path += "/" ; 
526   path += GetName() ;
527   if ( gROOT->FindObjectAny(path.Data()) ) {
528     cerr << "WARNING: AliEMCALDigitizer::MixWith -> Entry already exists, do not add" << endl ;
529     return;
530   }
531
532   AliEMCALGetter * gime = AliEMCALGetter::GetInstance() ;
533   gime->PostSDigits(GetName(),headerFile) ;
534   
535   // check if the requested file is already open or exist and if SDigits Branch exist
536   TFile * file = (TFile*)gROOT->FindObject(headerFile); 
537   if ( !file ) { 
538     file = new TFile(headerFile, "READ") ; 
539     if (!file) { 
540       cerr << "ERROR: AliEMCALDigitizer::MixWith -> File " << headerFile << " does not exist!" << endl ; 
541       return ; 
542     }
543   }
544   
545 }
546  
547 //__________________________________________________________________
548 void AliEMCALDigitizer::Print(Option_t* option)const {
549  
550   if( strcmp(GetName(), "") != 0) {
551     
552     cout << "------------------- "<< GetName() << " -------------" << endl ;
553     const AliRunDigitizer * rd = Manager() ; 
554     if (rd) {
555       Int_t ninput = rd->GetInputStreams()->GetEntries() ;
556       Int_t index = 0 ; 
557       const AliStream * st = 0 ; 
558       TString out("") ; 
559       for (index = 0 ; index < ninput ; index++) { 
560         st = static_cast<AliStream*>(rd->GetInputStreams()->At(index))  ;
561         if (index == 0 ) 
562           out = st->GetFileNames()->At(0)->GetName() ; 
563         cout << "Adding SDigits " << GetName() << " from " <<   st->GetFileNames()->At(0)->GetName() << endl ; 
564       }
565       cout << endl ;
566       cout << "Writing digits to " <<  out.Data() << endl ;   
567     } else { 
568       AliEMCALGetter * gime = AliEMCALGetter::GetInstance() ;  
569       gime->Folder("sdigits")  ;
570       cout << "Digitizing sDigits from file(s): " <<endl ;
571       TCollection * folderslist = gime->Folder("sdigits")->GetListOfFolders() ; 
572       TIter next(folderslist) ; 
573       TFolder * folder = 0 ; 
574       
575       while ( (folder = (TFolder*)next()) ) {
576         if ( folder->FindObject(GetName())  ) 
577           cout << "Adding SDigits " << GetName() << " from " << folder->GetName() << endl ; 
578       }
579       cout << endl ;
580       cout << "Writing digits to " << GetTitle() << endl ;
581     }       
582     cout << endl ;
583     cout << "With following parameters: " << endl ;
584     cout << "     Electronics noise in EMC (fPinNoise) = " << fPinNoise << endl ;
585     cout << "  Threshold  in EMC  (fTowerDigitThreshold) = " << fTowerDigitThreshold  << endl;
586     cout << "  Threshold  in PreShower  (fPreShowerDigitThreshold) = " << fPreShowerDigitThreshold  << endl ; ;
587     cout << "---------------------------------------------------" << endl ;
588   }
589   else
590     cout << "AliEMCALDigitizer not initialized " << endl ;
591 }
592
593 //__________________________________________________________________
594 void AliEMCALDigitizer::PrintDigits(Option_t * option){
595     
596   AliEMCALGetter * gime = AliEMCALGetter::GetInstance() ; 
597   TClonesArray * fDigits = gime->Digits() ;
598
599   cout << "AliEMCALDigitiser:"<< endl ;
600   cout << "       Number of entries in Digits list " << fDigits->GetEntriesFast() << endl ;
601   cout << endl ;
602   if(strstr(option,"all")){
603     
604     //loop over digits
605     AliEMCALDigit * digit;
606     cout << "Digit Id " << " Amplitude " <<  " Index "  <<  " Nprim " << " Primaries list " <<  endl;      
607     Int_t index ;
608     for (index = 0 ; index < fDigits->GetEntries() ; index++) {
609       digit = (AliEMCALDigit * )  fDigits->At(index) ;
610       cout << setw(8)  <<  digit->GetId() << " "  <<    setw(3)  <<  digit->GetAmp() <<   "  "  
611            << setw(6)  <<  digit->GetIndexInList() << "  "   
612            << setw(5)  <<  digit->GetNprimary() <<"  ";
613       
614       Int_t iprimary;
615       for (iprimary=0; iprimary<digit->GetNprimary(); iprimary++)
616         cout << setw(5)  <<  digit->GetPrimary(iprimary+1) << " ";
617       cout << endl;      
618     }
619     
620   }
621 }
622 //_________________________________________________________________________________________
623 void AliEMCALDigitizer::WriteDigits(Int_t event)
624 {
625
626   // Makes TreeD in the output file. 
627   // Check if branch already exists: 
628   //   if yes, exit without writing: ROOT TTree does not support overwriting/updating of 
629   //      already existing branches. 
630   //   else creates branch with Digits, named "EMCAL", title "...",
631   //      and branch "AliEMCALDigitizer", with the same title to keep all the parameters
632   //      and names of files, from which digits are made.
633
634   AliEMCALGetter * gime = AliEMCALGetter::GetInstance() ; 
635   const TClonesArray * digits = gime->Digits(GetName()) ; 
636  TTree * treeD ;
637
638  if(fManager)
639    treeD = fManager->GetTreeD() ;
640  else {
641    if (!gAlice->TreeD() ) 
642      gAlice->MakeTree("D",fSplitFile);
643    treeD = gAlice->TreeD();
644  }
645  
646  // -- create Digits branch
647  Int_t bufferSize = 32000 ;    
648  TBranch * digitsBranch = treeD->Branch("EMCAL",&digits,bufferSize);
649  digitsBranch->SetTitle(GetName());
650  
651  // -- Create Digitizer branch
652  Int_t splitlevel = 0 ;
653  AliEMCALDigitizer * d = gime->Digitizer(GetName()) ;
654  TBranch * digitizerBranch = treeD->Branch("AliEMCALDigitizer", "AliEMCALDigitizer", &d,bufferSize,splitlevel); 
655  digitizerBranch->SetTitle(GetName());
656  
657  digitsBranch->Fill() ;
658  digitizerBranch->Fill() ; 
659  treeD->AutoSave() ;  
660  
661 }
662 //____________________________________________________________________________ 
663 Float_t AliEMCALDigitizer::FrontEdgeTime(TClonesArray * ticks) 
664 { // 
665   ticks->Sort() ; //Sort in accordance with times of ticks
666   TIter it(ticks) ;
667   AliEMCALTick * ctick = (AliEMCALTick *) it.Next() ;
668   Float_t time = ctick->CrossingTime(fTimeThreshold) ;    
669   
670   AliEMCALTick * t ;  
671   while((t=(AliEMCALTick*) it.Next())){
672     if(t->GetTime() < time)  //This tick starts before crossing
673       *ctick+=*t ;
674     else
675       return time ;
676     
677     time = ctick->CrossingTime(fTimeThreshold) ;    
678   }
679   return time ;
680 }
681 //____________________________________________________________________________ 
682 Float_t AliEMCALDigitizer::TimeOfNoise(void)
683 {  // Calculates the time signal generated by noise
684   //to be rewritten, now returns just big number
685   return 1. ;
686
687 }
688 //____________________________________________________________________________
689 void AliEMCALDigitizer::SetSDigitsBranch(const char* title)
690 {
691   // we set title (comment) of the SDigits branch in the first! header file
692   if( strcmp(GetName(), "") == 0 )
693     Init() ;
694
695   AliEMCALGetter::GetInstance()->SDigits()->SetName(title) ; 
696 }
697
698 //__________________________________________________________________
699 void AliEMCALDigitizer::SetSplitFile(const TString splitFileName)
700 {
701   // Diverts the Digits in a file separate from the hits file
702   
703   // I guess it is not going to work if we do merging
704   if (fManager) {
705     cerr << "ERROR: AliEMCALDigitizer::SetSplitFile -> Not yet available in case of merging activated " << endl ;  
706     return ; 
707   }
708
709   TDirectory * cwd = gDirectory ;
710   if ( !(gAlice->GetTreeDFileName() == splitFileName) ) {
711     if (gAlice->GetTreeDFile() )  
712       gAlice->GetTreeDFile()->Close() ; 
713   }
714
715   fSplitFile = gAlice->InitTreeFile("D",splitFileName.Data());
716   fSplitFile->cd() ; 
717   gAlice->Write(0, TObject::kOverwrite);
718   
719   TTree *treeE  = gAlice->TreeE();
720   if (!treeE) {
721     cerr << "ERROR: AliEMCALDigitizer::SetSplitFile -> No TreeE found "<<endl;
722     abort() ;
723   }      
724   
725   // copy TreeE
726   AliHeader *header = new AliHeader();
727   treeE->SetBranchAddress("Header", &header);
728   treeE->SetBranchStatus("*",1);
729   TTree *treeENew =  treeE->CloneTree();
730   treeENew->Write(0, TObject::kOverwrite);
731
732   // copy AliceGeom
733   TGeometry *AliceGeom = static_cast<TGeometry*>(cwd->Get("AliceGeom"));
734   if (!AliceGeom) {
735     cerr << "ERROR: AliEMCALDigitizer::SetSplitFile -> AliceGeom was not found in the input file "<<endl;
736     abort() ;
737   }
738   AliceGeom->Write(0, TObject::kOverwrite);
739   
740   gAlice->MakeTree("D",fSplitFile);
741   cwd->cd() ; 
742   cout << "INFO: AliEMCALDigitizer::SetSPlitMode -> Digits will be stored in " << splitFileName.Data() << endl ; 
743 }