1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 /* History of cvs commits:
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)
24 * Revision 1.103 2007/11/07 11:25:06 schutz
25 * Comment out the QA checking before starting digitization
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.
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
33 * Revision 1.100 2007/10/10 09:05:10 schutz
34 * Changing name QualAss to QA
36 * Revision 1.99 2007/09/30 17:08:20 schutz
37 * Introducing the notion of QA data acquisition cycle (needed by online)
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.
42 * Revision 1.97 2007/08/07 14:12:03 kharlov
43 * Quality assurance added (Yves Schutz)
45 * Revision 1.96 2007/04/28 10:43:36 policheh
46 * Dead channels simulation: digit energy sets to 0.
48 * Revision 1.95 2007/04/10 07:20:52 kharlov
49 * Decalibration should use the same CDB as calibration in AliPHOSClusterizerv1
51 * Revision 1.94 2007/02/01 10:34:47 hristov
52 * Removing warnings on Solaris x86
54 * Revision 1.93 2006/10/17 13:17:01 kharlov
55 * Replace AliInfo by AliDebug
57 * Revision 1.92 2006/08/28 10:01:56 kharlov
58 * Effective C++ warnings fixed (Timur Pocheptsov)
60 * Revision 1.91 2006/04/29 20:25:30 hristov
61 * Decalibration is implemented (Yu.Kharlov)
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)
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)
69 * Revision 1.88 2006/03/13 14:05:43 kharlov
70 * Calibration objects for EMC and CPV
72 * Revision 1.87 2005/08/24 15:33:49 kharlov
73 * Calibration data for raw digits
75 * Revision 1.86 2005/07/12 20:07:35 hristov
76 * Changes needed to run simulation and reconstrruction in the same AliRoot session
78 * Revision 1.85 2005/05/28 14:19:04 schutz
79 * Compilation warnings fixed by T.P.
83 //_________________________________________________________________________
84 //*-- Author : Dmitri Peressounko (SUBATECH & Kurchatov Institute)
85 //////////////////////////////////////////////////////////////////////////////
86 // This class 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).
88 // In addition it performs mixing of summable digits from different events.
89 // The name of the class is also the title of the branch that will contain
90 // the created SDigits
91 // The title of the class is the name of the file that contains the hits from
92 // which the SDigits are created
94 // For each event two branches are created in TreeD:
95 // "PHOS" - list of digits
96 // "AliPHOSDigitizer" - AliPHOSDigitizer with all parameters used in digitization
98 // Note, that one can set a title for new digits branch, and repeat digitization with
99 // another set of parameters.
102 // root[0] AliPHOSDigitizer * d = new AliPHOSDigitizer() ;
103 // root[1] d->Digitize()
104 // Warning in <TDatabasePDG::TDatabasePDG>: object already instantiated
105 // //Digitizes SDigitis in all events found in file galice.root
107 // root[2] AliPHOSDigitizer * d1 = new AliPHOSDigitizer("galice1.root") ;
108 // // Will read sdigits from galice1.root
109 // root[3] d1->MixWith("galice2.root")
110 // Warning in <TDatabasePDG::TDatabasePDG>: object already instantiated
111 // // Reads another set of sdigits from galice2.root
112 // root[3] d1->MixWith("galice3.root")
113 // // Reads another set of sdigits from galice3.root
114 // root[4] d->Digitize("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
122 // --- ROOT system ---
125 #include "TBenchmark.h"
129 // --- Standard library ---
131 // --- AliRoot header files ---
132 #include <TGeoManager.h>
134 #include "AliDigitizationInput.h"
135 #include "AliPHOSDigit.h"
136 #include "AliPHOSDigitizer.h"
137 #include "AliPHOSGeometry.h"
138 #include "AliPHOSTick.h"
139 #include "AliPHOSSimParam.h"
140 #include "AliPHOSCalibData.h"
141 #include "AliRunLoader.h"
142 #include "AliPHOSLoader.h"
143 #include "AliPHOSPulseGenerator.h"
145 ClassImp(AliPHOSDigitizer)
148 //____________________________________________________________________________
149 AliPHOSDigitizer::AliPHOSDigitizer() :
155 fInputFileNames(0x0),
158 fEventFolderName(""),
169 fDigInput = 0 ; // We work in the standalong mode
172 //____________________________________________________________________________
173 AliPHOSDigitizer::AliPHOSDigitizer(TString alirunFileName,
174 TString eventFolderName):
175 AliDigitizer("PHOSDigitizer", alirunFileName),
176 fDefaultInit(kFALSE),
180 fInputFileNames(0x0),
183 fEventFolderName(eventFolderName),
195 fDefaultInit = kFALSE ;
196 fDigInput = 0 ; // We work in the standalone mode
197 fcdb = new AliPHOSCalibData(-1);
200 //____________________________________________________________________________
201 AliPHOSDigitizer::AliPHOSDigitizer(const AliPHOSDigitizer & d) :
203 fDefaultInit(d.fDefaultInit),
204 fDigitsInRun(d.fDigitsInRun),
207 fInputFileNames(0x0),
209 fEmcCrystals(d.fEmcCrystals),
210 fEventFolderName(d.fEventFolderName),
211 fFirstEvent(d.fFirstEvent),
212 fLastEvent(d.fLastEvent),
213 fcdb (new AliPHOSCalibData(-1)),
215 fPulse(new AliPHOSPulseGenerator),
220 SetName(d.GetName()) ;
221 SetTitle(d.GetTitle()) ;
222 for (Int_t iInput=0; iInput<fInput; iInput++) {
223 fInputFileNames[iInput] = d.fInputFileNames[iInput];
224 fEventNames[iInput] = d.fEventNames[iInput];
226 fADCValuesLG = new Int_t[fPulse->GetRawFormatTimeBins()];
227 fADCValuesHG = new Int_t[fPulse->GetRawFormatTimeBins()];
230 //____________________________________________________________________________
231 AliPHOSDigitizer::AliPHOSDigitizer(AliDigitizationInput * rd) :
232 AliDigitizer(rd,"PHOSDigitizer"),
233 fDefaultInit(kFALSE),
237 fInputFileNames(0x0),
240 fEventFolderName(fDigInput->GetInputFolderName(0)),
250 // ctor Init() is called by RunDigitizer
252 SetTitle(static_cast<AliStream*>(fDigInput->GetInputStream(0))->GetFileName(0));
254 fDefaultInit = kFALSE ;
255 fcdb = new AliPHOSCalibData(-1);
258 //____________________________________________________________________________
259 AliPHOSDigitizer::~AliPHOSDigitizer()
262 delete [] fInputFileNames ;
263 delete [] fEventNames ;
266 delete [] fADCValuesLG;
267 delete [] fADCValuesHG;
269 if(fcdb){ delete fcdb ; fcdb=0;}
273 //____________________________________________________________________________
274 void AliPHOSDigitizer::Digitize(Int_t event)
277 // Makes the digitization of the collected summable digits.
278 // It first creates the array of all PHOS modules
279 // filled with noise (different for EMC, and CPV) and
280 // then adds contributions from SDigits.
281 // This design avoids scanning over the list of digits to add
282 // contribution to new SDigits only.
284 Bool_t toMakeNoise = kTRUE ; //Do not create noisy digits if merge with real data
287 AliRunLoader* rl = AliRunLoader::GetRunLoader(fEventFolderName) ;
288 AliPHOSLoader * phosLoader = static_cast<AliPHOSLoader*>(rl->GetLoader("PHOSLoader"));
290 Int_t readEvent = event ;
292 readEvent = static_cast<AliStream*>(fDigInput->GetInputStream(0))->GetCurrentEventNumber() ;
293 AliDebug(1,Form("Adding event %d from input stream 0 %s %s",
294 readEvent, GetTitle(), fEventFolderName.Data())) ;
295 rl->GetEvent(readEvent) ;
296 phosLoader->CleanSDigits() ;
297 phosLoader->LoadSDigits("READ") ;
300 TClonesArray * digits = phosLoader->Digits() ;
302 phosLoader->MakeDigitsArray() ;
303 digits = phosLoader->Digits() ;
309 const AliPHOSGeometry *geom = AliPHOSGeometry::GetInstance() ;
310 //Making digits with noise, first EMC
311 //Check which PHOS modules are present
312 Bool_t isPresent[5] ;
315 for(Int_t i=0; i<5; i++){
316 volpath = "/ALIC_1/PHOS_";
318 if (gGeoManager->CheckPath(volpath.Data())) {
327 Int_t nEMC = nmod*geom->GetNPhi()*geom->GetNZ();
332 //check if CPV exists
333 Bool_t isCPVpresent=0 ;
334 for(Int_t i=1; i<=5 && !isCPVpresent; i++){
335 volpath = "/ALIC_1/PHOS_";
337 volpath += "/PCPV_1";
338 if (gGeoManager->CheckPath(volpath.Data()))
343 nCPV = nEMC + geom->GetNumberOfCPVPadsZ() * geom->GetNumberOfCPVPadsPhi() * nmod ;
349 digits->Expand(nCPV) ;
351 //take all the inputs to add together and load the SDigits
352 TObjArray * sdigArray = new TObjArray(fInput) ;
353 sdigArray->AddAt(phosLoader->SDigits(), 0) ;
355 for(Int_t i = 1 ; i < fInput ; i++){
356 TString tempo(fEventNames[i]) ;
358 AliRunLoader* rl2 = AliRunLoader::GetRunLoader(tempo) ;
360 rl2 = AliRunLoader::Open(fInputFileNames[i], tempo) ;
362 Fatal("AliPHOSDigitizer", "Could not find the Run Loader for %s - %s",fInputFileNames[i].Data(), tempo.Data()) ;
367 AliPHOSLoader * phosLoader2 = static_cast<AliPHOSLoader*>(rl2->GetLoader("PHOSLoader"));
370 readEvent = static_cast<AliStream*>(fDigInput->GetInputStream(i))->GetCurrentEventNumber() ;
372 TClonesArray * digs ;
373 if(AliPHOSSimParam::GetInstance()->IsStreamDigits(i)){ //This is Digits Stream
374 AliInfo(Form("Adding event %d from input stream %d %s %s",
375 readEvent, i, fInputFileNames[i].Data(), tempo.Data())) ;
376 rl2->GetEvent(readEvent) ;
377 phosLoader2->CleanDigits() ;
378 phosLoader2->LoadDigits("READ") ;
379 digs = phosLoader2->Digits() ;
380 toMakeNoise=0 ; //Do not add noise, it is already in stream
383 AliInfo(Form("Adding event %d (SDigits) from input stream %d %s %s",
384 readEvent, i, fInputFileNames[i].Data(), tempo.Data())) ;
385 rl2->GetEvent(readEvent) ;
386 phosLoader2->CleanSDigits() ;
387 phosLoader2->LoadSDigits("READ") ;
388 digs = phosLoader2->SDigits() ;
390 sdigArray->AddAt(digs, i) ;
393 //Find the first crystal with signal
394 Int_t nextSig = 200000 ;
395 TClonesArray * sdigits ;
396 for(Int_t i = 0 ; i < fInput ; i++){
397 sdigits = static_cast<TClonesArray *>(sdigArray->At(i)) ;
398 if ( !sdigits->GetEntriesFast() )
400 Int_t curNext = static_cast<AliPHOSDigit *>(sdigits->At(0))->GetId() ;
401 if(curNext < nextSig)
405 TArrayI index(fInput) ;
406 index.Reset() ; //Set all indexes to zero
408 AliPHOSDigit * digit ;
409 AliPHOSDigit * curSDigit ;
411 // TClonesArray * ticks = new TClonesArray("AliPHOSTick",1000) ;
413 //Put Noise contribution
414 Double_t apdNoise = 0. ;
416 apdNoise = AliPHOSSimParam::GetInstance()->GetAPDNoise() ;
418 Int_t emcpermod=geom->GetNPhi()*geom->GetNZ();
420 for(Int_t imod=0; imod<5; imod++){
423 Int_t firstAbsId=imod*emcpermod+1 ;
424 Int_t lastAbsId =(imod+1)*emcpermod ;
425 for(absID = firstAbsId ; absID <= lastAbsId ; absID++){
426 Float_t noise = gRandom->Gaus(0.,apdNoise) ;
427 new((*digits)[idigit]) AliPHOSDigit( -1, absID, noise, TimeOfNoise() ) ;
428 //look if we have to add signal?
429 digit = static_cast<AliPHOSDigit *>(digits->At(idigit)) ;
433 //Add SDigits from all inputs
435 // Int_t contrib = 0 ;
437 //New Timing model is necessary
438 // Float_t a = digit->GetEnergy() ;
439 // Float_t b = TMath::Abs( a / fTimeSignalLength) ;
440 // //Mark the beginning of the signal
441 // new((*ticks)[contrib++]) AliPHOSTick(digit->GetTime(),0, b);
442 // //Mark the end of the signal
443 // new((*ticks)[contrib++]) AliPHOSTick(digit->GetTime()+fTimeSignalLength, -a, -b);
445 // Calculate time as time of the largest digit
446 Float_t time = digit->GetTime() ;
447 Float_t eTime= digit->GetEnergy() ;
450 for(Int_t i = 0 ; i < fInput ; i++){
451 if( static_cast<TClonesArray *>(sdigArray->At(i))->GetEntriesFast() > index[i] ){
452 curSDigit = static_cast<AliPHOSDigit*>(static_cast<TClonesArray *>(sdigArray->At(i))->At(index[i])) ;
453 if(AliPHOSSimParam::GetInstance()->IsStreamDigits(i)){ //This is Digits Stream
454 curSDigit->SetEnergy(Calibrate(curSDigit->GetEnergy(),curSDigit->GetId())) ;
455 curSDigit->SetTime(CalibrateT(curSDigit->GetTime(),curSDigit->GetId())) ;
460 //May be several digits will contribute from the same input
461 while(curSDigit && curSDigit->GetId() == absID){
462 //Shift primary to separate primaries belonging different inputs
463 Int_t primaryoffset ;
465 primaryoffset = fDigInput->GetMask(i) ;
467 primaryoffset = 10000000*i ;
468 curSDigit->ShiftPrimary(primaryoffset) ;
470 //New Timing model is necessary
471 // a = curSDigit->GetEnergy() ;
472 // b = a /fTimeSignalLength ;
473 // new((*ticks)[contrib++]) AliPHOSTick(curSDigit->GetTime(),0, b);
474 // new((*ticks)[contrib++]) AliPHOSTick(curSDigit->GetTime()+fTimeSignalLength, -a, -b);
475 if(curSDigit->GetEnergy()>eTime){
476 eTime=curSDigit->GetEnergy() ;
477 time=curSDigit->GetTime() ;
479 *digit += *curSDigit ; //add energies
482 if( static_cast<TClonesArray *>(sdigArray->At(i))->GetEntriesFast() > index[i] )
483 curSDigit = static_cast<AliPHOSDigit*>(static_cast<TClonesArray *>(sdigArray->At(i))->At(index[i])) ;
489 //calculate and set time
490 //New Timing model is necessary
491 // Float_t time = FrontEdgeTime(ticks) ;
492 digit->SetTime(time) ;
494 //Find next signal module
496 for(Int_t i = 0 ; i < fInput ; i++){
497 sdigits = static_cast<TClonesArray *>(sdigArray->At(i)) ;
498 Int_t curNext = nextSig ;
499 if(sdigits->GetEntriesFast() > index[i] ){
500 curNext = static_cast<AliPHOSDigit *>(sdigits->At(index[i]))->GetId() ;
502 if(curNext < nextSig) nextSig = curNext ;
509 //Apply non-linearity
510 if(AliPHOSSimParam::GetInstance()->IsCellNonlinearityOn()){ //Apply non-lineairyt on cell level
511 const Double_t aNL = AliPHOSSimParam::GetInstance()->GetCellNonLineairyA() ;
512 const Double_t bNL = AliPHOSSimParam::GetInstance()->GetCellNonLineairyB() ;
513 const Double_t cNL = AliPHOSSimParam::GetInstance()->GetCellNonLineairyC() ;
514 for(Int_t i = 0 ; i < nEMC ; i++){
515 digit = static_cast<AliPHOSDigit*>( digits->At(i) ) ;
516 Double_t e= digit->GetEnergy() ;
517 // version(1) digit->SetEnergy(e*(1+a*TMath::Exp(-e/b))) ;
518 digit->SetEnergy(e*cNL*(1.+aNL*TMath::Exp(-e*e/2./bNL/bNL))) ; //Better agreement with data...
523 //distretize energy if necessary
524 if(AliPHOSSimParam::GetInstance()->IsEDigitizationOn()){
525 Float_t adcW=AliPHOSSimParam::GetInstance()->GetADCchannelW() ;
526 for(Int_t i = 0 ; i < nEMC ; i++){
527 digit = static_cast<AliPHOSDigit*>( digits->At(i) ) ;
528 digit->SetEnergy(adcW*ceil(digit->GetEnergy()/adcW)) ;
532 //Apply decalibration if necessary
533 for(Int_t i = 0 ; i < nEMC ; i++){
534 digit = static_cast<AliPHOSDigit*>( digits->At(i) ) ;
541 //Now CPV digits (different noise and no timing)
542 Int_t cpvpermod = geom->GetNumberOfCPVPadsZ() * geom->GetNumberOfCPVPadsPhi() ;
543 Int_t nEMCtotal=emcpermod*5 ;
544 Float_t cpvNoise = AliPHOSSimParam::GetInstance()->GetCPVNoise() ;
545 if(isCPVpresent){ //CPV is present in current geometry
546 for(Int_t imod=0; imod<5; imod++){ //module is present in current geometry
549 Int_t firstAbsId=nEMCtotal+imod*cpvpermod+1 ;
550 Int_t lastAbsId =nEMCtotal+(imod+1)*cpvpermod ;
551 for(absID = firstAbsId; absID <= lastAbsId; absID++){
552 Float_t noise = gRandom->Gaus(0., cpvNoise) ;
553 new((*digits)[idigit]) AliPHOSDigit( -1,absID,noise, TimeOfNoise() ) ;
555 //look if we have to add signal?
557 digit = static_cast<AliPHOSDigit *>(digits->At(idigit-1)) ;
558 //Add SDigits from all inputs
559 for(Int_t i = 0 ; i < fInput ; i++){
560 if( static_cast<TClonesArray *>(sdigArray->At(i))->GetEntriesFast() > index[i] )
561 curSDigit = static_cast<AliPHOSDigit*>( static_cast<TClonesArray *>(sdigArray->At(i))->At(index[i])) ;
565 //May be several digits will contribute from the same input
566 while(curSDigit && curSDigit->GetId() == absID){
567 //Shift primary to separate primaries belonging different inputs
568 Int_t primaryoffset ;
570 primaryoffset = fDigInput->GetMask(i) ;
572 primaryoffset = 10000000*i ;
573 curSDigit->ShiftPrimary(primaryoffset) ;
576 *digit += *curSDigit ;
578 if( static_cast<TClonesArray *>(sdigArray->At(i))->GetEntriesFast() > index[i] )
579 curSDigit = static_cast<AliPHOSDigit*>( static_cast<TClonesArray *>(sdigArray->At(i))->At(index[i]) ) ;
585 //Find next signal module
587 for(Int_t i = 0 ; i < fInput ; i++){
588 sdigits = static_cast<TClonesArray *>(sdigArray->At(i)) ;
589 Int_t curNext = nextSig ;
590 if(sdigits->GetEntriesFast() > index[i] )
591 curNext = static_cast<AliPHOSDigit *>( sdigits->At(index[i]) )->GetId() ;
592 if(curNext < nextSig) nextSig = curNext ;
600 delete sdigArray ; //We should not delete its contents
604 //set amplitudes in bad channels to zero
606 for(Int_t i = 0 ; i <digits->GetEntriesFast(); i++){
607 digit = static_cast<AliPHOSDigit*>( digits->At(i) ) ;
608 geom->AbsToRelNumbering(digit->GetId(),relId);
609 if(relId[1] == 0) // Emc
610 if(fcdb->IsBadChannelEmc(relId[0],relId[3],relId[2])) digit->SetEnergy(0.);
613 //remove digits below thresholds
614 Float_t emcThreshold = AliPHOSSimParam::GetInstance()->GetEmcDigitsThreshold() ;
615 for(Int_t i = 0 ; i < nEMC ; i++){
616 digit = static_cast<AliPHOSDigit*>( digits->At(i) ) ;
618 if(digit->GetEnergy() < emcThreshold){
619 digits->RemoveAt(i) ;
623 geom->AbsToRelNumbering(digit->GetId(),relId);
625 // digit->SetEnergy(TMath::Ceil(digit->GetEnergy())-0.9999) ;
627 Float_t tres = TimeResolution(digit->GetEnergy()) ;
628 digit->SetTime(gRandom->Gaus(digit->GetTime(), tres) ) ;
631 fPulse->SetAmplitude(digit->GetEnergy()/
632 fcdb->GetADCchannelEmc(relId[0],relId[3],relId[2]));
633 fPulse->SetTZero(digit->GetTimeR());
634 fPulse->MakeSamples();
635 fPulse->GetSamples(fADCValuesHG, fADCValuesLG) ;
636 Int_t nSamples = fPulse->GetRawFormatTimeBins();
637 digit->SetALTROSamplesHG(nSamples,fADCValuesHG);
638 digit->SetALTROSamplesLG(nSamples,fADCValuesLG);
641 Float_t cpvDigitThreshold = AliPHOSSimParam::GetInstance()->GetCpvDigitsThreshold() ;
642 for(Int_t i = nEMC; i < nCPV ; i++){
643 if( static_cast<AliPHOSDigit*>(digits->At(i))->GetEnergy() < cpvDigitThreshold )
644 digits->RemoveAt(i) ;
648 Int_t ndigits = digits->GetEntriesFast() ;
650 //Set indexes in list of digits and make true digitization of the energy
651 for (Int_t i = 0 ; i < ndigits ; i++) {
652 digit = static_cast<AliPHOSDigit*>( digits->At(i) ) ;
653 digit->SetIndexInList(i) ;
654 if(digit->GetId() > fEmcCrystals){ //digitize CPV only
655 digit->SetAmp(DigitizeCPV(digit->GetEnergy(),digit->GetId()) ) ;
660 //____________________________________________________________________________
661 Float_t AliPHOSDigitizer::Calibrate(Float_t amp,Int_t absId){
663 const AliPHOSGeometry *geom = AliPHOSGeometry::GetInstance() ;
665 //Determine rel.position of the cell absolute ID
667 geom->AbsToRelNumbering(absId,relId);
668 Int_t module=relId[0];
670 Int_t column=relId[3];
671 if(relId[1]==0){ //This Is EMC
672 Float_t calibration = fcdb->GetADCchannelEmc(module,column,row);
673 return amp*calibration ;
677 //____________________________________________________________________________
678 void AliPHOSDigitizer::Decalibrate(AliPHOSDigit *digit)
680 // Decalibrate EMC digit, i.e. change its energy by a factor read from CDB
682 const AliPHOSGeometry *geom = AliPHOSGeometry::GetInstance() ;
684 //Determine rel.position of the cell absolute ID
686 geom->AbsToRelNumbering(digit->GetId(),relId);
687 Int_t module=relId[0];
689 Int_t column=relId[3];
690 if(relId[1]==0){ //This Is EMC
691 Float_t decalib = fcdb->GetADCchannelEmcDecalib(module,column,row); // O(1)
692 Float_t calibration = fcdb->GetADCchannelEmc(module,column,row)*decalib;
693 Float_t energy = digit->GetEnergy()/calibration;
694 digit->SetEnergy(energy); //Now digit measures E in ADC counts
695 Float_t time = digit->GetTime() ;
696 time-=fcdb->GetTimeShiftEmc(module,column,row);
697 digit->SetTime(time) ;
700 //____________________________________________________________________________
701 Float_t AliPHOSDigitizer::CalibrateT(Float_t time,Int_t absId){
702 //Apply time calibration
703 const AliPHOSGeometry *geom = AliPHOSGeometry::GetInstance() ;
705 //Determine rel.position of the cell absolute ID
707 geom->AbsToRelNumbering(absId,relId);
708 Int_t module=relId[0];
710 Int_t column=relId[3];
711 time += fcdb->GetTimeShiftEmc(module,column,row);
714 //____________________________________________________________________________
715 Int_t AliPHOSDigitizer::DigitizeCPV(Float_t charge, Int_t absId)
717 // Returns digitized value of the CPV charge in a pad absId
719 const AliPHOSGeometry *geom = AliPHOSGeometry::GetInstance() ;
721 //Determine rel.position of the cell absId
723 geom->AbsToRelNumbering(absId,relId);
724 Int_t module=relId[0];
726 Int_t column=relId[3];
730 if(absId > fEmcCrystals){ //digitize CPV only
732 //reading calibration data for cell absId.
733 Float_t adcPedestalCpv = fcdb->GetADCpedestalCpv(module,column,row);
734 Float_t adcChanelCpv = fcdb->GetADCchannelCpv( module,column,row);
736 channel = (Int_t) TMath::Ceil((charge - adcPedestalCpv)/adcChanelCpv) ;
737 Int_t nMax = AliPHOSSimParam::GetInstance()->GetNADCcpv() ;
738 if(channel > nMax ) channel = nMax ;
743 //____________________________________________________________________________
744 void AliPHOSDigitizer::Digitize(Option_t *option)
746 // Steering method to process digitization for events
747 // in the range from fFirstEvent to fLastEvent.
748 // This range is optionally set by SetEventRange().
749 // if fLastEvent=-1, then process events until the end.
750 // by default fLastEvent = fFirstEvent (process only one event)
752 if (!fInit) { // to prevent overwrite existing file
753 AliError(Form("Give a version name different from %s",
754 fEventFolderName.Data() )) ;
758 if (strstr(option,"print")) {
763 if(strstr(option,"tim"))
764 gBenchmark->Start("PHOSDigitizer");
766 AliRunLoader* rl = AliRunLoader::GetRunLoader(fEventFolderName) ;
767 AliPHOSLoader * phosLoader = static_cast<AliPHOSLoader*>(rl->GetLoader("PHOSLoader"));
769 if (fLastEvent == -1)
770 fLastEvent = rl->GetNumberOfEvents() - 1 ;
772 fLastEvent = fFirstEvent ;
774 Int_t nEvents = fLastEvent - fFirstEvent + 1;
778 for (ievent = fFirstEvent; ievent <= fLastEvent; ievent++) {
781 Digitize(ievent) ; //Add prepared SDigits to digits and add the noise
785 if(strstr(option,"deb"))
788 //increment the total number of Digits per run
789 fDigitsInRun += phosLoader->Digits()->GetEntriesFast() ;
792 if(strstr(option,"tim")){
793 gBenchmark->Stop("PHOSDigitizer");
795 message = " took %f seconds for Digitizing %f seconds per event\n" ;
796 AliInfo(Form( message.Data(),
797 gBenchmark->GetCpuTime("PHOSDigitizer"),
798 gBenchmark->GetCpuTime("PHOSDigitizer")/nEvents ));
801 //____________________________________________________________________________
802 Float_t AliPHOSDigitizer::TimeResolution(Float_t e){
803 //calculate TOF resolution using beam-test resutls
804 Float_t a=AliPHOSSimParam::GetInstance()->GetTOFa() ;
805 Float_t b=AliPHOSSimParam::GetInstance()->GetTOFb() ;
806 return TMath::Sqrt(a*a+b*b/e) ;
809 ////____________________________________________________________________________
810 //Float_t AliPHOSDigitizer::FrontEdgeTime(TClonesArray * ticks) const
812 // // Returns the shortest time among all time ticks
814 // ticks->Sort() ; //Sort in accordance with times of ticks
816 // AliPHOSTick * ctick = (AliPHOSTick *) it.Next() ;
817 // Float_t time = ctick->CrossingTime(fTimeThreshold) ;
820 // while((t=(AliPHOSTick*) it.Next())){
821 // if(t->GetTime() < time) //This tick starts before crossing
826 // time = ctick->CrossingTime(fTimeThreshold) ;
831 //____________________________________________________________________________
832 Bool_t AliPHOSDigitizer::Init()
834 // Makes all memory allocations
837 AliPHOSGeometry *geom;
838 if (!(geom = AliPHOSGeometry::GetInstance()))
839 geom = AliPHOSGeometry::GetInstance("IHEP","");
840 // const AliPHOSGeometry *geom = AliPHOSGeometry::GetInstance() ;
842 fEmcCrystals = geom->GetNModules() * geom->GetNCristalsInModule() ;
845 fLastEvent = fFirstEvent ;
847 fInput = fDigInput->GetNinputs() ;
851 fInputFileNames = new TString[fInput] ;
852 fEventNames = new TString[fInput] ;
853 fInputFileNames[0] = GetTitle() ;
854 fEventNames[0] = fEventFolderName.Data() ;
856 for (index = 1 ; index < fInput ; index++) {
857 fInputFileNames[index] = static_cast<AliStream*>(fDigInput->GetInputStream(index))->GetFileName(0);
858 TString tempo = fDigInput->GetInputFolderName(index) ;
859 fEventNames[index] = tempo.Remove(tempo.Length()-1) ; // strip of the stream number added by fDigInput
862 //to prevent cleaning of this object while GetEvent is called
863 AliRunLoader* rl = AliRunLoader::GetRunLoader(fEventFolderName) ;
865 AliRunLoader::Open(GetTitle(), fEventFolderName) ;
870 //____________________________________________________________________________
871 void AliPHOSDigitizer::InitParameters()
873 // Set initial parameters Digitizer
876 SetEventRange(0,-1) ;
877 fPulse = new AliPHOSPulseGenerator();
878 fADCValuesLG = new Int_t[fPulse->GetRawFormatTimeBins()];
879 fADCValuesHG = new Int_t[fPulse->GetRawFormatTimeBins()];
883 //__________________________________________________________________
884 void AliPHOSDigitizer::Print(const Option_t *)const
886 // Print Digitizer's parameters
887 AliInfo(Form("\n------------------- %s -------------", GetName() )) ;
888 if( strcmp(fEventFolderName.Data(), "") != 0 ){
889 printf(" Writing Digits to branch with title %s\n", fEventFolderName.Data()) ;
893 nStreams = GetNInputStreams() ;
898 for (index = 0 ; index < nStreams ; index++) {
899 TString tempo(fEventNames[index]) ;
901 printf ("Adding SDigits from %s \n", fInputFileNames[index].Data()) ;
904 // printf("\nWith following parameters:\n") ;
905 // printf(" Electronics noise in EMC (fPinNoise) = %f GeV\n", fPinNoise ) ;
906 // printf(" Threshold in EMC (fEMCDigitThreshold) = %f GeV\n", fEMCDigitThreshold ) ;
907 // printf(" Noise in CPV (fCPVNoise) = %f aux units\n", fCPVNoise ) ;
908 // printf(" Threshold in CPV (fCPVDigitThreshold) = %f aux units\n",fCPVDigitThreshold ) ;
909 printf(" ---------------------------------------------------\n") ;
912 AliInfo(Form("AliPHOSDigitizer not initialized" )) ;
916 //__________________________________________________________________
917 void AliPHOSDigitizer::PrintDigits(Option_t * option)
919 // Print a table of digits
922 AliRunLoader* rl = AliRunLoader::GetRunLoader(fEventFolderName) ;
923 AliPHOSLoader * phosLoader = static_cast<AliPHOSLoader*>(rl->GetLoader("PHOSLoader"));
924 TClonesArray * digits = phosLoader->Digits() ;
925 const AliPHOSGeometry *geom = AliPHOSGeometry::GetInstance() ;
927 AliInfo(Form("%d", digits->GetEntriesFast())) ;
928 printf("\nevent %d", gAlice->GetEvNumber()) ;
929 printf("\n Number of entries in Digits list %d", digits->GetEntriesFast() ) ;
932 if(strstr(option,"all")||strstr(option,"EMC")){
934 AliPHOSDigit * digit;
935 printf("\nEMC digits (with primaries):\n") ;
936 printf("\n Id Amplitude Time Index Nprim: Primaries list \n") ;
937 Int_t maxEmc = geom->GetNModules()*geom->GetNCristalsInModule() ;
939 for (index = 0 ; (index < digits->GetEntriesFast()) &&
940 (static_cast<AliPHOSDigit *>(digits->At(index))->GetId() <= maxEmc) ; index++) {
941 digit = (AliPHOSDigit * ) digits->At(index) ;
942 if(digit->GetNprimary() == 0)
944 // printf("%6d %8d %6.5e %4d %2d :",
945 // digit->GetId(), digit->GetAmp(), digit->GetTime(), digit->GetIndexInList(), digit->GetNprimary()) ; // YVK
946 printf("%6d %.4f %6.5e %4d %2d :",
947 digit->GetId(), digit->GetEnergy(), digit->GetTime(), digit->GetIndexInList(), digit->GetNprimary()) ;
949 for (iprimary=0; iprimary<digit->GetNprimary(); iprimary++) {
950 printf("%d ",digit->GetPrimary(iprimary+1) ) ;
956 if(strstr(option,"all")||strstr(option,"CPV")){
958 //loop over CPV digits
959 AliPHOSDigit * digit;
960 printf("\nCPV digits (with primaries):\n") ;
961 printf("\n Id Amplitude Time Index Nprim: Primaries list \n") ;
962 Int_t maxEmc = geom->GetNModules()*geom->GetNCristalsInModule() ;
964 for (index = 0 ; index < digits->GetEntriesFast(); index++) {
965 digit = (AliPHOSDigit * ) digits->At(index) ;
966 if(digit->GetId() > maxEmc){
967 printf("%6d %8d %4d %2d :",
968 digit->GetId(), digit->GetAmp(), digit->GetIndexInList(), digit->GetNprimary()) ;
970 for (iprimary=0; iprimary<digit->GetNprimary(); iprimary++) {
971 printf("%d ",digit->GetPrimary(iprimary+1) ) ;
980 //__________________________________________________________________
981 Float_t AliPHOSDigitizer::TimeOfNoise(void) const
982 { // Calculates the time signal generated by noise
983 //PH Info("TimeOfNoise", "Change me") ;
984 return gRandom->Rndm() * 1.28E-5;
987 //__________________________________________________________________
988 void AliPHOSDigitizer::Unload()
992 for(i = 1 ; i < fInput ; i++){
993 TString tempo(fEventNames[i]) ;
995 AliRunLoader* rl = AliRunLoader::GetRunLoader(tempo) ;
996 AliPHOSLoader * phosLoader = static_cast<AliPHOSLoader*>(rl->GetLoader("PHOSLoader"));
997 phosLoader->UnloadSDigits() ;
1000 AliRunLoader* rl = AliRunLoader::GetRunLoader(fEventFolderName) ;
1001 AliPHOSLoader * phosLoader = static_cast<AliPHOSLoader*>(rl->GetLoader("PHOSLoader"));
1002 phosLoader->UnloadDigits() ;
1005 //____________________________________________________________________________
1006 void AliPHOSDigitizer::WriteDigits()
1009 // Makes TreeD in the output file.
1010 // Check if branch already exists:
1011 // if yes, exit without writing: ROOT TTree does not support overwriting/updating of
1012 // already existing branches.
1013 // else creates branch with Digits, named "PHOS", title "...",
1014 // and branch "AliPHOSDigitizer", with the same title to keep all the parameters
1015 // and names of files, from which digits are made.
1017 AliRunLoader* rl = AliRunLoader::GetRunLoader(fEventFolderName) ;
1018 AliPHOSLoader * phosLoader = static_cast<AliPHOSLoader*>(rl->GetLoader("PHOSLoader"));
1020 const TClonesArray * digits = phosLoader->Digits() ;
1021 TTree * treeD = phosLoader->TreeD();
1023 phosLoader->MakeTree("D");
1024 treeD = phosLoader->TreeD();
1027 // -- create Digits branch
1028 Int_t bufferSize = 32000 ;
1029 TBranch * digitsBranch = treeD->Branch("PHOS","TClonesArray",&digits,bufferSize);
1030 digitsBranch->SetTitle(fEventFolderName);
1031 digitsBranch->Fill() ;
1033 phosLoader->WriteDigits("OVERWRITE");