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