]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PHOS/AliPHOSDigitizer.cxx
Memory leaks fixed
[u/mrichter/AliRoot.git] / PHOS / AliPHOSDigitizer.cxx
CommitLineData
990119d6 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
702ab87e 18/* History of cvs commits:
19 *
20 * $Log$
5b188f2f 21 * Revision 1.98 2007/09/26 14:22:17 cvetan
22 * Important changes to the reconstructor classes. Complete elimination of the run-loaders, which are now steered only from AliReconstruction. Removal of the corresponding Reconstruct() and FillESD() methods.
23 *
d76c31f4 24 * Revision 1.97 2007/08/07 14:12:03 kharlov
25 * Quality assurance added (Yves Schutz)
26 *
ddd1a39c 27 * Revision 1.96 2007/04/28 10:43:36 policheh
28 * Dead channels simulation: digit energy sets to 0.
29 *
1c6a163f 30 * Revision 1.95 2007/04/10 07:20:52 kharlov
31 * Decalibration should use the same CDB as calibration in AliPHOSClusterizerv1
32 *
1a197b77 33 * Revision 1.94 2007/02/01 10:34:47 hristov
34 * Removing warnings on Solaris x86
35 *
ad4aeaf4 36 * Revision 1.93 2006/10/17 13:17:01 kharlov
37 * Replace AliInfo by AliDebug
38 *
d6e8d7d3 39 * Revision 1.92 2006/08/28 10:01:56 kharlov
40 * Effective C++ warnings fixed (Timur Pocheptsov)
41 *
3663622c 42 * Revision 1.91 2006/04/29 20:25:30 hristov
43 * Decalibration is implemented (Yu.Kharlov)
44 *
877695e7 45 * Revision 1.90 2006/04/22 10:30:17 hristov
46 * Add fEnergy to AliPHOSDigit and operate with EMC amplitude in energy units (Yu.Kharlov)
47 *
27a73a5d 48 * Revision 1.89 2006/04/11 15:22:59 hristov
49 * run number in query set to -1: forces AliCDBManager to use its run number (A.Colla)
50 *
28871337 51 * Revision 1.88 2006/03/13 14:05:43 kharlov
52 * Calibration objects for EMC and CPV
53 *
fc6706cb 54 * Revision 1.87 2005/08/24 15:33:49 kharlov
55 * Calibration data for raw digits
56 *
a8ec0771 57 * Revision 1.86 2005/07/12 20:07:35 hristov
58 * Changes needed to run simulation and reconstrruction in the same AliRoot session
59 *
7c193632 60 * Revision 1.85 2005/05/28 14:19:04 schutz
61 * Compilation warnings fixed by T.P.
62 *
702ab87e 63 */
88cb7938 64
990119d6 65//_________________________________________________________________________
990119d6 66//*-- Author : Dmitri Peressounko (SUBATECH & Kurchatov Institute)
67//////////////////////////////////////////////////////////////////////////////
a4e98857 68// This TTask performs digitization of Summable digits (in the PHOS case it is just
69// the sum of contributions from all primary particles into a given cell).
990119d6 70// In addition it performs mixing of summable digits from different events.
7b7c1533 71// The name of the TTask is also the title of the branch that will contain
72// the created SDigits
73// The title of the TTAsk is the name of the file that contains the hits from
74// which the SDigits are created
bca3b32a 75//
76// For each event two branches are created in TreeD:
77// "PHOS" - list of digits
78// "AliPHOSDigitizer" - AliPHOSDigitizer with all parameters used in digitization
79//
a4e98857 80// Note, that one can set a title for new digits branch, and repeat digitization with
bca3b32a 81// another set of parameters.
82//
a4e98857 83// Use case:
990119d6 84// root[0] AliPHOSDigitizer * d = new AliPHOSDigitizer() ;
85// root[1] d->ExecuteTask()
86// Warning in <TDatabasePDG::TDatabasePDG>: object already instantiated
87// //Digitizes SDigitis in all events found in file galice.root
bca3b32a 88//
8cb3533f 89// root[2] AliPHOSDigitizer * d1 = new AliPHOSDigitizer("galice1.root") ;
90// // Will read sdigits from galice1.root
91// root[3] d1->MixWith("galice2.root")
990119d6 92// Warning in <TDatabasePDG::TDatabasePDG>: object already instantiated
a4e98857 93// // Reads another set of sdigits from galice2.root
8cb3533f 94// root[3] d1->MixWith("galice3.root")
a4e98857 95// // Reads another set of sdigits from galice3.root
8cb3533f 96// root[4] d->ExecuteTask("deb timing")
97// // Reads SDigits from files galice1.root, galice2.root ....
98// // mixes them and stores produced Digits in file galice1.root
99// // deb - prints number of produced digits
100// // deb all - prints list of produced digits
101// // timing - prints time used for digitization
990119d6 102//
990119d6 103
104// --- ROOT system ---
990119d6 105#include "TTree.h"
106#include "TSystem.h"
8cb3533f 107#include "TBenchmark.h"
e957fea8 108#include "TRandom.h"
ba54256b 109
990119d6 110// --- Standard library ---
111
112// --- AliRoot header files ---
351dd634 113#include "AliLog.h"
3f81a70b 114#include "AliRunDigitizer.h"
990119d6 115#include "AliPHOSDigit.h"
7b7c1533 116#include "AliPHOSGetter.h"
990119d6 117#include "AliPHOSDigitizer.h"
118#include "AliPHOSSDigitizer.h"
8cb3533f 119#include "AliPHOSGeometry.h"
7437a0f7 120#include "AliPHOSTick.h"
ddd1a39c 121#include "AliPHOSQualAssDataMaker.h"
990119d6 122
123ClassImp(AliPHOSDigitizer)
124
125
126//____________________________________________________________________________
3663622c 127AliPHOSDigitizer::AliPHOSDigitizer() :
128 AliDigitizer("",""),
129 fDefaultInit(kTRUE),
130 fDigitsInRun(0),
131 fInit(kFALSE),
132 fInput(0),
133 fInputFileNames(0x0),
134 fEventNames(0x0),
135 fEmcCrystals(0),
136 fPinNoise(0.f),
137 fEMCDigitThreshold(0.f),
138 fCPVNoise(0.f),
139 fCPVDigitThreshold(0.f),
140 fTimeResolution(0.f),
141 fTimeThreshold(0.f),
142 fTimeSignalLength(0.f),
143 fADCchanelEmc(0.f),
144 fADCpedestalEmc(0.f),
145 fNADCemc(0),
146 fADCchanelCpv(0.f),
147 fADCpedestalCpv(0.f),
148 fNADCcpv(0),
149 fEventFolderName(""),
150 fFirstEvent(0),
ddd1a39c 151 fLastEvent(0),
152 fQADM (0x0),
153 fEventCounter(0)
990119d6 154{
155 // ctor
8d0f3f77 156 InitParameters() ;
fbf811ec 157 fManager = 0 ; // We work in the standalong mode
88cb7938 158}
3f81a70b 159
160//____________________________________________________________________________
e191bb57 161AliPHOSDigitizer::AliPHOSDigitizer(TString alirunFileName,
162 TString eventFolderName):
3663622c 163 AliDigitizer("PHOS"+AliConfig::Instance()->GetDigitizerTaskName(), alirunFileName),
164 fDefaultInit(kFALSE),
165 fDigitsInRun(0),
166 fInit(kFALSE),
167 fInput(0),
168 fInputFileNames(0x0),
169 fEventNames(0x0),
170 fEmcCrystals(0),
171 fPinNoise(0.f),
172 fEMCDigitThreshold(0.f),
173 fCPVNoise(0.f),
174 fCPVDigitThreshold(0.f),
175 fTimeResolution(0.f),
176 fTimeThreshold(0.f),
177 fTimeSignalLength(0.f),
178 fADCchanelEmc(0.f),
179 fADCpedestalEmc(0.f),
180 fNADCemc(0),
181 fADCchanelCpv(0.f),
182 fADCpedestalCpv(0.f),
183 fNADCcpv(0),
184 fEventFolderName(eventFolderName),
185 fFirstEvent(0),
ddd1a39c 186 fLastEvent(0),
187 fQADM (0x0),
188 fEventCounter(0)
3f81a70b 189{
190 // ctor
8d0f3f77 191 InitParameters() ;
3f81a70b 192 Init() ;
92f521a9 193 fDefaultInit = kFALSE ;
88cb7938 194 fManager = 0 ; // We work in the standalong mode
ddd1a39c 195 //Initialize the quality assurance data maker only once
196 fQADM = new AliPHOSQualAssDataMaker() ;
5b188f2f 197 //FIXME: get the run number
198 Int_t run = 0 ;
199 //EMXIF
200 GetQualAssDataMaker()->Init(AliQualAss::kDIGITS, run, fgkCycles) ;
201 GetQualAssDataMaker()->StartOfCycle(AliQualAss::kDIGITS) ;
88cb7938 202}
203
204//____________________________________________________________________________
3663622c 205AliPHOSDigitizer::AliPHOSDigitizer(const AliPHOSDigitizer & d) :
206 AliDigitizer(d),
207 fDefaultInit(d.fDefaultInit),
208 fDigitsInRun(d.fDigitsInRun),
209 fInit(d.fInit),
210 fInput(d.fInput),
211 fInputFileNames(0x0),//?
212 fEventNames(0x0),//?
213 fEmcCrystals(d.fEmcCrystals),
214 fPinNoise(d.fPinNoise),
215 fEMCDigitThreshold(d.fEMCDigitThreshold),
216 fCPVNoise(d.fCPVNoise),
217 fCPVDigitThreshold(d.fCPVDigitThreshold),
218 fTimeResolution(d.fTimeResolution),
219 fTimeThreshold(d.fTimeThreshold),
220 fTimeSignalLength(d.fTimeSignalLength),
221 fADCchanelEmc(d.fADCchanelEmc),
222 fADCpedestalEmc(d.fADCpedestalEmc),
223 fNADCemc(d.fNADCemc),
224 fADCchanelCpv(d.fADCchanelCpv),
225 fADCpedestalCpv(d.fADCpedestalCpv),
226 fNADCcpv(d.fNADCcpv),
227 fEventFolderName(d.fEventFolderName),
228 fFirstEvent(d.fFirstEvent),
ddd1a39c 229 fLastEvent(d.fLastEvent),
230 fQADM (d.fQADM),
231 fEventCounter(0)
232
88cb7938 233{
234 // copyy ctor
88cb7938 235 SetName(d.GetName()) ;
236 SetTitle(d.GetTitle()) ;
ddd1a39c 237//Initialize the quality assurance data maker only once
5b188f2f 238 //FIXME: get the run number
239 Int_t run = 0 ;
240 //EMXIF
241 GetQualAssDataMaker()->Init(AliQualAss::kDIGITS, run, fgkCycles) ;
242 GetQualAssDataMaker()->StartOfCycle(AliQualAss::kDIGITS) ;
990119d6 243}
244
990119d6 245//____________________________________________________________________________
3663622c 246AliPHOSDigitizer::AliPHOSDigitizer(AliRunDigitizer * rd) :
247 AliDigitizer(rd,"PHOS"+AliConfig::Instance()->GetDigitizerTaskName()),
248 fDefaultInit(kFALSE),
249 fDigitsInRun(0),
250 fInit(kFALSE),
251 fInput(0),
252 fInputFileNames(0x0),
253 fEventNames(0x0),
254 fEmcCrystals(0),
255 fPinNoise(0.f),
256 fEMCDigitThreshold(0.f),
257 fCPVNoise(0.f),
258 fCPVDigitThreshold(0.f),
259 fTimeResolution(0.f),
260 fTimeThreshold(0.f),
261 fTimeSignalLength(0.f),
262 fADCchanelEmc(0.f),
263 fADCpedestalEmc(0.f),
264 fNADCemc(0),
265 fADCchanelCpv(0.f),
266 fADCpedestalCpv(0.f),
267 fNADCcpv(0),
268 fEventFolderName(fManager->GetInputFolderName(0)),
269 fFirstEvent(0),
ddd1a39c 270 fLastEvent(0),
271 fQADM (0x0),
272 fEventCounter(0)
273
990119d6 274{
45fa49ca 275 // ctor Init() is called by RunDigitizer
88cb7938 276 fManager = rd ;
88cb7938 277 SetTitle(dynamic_cast<AliStream*>(fManager->GetInputStream(0))->GetFileName(0));
b22e4735 278 InitParameters() ;
fbf811ec 279 fDefaultInit = kFALSE ;
ddd1a39c 280//Initialize the quality assurance data maker only once
281 fQADM = new AliPHOSQualAssDataMaker() ;
5b188f2f 282 //FIXME: get the run number
283 Int_t run = 0 ;
284 //EMXIF
285 GetQualAssDataMaker()->Init(AliQualAss::kDIGITS, run) ;
286 GetQualAssDataMaker()->StartOfCycle(AliQualAss::kDIGITS) ;
990119d6 287}
288
289//____________________________________________________________________________
290 AliPHOSDigitizer::~AliPHOSDigitizer()
291{
7c193632 292 AliPHOSGetter * gime = AliPHOSGetter::Instance(GetTitle()) ;
293
294 // Clean Digitizer from the white board
295 gime->PhosLoader()->CleanDigitizer() ;
990119d6 296 // dtor
88cb7938 297 delete [] fInputFileNames ;
298 delete [] fEventNames ;
ddd1a39c 299
300 delete fQADM ;
301
990119d6 302}
303
304//____________________________________________________________________________
fc7e2f43 305void AliPHOSDigitizer::Digitize(Int_t event)
a4e98857 306{
307
308 // Makes the digitization of the collected summable digits.
309 // It first creates the array of all PHOS modules
dc986a1d 310 // filled with noise (different for EMC, and CPV) and
a4e98857 311 // then adds contributions from SDigits.
312 // This design avoids scanning over the list of digits to add
313 // contribution to new SDigits only.
990119d6 314
f98c06a1 315 AliPHOSGetter * gime = AliPHOSGetter::Instance(GetTitle()) ;
45fa49ca 316 Int_t ReadEvent = event ;
317 if (fManager)
318 ReadEvent = dynamic_cast<AliStream*>(fManager->GetInputStream(0))->GetCurrentEventNumber() ;
d6e8d7d3 319 AliDebug(1,Form("Adding event %d from input stream 0 %s %s",
320 ReadEvent, GetTitle(), fEventFolderName.Data())) ;
45fa49ca 321 gime->Event(ReadEvent, "S") ;
88cb7938 322 TClonesArray * digits = gime->Digits() ;
7b7c1533 323 digits->Clear() ;
990119d6 324
7b7c1533 325 const AliPHOSGeometry *geom = gime->PHOSGeometry() ;
990119d6 326 //Making digits with noise, first EMC
327 Int_t nEMC = geom->GetNModules()*geom->GetNPhi()*geom->GetNZ();
328
329 Int_t nCPV ;
990119d6 330 Int_t absID ;
990119d6 331
88cb7938 332 nCPV = nEMC + geom->GetNumberOfCPVPadsZ() * geom->GetNumberOfCPVPadsPhi() * geom->GetNModules() ;
333
9688c1dd 334 digits->Expand(nCPV) ;
8cb3533f 335
88cb7938 336 // get first the sdigitizer from the tasks list
337 if ( !gime->SDigitizer() )
338 gime->LoadSDigitizer();
339 AliPHOSSDigitizer * sDigitizer = gime->SDigitizer();
340
341 if ( !sDigitizer )
351dd634 342 AliFatal(Form("SDigitizer with name %s %s not found",
343 GetTitle(), fEventFolderName.Data() )) ;
88cb7938 344
345 //take all the inputs to add together and load the SDigits
346 TObjArray * sdigArray = new TObjArray(fInput) ;
347 sdigArray->AddAt(gime->SDigits(), 0) ;
348 Int_t i ;
349 for(i = 1 ; i < fInput ; i++){
350 TString tempo(fEventNames[i]) ;
351 tempo += i ;
ad4aeaf4 352 AliPHOSGetter * gime1 = AliPHOSGetter::Instance(fInputFileNames[i], tempo) ;
45fa49ca 353 if (fManager)
354 ReadEvent = dynamic_cast<AliStream*>(fManager->GetInputStream(i))->GetCurrentEventNumber() ;
351dd634 355 AliInfo(Form("Adding event %d from input stream %d %s %s",
356 ReadEvent, i, fInputFileNames[i].Data(), tempo.Data())) ;
ad4aeaf4 357 gime1->Event(ReadEvent,"S");
358 sdigArray->AddAt(gime1->SDigits(), i) ;
38bb0fd5 359 }
9688c1dd 360
27a73a5d 361 //Find the first crystal with signal
9688c1dd 362 Int_t nextSig = 200000 ;
88cb7938 363 TClonesArray * sdigits ;
364 for(i = 0 ; i < fInput ; i++){
365 sdigits = dynamic_cast<TClonesArray *>(sdigArray->At(i)) ;
a6eedfad 366 if ( !sdigits->GetEntriesFast() )
7a9d98f9 367 continue ;
88cb7938 368 Int_t curNext = dynamic_cast<AliPHOSDigit *>(sdigits->At(0))->GetId() ;
369 if(curNext < nextSig)
370 nextSig = curNext ;
9688c1dd 371 }
88cb7938 372
373 TArrayI index(fInput) ;
9688c1dd 374 index.Reset() ; //Set all indexes to zero
88cb7938 375
9688c1dd 376 AliPHOSDigit * digit ;
377 AliPHOSDigit * curSDigit ;
88cb7938 378
7437a0f7 379 TClonesArray * ticks = new TClonesArray("AliPHOSTick",1000) ;
88cb7938 380
9688c1dd 381 //Put Noise contribution
88cb7938 382 for(absID = 1 ; absID <= nEMC ; absID++){
9688c1dd 383 Float_t noise = gRandom->Gaus(0., fPinNoise) ;
27a73a5d 384 // YVK: do not digitize amplitudes for EMC
385// new((*digits)[absID-1]) AliPHOSDigit( -1, absID, sDigitizer->Digitize(noise), TimeOfNoise() ) ;
386 new((*digits)[absID-1]) AliPHOSDigit( -1, absID, noise, TimeOfNoise() ) ;
9688c1dd 387 //look if we have to add signal?
88cb7938 388 digit = dynamic_cast<AliPHOSDigit *>(digits->At(absID-1)) ;
389
9688c1dd 390 if(absID==nextSig){
391 //Add SDigits from all inputs
7437a0f7 392 ticks->Clear() ;
9688c1dd 393 Int_t contrib = 0 ;
27a73a5d 394 Float_t a = digit->GetEnergy() ;
88cb7938 395 Float_t b = TMath::Abs( a / fTimeSignalLength) ;
396 //Mark the beginning of the signal
7437a0f7 397 new((*ticks)[contrib++]) AliPHOSTick(digit->GetTime(),0, b);
27a73a5d 398 //Mark the end of the signal
7437a0f7 399 new((*ticks)[contrib++]) AliPHOSTick(digit->GetTime()+fTimeSignalLength, -a, -b);
88cb7938 400
9688c1dd 401 //loop over inputs
88cb7938 402 for(i = 0 ; i < fInput ; i++){
403 if( dynamic_cast<TClonesArray *>(sdigArray->At(i))->GetEntriesFast() > index[i] )
404 curSDigit = dynamic_cast<AliPHOSDigit*>(dynamic_cast<TClonesArray *>(sdigArray->At(i))->At(index[i])) ;
5c9dfca0 405 else
406 curSDigit = 0 ;
9688c1dd 407 //May be several digits will contribute from the same input
408 while(curSDigit && curSDigit->GetId() == absID){
409 //Shift primary to separate primaries belonging different inputs
410 Int_t primaryoffset ;
9891b76e 411 if(fManager)
412 primaryoffset = fManager->GetMask(i) ;
9688c1dd 413 else
21c293b7 414 primaryoffset = 10000000*i ;
415 curSDigit->ShiftPrimary(primaryoffset) ;
7437a0f7 416
27a73a5d 417 a = curSDigit->GetEnergy() ;
7437a0f7 418 b = a /fTimeSignalLength ;
419 new((*ticks)[contrib++]) AliPHOSTick(curSDigit->GetTime(),0, b);
420 new((*ticks)[contrib++]) AliPHOSTick(curSDigit->GetTime()+fTimeSignalLength, -a, -b);
88cb7938 421
3663622c 422 *digit += *curSDigit ; //add energies
27a73a5d 423
9688c1dd 424 index[i]++ ;
88cb7938 425 if( dynamic_cast<TClonesArray *>(sdigArray->At(i))->GetEntriesFast() > index[i] )
426 curSDigit = dynamic_cast<AliPHOSDigit*>(dynamic_cast<TClonesArray *>(sdigArray->At(i))->At(index[i])) ;
5c9dfca0 427 else
428 curSDigit = 0 ;
9688c1dd 429 }
430 }
88cb7938 431
9688c1dd 432 //calculate and set time
7437a0f7 433 Float_t time = FrontEdgeTime(ticks) ;
9688c1dd 434 digit->SetTime(time) ;
88cb7938 435
9688c1dd 436 //Find next signal module
7437a0f7 437 nextSig = 200000 ;
88cb7938 438 for(i = 0 ; i < fInput ; i++){
439 sdigits = dynamic_cast<TClonesArray *>(sdigArray->At(i)) ;
5c9dfca0 440 Int_t curNext = nextSig ;
441 if(sdigits->GetEntriesFast() > index[i] ){
88cb7938 442 curNext = dynamic_cast<AliPHOSDigit *>(sdigits->At(index[i]))->GetId() ;
5c9dfca0 443 }
9688c1dd 444 if(curNext < nextSig) nextSig = curNext ;
7b7c1533 445 }
446 }
990119d6 447 }
3f81a70b 448
7437a0f7 449 ticks->Delete() ;
450 delete ticks ;
88cb7938 451
9688c1dd 452 //Now CPV digits (different noise and no timing)
453 for(absID = nEMC+1; absID <= nCPV; absID++){
454 Float_t noise = gRandom->Gaus(0., fCPVNoise) ;
455 new((*digits)[absID-1]) AliPHOSDigit( -1,absID,sDigitizer->Digitize(noise), TimeOfNoise() ) ;
456 //look if we have to add signal?
457 if(absID==nextSig){
88cb7938 458 digit = dynamic_cast<AliPHOSDigit *>(digits->At(absID-1)) ;
9688c1dd 459 //Add SDigits from all inputs
88cb7938 460 for(i = 0 ; i < fInput ; i++){
461 if( dynamic_cast<TClonesArray *>(sdigArray->At(i))->GetEntriesFast() > index[i] )
462 curSDigit = dynamic_cast<AliPHOSDigit*>( dynamic_cast<TClonesArray *>(sdigArray->At(i))->At(index[i])) ;
5c9dfca0 463 else
464 curSDigit = 0 ;
a6eedfad 465
9688c1dd 466 //May be several digits will contribute from the same input
467 while(curSDigit && curSDigit->GetId() == absID){
468 //Shift primary to separate primaries belonging different inputs
469 Int_t primaryoffset ;
9891b76e 470 if(fManager)
471 primaryoffset = fManager->GetMask(i) ;
9688c1dd 472 else
473 primaryoffset = 10000000*i ;
474 curSDigit->ShiftPrimary(primaryoffset) ;
475
476 //add energies
3663622c 477 *digit += *curSDigit ;
9688c1dd 478 index[i]++ ;
88cb7938 479 if( dynamic_cast<TClonesArray *>(sdigArray->At(i))->GetEntriesFast() > index[i] )
480 curSDigit = dynamic_cast<AliPHOSDigit*>( dynamic_cast<TClonesArray *>(sdigArray->At(i))->At(index[i]) ) ;
5c9dfca0 481 else
482 curSDigit = 0 ;
9688c1dd 483 }
484 }
a6eedfad 485
9688c1dd 486 //Find next signal module
a6eedfad 487 nextSig = 200000 ;
88cb7938 488 for(i = 0 ; i < fInput ; i++){
489 sdigits = dynamic_cast<TClonesArray *>(sdigArray->At(i)) ;
5c9dfca0 490 Int_t curNext = nextSig ;
491 if(sdigits->GetEntriesFast() > index[i] )
88cb7938 492 curNext = dynamic_cast<AliPHOSDigit *>( sdigits->At(index[i]) )->GetId() ;
9688c1dd 493 if(curNext < nextSig) nextSig = curNext ;
494 }
495
496 }
497 }
88cb7938 498
499 delete sdigArray ; //We should not delete its contents
9688c1dd 500
990119d6 501 //remove digits below thresholds
88cb7938 502 for(i = 0 ; i < nEMC ; i++){
548f0134 503 digit = dynamic_cast<AliPHOSDigit*>( digits->At(i) ) ;
877695e7 504 DecalibrateEMC(digit);
27a73a5d 505 if(digit->GetEnergy() < fEMCDigitThreshold)
a6eedfad 506 digits->RemoveAt(i) ;
aaf8a71c 507 else
508 digit->SetTime(gRandom->Gaus(digit->GetTime(),fTimeResolution) ) ;
509 }
510
a6eedfad 511
512 for(i = nEMC; i < nCPV ; i++)
27a73a5d 513// if( sDigitizer->Calibrate( dynamic_cast<AliPHOSDigit*>(digits->At(i))->GetAmp() ) < fCPVDigitThreshold )
514 if( dynamic_cast<AliPHOSDigit*>(digits->At(i))->GetEnergy() < fCPVDigitThreshold )
a6eedfad 515 digits->RemoveAt(i) ;
9688c1dd 516
7b7c1533 517 digits->Compress() ;
990119d6 518
7b7c1533 519 Int_t ndigits = digits->GetEntriesFast() ;
7b7c1533 520 digits->Expand(ndigits) ;
990119d6 521
3758d9fc 522 //Set indexes in list of digits and make true digitization of the energy
990119d6 523 for (i = 0 ; i < ndigits ; i++) {
548f0134 524 digit = dynamic_cast<AliPHOSDigit*>( digits->At(i) ) ;
990119d6 525 digit->SetIndexInList(i) ;
27a73a5d 526 if(digit->GetId() > fEmcCrystals){ //digitize CPV only
877695e7 527 digit->SetAmp(DigitizeCPV(digit->GetEnergy(),digit->GetId()) ) ;
27a73a5d 528 }
990119d6 529 }
1c6a163f 530
531 Int_t relId[4];
532
533 //set amplitudes in bad channels to zero
534 for(i = 0 ; i <digits->GetEntries(); i++){
535 digit = dynamic_cast<AliPHOSDigit*>( digits->At(i) ) ;
536 gime->PHOSGeometry()->AbsToRelNumbering(digit->GetId(),relId);
537 if(relId[1] == 0) // Emc
538 if(gime->CalibData()->IsBadChannelEmc(relId[0],relId[3],relId[2])) digit->SetEnergy(0.);
539 }
540
7b7c1533 541}
548f0134 542
3758d9fc 543//____________________________________________________________________________
877695e7 544void AliPHOSDigitizer::DecalibrateEMC(AliPHOSDigit *digit)
3758d9fc 545{
877695e7 546 // Decalibrate EMC digit, i.e. change its energy by a factor read from CDB
547
548 AliPHOSGetter* gime = AliPHOSGetter::Instance();
549
550 if(!gime->CalibData()) {
551 AliPHOSCalibData* cdb = new AliPHOSCalibData(-1);
552 gime->SetCalibData(cdb);
553 }
554
555 //Determine rel.position of the cell absolute ID
556 Int_t relId[4];
557 gime->PHOSGeometry()->AbsToRelNumbering(digit->GetId(),relId);
558 Int_t module=relId[0];
559 Int_t row =relId[2];
560 Int_t column=relId[3];
561 Float_t decalibration = gime->CalibData()->GetADCchannelEmc(module,column,row);
1a197b77 562 Float_t energy = digit->GetEnergy() / decalibration;
877695e7 563 digit->SetEnergy(energy);
564}
565//____________________________________________________________________________
566Int_t AliPHOSDigitizer::DigitizeCPV(Float_t charge, Int_t absId)
567{
568 // Returns digitized value of the CPV charge in a pad absId
0bc3b8ed 569
a8ec0771 570 AliPHOSGetter* gime = AliPHOSGetter::Instance();
571
fc6706cb 572 if(!gime->CalibData()) {
28871337 573 AliPHOSCalibData* cdb = new AliPHOSCalibData(-1); // use AliCDBManager's run number
fc6706cb 574 gime->SetCalibData(cdb);
575 }
576
a8ec0771 577 //Determine rel.position of the cell absId
578 Int_t relId[4];
579 gime->PHOSGeometry()->AbsToRelNumbering(absId,relId);
580 Int_t module=relId[0];
27a73a5d 581 Int_t row =relId[2];
a8ec0771 582 Int_t column=relId[3];
583
877695e7 584 Int_t channel = 0;
a8ec0771 585
877695e7 586 if(absId > fEmcCrystals){ //digitize CPV only
a8ec0771 587
588 //reading calibration data for cell absId.
589 //If no calibration DB found, accept default values.
590
fc6706cb 591 if(gime->CalibData()) {
27a73a5d 592 fADCpedestalCpv = gime->CalibData()->GetADCpedestalCpv(module,column,row);
877695e7 593 fADCchanelCpv = gime->CalibData()->GetADCchannelCpv( module,column,row);
fc6706cb 594 }
595
877695e7 596 channel = (Int_t) TMath::Ceil((charge - fADCpedestalCpv)/fADCchanelCpv) ;
597 if(channel > fNADCcpv ) channel = fNADCcpv ;
3758d9fc 598 }
877695e7 599 return channel ;
3758d9fc 600}
548f0134 601
7b7c1533 602//____________________________________________________________________________
603void AliPHOSDigitizer::Exec(Option_t *option)
604{
212d1c0f 605 // Steering method to process digitization for events
606 // in the range from fFirstEvent to fLastEvent.
607 // This range is optionally set by SetEventRange().
45fa49ca 608 // if fLastEvent=-1, then process events until the end.
609 // by default fLastEvent = fFirstEvent (process only one event)
88cb7938 610
611 if (!fInit) { // to prevent overwrite existing file
351dd634 612 AliError(Form("Give a version name different from %s",
613 fEventFolderName.Data() )) ;
88cb7938 614 return ;
615 }
990119d6 616
7b7c1533 617 if (strstr(option,"print")) {
88cb7938 618 Print();
7b7c1533 619 return ;
8cb3533f 620 }
990119d6 621
7b7c1533 622 if(strstr(option,"tim"))
623 gBenchmark->Start("PHOSDigitizer");
3f81a70b 624
fb43ada4 625 AliPHOSGetter * gime = AliPHOSGetter::Instance(GetTitle()) ;
88cb7938 626
5b4d2c50 627 // Post Digitizer to the white board
628 gime->PostDigitizer(this) ;
629
212d1c0f 630 if (fLastEvent == -1)
631 fLastEvent = gime->MaxEvent() - 1 ;
396a348e 632 else if (fManager)
633 fLastEvent = fFirstEvent ;
45fa49ca 634
212d1c0f 635 Int_t nEvents = fLastEvent - fFirstEvent + 1;
636
7b7c1533 637 Int_t ievent ;
88cb7938 638
212d1c0f 639 for (ievent = fFirstEvent; ievent <= fLastEvent; ievent++) {
ddd1a39c 640 fEventCounter++ ;
88cb7938 641 gime->Event(ievent,"S") ;
b22e4735 642
7b7c1533 643 Digitize(ievent) ; //Add prepared SDigits to digits and add the noise
88cb7938 644
ddd1a39c 645 //makes the quality assurance data
5b188f2f 646 if (GetQualAssDataMaker()->IsCycleDone() ) {
647 GetQualAssDataMaker()->EndOfCycle(AliQualAss::kDIGITS) ;
648 GetQualAssDataMaker()->StartOfCycle(AliQualAss::kDIGITS) ;
649 }
d76c31f4 650 GetQualAssDataMaker()->Exec(AliQualAss::kDIGITS, gime->Digits()) ;
5b188f2f 651 GetQualAssDataMaker()->Increment() ;
ddd1a39c 652
90cceaf6 653 WriteDigits() ;
88cb7938 654
01a599c9 655 if(strstr(option,"deb"))
656 PrintDigits(option);
94de8339 657
658 //increment the total number of Digits per run
659 fDigitsInRun += gime->Digits()->GetEntriesFast() ;
88cb7938 660 }
ddd1a39c 661
662 //Write the quality assurance data only after the last event
5b188f2f 663 if ( fEventCounter == gime->MaxEvent() ) {
664 GetQualAssDataMaker()->EndOfCycle(AliQualAss::kDIGITS) ;
ddd1a39c 665 GetQualAssDataMaker()->Finish(AliQualAss::kDIGITS) ;
5b188f2f 666 }
88cb7938 667
5b4d2c50 668 gime->PhosLoader()->CleanDigitizer();
669
8cb3533f 670 if(strstr(option,"tim")){
671 gBenchmark->Stop("PHOSDigitizer");
21cd0c07 672 TString message ;
673 message = " took %f seconds for Digitizing %f seconds per event\n" ;
351dd634 674 AliInfo(Form( message.Data(),
21cd0c07 675 gBenchmark->GetCpuTime("PHOSDigitizer"),
351dd634 676 gBenchmark->GetCpuTime("PHOSDigitizer")/nEvents ));
21cd0c07 677 }
990119d6 678}
679
9688c1dd 680//____________________________________________________________________________
0bc3b8ed 681Float_t AliPHOSDigitizer::FrontEdgeTime(TClonesArray * ticks) const
682{
683 // Returns the shortest time among all time ticks
684
7437a0f7 685 ticks->Sort() ; //Sort in accordance with times of ticks
686 TIter it(ticks) ;
687 AliPHOSTick * ctick = (AliPHOSTick *) it.Next() ;
688 Float_t time = ctick->CrossingTime(fTimeThreshold) ;
689
690 AliPHOSTick * t ;
691 while((t=(AliPHOSTick*) it.Next())){
692 if(t->GetTime() < time) //This tick starts before crossing
693 *ctick+=*t ;
694 else
695 return time ;
696
697 time = ctick->CrossingTime(fTimeThreshold) ;
9688c1dd 698 }
699 return time ;
9688c1dd 700}
8d0f3f77 701
7b7c1533 702//____________________________________________________________________________
3f81a70b 703Bool_t AliPHOSDigitizer::Init()
8d0f3f77 704{
fbf811ec 705 // Makes all memory allocations
88cb7938 706 fInit = kTRUE ;
707 AliPHOSGetter * gime = AliPHOSGetter::Instance(GetTitle(), fEventFolderName) ;
8d0f3f77 708 if ( gime == 0 ) {
351dd634 709 AliFatal(Form("Could not obtain the Getter object for file %s and event %s !",
710 GetTitle(), fEventFolderName.Data()));
8d0f3f77 711 return kFALSE;
712 }
713
714 const AliPHOSGeometry * geom = gime->PHOSGeometry() ;
b22e4735 715
88cb7938 716 fEmcCrystals = geom->GetNModules() * geom->GetNCristalsInModule() ;
8d0f3f77 717
88cb7938 718 TString opt("Digits") ;
719 if(gime->VersionExists(opt) ) {
351dd634 720 AliError(Form("Give a version name different from %s",
721 fEventFolderName.Data() )) ;
88cb7938 722 fInit = kFALSE ;
723 }
724
45fa49ca 725 fFirstEvent = 0 ;
726 fLastEvent = fFirstEvent ;
88cb7938 727 if (fManager)
728 fInput = fManager->GetNinputs() ;
729 else
730 fInput = 1 ;
731
732 fInputFileNames = new TString[fInput] ;
733 fEventNames = new TString[fInput] ;
734 fInputFileNames[0] = GetTitle() ;
735 fEventNames[0] = fEventFolderName.Data() ;
736 Int_t index ;
737 for (index = 1 ; index < fInput ; index++) {
738 fInputFileNames[index] = dynamic_cast<AliStream*>(fManager->GetInputStream(index))->GetFileName(0);
739 TString tempo = fManager->GetInputFolderName(index) ;
45fa49ca 740 fEventNames[index] = tempo.Remove(tempo.Length()-1) ; // strip of the stream number added by fManager
8d0f3f77 741 }
88cb7938 742
743 //to prevent cleaning of this object while GetEvent is called
744 gime->PhosLoader()->GetDigitsDataLoader()->GetBaseTaskLoader()->SetDoNotReload(kTRUE);
745
746 return fInit ;
8d0f3f77 747}
748
749//____________________________________________________________________________
750void AliPHOSDigitizer::InitParameters()
a4e98857 751{
45fa49ca 752 // Set initial parameters Digitizer
0bc3b8ed 753
27a73a5d 754 fPinNoise = 0.004 ; // [GeV]
755 fEMCDigitThreshold = 0.012 ; // [GeV]
756 fCPVNoise = 0.01; // [aux units]
757 fCPVDigitThreshold = 0.09 ; // [aux units]
758 fTimeResolution = 0.5e-9 ; // [sec]
759 fTimeSignalLength = 1.0e-9 ; // [sec]
3758d9fc 760 fDigitsInRun = 0 ;
877695e7 761 fADCchanelEmc = 1.0; // Coefficient between real and measured energies in EMC
762 fADCpedestalEmc = 0. ; //
3758d9fc 763 fNADCemc = (Int_t) TMath::Power(2,16) ; // number of channels in EMC ADC
764
765 fADCchanelCpv = 0.0012 ; // width of one ADC channel in CPV 'popugais'
766 fADCpedestalCpv = 0.012 ; //
767 fNADCcpv = (Int_t) TMath::Power(2,12); // number of channels in CPV ADC
768
27a73a5d 769// fTimeThreshold = 0.001*10000000 ; //Means 1 MeV in terms of SDigits amplitude
770 fTimeThreshold = 0.001 ; // [GeV]
212d1c0f 771 SetEventRange(0,-1) ;
8cb3533f 772
990119d6 773}
7b7c1533 774
990119d6 775//__________________________________________________________________
fc7e2f43 776void AliPHOSDigitizer::MixWith(TString alirunFileName, TString eventFolderName)
a4e98857 777{
ba54256b 778 // Allows to produce digits by superimposing background and signal event.
bca3b32a 779 // It is assumed, that headers file with SIGNAL events is opened in
a4e98857 780 // the constructor.
781 // Sets the BACKGROUND event, with which the SIGNAL event is to be mixed
782 // Thus we avoid writing (changing) huge and expensive
bca3b32a 783 // backgound files: all output will be writen into SIGNAL, i.e.
784 // opened in constructor file.
785 //
a4e98857 786 // One can open as many files to mix with as one needs.
7b7c1533 787 // However only Sdigits with the same name (i.e. constructed with the same SDigitizer)
788 // can be mixed.
bca3b32a 789
88cb7938 790 if( strcmp(fEventFolderName, "") == 0 )
8cb3533f 791 Init() ;
792
9891b76e 793 if(fManager){
88cb7938 794 Warning("MixWith", "Cannot use this method with AliRunDigitizer\n" ) ;
3f81a70b 795 return ;
796 }
88cb7938 797 // looking for file which contains AliRun
798 if (gSystem->AccessPathName(alirunFileName)) {// file does not exist
351dd634 799 AliError(Form("File %s does not exist!", alirunFileName.Data())) ;
88cb7938 800 return ;
990119d6 801 }
88cb7938 802 // looking for the file which contains SDigits
803 AliPHOSGetter * gime = AliPHOSGetter::Instance() ;
804 TString fileName( gime->GetSDigitsFileName() ) ;
e191bb57 805 if ( eventFolderName != AliConfig::GetDefaultEventFolderName()) // only if not the default folder name
88cb7938 806 fileName = fileName.ReplaceAll(".root", "") + "_" + eventFolderName + ".root" ;
807 if ( (gSystem->AccessPathName(fileName)) ) {
351dd634 808 AliError(Form("The file %s does not exist!", fileName.Data())) ;
88cb7938 809 return ;
7b7c1533 810 }
88cb7938 811 // need to increase the arrays
812 TString tempo = fInputFileNames[fInput-1] ;
813 delete [] fInputFileNames ;
814 fInputFileNames = new TString[fInput+1] ;
815 fInputFileNames[fInput-1] = tempo ;
816
817 tempo = fEventNames[fInput-1] ;
818 delete [] fEventNames ;
819 fEventNames = new TString[fInput+1] ;
820 fEventNames[fInput-1] = tempo ;
821
822 fInputFileNames[fInput] = alirunFileName ;
823 fEventNames[fInput] = eventFolderName ;
824 fInput++ ;
990119d6 825}
7b7c1533 826
990119d6 827//__________________________________________________________________
702ab87e 828void AliPHOSDigitizer::Print(const Option_t *)const
21cd0c07 829{
dd5c4038 830 // Print Digitizer's parameters
351dd634 831 AliInfo(Form("\n------------------- %s -------------", GetName() )) ;
88cb7938 832 if( strcmp(fEventFolderName.Data(), "") != 0 ){
833 printf(" Writing Digits to branch with title %s\n", fEventFolderName.Data()) ;
834
835 Int_t nStreams ;
836 if (fManager)
837 nStreams = GetNInputStreams() ;
838 else
839 nStreams = fInput ;
840
841 Int_t index = 0 ;
842 for (index = 0 ; index < nStreams ; index++) {
843 TString tempo(fEventNames[index]) ;
844 tempo += index ;
845 AliPHOSGetter * gime = AliPHOSGetter::Instance(fInputFileNames[index], tempo) ;
846 TString fileName( gime->GetSDigitsFileName() ) ;
e191bb57 847 if ( fEventNames[index] != AliConfig::GetDefaultEventFolderName()) // only if not the default folder name
88cb7938 848 fileName = fileName.ReplaceAll(".root", "") + "_" + fEventNames[index] + ".root" ;
849 printf ("Adding SDigits from %s %s\n", fInputFileNames[index].Data(), fileName.Data()) ;
850 }
851 AliPHOSGetter * gime = AliPHOSGetter::Instance(GetTitle(), fEventFolderName) ;
852 printf("\nWriting digits to %s", gime->GetDigitsFileName().Data()) ;
853
854 printf("\nWith following parameters:\n") ;
27a73a5d 855 printf(" Electronics noise in EMC (fPinNoise) = %f GeV\n", fPinNoise ) ;
856 printf(" Threshold in EMC (fEMCDigitThreshold) = %f GeV\n", fEMCDigitThreshold ) ;
857 printf(" Noise in CPV (fCPVNoise) = %f aux units\n", fCPVNoise ) ;
858 printf(" Threshold in CPV (fCPVDigitThreshold) = %f aux units\n",fCPVDigitThreshold ) ;
88cb7938 859 printf(" ---------------------------------------------------\n") ;
990119d6 860 }
8cb3533f 861 else
351dd634 862 AliInfo(Form("AliPHOSDigitizer not initialized" )) ;
8cb3533f 863
864}
88cb7938 865
8cb3533f 866//__________________________________________________________________
21cd0c07 867 void AliPHOSDigitizer::PrintDigits(Option_t * option)
868{
3bf72d32 869 // Print a table of digits
21cd0c07 870
88cb7938 871 AliPHOSGetter * gime = AliPHOSGetter::Instance(GetTitle(), fEventFolderName) ;
3bf72d32 872 TClonesArray * digits = gime->Digits() ;
873
351dd634 874 AliInfo(Form("%d", digits->GetEntriesFast())) ;
88cb7938 875 printf("\nevent %d", gAlice->GetEvNumber()) ;
876 printf("\n Number of entries in Digits list %d", digits->GetEntriesFast() ) ;
877
11f9c5ff 878
3bf72d32 879 if(strstr(option,"all")||strstr(option,"EMC")){
8cb3533f 880 //loop over digits
881 AliPHOSDigit * digit;
88cb7938 882 printf("\nEMC digits (with primaries):\n") ;
883 printf("\n Id Amplitude Time Index Nprim: Primaries list \n") ;
9688c1dd 884 Int_t maxEmc = gime->PHOSGeometry()->GetNModules()*gime->PHOSGeometry()->GetNCristalsInModule() ;
8cb3533f 885 Int_t index ;
a6eedfad 886 for (index = 0 ; (index < digits->GetEntriesFast()) &&
88cb7938 887 (dynamic_cast<AliPHOSDigit *>(digits->At(index))->GetId() <= maxEmc) ; index++) {
7b7c1533 888 digit = (AliPHOSDigit * ) digits->At(index) ;
21cd0c07 889 if(digit->GetNprimary() == 0)
890 continue;
27a73a5d 891// printf("%6d %8d %6.5e %4d %2d :",
892// digit->GetId(), digit->GetAmp(), digit->GetTime(), digit->GetIndexInList(), digit->GetNprimary()) ; // YVK
893 printf("%6d %.4f %6.5e %4d %2d :",
894 digit->GetId(), digit->GetEnergy(), digit->GetTime(), digit->GetIndexInList(), digit->GetNprimary()) ;
8cb3533f 895 Int_t iprimary;
21cd0c07 896 for (iprimary=0; iprimary<digit->GetNprimary(); iprimary++) {
88cb7938 897 printf("%d ",digit->GetPrimary(iprimary+1) ) ;
21cd0c07 898 }
81d5f731 899 printf("\n") ;
21cd0c07 900 }
9688c1dd 901 }
3bf72d32 902
9688c1dd 903 if(strstr(option,"all")||strstr(option,"CPV")){
8cb3533f 904
9688c1dd 905 //loop over CPV digits
906 AliPHOSDigit * digit;
88cb7938 907 printf("\nCPV digits (with primaries):\n") ;
908 printf("\n Id Amplitude Time Index Nprim: Primaries list \n") ;
9688c1dd 909 Int_t maxEmc = gime->PHOSGeometry()->GetNModules()*gime->PHOSGeometry()->GetNCristalsInModule() ;
910 Int_t index ;
a6eedfad 911 for (index = 0 ; index < digits->GetEntriesFast(); index++) {
9688c1dd 912 digit = (AliPHOSDigit * ) digits->At(index) ;
913 if(digit->GetId() > maxEmc){
81d5f731 914 printf("%6d %8d %4d %2d :",
11f9c5ff 915 digit->GetId(), digit->GetAmp(), digit->GetIndexInList(), digit->GetNprimary()) ;
9688c1dd 916 Int_t iprimary;
21cd0c07 917 for (iprimary=0; iprimary<digit->GetNprimary(); iprimary++) {
88cb7938 918 printf("%d ",digit->GetPrimary(iprimary+1) ) ;
21cd0c07 919 }
81d5f731 920 printf("\n") ;
21cd0c07 921 }
9688c1dd 922 }
8cb3533f 923 }
88cb7938 924
8cb3533f 925}
7b7c1533 926
9688c1dd 927//__________________________________________________________________
0bc3b8ed 928Float_t AliPHOSDigitizer::TimeOfNoise(void) const
9688c1dd 929{ // Calculates the time signal generated by noise
26a2ef9d 930 //PH Info("TimeOfNoise", "Change me") ;
04f0bda3 931 return gRandom->Rndm() * 1.28E-5;
8cb3533f 932}
7b7c1533 933
88cb7938 934//__________________________________________________________________
935void AliPHOSDigitizer::Unload()
936{
937
938 Int_t i ;
939 for(i = 1 ; i < fInput ; i++){
940 TString tempo(fEventNames[i]) ;
941 tempo += i ;
942 AliPHOSGetter * gime = AliPHOSGetter::Instance(fInputFileNames[i], tempo) ;
943 gime->PhosLoader()->UnloadSDigits() ;
944 }
945
946 AliPHOSGetter * gime = AliPHOSGetter::Instance(GetTitle(), fEventFolderName) ;
947 gime->PhosLoader()->UnloadDigits() ;
948}
949
7b7c1533 950//____________________________________________________________________________
90cceaf6 951void AliPHOSDigitizer::WriteDigits()
7b7c1533 952{
953
954 // Makes TreeD in the output file.
955 // Check if branch already exists:
956 // if yes, exit without writing: ROOT TTree does not support overwriting/updating of
957 // already existing branches.
958 // else creates branch with Digits, named "PHOS", title "...",
959 // and branch "AliPHOSDigitizer", with the same title to keep all the parameters
960 // and names of files, from which digits are made.
961
f98c06a1 962 AliPHOSGetter * gime = AliPHOSGetter::Instance(GetTitle()) ;
88cb7938 963 const TClonesArray * digits = gime->Digits() ;
964 TTree * treeD = gime->TreeD();
965
7b7c1533 966 // -- create Digits branch
967 Int_t bufferSize = 32000 ;
2524c56f 968 TBranch * digitsBranch = treeD->Branch("PHOS","TClonesArray",&digits,bufferSize);
88cb7938 969 digitsBranch->SetTitle(fEventFolderName);
970 digitsBranch->Fill() ;
fbf811ec 971
88cb7938 972 gime->WriteDigits("OVERWRITE");
973 gime->WriteDigitizer("OVERWRITE");
974
975 Unload() ;
b3690abb 976
7b7c1533 977}