]> git.uio.no Git - u/mrichter/AliRoot.git/blame - EMCAL/AliEMCALDigitizer.cxx
Suppressed Sumw2 in ITS QA and Calib tasks to reduce the memory
[u/mrichter/AliRoot.git] / EMCAL / AliEMCALDigitizer.cxx
CommitLineData
61e0abb5 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//_________________________________________________________________________
ffa6d63b 19//
61e0abb5 20//////////////////////////////////////////////////////////////////////////////
ab6a174f 21// Class performs digitization of Summable digits from simulated data
ffa6d63b 22//
6cc75819 23// In addition it performs mixing/embedding of summable digits from different events.
61e0abb5 24//
61d80ce0 25// For each event 3 branches are created in TreeD:
61e0abb5 26// "EMCAL" - list of digits
61d80ce0 27// "EMCALTRG" - list of trigger digits
61e0abb5 28// "AliEMCALDigitizer" - AliEMCALDigitizer with all parameters used in digitization
29//
61e0abb5 30//
ffa6d63b 31////////////////////////////////////////////////////////////////////////////////////
61e0abb5 32//
ffa6d63b 33//*-- Author: Sahal Yacoob (LBL)
814ad4bf 34// based on : AliEMCALDigitizer
05a92d59 35// Modif:
36// August 2002 Yves Schutz: clone PHOS as closely as possible and intoduction
6cc75819 37// of new IO (a la PHOS)
1963b290 38// November 2003 Aleksei Pavlinov : adopted for Shish-Kebab geometry
61d80ce0 39// July 2011 GCB: Digitizer modified to accomodate embedding.
40// Time calibration added. Decalibration possibility of energy and time added
1963b290 41//_________________________________________________________________________________
61e0abb5 42
43// --- ROOT system ---
e939a978 44#include <TROOT.h>
45#include <TTree.h>
46#include <TSystem.h>
47#include <TBenchmark.h>
e939a978 48#include <TBrowser.h>
49#include <TObjectTable.h>
50#include <TRandom.h>
916f1e76 51#include <TF1.h>
21e7df44 52#include <cassert>
61e0abb5 53
54// --- AliRoot header files ---
b42d4197 55#include "AliLog.h"
e4dcc484 56#include "AliRun.h"
f21fc003 57#include "AliDigitizationInput.h"
5dee926e 58#include "AliRunLoader.h"
53f1c378 59#include "AliCDBManager.h"
60#include "AliCDBEntry.h"
61e0abb5 61#include "AliEMCALDigit.h"
05a92d59 62#include "AliEMCAL.h"
5dee926e 63#include "AliEMCALLoader.h"
61e0abb5 64#include "AliEMCALDigitizer.h"
65#include "AliEMCALSDigitizer.h"
66#include "AliEMCALGeometry.h"
a435f763 67#include "AliEMCALCalibData.h"
33a52e55 68#include "AliEMCALSimParam.h"
916f1e76 69#include "AliEMCALRawDigit.h"
6995e8b7 70#include "AliCaloCalibPedestal.h"
916f1e76 71
61d80ce0 72 namespace
73 {
74 Double_t HeavisideTheta(Double_t x)
75 {
76 Double_t signal = 0.;
77
78 if (x > 0.) signal = 1.;
79
80 return signal;
81 }
82
83 Double_t AnalogFastORFunction(Double_t *x, Double_t *par)
84 {
85 Double_t v0 = par[0];
86 Double_t t0 = par[1];
87 Double_t tr = par[2];
88
89 Double_t R1 = 1000.;
90 Double_t C1 = 33e-12;
91 Double_t R2 = 1800;
92 Double_t C2 = 22e-12;
93
94 Double_t t = x[0];
95
96 return (((0.8*(-((TMath::Power(C1,2)*C2*TMath::Power(TMath::E(),(-t + t0)/(C1*R1))*
97 TMath::Power(R1,2)*R2)/(C1*R1 - C2*R2)) +
98 C1*C2*R1*R2*(1 - (C2*TMath::Power(TMath::E(),(-t + t0)/(C2*R2))*R2)/(-(C1*R1) + C2*R2)))*v0*
99 HeavisideTheta(t - t0))/tr
100 - (0.8*(C1*C2*R1*R2 -
101 (TMath::Power(C1,2)*C2*TMath::Power(TMath::E(),(-1.*t + t0 + 1.25*tr)/(C1*R1))*
102 TMath::Power(R1,2)*R2)/(C1*R1 - C2*R2) +
103 (C1*TMath::Power(C2,2)*TMath::Power(TMath::E(),(-1.*t + t0 + 1.25*tr)/(C2*R2))*
104 R1*TMath::Power(R2,2))/(C1*R1 - C2*R2))*v0*
105 HeavisideTheta(t - t0 - 1.25*tr))/tr)/(C2*R1));
106 }
107 }
05a92d59 108
61e0abb5 109ClassImp(AliEMCALDigitizer)
61d80ce0 110
111
61e0abb5 112//____________________________________________________________________________
18a21c7c 113AliEMCALDigitizer::AliEMCALDigitizer()
114 : AliDigitizer("",""),
115 fDefaultInit(kTRUE),
116 fDigitsInRun(0),
117 fInit(0),
118 fInput(0),
119 fInputFileNames(0x0),
120 fEventNames(0x0),
121 fDigitThreshold(0),
122 fMeanPhotonElectron(0),
5fb45456 123 fGainFluctuations(0),
18a21c7c 124 fPinNoise(0),
6cc75819 125 fTimeNoise(0),
f0a6dc6f 126 fTimeDelay(0),
a2f8e711 127 fTimeResolutionPar0(0),
128 fTimeResolutionPar1(0),
18a21c7c 129 fADCchannelEC(0),
130 fADCpedestalEC(0),
6cc75819 131 fADCchannelECDecal(0),
132 fTimeChannel(0),
133 fTimeChannelDecal(0),
18a21c7c 134 fNADCEC(0),
135 fEventFolderName(""),
136 fFirstEvent(0),
137 fLastEvent(0),
f21fc003 138 fCalibData(0x0),
139 fSDigitizer(0x0)
61e0abb5 140{
141 // ctor
88cb7938 142 InitParameters() ;
f21fc003 143 fDigInput = 0 ; // We work in the standalone mode
839828a6 144}
61e0abb5 145
839828a6 146//____________________________________________________________________________
18a21c7c 147AliEMCALDigitizer::AliEMCALDigitizer(TString alirunFileName, TString eventFolderName)
f21fc003 148 : AliDigitizer("EMCALDigitizer", alirunFileName),
18a21c7c 149 fDefaultInit(kFALSE),
150 fDigitsInRun(0),
151 fInit(0),
152 fInput(0),
153 fInputFileNames(0),
154 fEventNames(0),
155 fDigitThreshold(0),
156 fMeanPhotonElectron(0),
5fb45456 157 fGainFluctuations(0),
18a21c7c 158 fPinNoise(0),
6cc75819 159 fTimeNoise(0),
96d5ea0d 160 fTimeDelay(0),
a2f8e711 161 fTimeResolutionPar0(0),
162 fTimeResolutionPar1(0),
18a21c7c 163 fADCchannelEC(0),
164 fADCpedestalEC(0),
6cc75819 165 fADCchannelECDecal(0),
166 fTimeChannel(0),
167 fTimeChannelDecal(0),
18a21c7c 168 fNADCEC(0),
169 fEventFolderName(eventFolderName),
170 fFirstEvent(0),
171 fLastEvent(0),
f21fc003 172 fCalibData(0x0),
173 fSDigitizer(0x0)
839828a6 174{
05a92d59 175 // ctor
a9485c37 176 InitParameters() ;
88cb7938 177 Init() ;
f21fc003 178 fDigInput = 0 ; // We work in the standalone mode
61e0abb5 179}
839828a6 180
61e0abb5 181//____________________________________________________________________________
18a21c7c 182AliEMCALDigitizer::AliEMCALDigitizer(const AliEMCALDigitizer & d)
183 : AliDigitizer(d.GetName(),d.GetTitle()),
184 fDefaultInit(d.fDefaultInit),
185 fDigitsInRun(d.fDigitsInRun),
186 fInit(d.fInit),
187 fInput(d.fInput),
188 fInputFileNames(d.fInputFileNames),
189 fEventNames(d.fEventNames),
190 fDigitThreshold(d.fDigitThreshold),
191 fMeanPhotonElectron(d.fMeanPhotonElectron),
5fb45456 192 fGainFluctuations(d.fGainFluctuations),
18a21c7c 193 fPinNoise(d.fPinNoise),
6cc75819 194 fTimeNoise(d.fTimeNoise),
f0a6dc6f 195 fTimeDelay(d.fTimeDelay),
a2f8e711 196 fTimeResolutionPar0(d.fTimeResolutionPar0),
197 fTimeResolutionPar1(d.fTimeResolutionPar1),
18a21c7c 198 fADCchannelEC(d.fADCchannelEC),
199 fADCpedestalEC(d.fADCpedestalEC),
6cc75819 200 fADCchannelECDecal(d.fADCchannelECDecal),
201 fTimeChannel(d.fTimeChannel), fTimeChannelDecal(d.fTimeChannelDecal),
18a21c7c 202 fNADCEC(d.fNADCEC),
203 fEventFolderName(d.fEventFolderName),
204 fFirstEvent(d.fFirstEvent),
205 fLastEvent(d.fLastEvent),
f21fc003 206 fCalibData(d.fCalibData),
207 fSDigitizer(d.fSDigitizer ? new AliEMCALSDigitizer(*d.fSDigitizer) : 0)
88cb7938 208{
209 // copyy ctor
96d5ea0d 210}
88cb7938 211
212//____________________________________________________________________________
f21fc003 213AliEMCALDigitizer::AliEMCALDigitizer(AliDigitizationInput * rd)
214 : AliDigitizer(rd,"EMCALDigitizer"),
18a21c7c 215 fDefaultInit(kFALSE),
216 fDigitsInRun(0),
217 fInit(0),
218 fInput(0),
219 fInputFileNames(0),
220 fEventNames(0),
da509d54 221 fDigitThreshold(0),
18a21c7c 222 fMeanPhotonElectron(0),
5fb45456 223 fGainFluctuations(0),
da509d54 224 fPinNoise(0.),
6cc75819 225 fTimeNoise(0.),
f0a6dc6f 226 fTimeDelay(0.),
a2f8e711 227 fTimeResolutionPar0(0.),
228 fTimeResolutionPar1(0.),
18a21c7c 229 fADCchannelEC(0),
230 fADCpedestalEC(0),
6cc75819 231 fADCchannelECDecal(0),
232 fTimeChannel(0),
233 fTimeChannelDecal(0),
18a21c7c 234 fNADCEC(0),
235 fEventFolderName(0),
236 fFirstEvent(0),
237 fLastEvent(0),
f21fc003 238 fCalibData(0x0),
239 fSDigitizer(0x0)
61e0abb5 240{
45fa49ca 241 // ctor Init() is called by RunDigitizer
f21fc003 242 fDigInput = rd ;
243 fEventFolderName = fDigInput->GetInputFolderName(0) ;
244 SetTitle(dynamic_cast<AliStream*>(fDigInput->GetInputStream(0))->GetFileName(0));
05a92d59 245 InitParameters() ;
839828a6 246}
814ad4bf 247
839828a6 248//____________________________________________________________________________
249 AliEMCALDigitizer::~AliEMCALDigitizer()
250{
14ce0a6e 251 //dtor
f5f384f4 252 delete [] fInputFileNames ;
253 delete [] fEventNames ;
f21fc003 254 if (fSDigitizer) delete fSDigitizer;
61e0abb5 255}
256
257//____________________________________________________________________________
a81281f7 258void AliEMCALDigitizer::Digitize(Int_t event)
259{
61e0abb5 260 // Makes the digitization of the collected summable digits
261 // for this it first creates the array of all EMCAL modules
a81281f7 262 // filled with noise and after that adds contributions from
263 // SDigits. This design helps to avoid scanning over the
ab6a174f 264 // list of digits to add contribution of any new SDigit.
265 //
266 // JLK 26-Jun-2008
267 // Note that SDigit energy info is stored as an amplitude, so we
268 // must call the Calibrate() method of the SDigitizer to convert it
269 // back to an energy in GeV before adding it to the Digit
270 //
f69e318a 271
33c3c91a 272 AliRunLoader *rl = AliRunLoader::Instance();
5dee926e 273 AliEMCALLoader *emcalLoader = dynamic_cast<AliEMCALLoader*>(rl->GetDetectorLoader("EMCAL"));
7e1d9a9b 274
f69e318a 275 if(!emcalLoader)
a81281f7 276 {
f69e318a 277 AliFatal("EMCALLoader is NULL!") ;
278 return; // not needed but in case coverity complains ...
279 }
280
281 Int_t readEvent = event ;
282 if (fDigInput) // fDigInput is data member from AliDigitizer
a81281f7 283 readEvent = dynamic_cast<AliStream*>(fDigInput->GetInputStream(0))->GetCurrentEventNumber() ;
f69e318a 284 AliDebug(1,Form("Adding event %d from input stream 0 %s %s",
285 readEvent, GetTitle(), fEventFolderName.Data())) ;
286 rl->GetEvent(readEvent);
287
288 TClonesArray * digits = emcalLoader->Digits() ;
289 digits->Delete() ; //correct way to clear array when memory is
290 //allocated by objects stored in array
291
292 // Load Geometry
293 if (!rl->GetAliRun())
294 {
295 AliFatal("Could not get AliRun from runLoader");
296 return; // not needed but in case coverity complains ...
297 }
298
299 AliEMCAL * emcal = (AliEMCAL*)rl->GetAliRun()->GetDetector("EMCAL");
300 AliEMCALGeometry *geom = emcal->GetGeometry();
301 static int nEMC = geom->GetNCells();//max number of digits possible
302 AliDebug(1,Form("nEMC %i (number cells in EMCAL) | %s \n", nEMC, geom->GetName()));
303
304 digits->Expand(nEMC) ;
305
306 // RS create a digitizer on the fly
307 if (!fSDigitizer) fSDigitizer = new AliEMCALSDigitizer(rl->GetFileName().Data());
308 fSDigitizer->SetEventRange(0, -1) ;
309
cd9ed873 310 //-------------------------------------------------------
f69e318a 311 //take all the inputs to add together and load the SDigits
312 TObjArray * sdigArray = new TObjArray(fInput) ;
313 sdigArray->AddAt(emcalLoader->SDigits(), 0) ;
314
315 Int_t i ;
316 Int_t embed = kFALSE;
317 for(i = 1 ; i < fInput ; i++)
318 {
319 TString tempo(fEventNames[i]) ;
320 tempo += i ;
6cc75819 321
f69e318a 322 AliRunLoader * rl2 = AliRunLoader::GetRunLoader(tempo) ;
6cc75819 323
cd9ed873 324 if (!rl2)
325 rl2 = AliRunLoader::Open(fInputFileNames[i], tempo) ;
326
327 if(!rl2)
328 {
329 AliFatal("Run Loader of second event not available!");
330 return; // not needed but in case coverity complains ...
331 }
96d5ea0d 332
f69e318a 333 if (fDigInput)
cd9ed873 334 readEvent = dynamic_cast<AliStream*>(fDigInput->GetInputStream(i))->GetCurrentEventNumber() ;
335
f69e318a 336 Info("Digitize", "Adding event %d from input stream %d %s %s", readEvent, i, fInputFileNames[i].Data(), tempo.Data()) ;
cd9ed873 337
f69e318a 338 rl2->LoadSDigits();
339 // rl2->LoadDigits();
340 rl2->GetEvent(readEvent);
cd9ed873 341
342 if(!rl2->GetDetectorLoader("EMCAL"))
a81281f7 343 {
cd9ed873 344 AliFatal("Loader of second input not found");
345 return; // not needed but in case coverity complains ...
346 }
347
348 AliEMCALLoader *emcalLoader2 = dynamic_cast<AliEMCALLoader*>(rl2->GetDetectorLoader("EMCAL"));
349
350 if(!emcalLoader2)
351 {
352 AliFatal("EMCAL Loader of second event not available!");
353 return; // not needed but in case coverity complains ...
f69e318a 354 }
cd9ed873 355
356 //Merge 2 simulated sdigits
357 if(!emcalLoader2->SDigits()) continue;
358
359 TClonesArray* sdigits2 = emcalLoader2->SDigits();
360 sdigArray->AddAt(sdigits2, i) ;
361
362 // Check if first sdigit is of embedded type, if so, handle the sdigits differently:
363 // do not smear energy of embedded, do not add noise to any sdigits
364 if( sdigits2->GetEntriesFast() <= 0 ) continue;
365
366 //printf("Merged digit type: %d\n",dynamic_cast<AliEMCALDigit*> (sdigits2->At(0))->GetType());
367 AliEMCALDigit * digit2 = dynamic_cast<AliEMCALDigit*> (sdigits2->At(0));
368 if( digit2 && digit2->GetType()==AliEMCALDigit::kEmbedded ) embed = kTRUE;
369
f69e318a 370 }// input loop
371
cd9ed873 372 //--------------------------------
f69e318a 373 //Find the first tower with signal
374 Int_t nextSig = nEMC + 1 ;
375 TClonesArray * sdigits ;
cd9ed873 376 for(i = 0 ; i < fInput ; i++)
377 {
f69e318a 378 if(i > 0 && embed) continue;
8e708def 379
f69e318a 380 sdigits = dynamic_cast<TClonesArray *>(sdigArray->At(i)) ;
8e708def 381 if(!sdigits)
f69e318a 382 {
383 AliDebug(1,"Null sdigit pointer");
384 continue;
385 }
8e708def 386
387 if (sdigits->GetEntriesFast() <= 0 )
388 {
389 AliDebug(1, "No sdigits entries");
390 continue;
391 }
392
393 AliEMCALDigit *sd = dynamic_cast<AliEMCALDigit *>(sdigits->At(0));
394 if(!sd)
395 {
396 AliDebug(1, "NULL sdigit pointer");
397 continue;
398 }
399
400 Int_t curNext = sd->GetId() ;
401 if(curNext < nextSig)
402 nextSig = curNext ;
403 AliDebug(1,Form("input %i : #sdigits %i \n",i, sdigits->GetEntriesFast()));
404
f69e318a 405 }// input loop
8e708def 406
f69e318a 407 AliDebug(1,Form("FIRST tower with signal %i \n", nextSig));
408
409 TArrayI index(fInput) ;
410 index.Reset() ; //Set all indexes to zero
411
412 AliEMCALDigit * digit ;
413 AliEMCALDigit * curSDigit ;
414
cd9ed873 415 //---------------------------------------------
f69e318a 416 //Put Noise contribution, smear time and energy
417 Float_t timeResolution = 0;
418 Int_t absID = -1 ;
419 for(absID = 0; absID < nEMC; absID++)
c4b2aadf 420 {
f69e318a 421 Float_t energy = 0 ;
a81281f7 422
f69e318a 423 // amplitude set to zero, noise will be added later
424 Float_t noiseTime = 0.;
425 if(!embed) noiseTime = TimeOfNoise(); //No need for embedded events?
426 new((*digits)[absID]) AliEMCALDigit( -1, -1, absID, 0., noiseTime,kFALSE); // absID-1->absID
427 //look if we have to add signal?
428 digit = dynamic_cast<AliEMCALDigit *>(digits->At(absID)); // absID-1->absID
429
8e708def 430 if (!digit)
431 {
432 AliDebug(1,"Digit pointer is null");
433 continue;
434 }
435
436 if(absID==nextSig)
f69e318a 437 {
8e708def 438 // Calculate time as time of the largest digit
439 Float_t time = digit->GetTime() ;
440 Float_t aTime= digit->GetAmplitude() ;
441
442 // loop over input
443 Int_t nInputs = fInput;
444 if(embed) nInputs = 1; // In case of embedding, merge later real digits, do not smear energy and time of data
445 for(i = 0; i< nInputs ; i++)
a81281f7 446 {
8e708def 447 //loop over (possible) merge sources
448 TClonesArray* sdtclarr = dynamic_cast<TClonesArray *>(sdigArray->At(i));
449 if(sdtclarr)
450 {
451 Int_t sDigitEntries = sdtclarr->GetEntriesFast();
452
453 if(sDigitEntries > index[i] ) curSDigit = dynamic_cast<AliEMCALDigit*>(sdtclarr->At(index[i])) ;
454 else curSDigit = 0 ;
f69e318a 455
8e708def 456 //May be several digits will contribute from the same input
457 while(curSDigit && (curSDigit->GetId() == absID))
458 {
459 //Shift primary to separate primaries belonging different inputs
460 Int_t primaryoffset = i ;
461 if(fDigInput) primaryoffset = fDigInput->GetMask(i) ;
462 curSDigit->ShiftPrimary(primaryoffset) ;
463
464 if(curSDigit->GetAmplitude()>aTime)
f69e318a 465 {
8e708def 466 aTime = curSDigit->GetAmplitude();
467 time = curSDigit->GetTime();
f69e318a 468 }
8e708def 469
470 *digit = *digit + *curSDigit ; //adds amplitudes of each digit
471
472 index[i]++ ;
473
474 if( sDigitEntries > index[i] ) curSDigit = dynamic_cast<AliEMCALDigit*>(sdtclarr->At(index[i])) ;
475 else curSDigit = 0 ;
476 }// while
477 }// source exists
478 }// loop over merging sources
f69e318a 479
8e708def 480 //Here we convert the summed amplitude to an energy in GeV only for simulation or mixing of simulations
481 energy = fSDigitizer->Calibrate(digit->GetAmplitude()) ; // GeV
482
483 // add fluctuations for photo-electron creation
484 // corrected fluctuations after comparison with beam test, Paraskevi Ganoti (06/11/2011)
485 Float_t fluct = static_cast<Float_t>((energy*fMeanPhotonElectron)/fGainFluctuations);
486 energy *= static_cast<Float_t>(gRandom->Poisson(fluct)) / fluct ;
f69e318a 487
8e708def 488 //calculate and set time
489 digit->SetTime(time) ;
6cc75819 490
8e708def 491 //Find next signal module
492 nextSig = nEMC + 1 ;
493 for(i = 0 ; i < nInputs ; i++)
494 {
495 sdigits = dynamic_cast<TClonesArray *>(sdigArray->At(i)) ;
496
497 if(sdigits)
498 {
499 Int_t curNext = nextSig ;
500 if(sdigits->GetEntriesFast() > index[i])
501 {
502 AliEMCALDigit * tmpdigit = dynamic_cast<AliEMCALDigit *>(sdigits->At(index[i]));
83366f85 503 if ( tmpdigit ) curNext = tmpdigit->GetId() ;
8e708def 504 }
83366f85 505
8e708def 506 if(curNext < nextSig) nextSig = curNext ;
507 }// sdigits exist
508 } // input loop
f69e318a 509
8e708def 510 }//absID==nextSig
511
512 // add the noise now, no need for embedded events with real data
513 if(!embed)
514 energy += gRandom->Gaus(0., fPinNoise) ;
515
516 // JLK 26-June-2008
517 //Now digitize the energy according to the fSDigitizer method,
518 //which merely converts the energy to an integer. Later we will
519 //check that the stored value matches our allowed dynamic ranges
520 digit->SetAmplitude(fSDigitizer->Digitize(energy)) ;
521
522 //Set time resolution with final energy
523 timeResolution = GetTimeResolution(energy);
524 digit->SetTime(gRandom->Gaus(digit->GetTime(),timeResolution) ) ;
525 AliDebug(10,Form(" absID %5i energy %f nextSig %5i\n",
526 absID, energy, nextSig));
527 //Add delay to time
528 digit->SetTime(digit->GetTime()+fTimeDelay) ;
a81281f7 529
f69e318a 530 } // for(absID = 0; absID < nEMC; absID++)
531
cd9ed873 532 //---------------------------------------------------------
f69e318a 533 //Embed simulated amplitude (and time?) to real data digits
83366f85 534 if ( embed )
f69e318a 535 {
536 for(Int_t input = 1; input<fInput; input++)
a81281f7 537 {
f69e318a 538 TClonesArray *realDigits = dynamic_cast<TClonesArray*> (sdigArray->At(input));
539 if(!realDigits)
a81281f7 540 {
f69e318a 541 AliDebug(1,"No sdigits to merge\n");
542 continue;
543 }
544
545 for(Int_t i2 = 0 ; i2 < realDigits->GetEntriesFast() ; i2++)
546 {
547 AliEMCALDigit * digit2 = dynamic_cast<AliEMCALDigit*>( realDigits->At(i2) ) ;
83366f85 548 if ( !digit2 ) continue;
549
550 digit = dynamic_cast<AliEMCALDigit*>( digits->At(digit2->GetId()) ) ;
551 if ( !digit ) continue;
552
553 // Put the embedded cell energy in same units as simulated sdigits -> transform to energy units
554 // and multiply to get a big int.
555 Float_t time2 = digit2->GetTime();
556 Float_t e2 = digit2->GetAmplitude();
557 CalibrateADCTime(e2,time2,digit2->GetId());
558 Float_t amp2 = fSDigitizer->Digitize(e2);
559
560 Float_t e0 = digit ->GetAmplitude();
561 if(e0>0.01)
562 AliDebug(1,Form("digit 1: Abs ID %d, amp %f, type %d, time %e; digit2: Abs ID %d, amp %f, type %d, time %e\n",
563 digit ->GetId(),digit ->GetAmplitude(), digit ->GetType(), digit->GetTime(),
564 digit2->GetId(),amp2, digit2->GetType(), time2 ));
565
566 // Sum amplitudes, change digit amplitude
567 digit->SetAmplitude( digit->GetAmplitude() + amp2);
568
569 // Rough assumption, assign time of the largest of the 2 digits,
570 // data or signal to the final digit.
571 if(amp2 > digit->GetAmplitude()) digit->SetTime(time2);
572
573 //Mark the new digit as embedded
574 digit->SetType(AliEMCALDigit::kEmbedded);
575
576 if(digit2->GetAmplitude()>0.01 && e0> 0.01 )
577 AliDebug(1,Form("Embedded digit: Abs ID %d, amp %f, type %d\n",
578 digit->GetId(), digit->GetAmplitude(), digit->GetType()));
f69e318a 579 }//loop digit 2
580 }//input loop
581 }//embed
582
583 //JLK is it better to call Clear() here?
584 delete sdigArray ; //We should not delete its contents
585
cd9ed873 586 //------------------------------
f69e318a 587 //remove digits below thresholds
588 // until 10-02-2010 remove digits with energy smaller than fDigitThreshold 3*fPinNoise
589 // now, remove digits with Digitized ADC smaller than fDigitThreshold = 3,
590 // before merge in the same loop real data digits if available
591 Float_t energy = 0;
592 Float_t time = 0;
593 for(i = 0 ; i < nEMC ; i++)
594 {
595 digit = dynamic_cast<AliEMCALDigit*>( digits->At(i) ) ;
83366f85 596 if ( !digit ) continue;
597
598 //Then get the energy in GeV units.
599 energy = fSDigitizer->Calibrate(digit->GetAmplitude()) ;
600
601 //Then digitize using the calibration constants of the ocdb
602 Float_t ampADC = energy;
603 DigitizeEnergyTime(ampADC, time, digit->GetId()) ;
604
c4b2aadf 605 if(ampADC < fDigitThreshold || IsDead(digit->GetId()))
f69e318a 606 digits->RemoveAt(i) ;
83366f85 607
f69e318a 608 } // digit loop
609
610 digits->Compress() ;
611
612 Int_t ndigits = digits->GetEntriesFast() ;
613
cd9ed873 614 //---------------------------------------------------------------
f69e318a 615 //JLK 26-June-2008
616 //After we have done the summing and digitizing to create the
617 //digits, now we want to calibrate the resulting amplitude to match
618 //the dynamic range of our real data.
619 for (i = 0 ; i < ndigits ; i++)
620 {
621 digit = dynamic_cast<AliEMCALDigit *>( digits->At(i) ) ;
83366f85 622 if( !digit ) continue ;
623
624 digit->SetIndexInList(i) ;
625
626 time = digit->GetTime();
627 digit->SetTime(time);
628
629 energy = fSDigitizer->Calibrate(digit->GetAmplitude()) ;
630
631 Float_t ampADC = energy;
632 DigitizeEnergyTime(ampADC, time, digit->GetId());
633
634 digit->SetAmplitude(ampADC) ;
635 // printf("digit amplitude set at end: i %d, amp %f\n",i,digit->GetAmplitude());
f69e318a 636 }//Digit loop
6cc75819 637
814ad4bf 638}
61e0abb5 639
6cc75819 640//_____________________________________________________________________
641void AliEMCALDigitizer::DigitizeEnergyTime(Float_t & energy, Float_t & time, const Int_t absId)
a81281f7 642{
ab6a174f 643 // JLK 26-June-2008
e4dcc484 644 // Returns digitized value of the energy in a cell absId
ab6a174f 645 // using the calibration constants stored in the OCDB
646 // or default values if no CalibData object is found.
647 // This effectively converts everything to match the dynamic range
648 // of the real data we will collect
649 //
53f1c378 650 // Load Geometry
651 const AliEMCALGeometry * geom = AliEMCALGeometry::GetInstance();
d62a891a 652
a81281f7 653 if (geom==0)
654 {
96d5ea0d 655 AliFatal("Did not get geometry from EMCALLoader");
6cc75819 656 return;
e4dcc484 657 }
5eb74a51 658
6cc75819 659 Int_t iSupMod = -1;
660 Int_t nModule = -1;
661 Int_t nIphi = -1;
662 Int_t nIeta = -1;
663 Int_t iphi = -1;
664 Int_t ieta = -1;
665 Bool_t bCell = geom->GetCellIndex(absId, iSupMod, nModule, nIphi, nIeta) ;
666 if(!bCell)
a81281f7 667 Error("DigitizeEnergyTime","Wrong cell id number : absId %i ", absId) ;
6cc75819 668 geom->GetCellPhiEtaIndexInSModule(iSupMod,nModule,nIphi, nIeta,iphi,ieta);
96d5ea0d 669
a81281f7 670 if(fCalibData)
671 {
6cc75819 672 fADCpedestalEC = fCalibData->GetADCpedestal (iSupMod,ieta,iphi);
673 fADCchannelEC = fCalibData->GetADCchannel (iSupMod,ieta,iphi);
674 fADCchannelECDecal = fCalibData->GetADCchannelDecal (iSupMod,ieta,iphi);
031c3928 675 fTimeChannel = fCalibData->GetTimeChannel (iSupMod,ieta,iphi,0); // Assign bunch crossing number equal to 0 (has simulation different bunch crossings?)
a81281f7 676 fTimeChannelDecal = fCalibData->GetTimeChannelDecal(iSupMod,ieta,iphi);
6cc75819 677 }
678
679 //Apply calibration to get ADC counts and partial decalibration as especified in OCDB
680 energy = (energy + fADCpedestalEC)/fADCchannelEC/fADCchannelECDecal ;
681 time += fTimeChannel-fTimeChannelDecal;
682
6337857a 683 if ( energy > fNADCEC ) energy = fNADCEC ;
6cc75819 684}
829ba234 685
63c22917 686//_____________________________________________________________________
6337857a 687void AliEMCALDigitizer::DecalibrateTrigger(AliEMCALDigit *digit)
a81281f7 688{
689 // Decalibrate, used in Trigger digits
6337857a 690
691 if ( !fCalibData ) return ;
692
a81281f7 693 // Load Geometry
694 const AliEMCALGeometry *geom = AliEMCALGeometry::GetInstance();
63c22917 695
a81281f7 696 if (!geom)
697 {
698 AliFatal("Did not get geometry from EMCALLoader");
699 return;
700 }
63c22917 701
6337857a 702 // Recover the digit location in row-column-SM
a81281f7 703 Int_t absId = digit->GetId();
704 Int_t iSupMod = -1;
705 Int_t nModule = -1;
706 Int_t nIphi = -1;
707 Int_t nIeta = -1;
708 Int_t iphi = -1;
709 Int_t ieta = -1;
52e22b66 710
a81281f7 711 Bool_t bCell = geom->GetCellIndex(absId, iSupMod, nModule, nIphi, nIeta) ;
a81281f7 712 if (!bCell) Error("Decalibrate","Wrong cell id number : absId %i ", absId) ;
6337857a 713
a81281f7 714 geom->GetCellPhiEtaIndexInSModule(iSupMod,nModule,nIphi, nIeta,iphi,ieta);
63c22917 715
6337857a 716 // Now decalibrate
717 Float_t adcChannel = fCalibData->GetADCchannel (iSupMod,ieta,iphi);
718 Float_t adcChannelOnline = fCalibData->GetADCchannelOnline(iSupMod,ieta,iphi);
719 //printf("calib param for (SM%d,col%d,row%d): %1.4f - online param: %1.4f \n",iSupMod,ieta,iphi,adcChannel,adcChannelOnline);
720 Float_t factor = 1./(adcChannel/adcChannelOnline);
721
722 *digit = *digit * factor;
723
63c22917 724}
725
6cc75819 726//_____________________________________________________________________
727void AliEMCALDigitizer::CalibrateADCTime(Float_t & adc, Float_t & time, const Int_t absId)
a81281f7 728{
6cc75819 729 // Returns the energy in a cell absId with a given adc value
730 // using the calibration constants stored in the OCDB. Time also corrected from parameter in OCDB
731 // Used in case of embedding, transform ADC counts from real event into energy
732 // so that we can add the energy of the simulated sdigits which are in energy
733 // units.
734 // Same as in AliEMCALClusterizer::Calibrate() but here we do not reject channels being marked as hot
735 // or with time out of window
736
737 // Load Geometry
738 const AliEMCALGeometry * geom = AliEMCALGeometry::GetInstance();
739
a81281f7 740 if (!geom)
741 {
6cc75819 742 AliFatal("Did not get geometry from EMCALLoader");
743 return;
744 }
745
746 Int_t iSupMod = -1;
747 Int_t nModule = -1;
748 Int_t nIphi = -1;
749 Int_t nIeta = -1;
750 Int_t iphi = -1;
751 Int_t ieta = -1;
752 Bool_t bCell = geom->GetCellIndex(absId, iSupMod, nModule, nIphi, nIeta) ;
a81281f7 753 if(!bCell) Error("CalibrateADCTime","Wrong cell id number : absId %i ", absId) ;
6cc75819 754 geom->GetCellPhiEtaIndexInSModule(iSupMod,nModule,nIphi, nIeta,iphi,ieta);
755
a81281f7 756 if(fCalibData)
757 {
6cc75819 758 fADCpedestalEC = fCalibData->GetADCpedestal(iSupMod,ieta,iphi);
759 fADCchannelEC = fCalibData->GetADCchannel (iSupMod,ieta,iphi);
031c3928 760 fTimeChannel = fCalibData->GetTimeChannel(iSupMod,ieta,iphi,0);// Assign bunch crossing number equal to 0 (has simulation different bunch crossings?)
6cc75819 761 }
762
763 adc = adc * fADCchannelEC - fADCpedestalEC;
764 time -= fTimeChannel;
96d5ea0d 765
61e0abb5 766}
767
6cc75819 768
61e0abb5 769//____________________________________________________________________________
2f9aea1a 770void AliEMCALDigitizer::Digitize(Option_t *option)
771{
45fa49ca 772 // Steering method to process digitization for events
773 // in the range from fFirstEvent to fLastEvent.
774 // This range is optionally set by SetEventRange().
775 // if fLastEvent=-1, then process events until the end.
776 // by default fLastEvent = fFirstEvent (process only one event)
2f9aea1a 777
778 if (!fInit)
779 { // to prevent overwrite existing file
f21fc003 780 Error( "Digitize", "Give a version name different from %s", fEventFolderName.Data() ) ;
88cb7938 781 return ;
2f9aea1a 782 }
783
784 if (strstr(option,"print"))
785 {
88cb7938 786 Print();
2f9aea1a 787 return ;
814ad4bf 788 }
789
61e0abb5 790 if(strstr(option,"tim"))
791 gBenchmark->Start("EMCALDigitizer");
2f9aea1a 792
33c3c91a 793 AliRunLoader *rl = AliRunLoader::Instance();
2f9aea1a 794
5dee926e 795 AliEMCALLoader *emcalLoader = dynamic_cast<AliEMCALLoader*>(rl->GetDetectorLoader("EMCAL"));
efb8df82 796 if(!emcalLoader)
797 {
96d5ea0d 798 AliFatal("Did not get the Loader");
2f9aea1a 799 return; // coverity
30bc5594 800 }
2f9aea1a 801
802 if (fLastEvent == -1)
803 fLastEvent = rl->GetNumberOfEvents() - 1 ;
804 else if (fDigInput)
805 fLastEvent = fFirstEvent ; // what is this ??
806
807 Int_t nEvents = fLastEvent - fFirstEvent + 1;
808 Int_t ievent = -1;
809
810 AliEMCAL * emcal = dynamic_cast<AliEMCAL*>(rl->GetAliRun()->GetDetector("EMCAL"));
811 if(!emcal)
efb8df82 812 {
2f9aea1a 813 AliFatal("Did not get the AliEMCAL pointer");
814 return; // coverity
815 }
816
817 AliEMCALGeometry *geom = emcal->GetGeometry();
818 if(!geom)
819 {
820 AliFatal("Geometry pointer null");
821 return; // fix for coverity
822 }
823
824 const Int_t nTRU = geom->GetNTotalTRU();
825 TClonesArray* digitsTMP = new TClonesArray("AliEMCALDigit", nTRU*96);
826 TClonesArray* digitsTRG = new TClonesArray("AliEMCALRawDigit", nTRU*96);
827
828 rl->LoadSDigits("EMCAL");
829 for (ievent = fFirstEvent; ievent <= fLastEvent; ievent++)
830 {
831 rl->GetEvent(ievent);
96d5ea0d 832
2f9aea1a 833 Digitize(ievent) ; //Add prepared SDigits to digits and add the noise
efb8df82 834
2f9aea1a 835 WriteDigits() ;
836
837 //Trigger Digits
838 //-------------------------------------
839
840 Digits2FastOR(digitsTMP, digitsTRG);
841
842 WriteDigits(digitsTRG);
843
844 (emcalLoader->TreeD())->Fill();
845
846 emcalLoader->WriteDigits( "OVERWRITE");
847
848 Unload();
849
850 digitsTRG ->Delete();
851 digitsTMP ->Delete();
852
853 //-------------------------------------
854
855 if(strstr(option,"deb"))
856 PrintDigits(option);
857 if(strstr(option,"table")) gObjectTable->Print();
858
859 //increment the total number of Digits per run
860 fDigitsInRun += emcalLoader->Digits()->GetEntriesFast() ;
861 }//loop
64942713 862
2f9aea1a 863 if(strstr(option,"tim"))
864 {
61e0abb5 865 gBenchmark->Stop("EMCALDigitizer");
0bd264d5 866 Float_t cputime = gBenchmark->GetCpuTime("EMCALDigitizer");
867 Float_t avcputime = cputime;
868 if(nEvents==0) avcputime = 0 ;
869 AliInfo(Form("Digitize: took %f seconds for Digitizing %f seconds per event", cputime, avcputime)) ;
2f9aea1a 870 }
61e0abb5 871}
872
a2f8e711 873//__________________________________________________________________
874Float_t AliEMCALDigitizer::GetTimeResolution(Float_t energy) const
875{
a81281f7 876 // Assign a smeared time to the digit, from observed distribution in LED system (?).
a2f8e711 877 // From F. Blanco
878 Float_t res = -1;
a81281f7 879 if (energy > 0)
880 {
a2f8e711 881 res = TMath::Sqrt(fTimeResolutionPar0 +
882 fTimeResolutionPar1/(energy*energy) );
883 }
b2a891e0 884 // parametrization above is for ns. Convert to seconds:
885 return res*1e-9;
a2f8e711 886}
887
a81281f7 888//____________________________________________________________________________
916f1e76 889void AliEMCALDigitizer::Digits2FastOR(TClonesArray* digitsTMP, TClonesArray* digitsTRG)
890{
a81281f7 891 // FEE digits afterburner to produce TRG digits
de39a0ff 892 // we are only interested in the FEE digit deposited energy
893 // to be converted later into a voltage value
894
895 // push the FEE digit to its associated FastOR (numbered from 0:95)
896 // TRU is in charge of summing module digits
897
898 AliRunLoader *runLoader = AliRunLoader::Instance();
899
de39a0ff 900 AliEMCALLoader *emcalLoader = dynamic_cast<AliEMCALLoader*>(runLoader->GetDetectorLoader("EMCAL"));
6995e8b7 901 if (!emcalLoader) AliFatal("Did not get the Loader");
902
a81281f7 903 const AliEMCALGeometry* geom = AliEMCALGeometry::GetInstance();
efb8df82 904 if(!geom)
905 {
906 AliFatal("Geometry pointer null");
907 return; // fix for coverity
908 }
a81281f7 909
910 // build FOR from simulated digits
911 // and xfer to the corresponding TRU input (mapping)
912
913 TClonesArray* sdigits = emcalLoader->SDigits();
914
915 TClonesArray *digits = (TClonesArray*)sdigits->Clone();
916
917 AliDebug(999,Form("=== %d SDigits to trigger digits ===",digits->GetEntriesFast()));
918
919 TIter NextDigit(digits);
920 while (AliEMCALDigit* digit = (AliEMCALDigit*)NextDigit())
921 {
922 if (IsDead(digit)) continue;
923
6337857a 924 DecalibrateTrigger(digit);
a81281f7 925
926 Int_t id = digit->GetId();
927
928 Int_t trgid;
efb8df82 929 if (geom->GetFastORIndexFromCellIndex(id , trgid))
a81281f7 930 {
931 AliDebug(1,Form("trigger digit id: %d from cell id: %d\n",trgid,id));
7e1d9a9b 932
a81281f7 933 AliEMCALDigit* d = static_cast<AliEMCALDigit*>(digitsTMP->At(trgid));
7d525d9d 934
a81281f7 935 if (!d)
96d5ea0d 936 {
a81281f7 937 new((*digitsTMP)[trgid]) AliEMCALDigit(*digit);
938 d = (AliEMCALDigit*)digitsTMP->At(trgid);
939 d->SetId(trgid);
940 }
941 else
942 {
943 *d = *d + *digit;
96d5ea0d 944 }
a81281f7 945 }
946 }
947
948 if (AliDebugLevel()) printf("Number of TRG digits: %d\n",digitsTMP->GetEntriesFast());
949
950 Int_t nSamples = geom->GetNTotalTRU();
951 Int_t *timeSamples = new Int_t[nSamples];
952
953 NextDigit = TIter(digitsTMP);
954 while (AliEMCALDigit* digit = (AliEMCALDigit*)NextDigit())
955 {
956 if (digit)
957 {
958 Int_t id = digit->GetId();
959 Float_t time = 50.e-9;
7e1d9a9b 960
a81281f7 961 Double_t depositedEnergy = 0.;
962 for (Int_t j = 1; j <= digit->GetNprimary(); j++) depositedEnergy += digit->GetDEPrimary(j);
7e1d9a9b 963
a81281f7 964 if (AliDebugLevel()) printf("Deposited Energy: %f\n", depositedEnergy);
965
966 // FIXME: Check digit time!
967 if (depositedEnergy) {
968 depositedEnergy += gRandom->Gaus(0., .08);
969 DigitalFastOR(time, depositedEnergy, timeSamples, nSamples);
970
971 for (Int_t j=0;j<nSamples;j++) {
972 if (AliDebugLevel()) printf("timeSamples[%d]: %d\n",j,timeSamples[j]);
973 timeSamples[j] = ((j << 16) | (timeSamples[j] & 0xFFFF));
7e1d9a9b 974 }
a81281f7 975
976 new((*digitsTRG)[digitsTRG->GetEntriesFast()]) AliEMCALRawDigit(id, timeSamples, nSamples);
977
978 if (AliDebugLevel()) ((AliEMCALRawDigit*)digitsTRG->At(digitsTRG->GetEntriesFast() - 1))->Print("");
96d5ea0d 979 }
a81281f7 980 }
981 }
982
983 delete [] timeSamples;
984
985 if (digits && digits->GetEntriesFast()) digits->Delete();
916f1e76 986}
987
a81281f7 988//____________________________________________________________________________
916f1e76 989void AliEMCALDigitizer::DigitalFastOR( Double_t time, Double_t dE, Int_t timeSamples[], Int_t nSamples )
990{
a81281f7 991 // parameters:
992 // id: 0..95
993 const Int_t reso = 12; // 11-bit resolution ADC
994 const Double_t vFSR = 2.; // Full scale input voltage range 2V (p-p)
995//const Double_t dNe = 125; // signal of the APD per MeV of energy deposit in a tower: 125 photo-e-/MeV @ M=30
996 const Double_t dNe = 125/1.3; // F-ALTRO max V. FEE: factor 4
997 const Double_t vA = .136e-6; // CSP output range: 0.136uV/e-
998 const Double_t rise = 50e-9; // rise time (10-90%) of the FastOR signal before shaping
916f1e76 999
a81281f7 1000 const Double_t kTimeBinWidth = 25E-9; // sampling frequency (40MHz)
916f1e76 1001
a81281f7 1002 Double_t vV = 1000. * dE * dNe * vA; // GeV 2 MeV
1003
1004 TF1 signalF("signal", AnalogFastORFunction, 0, nSamples * kTimeBinWidth, 3);
1005 signalF.SetParameter( 0, vV );
1006 signalF.SetParameter( 1, time ); // FIXME: when does the signal arrive? Might account for cable lengths
1007 signalF.SetParameter( 2, rise );
916f1e76 1008
a81281f7 1009 for (Int_t iTime=0; iTime<nSamples; iTime++)
1010 {
1011 // FIXME: add noise (probably not simply Gaussian) according to DA measurements
1012 // probably plan an access to OCDB
28bcaaaa 1013 Double_t sig = signalF.Eval(iTime * kTimeBinWidth);
1014 if (TMath::Abs(sig) > vFSR/2.) {
1015 AliError("Signal overflow!");
1016 timeSamples[iTime] = (1 << reso) - 1;
1017 } else {
1018 AliDebug(999,Form("iTime: %d sig: %f\n",iTime,sig));
1019 timeSamples[iTime] = ((1 << reso) / vFSR) * sig + 0.5;
1020 }
a81281f7 1021 }
916f1e76 1022}
1023
05a92d59 1024//____________________________________________________________________________
1025Bool_t AliEMCALDigitizer::Init()
1026{
1027 // Makes all memory allocations
88cb7938 1028 fInit = kTRUE ;
33c3c91a 1029 AliEMCALLoader *emcalLoader = dynamic_cast<AliEMCALLoader*>(AliRunLoader::Instance()->GetDetectorLoader("EMCAL"));
61d80ce0 1030
5dee926e 1031 if ( emcalLoader == 0 ) {
1032 Fatal("Init", "Could not obtain the AliEMCALLoader");
05a92d59 1033 return kFALSE;
1034 }
61d80ce0 1035
45fa49ca 1036 fFirstEvent = 0 ;
1037 fLastEvent = fFirstEvent ;
1038
f21fc003 1039 if(fDigInput)
1040 fInput = fDigInput->GetNinputs() ;
88cb7938 1041 else
1042 fInput = 1 ;
1043
1044 fInputFileNames = new TString[fInput] ;
1045 fEventNames = new TString[fInput] ;
1046 fInputFileNames[0] = GetTitle() ;
1047 fEventNames[0] = fEventFolderName.Data() ;
1048 Int_t index ;
1049 for (index = 1 ; index < fInput ; index++) {
f21fc003 1050 fInputFileNames[index] = dynamic_cast<AliStream*>(fDigInput->GetInputStream(index))->GetFileName(0);
1051 TString tempo = fDigInput->GetInputFolderName(index) ;
1052 fEventNames[index] = tempo.Remove(tempo.Length()-1) ; // strip of the stream number added bt fDigInput
05a92d59 1053 }
f21fc003 1054
53f1c378 1055 //Calibration instance
1056 fCalibData = emcalLoader->CalibData();
88cb7938 1057 return fInit ;
05a92d59 1058}
1059
1060//____________________________________________________________________________
1061void AliEMCALDigitizer::InitParameters()
14ce0a6e 1062{
29b5d492 1063 // Parameter initialization for digitizer
6569f329 1064
1065 // Get the parameters from the OCDB via the loader
1066 AliRunLoader *rl = AliRunLoader::Instance();
1067 AliEMCALLoader *emcalLoader = dynamic_cast<AliEMCALLoader*>(rl->GetDetectorLoader("EMCAL"));
1068 AliEMCALSimParam * simParam = 0x0;
1069 if(emcalLoader) simParam = emcalLoader->SimulationParameters();
1070
1071 if(!simParam){
61d80ce0 1072 simParam = AliEMCALSimParam::GetInstance();
1073 AliWarning("Simulation Parameters not available in OCDB?");
6569f329 1074 }
61d80ce0 1075
5fb45456 1076 fMeanPhotonElectron = simParam->GetMeanPhotonElectron() ; // 4400; // electrons per GeV
1077 fGainFluctuations = simParam->GetGainFluctuations() ; // 15.0;
1078
6569f329 1079 fPinNoise = simParam->GetPinNoise();//0.012; // pin noise in GeV from analysis test beam data
33a52e55 1080 if (fPinNoise < 0.0001 )
88cb7938 1081 Warning("InitParameters", "No noise added\n") ;
6cc75819 1082 fTimeNoise = simParam->GetTimeNoise(); // 1.28E-5 s
6569f329 1083 fDigitThreshold = simParam->GetDigitThreshold(); //fPinNoise * 3; // 3 * sigma
a2f8e711 1084 fTimeResolutionPar0 = simParam->GetTimeResolutionPar0();
1085 fTimeResolutionPar1 = simParam->GetTimeResolutionPar1();
f0a6dc6f 1086 fTimeDelay = simParam->GetTimeDelay(); //600e-9 ; // 600 ns
61d80ce0 1087
97075cd8 1088 // These defaults are normally not used.
1089 // Values are read from calibration database instead
6337857a 1090 fADCchannelEC = 0.0162; // Nominal value set online for most of the channels, MIP peak sitting at ~266./16/1024
6cc75819 1091 fADCpedestalEC = 0.0 ; // GeV
1092 fADCchannelECDecal = 1.0; // No decalibration by default
1093 fTimeChannel = 0.0; // No time calibration by default
1094 fTimeChannelDecal = 0.0; // No time decalibration by default
33a52e55 1095
6cc75819 1096 fNADCEC = simParam->GetNADCEC();//(Int_t) TMath::Power(2,16) ; // number of channels in Tower ADC - 65536
61d80ce0 1097
5fb45456 1098 AliDebug(2,Form("Mean Photon Electron %d, Gain Fluct. %2.1f; Noise: APD %f, Time %f; Digit Threshold %d,Time Resolution Par0 %g Par1 %g,NADCEC %d",
1099 fMeanPhotonElectron, fGainFluctuations, fPinNoise,fTimeNoise, fDigitThreshold,fTimeResolutionPar0,fTimeResolutionPar1,fNADCEC));
1100
05a92d59 1101}
61e0abb5 1102
fe93d365 1103//__________________________________________________________________
1963b290 1104void AliEMCALDigitizer::Print1(Option_t * option)
6cc75819 1105{ // 19-nov-04 - just for convenience
1963b290 1106 Print();
1107 PrintDigits(option);
1108}
1109
61e0abb5 1110//__________________________________________________________________
6cc75819 1111void AliEMCALDigitizer::Print (Option_t * ) const
88cb7938 1112{
1113 // Print Digitizer's parameters
fdebddeb 1114 printf("Print: \n------------------- %s -------------", GetName() ) ;
88cb7938 1115 if( strcmp(fEventFolderName.Data(), "") != 0 ){
1116 printf(" Writing Digits to branch with title %s\n", fEventFolderName.Data()) ;
1117
1118 Int_t nStreams ;
f21fc003 1119 if (fDigInput)
88cb7938 1120 nStreams = GetNInputStreams() ;
1121 else
1122 nStreams = fInput ;
61d80ce0 1123
53e430a3 1124 AliRunLoader *rl=0;
88cb7938 1125
1126 Int_t index = 0 ;
1127 for (index = 0 ; index < nStreams ; index++) {
1128 TString tempo(fEventNames[index]) ;
1129 tempo += index ;
5dee926e 1130 if ((rl = AliRunLoader::GetRunLoader(tempo)) == 0)
96d5ea0d 1131 rl = AliRunLoader::Open(fInputFileNames[index], tempo) ;
5dee926e 1132 AliEMCALLoader *emcalLoader = dynamic_cast<AliEMCALLoader*>(rl->GetDetectorLoader("EMCAL"));
96d5ea0d 1133 if(emcalLoader){
1134 TString fileName( emcalLoader->GetSDigitsFileName() ) ;
1135 if ( fEventNames[index] != AliConfig::GetDefaultEventFolderName()) // only if not the default folder name
1136 fileName = fileName.ReplaceAll(".root", "") + "_" + fEventNames[index] + ".root" ;
1137 printf ("Adding SDigits from %s %s\n", fInputFileNames[index].Data(), fileName.Data()) ;
1138 }//loader
88cb7938 1139 }
61d80ce0 1140
33c3c91a 1141 AliEMCALLoader *emcalLoader = dynamic_cast<AliEMCALLoader*>(AliRunLoader::Instance()->GetDetectorLoader("EMCAL"));
61d80ce0 1142
96d5ea0d 1143 if(emcalLoader) printf("\nWriting digits to %s", emcalLoader->GetDigitsFileName().Data()) ;
1144 else printf("\nNULL LOADER");
61d80ce0 1145
88cb7938 1146 printf("\nWith following parameters:\n") ;
6cc75819 1147 printf(" Electronics noise in EMC, APD (fPinNoise) = %f, Time = %f \n", fPinNoise, fTimeNoise) ;
4354827d 1148 printf(" Threshold in Tower (fDigitThreshold) = %d\n", fDigitThreshold) ;
88cb7938 1149 printf("---------------------------------------------------\n") ;
ea5f3389 1150 }
1151 else
fdebddeb 1152 printf("Print: AliEMCALDigitizer not initialized") ;
61e0abb5 1153}
814ad4bf 1154
e41b8233 1155//__________________________________________________________________
14ce0a6e 1156void AliEMCALDigitizer::PrintDigits(Option_t * option)
1157{
1158 //utility method for printing digit information
61d80ce0 1159
33c3c91a 1160 AliEMCALLoader *emcalLoader = dynamic_cast<AliEMCALLoader*>(AliRunLoader::Instance()->GetDetectorLoader("EMCAL"));
96d5ea0d 1161 if(emcalLoader){
1162 TClonesArray * digits = emcalLoader->Digits() ;
1163 TClonesArray * sdigits = emcalLoader->SDigits() ;
1164
1165 printf("\n #Digits: %d : sdigits %d ", digits->GetEntriesFast(), sdigits->GetEntriesFast()) ;
1166 printf("\n event %d", emcalLoader->GetRunLoader()->GetEventNumber());
1167
1168 if(strstr(option,"all")){
1169 //loop over digits
1170 AliEMCALDigit * digit;
1171 printf("\nEMC digits (with primaries):\n") ;
1172 printf("\n Id Amplitude Time Index Nprim: Primaries list \n") ;
1173 Int_t index ;
1174 for (index = 0 ; index < digits->GetEntries() ; index++) {
1175 digit = dynamic_cast<AliEMCALDigit *>(digits->At(index)) ;
1176 if(digit){
1177 printf("\n%6d %8f %6.5e %4d %2d : ",
1178 digit->GetId(), digit->GetAmplitude(), digit->GetTime(), digit->GetIndexInList(), digit->GetNprimary()) ;
1179 Int_t iprimary;
1180 for (iprimary=0; iprimary<digit->GetNprimary(); iprimary++) {
1181 printf("%d ",digit->GetPrimary(iprimary+1) ) ;
1182 }
1183 }// digit exists
1184 }// loop
1185 }
1186 printf("\n");
1187 }// loader exists
1188 else printf("NULL LOADER, cannot print\n");
61e0abb5 1189}
05a92d59 1190
1191//__________________________________________________________________
1192Float_t AliEMCALDigitizer::TimeOfNoise(void)
04f0bda3 1193{
1194 // Calculates the time signal generated by noise
6cc75819 1195 //printf("Time noise %e\n",fTimeNoise);
1196 return gRandom->Rndm() * fTimeNoise;
05a92d59 1197}
1198
88cb7938 1199//__________________________________________________________________
1200void AliEMCALDigitizer::Unload()
1201{
fdebddeb 1202 // Unloads the SDigits and Digits
5dee926e 1203 AliRunLoader *rl=0;
1204
88cb7938 1205 Int_t i ;
1206 for(i = 1 ; i < fInput ; i++){
1207 TString tempo(fEventNames[i]) ;
5dee926e 1208 tempo += i;
1209 if ((rl = AliRunLoader::GetRunLoader(tempo)))
1210 rl->GetDetectorLoader("EMCAL")->UnloadSDigits() ;
88cb7938 1211 }
33c3c91a 1212 AliEMCALLoader *emcalLoader = dynamic_cast<AliEMCALLoader*>(AliRunLoader::Instance()->GetDetectorLoader("EMCAL"));
96d5ea0d 1213 if(emcalLoader)emcalLoader->UnloadDigits() ;
1214 else AliFatal("Did not get the loader");
88cb7938 1215}
1216
814ad4bf 1217//_________________________________________________________________________________________
9e5d2067 1218void AliEMCALDigitizer::WriteDigits()
a2f8e711 1219{ // Makes TreeD in the output file.
814ad4bf 1220 // Check if branch already exists:
1221 // if yes, exit without writing: ROOT TTree does not support overwriting/updating of
1222 // already existing branches.
1223 // else creates branch with Digits, named "EMCAL", title "...",
1224 // and branch "AliEMCALDigitizer", with the same title to keep all the parameters
1225 // and names of files, from which digits are made.
96d5ea0d 1226
33c3c91a 1227 AliEMCALLoader *emcalLoader = dynamic_cast<AliEMCALLoader*>(AliRunLoader::Instance()->GetDetectorLoader("EMCAL"));
96d5ea0d 1228
1229 if(emcalLoader){
1230 const TClonesArray * digits = emcalLoader->Digits() ;
1231 TTree * treeD = emcalLoader->TreeD();
1232 if ( !treeD ) {
1233 emcalLoader->MakeDigitsContainer();
1234 treeD = emcalLoader->TreeD();
1235 }
1236
1237 // -- create Digits branch
1238 Int_t bufferSize = 32000 ;
1239 TBranch * digitsBranch = 0;
1240 if ((digitsBranch = treeD->GetBranch("EMCAL"))) {
1241 digitsBranch->SetAddress(&digits);
1242 AliWarning("Digits Branch already exists. Not all digits will be visible");
1243 }
1244 else
1245 treeD->Branch("EMCAL","TClonesArray",&digits,bufferSize);
1246 //digitsBranch->SetTitle(fEventFolderName);
1247
1248 // treeD->Fill() ;
1249 /*
1250 emcalLoader->WriteDigits("OVERWRITE");
1251 emcalLoader->WriteDigitizer("OVERWRITE");
1252
1253 Unload() ;
1254 */
1255
1256 }// loader exists
1257 else AliFatal("Loader not available");
916f1e76 1258}
88cb7938 1259
916f1e76 1260//__________________________________________________________________
1261void AliEMCALDigitizer::WriteDigits(TClonesArray* digits, const char* branchName)
efb8df82 1262{
1263 // overloaded method
61d80ce0 1264 AliEMCALLoader *emcalLoader = dynamic_cast<AliEMCALLoader*>(AliRunLoader::Instance()->GetDetectorLoader("EMCAL"));
1265 if(emcalLoader){
96d5ea0d 1266
1267 TTree* treeD = emcalLoader->TreeD();
1268 if (!treeD)
61d80ce0 1269 {
1270 emcalLoader->MakeDigitsContainer();
1271 treeD = emcalLoader->TreeD();
1272 }
96d5ea0d 1273
1274 // -- create Digits branch
1275 Int_t bufferSize = 32000;
1276
1277 if (TBranch* triggerBranch = treeD->GetBranch(branchName))
61d80ce0 1278 {
1279 triggerBranch->SetAddress(&digits);
1280 }
96d5ea0d 1281 else
61d80ce0 1282 {
1283 treeD->Branch(branchName,"TClonesArray",&digits,bufferSize);
1284 }
96d5ea0d 1285
1286 // treeD->Fill();
1287 }// loader exists
1288 else AliFatal("Loader not available");
814ad4bf 1289}
61e0abb5 1290
6995e8b7 1291//__________________________________________________________________
1292Bool_t AliEMCALDigitizer::IsDead(AliEMCALDigit *digit)
1293{
efb8df82 1294 // Check if cell is defined as dead, so that it is not included
1295 // input is digit
6995e8b7 1296 Int_t absId = digit->GetId();
6995e8b7 1297
efb8df82 1298 return IsDead(absId);
1299
6995e8b7 1300}
1301
1302
1303//__________________________________________________________________
1304Bool_t AliEMCALDigitizer::IsDead(Int_t absId)
1305{
efb8df82 1306 // Check if cell absID is defined as dead, so that it is not included
1307
6995e8b7 1308 AliRunLoader *runLoader = AliRunLoader::Instance();
1309 AliEMCALLoader *emcalLoader = dynamic_cast<AliEMCALLoader*>(runLoader->GetDetectorLoader("EMCAL"));
efb8df82 1310 if (!emcalLoader)
1311 {
1312 AliFatal("Did not get the Loader");
1313 return kTRUE;
1314 }
1315
6995e8b7 1316 AliCaloCalibPedestal *caloPed = emcalLoader->PedestalData();
efb8df82 1317 if (!caloPed)
1318 {
6995e8b7 1319 AliWarning("Could not access pedestal data! No dead channel removal applied");
1320 return kFALSE;
1321 }
1322
1323 // Load Geometry
1324 const AliEMCALGeometry *geom = AliEMCALGeometry::GetInstance();
efb8df82 1325 if (!geom)
1326 {
1327 AliFatal("Did not get geometry from EMCALLoader");
1328 return kTRUE; //coverity
1329 }
1330
6995e8b7 1331 Int_t iSupMod = -1;
1332 Int_t nModule = -1;
1333 Int_t nIphi = -1;
1334 Int_t nIeta = -1;
1335 Int_t iphi = -1;
1336 Int_t ieta = -1;
1337
1338 Bool_t bCell = geom->GetCellIndex(absId, iSupMod, nModule, nIphi, nIeta) ;
1339
1340 if (!bCell) Error("IsDead","Wrong cell id number : absId %i ", absId) ;
1341 geom->GetCellPhiEtaIndexInSModule(iSupMod,nModule,nIphi, nIeta,iphi,ieta);
1342
1343 Int_t channelStatus = (Int_t)(caloPed->GetDeadMap(iSupMod))->GetBinContent(ieta,iphi);
1344
1345 if (channelStatus == AliCaloCalibPedestal::kDead)
1346 return kTRUE;
1347 else
1348 return kFALSE;
1349}
1350