]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PHOS/AliPHOSDigitizer.cxx
Addes script to compare Naiive, Poisson to Hits, Primaries
[u/mrichter/AliRoot.git] / PHOS / AliPHOSDigitizer.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 /* History of cvs commits:
19  *
20  * $Log$
21  * Revision 1.86  2005/07/12 20:07:35  hristov
22  * Changes needed to run simulation and reconstrruction in the same AliRoot session
23  *
24  * Revision 1.85  2005/05/28 14:19:04  schutz
25  * Compilation warnings fixed by T.P.
26  *
27  */
28
29 //_________________________________________________________________________
30 //*-- Author :  Dmitri Peressounko (SUBATECH & Kurchatov Institute) 
31 //////////////////////////////////////////////////////////////////////////////
32 // This TTask performs digitization of Summable digits (in the PHOS case it is just
33 // the sum of contributions from all primary particles into a given cell). 
34 // In addition it performs mixing of summable digits from different events.
35 // The name of the TTask is also the title of the branch that will contain 
36 // the created SDigits
37 // The title of the TTAsk is the name of the file that contains the hits from
38 // which the SDigits are created
39 //
40 // For each event two branches are created in TreeD:
41 //   "PHOS" - list of digits
42 //   "AliPHOSDigitizer" - AliPHOSDigitizer with all parameters used in digitization
43 //
44 // Note, that one can set a title for new digits branch, and repeat digitization with
45 // another set of parameters.
46 //
47 // Use case:
48 // root[0] AliPHOSDigitizer * d = new AliPHOSDigitizer() ;
49 // root[1] d->ExecuteTask()             
50 // Warning in <TDatabasePDG::TDatabasePDG>: object already instantiated
51 //                       //Digitizes SDigitis in all events found in file galice.root 
52 //
53 // root[2] AliPHOSDigitizer * d1 = new AliPHOSDigitizer("galice1.root") ;  
54 //                       // Will read sdigits from galice1.root
55 // root[3] d1->MixWith("galice2.root")       
56 // Warning in <TDatabasePDG::TDatabasePDG>: object already instantiated
57 //                       // Reads another set of sdigits from galice2.root
58 // root[3] d1->MixWith("galice3.root")       
59 //                       // Reads another set of sdigits from galice3.root
60 // root[4] d->ExecuteTask("deb timing")    
61 //                       // Reads SDigits from files galice1.root, galice2.root ....
62 //                       // mixes them and stores produced Digits in file galice1.root          
63 //                       // deb - prints number of produced digits
64 //                       // deb all - prints list of produced digits
65 //                       // timing  - prints time used for digitization
66 //
67
68 // --- ROOT system ---
69 #include "TTree.h"
70 #include "TSystem.h"
71 #include "TBenchmark.h"
72 #include "TRandom.h"
73
74 // --- Standard library ---
75
76 // --- AliRoot header files ---
77 #include "AliLog.h"
78 #include "AliRunDigitizer.h"
79 #include "AliPHOSDigit.h"
80 #include "AliPHOSGetter.h"
81 #include "AliPHOSDigitizer.h"
82 #include "AliPHOSSDigitizer.h"
83 #include "AliPHOSGeometry.h"
84 #include "AliPHOSTick.h"
85
86 ClassImp(AliPHOSDigitizer)
87
88
89 //____________________________________________________________________________ 
90   AliPHOSDigitizer::AliPHOSDigitizer():AliDigitizer("",""),
91                                        fInput(0),
92                                        fInputFileNames(0x0),
93                                        fEventNames(0x0)
94 {
95   // ctor
96   InitParameters() ; 
97   fDefaultInit = kTRUE ;
98   fManager = 0 ;                     // We work in the standalong mode
99   fEventFolderName = "" ; 
100 }
101
102 //____________________________________________________________________________ 
103 AliPHOSDigitizer::AliPHOSDigitizer(TString alirunFileName, 
104                                    TString eventFolderName):
105   AliDigitizer("PHOS"+AliConfig::Instance()->GetDigitizerTaskName(), 
106                alirunFileName), 
107   fInputFileNames(0), fEventNames(0), fEventFolderName(eventFolderName)
108 {
109   // ctor
110   InitParameters() ; 
111   Init() ;
112   fDefaultInit = kFALSE ; 
113   fManager = 0 ;                     // We work in the standalong mode
114 }
115
116 //____________________________________________________________________________ 
117 AliPHOSDigitizer::AliPHOSDigitizer(const AliPHOSDigitizer & d)
118   : AliDigitizer(d)
119 {
120   // copyy ctor 
121
122   SetName(d.GetName()) ; 
123   SetTitle(d.GetTitle()) ; 
124   fPinNoise = d.fPinNoise ; 
125   fEMCDigitThreshold = d.fEMCDigitThreshold ; 
126   fCPVNoise          = d.fCPVNoise ; 
127   fCPVDigitThreshold = d.fCPVDigitThreshold ; 
128   fTimeResolution    = d.fTimeResolution ; 
129   fTimeThreshold     = d.fTimeThreshold ; 
130   fTimeSignalLength  = d.fTimeSignalLength ; 
131   fADCchanelEmc      = d.fADCchanelEmc ; 
132   fADCpedestalEmc    = d.fADCpedestalEmc ; 
133   fNADCemc           = d.fNADCemc ;
134   fADCchanelCpv      = d.fADCchanelCpv ;
135   fADCpedestalCpv    = d.fADCpedestalCpv ;
136   fNADCcpv           = d.fNADCcpv ; 
137   fEventFolderName   = d.fEventFolderName;
138 }
139
140 //____________________________________________________________________________ 
141 AliPHOSDigitizer::AliPHOSDigitizer(AliRunDigitizer * rd):
142  AliDigitizer(rd,"PHOS"+AliConfig::Instance()->GetDigitizerTaskName()),
143  fEventFolderName(0)
144 {
145   // ctor Init() is called by RunDigitizer
146   fManager = rd ; 
147   fEventFolderName = fManager->GetInputFolderName(0) ;
148   SetTitle(dynamic_cast<AliStream*>(fManager->GetInputStream(0))->GetFileName(0));
149   InitParameters() ; 
150   fDefaultInit = kFALSE ; 
151 }
152
153 //____________________________________________________________________________ 
154   AliPHOSDigitizer::~AliPHOSDigitizer()
155 {
156   AliPHOSGetter * gime = AliPHOSGetter::Instance(GetTitle()) ;
157
158   // Clean Digitizer from the white board
159   gime->PhosLoader()->CleanDigitizer() ;
160   // dtor
161   delete [] fInputFileNames ; 
162   delete [] fEventNames ; 
163  
164 }
165
166 //____________________________________________________________________________
167 void AliPHOSDigitizer::Digitize(Int_t event) 
168
169   
170   // Makes the digitization of the collected summable digits.
171   //  It first creates the array of all PHOS modules
172   //  filled with noise (different for EMC, and CPV) and
173   //  then adds contributions from SDigits. 
174   // This design avoids scanning over the list of digits to add 
175   // contribution to new SDigits only.
176
177   AliPHOSGetter * gime = AliPHOSGetter::Instance(GetTitle()) ; 
178   Int_t ReadEvent = event ; 
179   if (fManager) 
180     ReadEvent = dynamic_cast<AliStream*>(fManager->GetInputStream(0))->GetCurrentEventNumber() ; 
181   AliInfo(Form("Adding event %d from input stream 0 %s %s", 
182                ReadEvent, GetTitle(), fEventFolderName.Data())) ; 
183   gime->Event(ReadEvent, "S") ;
184   TClonesArray * digits = gime->Digits() ; 
185   digits->Clear() ;
186
187   const AliPHOSGeometry *geom = gime->PHOSGeometry() ; 
188   //Making digits with noise, first EMC
189   Int_t nEMC = geom->GetNModules()*geom->GetNPhi()*geom->GetNZ();
190   
191   Int_t nCPV ;
192   Int_t absID ;
193   
194   nCPV = nEMC + geom->GetNumberOfCPVPadsZ() * geom->GetNumberOfCPVPadsPhi() * geom->GetNModules() ;
195   
196   digits->Expand(nCPV) ;
197
198   // get first the sdigitizer from the tasks list 
199   if ( !gime->SDigitizer() ) 
200     gime->LoadSDigitizer();
201   AliPHOSSDigitizer * sDigitizer = gime->SDigitizer(); 
202
203   if ( !sDigitizer )
204     AliFatal(Form("SDigitizer with name %s %s not found", 
205                   GetTitle(), fEventFolderName.Data() )) ; 
206
207   //take all the inputs to add together and load the SDigits
208   TObjArray * sdigArray = new TObjArray(fInput) ;
209   sdigArray->AddAt(gime->SDigits(), 0) ;
210   Int_t i ;
211   for(i = 1 ; i < fInput ; i++){
212     TString tempo(fEventNames[i]) ; 
213     tempo += i ;
214     AliPHOSGetter * gime = AliPHOSGetter::Instance(fInputFileNames[i], tempo) ;
215     if (fManager) 
216       ReadEvent = dynamic_cast<AliStream*>(fManager->GetInputStream(i))->GetCurrentEventNumber() ; 
217     AliInfo(Form("Adding event %d from input stream %d %s %s", 
218                  ReadEvent, i, fInputFileNames[i].Data(), tempo.Data())) ; 
219     gime->Event(ReadEvent,"S");
220     sdigArray->AddAt(gime->SDigits(), i) ;
221   }
222
223   //Find the first crystall with signal
224   Int_t nextSig = 200000 ; 
225   TClonesArray * sdigits ;  
226   for(i = 0 ; i < fInput ; i++){
227     sdigits = dynamic_cast<TClonesArray *>(sdigArray->At(i)) ;
228     if ( !sdigits->GetEntriesFast() )
229       continue ; 
230     Int_t curNext = dynamic_cast<AliPHOSDigit *>(sdigits->At(0))->GetId() ;
231     if(curNext < nextSig) 
232       nextSig = curNext ;
233   }
234   
235   TArrayI index(fInput) ;
236   index.Reset() ;  //Set all indexes to zero
237   
238   AliPHOSDigit * digit ;
239   AliPHOSDigit * curSDigit ;
240   
241   TClonesArray * ticks = new TClonesArray("AliPHOSTick",1000) ;
242   
243   //Put Noise contribution
244   for(absID = 1 ; absID <= nEMC ; absID++){
245     Float_t noise = gRandom->Gaus(0., fPinNoise) ; 
246     new((*digits)[absID-1]) AliPHOSDigit( -1, absID, sDigitizer->Digitize(noise), TimeOfNoise() ) ;
247     //look if we have to add signal?
248     digit = dynamic_cast<AliPHOSDigit *>(digits->At(absID-1)) ;
249     
250     if(absID==nextSig){
251       //Add SDigits from all inputs 
252       ticks->Clear() ;
253       Int_t contrib = 0 ;
254       Float_t a = digit->GetAmp() ;
255       Float_t b = TMath::Abs( a / fTimeSignalLength) ;
256       //Mark the beginning of the signal
257       new((*ticks)[contrib++]) AliPHOSTick(digit->GetTime(),0, b);  
258       //Mark the end of the ignal     
259       new((*ticks)[contrib++]) AliPHOSTick(digit->GetTime()+fTimeSignalLength, -a, -b); 
260       
261       //loop over inputs
262       for(i = 0 ; i < fInput ; i++){
263         if( dynamic_cast<TClonesArray *>(sdigArray->At(i))->GetEntriesFast() > index[i] )
264           curSDigit = dynamic_cast<AliPHOSDigit*>(dynamic_cast<TClonesArray *>(sdigArray->At(i))->At(index[i])) ;       
265         else
266           curSDigit = 0 ;
267         //May be several digits will contribute from the same input
268         while(curSDigit && curSDigit->GetId() == absID){           
269           //Shift primary to separate primaries belonging different inputs
270           Int_t primaryoffset ;
271           if(fManager)
272             primaryoffset = fManager->GetMask(i) ; 
273           else
274             primaryoffset = 10000000*i ;
275           curSDigit->ShiftPrimary(primaryoffset) ;
276           
277           a = curSDigit->GetAmp() ;
278           b = a /fTimeSignalLength ;
279           new((*ticks)[contrib++]) AliPHOSTick(curSDigit->GetTime(),0, b);  
280           new((*ticks)[contrib++]) AliPHOSTick(curSDigit->GetTime()+fTimeSignalLength, -a, -b); 
281           
282           *digit = *digit + *curSDigit ;  //add energies
283           
284           index[i]++ ;
285           if( dynamic_cast<TClonesArray *>(sdigArray->At(i))->GetEntriesFast() > index[i] )
286             curSDigit = dynamic_cast<AliPHOSDigit*>(dynamic_cast<TClonesArray *>(sdigArray->At(i))->At(index[i])) ;     
287           else
288             curSDigit = 0 ;
289         }
290       }
291       
292       //calculate and set time
293       Float_t time = FrontEdgeTime(ticks) ;
294       digit->SetTime(time) ;
295       
296       //Find next signal module
297       nextSig = 200000 ;
298       for(i = 0 ; i < fInput ; i++){
299         sdigits = dynamic_cast<TClonesArray *>(sdigArray->At(i)) ;
300         Int_t curNext = nextSig ;
301         if(sdigits->GetEntriesFast() > index[i] ){
302           curNext = dynamic_cast<AliPHOSDigit *>(sdigits->At(index[i]))->GetId() ;
303         }
304         if(curNext < nextSig) nextSig = curNext ;
305       }
306     }
307   }
308   
309   ticks->Delete() ;
310   delete ticks ;
311   
312   //Now CPV digits (different noise and no timing)
313   for(absID = nEMC+1; absID <= nCPV; absID++){
314     Float_t noise = gRandom->Gaus(0., fCPVNoise) ; 
315     new((*digits)[absID-1]) AliPHOSDigit( -1,absID,sDigitizer->Digitize(noise), TimeOfNoise() ) ;
316     //look if we have to add signal?
317     if(absID==nextSig){
318       digit = dynamic_cast<AliPHOSDigit *>(digits->At(absID-1)) ;
319       //Add SDigits from all inputs
320       for(i = 0 ; i < fInput ; i++){
321         if( dynamic_cast<TClonesArray *>(sdigArray->At(i))->GetEntriesFast() > index[i] )
322           curSDigit = dynamic_cast<AliPHOSDigit*>( dynamic_cast<TClonesArray *>(sdigArray->At(i))->At(index[i])) ;      
323         else
324           curSDigit = 0 ;
325
326         //May be several digits will contribute from the same input
327         while(curSDigit && curSDigit->GetId() == absID){           
328           //Shift primary to separate primaries belonging different inputs
329           Int_t primaryoffset ;
330           if(fManager)
331             primaryoffset = fManager->GetMask(i) ; 
332           else
333             primaryoffset = 10000000*i ;
334           curSDigit->ShiftPrimary(primaryoffset) ;
335
336           //add energies
337           *digit = *digit + *curSDigit ;  
338           index[i]++ ;
339           if( dynamic_cast<TClonesArray *>(sdigArray->At(i))->GetEntriesFast() > index[i] )
340             curSDigit = dynamic_cast<AliPHOSDigit*>( dynamic_cast<TClonesArray *>(sdigArray->At(i))->At(index[i]) ) ;   
341           else
342             curSDigit = 0 ;
343         }
344       }
345
346       //Find next signal module
347       nextSig = 200000 ;
348       for(i = 0 ; i < fInput ; i++){
349         sdigits = dynamic_cast<TClonesArray *>(sdigArray->At(i)) ;
350         Int_t curNext = nextSig ;
351         if(sdigits->GetEntriesFast() > index[i] )
352           curNext = dynamic_cast<AliPHOSDigit *>( sdigits->At(index[i]) )->GetId() ;
353         if(curNext < nextSig) nextSig = curNext ;
354       }
355       
356     }
357   }
358
359   delete sdigArray ; //We should not delete its contents 
360   
361   //remove digits below thresholds
362   for(i = 0 ; i < nEMC ; i++){
363     digit = dynamic_cast<AliPHOSDigit*>( digits->At(i) ) ;
364     if(sDigitizer->Calibrate( digit->GetAmp() ) < fEMCDigitThreshold)
365       digits->RemoveAt(i) ;
366     else
367       digit->SetTime(gRandom->Gaus(digit->GetTime(),fTimeResolution) ) ;
368   }
369
370
371   for(i = nEMC; i < nCPV ; i++)
372     if( sDigitizer->Calibrate( dynamic_cast<AliPHOSDigit*>(digits->At(i))->GetAmp() ) < fCPVDigitThreshold )
373       digits->RemoveAt(i) ;
374     
375   digits->Compress() ;  
376   
377   Int_t ndigits = digits->GetEntriesFast() ;
378   digits->Expand(ndigits) ;
379
380   //Set indexes in list of digits and make true digitization of the energy
381   for (i = 0 ; i < ndigits ; i++) { 
382     digit = dynamic_cast<AliPHOSDigit*>( digits->At(i) ) ; 
383     digit->SetIndexInList(i) ;     
384     Float_t energy = sDigitizer->Calibrate(digit->GetAmp()) ;
385     digit->SetAmp(DigitizeEnergy(energy,digit->GetId()) ) ;
386   }
387 }
388
389 //____________________________________________________________________________
390 Int_t AliPHOSDigitizer::DigitizeEnergy(Float_t energy, Int_t absId)
391 {
392   // Returns digitized value of the energy in a cell absId
393
394   AliPHOSGetter* gime = AliPHOSGetter::Instance();
395
396   //Determine rel.position of the cell absId
397   Int_t relId[4];
398   gime->PHOSGeometry()->AbsToRelNumbering(absId,relId);
399   Int_t module=relId[0];
400   Int_t raw=relId[2];
401   Int_t column=relId[3];
402   
403   Int_t chanel ;
404   
405   if(absId <= fEmcCrystals){ //digitize as EMC 
406
407     //reading calibration data for cell absId.
408     //If no calibration DB found, accept default values.
409
410     if(gime->CalibData()) {
411       fADCpedestalEmc = gime->CalibData()->GetADCpedestalEmc(module,column,raw);
412       fADCchanelEmc = gime->CalibData()->GetADCchannelEmc(module,column,raw);
413     }
414 //         printf("\t\tabsId %d ==>>module=%d column=%d raw=%d ped=%.4f gain=%.4f\n",
415 //         absId,module,column,raw,fADCpedestalEmc,fADCchanelEmc);
416
417     chanel = (Int_t) TMath::Ceil((energy - fADCpedestalEmc)/fADCchanelEmc) ;       
418     if(chanel > fNADCemc ) chanel =  fNADCemc ;
419   }
420   else{ //Digitize as CPV
421     chanel = (Int_t) TMath::Ceil((energy - fADCpedestalCpv)/fADCchanelCpv) ;       
422     if(chanel > fNADCcpv ) chanel =  fNADCcpv ;
423   }
424   return chanel ;
425 }
426
427 //____________________________________________________________________________
428 void AliPHOSDigitizer::Exec(Option_t *option) 
429
430   // Steering method to process digitization for events
431   // in the range from fFirstEvent to fLastEvent.
432   // This range is optionally set by SetEventRange().
433   // if fLastEvent=-1, then process events until the end.
434   // by default fLastEvent = fFirstEvent (process only one event)
435
436   if (!fInit) { // to prevent overwrite existing file
437     AliError(Form("Give a version name different from %s", 
438                   fEventFolderName.Data() )) ;
439     return ;
440   }   
441
442   if (strstr(option,"print")) {
443     Print();
444     return ; 
445   }
446   
447   if(strstr(option,"tim"))
448     gBenchmark->Start("PHOSDigitizer");
449   
450   AliPHOSGetter * gime = AliPHOSGetter::Instance(GetTitle()) ;
451
452   // Post Digitizer to the white board
453   gime->PostDigitizer(this) ;
454   
455   if (fLastEvent == -1) 
456     fLastEvent = gime->MaxEvent() - 1 ;
457   else if (fManager) 
458     fLastEvent = fFirstEvent ; 
459  
460   Int_t nEvents   = fLastEvent - fFirstEvent + 1;
461   
462   Int_t ievent ;
463
464   for (ievent = fFirstEvent; ievent <= fLastEvent; ievent++) {
465  
466     gime->Event(ievent,"S") ;
467
468     Digitize(ievent) ; //Add prepared SDigits to digits and add the noise
469
470     WriteDigits() ;
471
472     if(strstr(option,"deb"))
473       PrintDigits(option);
474     
475     //increment the total number of Digits per run 
476     fDigitsInRun += gime->Digits()->GetEntriesFast() ;  
477  }
478   
479   gime->PhosLoader()->CleanDigitizer();
480
481   if(strstr(option,"tim")){
482     gBenchmark->Stop("PHOSDigitizer");
483     TString message ; 
484     message = "  took %f seconds for Digitizing %f seconds per event\n" ; 
485     AliInfo(Form( message.Data(), 
486          gBenchmark->GetCpuTime("PHOSDigitizer"), 
487          gBenchmark->GetCpuTime("PHOSDigitizer")/nEvents )); 
488   } 
489 }
490
491 //____________________________________________________________________________ 
492 Float_t AliPHOSDigitizer::FrontEdgeTime(TClonesArray * ticks) const
493 {
494   // Returns the shortest time among all time ticks
495
496   ticks->Sort() ; //Sort in accordance with times of ticks
497   TIter it(ticks) ;
498   AliPHOSTick * ctick = (AliPHOSTick *) it.Next() ;
499   Float_t time = ctick->CrossingTime(fTimeThreshold) ;    
500
501   AliPHOSTick * t ;  
502   while((t=(AliPHOSTick*) it.Next())){
503     if(t->GetTime() < time)  //This tick starts before crossing
504       *ctick+=*t ;
505     else
506       return time ;
507
508     time = ctick->CrossingTime(fTimeThreshold) ;    
509   }
510   return time ;
511 }
512
513 //____________________________________________________________________________ 
514 Bool_t AliPHOSDigitizer::Init()
515 {
516   // Makes all memory allocations
517   fInit = kTRUE ; 
518   AliPHOSGetter * gime = AliPHOSGetter::Instance(GetTitle(), fEventFolderName) ; 
519   if ( gime == 0 ) {
520     AliFatal(Form("Could not obtain the Getter object for file %s and event %s !", 
521                   GetTitle(), fEventFolderName.Data()));  
522     return kFALSE;
523   } 
524   
525   const AliPHOSGeometry * geom = gime->PHOSGeometry() ;
526
527   fEmcCrystals = geom->GetNModules() * geom->GetNCristalsInModule() ;
528   
529   TString opt("Digits") ; 
530   if(gime->VersionExists(opt) ) { 
531     AliError(Form("Give a version name different from %s", 
532                   fEventFolderName.Data() )) ;
533     fInit = kFALSE ; 
534   }
535
536   fFirstEvent = 0 ; 
537   fLastEvent = fFirstEvent ; 
538   if (fManager) 
539     fInput = fManager->GetNinputs() ; 
540   else 
541     fInput           = 1 ;
542   
543   fInputFileNames  = new TString[fInput] ; 
544   fEventNames      = new TString[fInput] ; 
545   fInputFileNames[0] = GetTitle() ; 
546   fEventNames[0]     = fEventFolderName.Data() ; 
547   Int_t index ; 
548   for (index = 1 ; index < fInput ; index++) {
549     fInputFileNames[index] = dynamic_cast<AliStream*>(fManager->GetInputStream(index))->GetFileName(0); 
550     TString tempo = fManager->GetInputFolderName(index) ;
551     fEventNames[index] = tempo.Remove(tempo.Length()-1) ; // strip of the stream number added by fManager
552   }
553
554   //to prevent cleaning of this object while GetEvent is called
555   gime->PhosLoader()->GetDigitsDataLoader()->GetBaseTaskLoader()->SetDoNotReload(kTRUE);
556
557   return fInit ; 
558 }
559
560 //____________________________________________________________________________ 
561 void AliPHOSDigitizer::InitParameters()
562 {
563   // Set initial parameters Digitizer
564
565   fPinNoise           = 0.004 ;
566   fEMCDigitThreshold  = 0.012 ;
567   fCPVNoise           = 0.01;
568   fCPVDigitThreshold  = 0.09 ;
569   fTimeResolution     = 0.5e-9 ;
570   fTimeSignalLength   = 1.0e-9 ;
571   fDigitsInRun  = 0 ; 
572   fADCchanelEmc = 0.0015;        // width of one ADC channel in GeV
573   fADCpedestalEmc = 0.005 ;      //
574   fNADCemc = (Int_t) TMath::Power(2,16) ;  // number of channels in EMC ADC
575
576   fADCchanelCpv = 0.0012 ;          // width of one ADC channel in CPV 'popugais'
577   fADCpedestalCpv = 0.012 ;         // 
578   fNADCcpv = (Int_t) TMath::Power(2,12);      // number of channels in CPV ADC
579
580   fTimeThreshold = 0.001*10000000 ; //Means 1 MeV in terms of SDigits amplitude
581   SetEventRange(0,-1) ;
582     
583 }
584
585 //__________________________________________________________________
586 void AliPHOSDigitizer::MixWith(TString alirunFileName, TString eventFolderName)
587 {
588   // Allows to produce digits by superimposing background and signal event.
589   // It is assumed, that headers file with SIGNAL events is opened in 
590   // the constructor. 
591   // Sets the BACKGROUND event, with which the SIGNAL event is to be mixed 
592   // Thus we avoid writing (changing) huge and expensive 
593   // backgound files: all output will be writen into SIGNAL, i.e. 
594   // opened in constructor file. 
595   //
596   // One can open as many files to mix with as one needs.
597   // However only Sdigits with the same name (i.e. constructed with the same SDigitizer)
598   // can be mixed.
599
600   if( strcmp(fEventFolderName, "") == 0 )
601     Init() ;
602
603   if(fManager){
604     Warning("MixWith", "Cannot use this method with AliRunDigitizer\n" ) ;
605     return ;
606   }
607   // looking for file which contains AliRun
608   if (gSystem->AccessPathName(alirunFileName)) {// file does not exist
609     AliError(Form("File %s does not exist!", alirunFileName.Data())) ;
610     return ; 
611   }
612   // looking for the file which contains SDigits
613   AliPHOSGetter * gime = AliPHOSGetter::Instance() ; 
614   TString fileName( gime->GetSDigitsFileName() ) ; 
615     if ( eventFolderName != AliConfig::GetDefaultEventFolderName()) // only if not the default folder name 
616       fileName = fileName.ReplaceAll(".root", "") + "_" + eventFolderName + ".root" ;
617     if ( (gSystem->AccessPathName(fileName)) ) { 
618       AliError(Form("The file %s does not exist!", fileName.Data())) ;
619       return ;
620     }
621     // need to increase the arrays
622     TString tempo = fInputFileNames[fInput-1] ; 
623     delete [] fInputFileNames ; 
624     fInputFileNames = new TString[fInput+1] ; 
625     fInputFileNames[fInput-1] = tempo ; 
626  
627     tempo = fEventNames[fInput-1] ; 
628     delete [] fEventNames ; 
629     fEventNames = new TString[fInput+1] ; 
630     fEventNames[fInput-1] = tempo ; 
631
632     fInputFileNames[fInput] = alirunFileName ; 
633     fEventNames[fInput]     = eventFolderName ;
634     fInput++ ;
635 }
636
637 //__________________________________________________________________
638 void AliPHOSDigitizer::Print(const Option_t *)const 
639 {
640   // Print Digitizer's parameters
641   AliInfo(Form("\n------------------- %s -------------", GetName() )) ; 
642   if( strcmp(fEventFolderName.Data(), "") != 0 ){
643     printf(" Writing Digits to branch with title  %s\n", fEventFolderName.Data()) ;
644     
645     Int_t nStreams ; 
646     if (fManager) 
647       nStreams =  GetNInputStreams() ;
648     else 
649       nStreams = fInput ; 
650     
651     Int_t index = 0 ;  
652     for (index = 0 ; index < nStreams ; index++) {  
653       TString tempo(fEventNames[index]) ; 
654       tempo += index ;
655       AliPHOSGetter * gime = AliPHOSGetter::Instance(fInputFileNames[index], tempo) ; 
656       TString fileName( gime->GetSDigitsFileName() ) ; 
657       if ( fEventNames[index] != AliConfig::GetDefaultEventFolderName()) // only if not the default folder name 
658         fileName = fileName.ReplaceAll(".root", "") + "_" + fEventNames[index]  + ".root" ;
659       printf ("Adding SDigits from %s %s\n", fInputFileNames[index].Data(), fileName.Data()) ; 
660     }
661     AliPHOSGetter * gime = AliPHOSGetter::Instance(GetTitle(), fEventFolderName) ; 
662     printf("\nWriting digits to %s", gime->GetDigitsFileName().Data()) ;
663     
664     printf("\nWith following parameters:\n") ;
665     printf("  Electronics noise in EMC (fPinNoise) = %f\n", fPinNoise ) ; 
666     printf("  Threshold  in EMC  (fEMCDigitThreshold) = %f\n", fEMCDigitThreshold ) ;  
667     printf("  Noise in CPV (fCPVNoise) = %f\n", fCPVNoise ) ; 
668     printf("  Threshold in CPV (fCPVDigitThreshold) = %f\n",fCPVDigitThreshold ) ;  
669     printf(" ---------------------------------------------------\n") ;   
670   }
671   else
672     AliInfo(Form("AliPHOSDigitizer not initialized" )) ;
673   
674 }
675
676 //__________________________________________________________________
677  void AliPHOSDigitizer::PrintDigits(Option_t * option)
678 {
679   // Print a table of digits
680   
681   AliPHOSGetter * gime = AliPHOSGetter::Instance(GetTitle(), fEventFolderName) ; 
682   TClonesArray * digits = gime->Digits() ; 
683   
684   AliInfo(Form("%d", digits->GetEntriesFast())) ; 
685   printf("\nevent %d", gAlice->GetEvNumber()) ;
686   printf("\n       Number of entries in Digits list %d", digits->GetEntriesFast() )  ;  
687
688  
689   if(strstr(option,"all")||strstr(option,"EMC")){  
690     //loop over digits
691     AliPHOSDigit * digit;
692     printf("\nEMC digits (with primaries):\n")  ;
693     printf("\n   Id  Amplitude    Time          Index Nprim: Primaries list \n") ;    
694     Int_t maxEmc = gime->PHOSGeometry()->GetNModules()*gime->PHOSGeometry()->GetNCristalsInModule() ;
695     Int_t index ;
696     for (index = 0 ; (index < digits->GetEntriesFast()) && 
697            (dynamic_cast<AliPHOSDigit *>(digits->At(index))->GetId() <= maxEmc) ; index++) {
698       digit = (AliPHOSDigit * )  digits->At(index) ;
699       if(digit->GetNprimary() == 0) 
700         continue;
701       printf("%6d  %8d    %6.5e %4d      %2d :",
702               digit->GetId(), digit->GetAmp(), digit->GetTime(), digit->GetIndexInList(), digit->GetNprimary()) ;  
703       Int_t iprimary;
704       for (iprimary=0; iprimary<digit->GetNprimary(); iprimary++) {
705         printf("%d ",digit->GetPrimary(iprimary+1) ) ; 
706       }    
707       printf("\n") ;
708     }
709   }
710   
711   if(strstr(option,"all")||strstr(option,"CPV")){
712     
713     //loop over CPV digits
714     AliPHOSDigit * digit;
715     printf("\nCPV digits (with primaries):\n")  ;
716     printf("\n   Id  Amplitude    Time          Index Nprim: Primaries list \n") ;    
717     Int_t maxEmc = gime->PHOSGeometry()->GetNModules()*gime->PHOSGeometry()->GetNCristalsInModule() ;
718     Int_t index ;
719     for (index = 0 ; index < digits->GetEntriesFast(); index++) {
720       digit = (AliPHOSDigit * )  digits->At(index) ;
721       if(digit->GetId() > maxEmc){
722         printf("%6d  %8d    %4d      %2d :",
723                 digit->GetId(), digit->GetAmp(), digit->GetIndexInList(), digit->GetNprimary()) ;  
724         Int_t iprimary;
725         for (iprimary=0; iprimary<digit->GetNprimary(); iprimary++) {
726           printf("%d ",digit->GetPrimary(iprimary+1) ) ; 
727         }    
728         printf("\n") ;
729       }
730     }
731   }
732
733 }
734
735 //__________________________________________________________________
736 Float_t AliPHOSDigitizer::TimeOfNoise(void) const
737 {  // Calculates the time signal generated by noise
738   //PH  Info("TimeOfNoise", "Change me") ; 
739   return gRandom->Rndm() * 1.28E-5;
740 }
741
742 //__________________________________________________________________
743 void AliPHOSDigitizer::Unload() 
744 {  
745   
746   Int_t i ; 
747   for(i = 1 ; i < fInput ; i++){
748     TString tempo(fEventNames[i]) ; 
749     tempo += i ;
750     AliPHOSGetter * gime = AliPHOSGetter::Instance(fInputFileNames[i], tempo) ; 
751     gime->PhosLoader()->UnloadSDigits() ; 
752   }
753   
754   AliPHOSGetter * gime = AliPHOSGetter::Instance(GetTitle(), fEventFolderName) ; 
755   gime->PhosLoader()->UnloadDigits() ; 
756 }
757
758 //____________________________________________________________________________
759 void AliPHOSDigitizer::WriteDigits()
760 {
761
762   // Makes TreeD in the output file. 
763   // Check if branch already exists: 
764   //   if yes, exit without writing: ROOT TTree does not support overwriting/updating of 
765   //      already existing branches. 
766   //   else creates branch with Digits, named "PHOS", title "...",
767   //      and branch "AliPHOSDigitizer", with the same title to keep all the parameters
768   //      and names of files, from which digits are made.
769
770   AliPHOSGetter * gime = AliPHOSGetter::Instance(GetTitle()) ; 
771   const TClonesArray * digits = gime->Digits() ; 
772   TTree * treeD = gime->TreeD();
773
774   // -- create Digits branch
775   Int_t bufferSize = 32000 ;    
776   TBranch * digitsBranch = treeD->Branch("PHOS","TClonesArray",&digits,bufferSize);
777   digitsBranch->SetTitle(fEventFolderName);
778   digitsBranch->Fill() ;
779   
780   gime->WriteDigits("OVERWRITE");
781   gime->WriteDigitizer("OVERWRITE");
782
783   Unload() ; 
784
785 }