Line data Source code
1 : /**************************************************************************
2 : * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 : * *
4 : * Author: The ALICE Off-line Project. *
5 : * Contributors are mentioned in the code where appropriate. *
6 : * *
7 : * Permission to use, copy, modify and distribute this software and its *
8 : * documentation strictly for non-commercial purposes is hereby granted *
9 : * without fee, provided that the above copyright notice appears in all *
10 : * copies and that both the copyright notice and this permission notice *
11 : * appear in the supporting documentation. The authors make no claims *
12 : * about the suitability of this software for any purpose. It is *
13 : * provided "as is" without express or implied warranty. *
14 : **************************************************************************/
15 :
16 : /* $Id$ */
17 :
18 : /* History of cvs commits:
19 : *
20 : * $Log: 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 : *
24 : * Revision 1.103 2007/11/07 11:25:06 schutz
25 : * Comment out the QA checking before starting digitization
26 : *
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 : *
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 : *
33 : * Revision 1.100 2007/10/10 09:05:10 schutz
34 : * Changing name QualAss to QA
35 : *
36 : * Revision 1.99 2007/09/30 17:08:20 schutz
37 : * Introducing the notion of QA data acquisition cycle (needed by online)
38 : *
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 : *
42 : * Revision 1.97 2007/08/07 14:12:03 kharlov
43 : * Quality assurance added (Yves Schutz)
44 : *
45 : * Revision 1.96 2007/04/28 10:43:36 policheh
46 : * Dead channels simulation: digit energy sets to 0.
47 : *
48 : * Revision 1.95 2007/04/10 07:20:52 kharlov
49 : * Decalibration should use the same CDB as calibration in AliPHOSClusterizerv1
50 : *
51 : * Revision 1.94 2007/02/01 10:34:47 hristov
52 : * Removing warnings on Solaris x86
53 : *
54 : * Revision 1.93 2006/10/17 13:17:01 kharlov
55 : * Replace AliInfo by AliDebug
56 : *
57 : * Revision 1.92 2006/08/28 10:01:56 kharlov
58 : * Effective C++ warnings fixed (Timur Pocheptsov)
59 : *
60 : * Revision 1.91 2006/04/29 20:25:30 hristov
61 : * Decalibration is implemented (Yu.Kharlov)
62 : *
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 : *
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 : *
69 : * Revision 1.88 2006/03/13 14:05:43 kharlov
70 : * Calibration objects for EMC and CPV
71 : *
72 : * Revision 1.87 2005/08/24 15:33:49 kharlov
73 : * Calibration data for raw digits
74 : *
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 : *
78 : * Revision 1.85 2005/05/28 14:19:04 schutz
79 : * Compilation warnings fixed by T.P.
80 : *
81 : */
82 :
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
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 : //
98 : // Note, that one can set a title for new digits branch, and repeat digitization with
99 : // another set of parameters.
100 : //
101 : // Use case:
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
106 : //
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
120 : //
121 :
122 : // --- ROOT system ---
123 : #include "TTree.h"
124 : #include "TSystem.h"
125 : #include "TBenchmark.h"
126 : #include "TRandom.h"
127 : #include "TMath.h"
128 :
129 : // --- Standard library ---
130 :
131 : // --- AliRoot header files ---
132 : #include <TGeoManager.h>
133 : #include "AliLog.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"
144 :
145 22 : ClassImp(AliPHOSDigitizer)
146 :
147 :
148 : //____________________________________________________________________________
149 : AliPHOSDigitizer::AliPHOSDigitizer() :
150 0 : AliDigitizer("",""),
151 0 : fDefaultInit(kTRUE),
152 0 : fDigitsInRun(0),
153 0 : fInit(kFALSE),
154 0 : fInput(0),
155 0 : fInputFileNames(0x0),
156 0 : fEventNames(0x0),
157 0 : fEmcCrystals(0),
158 0 : fEventFolderName(""),
159 0 : fFirstEvent(0),
160 0 : fLastEvent(0),
161 0 : fcdb(0x0),
162 0 : fEventCounter(0),
163 0 : fPulse(0),
164 0 : fADCValuesLG(0),
165 0 : fADCValuesHG(0)
166 0 : {
167 : // ctor
168 0 : InitParameters() ;
169 0 : fDigInput = 0 ; // We work in the standalong mode
170 0 : }
171 :
172 : //____________________________________________________________________________
173 : AliPHOSDigitizer::AliPHOSDigitizer(TString alirunFileName,
174 : TString eventFolderName):
175 0 : AliDigitizer("PHOSDigitizer", alirunFileName),
176 0 : fDefaultInit(kFALSE),
177 0 : fDigitsInRun(0),
178 0 : fInit(kFALSE),
179 0 : fInput(0),
180 0 : fInputFileNames(0x0),
181 0 : fEventNames(0x0),
182 0 : fEmcCrystals(0),
183 0 : fEventFolderName(eventFolderName),
184 0 : fFirstEvent(0),
185 0 : fLastEvent(0),
186 0 : fcdb(0x0),
187 0 : fEventCounter(0),
188 0 : fPulse(0),
189 0 : fADCValuesLG(0),
190 0 : fADCValuesHG(0)
191 0 : {
192 : // ctor
193 0 : InitParameters() ;
194 0 : Init() ;
195 0 : fDefaultInit = kFALSE ;
196 0 : fDigInput = 0 ; // We work in the standalone mode
197 0 : fcdb = new AliPHOSCalibData(-1);
198 0 : }
199 :
200 : //____________________________________________________________________________
201 : AliPHOSDigitizer::AliPHOSDigitizer(AliDigitizationInput * rd) :
202 1 : AliDigitizer(rd,"PHOSDigitizer"),
203 1 : fDefaultInit(kFALSE),
204 1 : fDigitsInRun(0),
205 1 : fInit(kFALSE),
206 1 : fInput(0),
207 1 : fInputFileNames(0x0),
208 1 : fEventNames(0x0),
209 1 : fEmcCrystals(0),
210 2 : fEventFolderName(fDigInput->GetInputFolderName(0)),
211 1 : fFirstEvent(0),
212 1 : fLastEvent(0),
213 1 : fcdb (0x0),
214 1 : fEventCounter(0),
215 1 : fPulse(0),
216 1 : fADCValuesLG(0),
217 1 : fADCValuesHG(0)
218 :
219 5 : {
220 : // ctor Init() is called by RunDigitizer
221 1 : fDigInput = rd ;
222 5 : SetTitle(static_cast<AliStream*>(fDigInput->GetInputStream(0))->GetFileName(0));
223 1 : InitParameters() ;
224 1 : fDefaultInit = kFALSE ;
225 3 : fcdb = new AliPHOSCalibData(-1);
226 2 : }
227 :
228 : //____________________________________________________________________________
229 : AliPHOSDigitizer::~AliPHOSDigitizer()
230 6 : {
231 : // dtor
232 4 : delete [] fInputFileNames ;
233 4 : delete [] fEventNames ;
234 :
235 2 : delete fPulse;
236 2 : delete [] fADCValuesLG;
237 2 : delete [] fADCValuesHG;
238 :
239 4 : if(fcdb){ delete fcdb ; fcdb=0;}
240 :
241 3 : }
242 :
243 : //____________________________________________________________________________
244 : void AliPHOSDigitizer::Digitize(Int_t event)
245 : {
246 :
247 : // Makes the digitization of the collected summable digits.
248 : // It first creates the array of all PHOS modules
249 : // filled with noise (different for EMC, and CPV) and
250 : // then adds contributions from SDigits.
251 : // This design avoids scanning over the list of digits to add
252 : // contribution to new SDigits only.
253 :
254 : Bool_t toMakeNoise = kTRUE ; //Do not create noisy digits if merge with real data
255 :
256 : //First stream
257 8 : AliRunLoader* rl = AliRunLoader::GetRunLoader(fEventFolderName) ;
258 4 : AliPHOSLoader * phosLoader = static_cast<AliPHOSLoader*>(rl->GetLoader("PHOSLoader"));
259 :
260 : Int_t readEvent = event ;
261 4 : if (fDigInput)
262 4 : readEvent = static_cast<AliStream*>(fDigInput->GetInputStream(0))->GetCurrentEventNumber() ;
263 12 : AliDebug(1,Form("Adding event %d from input stream 0 %s %s",
264 : readEvent, GetTitle(), fEventFolderName.Data())) ;
265 4 : rl->GetEvent(readEvent) ;
266 4 : phosLoader->CleanSDigits() ;
267 4 : phosLoader->LoadSDigits("READ") ;
268 :
269 : //Prepare Output
270 4 : TClonesArray * digits = phosLoader->Digits() ;
271 4 : if( !digits ) {
272 1 : phosLoader->MakeDigitsArray() ;
273 1 : digits = phosLoader->Digits() ;
274 1 : }
275 :
276 4 : digits->Clear() ;
277 :
278 : //
279 4 : const AliPHOSGeometry *geom = AliPHOSGeometry::GetInstance() ;
280 : //Making digits with noise, first EMC
281 : //Check which PHOS modules are present
282 4 : Bool_t isPresent[5] ;
283 4 : Bool_t isCPVpresent[5] ;
284 4 : TString volpath ;
285 : Int_t nmod=0 ;
286 : Int_t nCPVmod=0 ;
287 48 : for(Int_t i=0; i<5; i++){
288 20 : isPresent[i]=0 ;
289 20 : isCPVpresent[i]=0 ;
290 60 : if (gGeoManager->CheckPath(Form("/ALIC_1/PHOS_%d",i+1))) { //PHOS module without CPV
291 12 : isPresent[i]=1 ;
292 12 : nmod++ ;
293 12 : }
294 60 : if (gGeoManager->CheckPath(Form("/ALIC_1/PHOC_%d",i+1))) { //PHOS module with CPV
295 0 : isPresent[i]=1 ;
296 0 : isCPVpresent[i]=1 ;
297 0 : nCPVmod++ ;
298 0 : nmod++ ;
299 0 : }
300 60 : if (gGeoManager->CheckPath(Form("/ALIC_1/PHOH_%d",i+1))) { //1/2 PHOS module
301 0 : isPresent[i]=1 ;
302 0 : nmod++ ;
303 0 : }
304 : }
305 :
306 12 : Int_t nEMC = nmod*geom->GetNPhi()*geom->GetNZ();
307 :
308 : Int_t nCPV ;
309 : Int_t absID ;
310 :
311 4 : if(nCPVmod){
312 0 : nCPV = nEMC + geom->GetNumberOfCPVPadsZ() * geom->GetNumberOfCPVPadsPhi() * nCPVmod ;
313 0 : }
314 : else{
315 : nCPV = nEMC ;
316 : }
317 :
318 4 : digits->Expand(nCPV) ;
319 :
320 : //take all the inputs to add together and load the SDigits
321 8 : TObjArray * sdigArray = new TObjArray(fInput) ;
322 8 : sdigArray->AddAt(phosLoader->SDigits(), 0) ;
323 :
324 12 : for(Int_t i = 1 ; i < fInput ; i++){
325 0 : TString tempo(fEventNames[i]) ;
326 0 : tempo += i ;
327 0 : AliRunLoader* rl2 = AliRunLoader::GetRunLoader(tempo) ;
328 0 : if(!rl2){
329 0 : rl2 = AliRunLoader::Open(fInputFileNames[i], tempo) ;
330 0 : if (!rl2) {
331 0 : Fatal("AliPHOSDigitizer", "Could not find the Run Loader for %s - %s",fInputFileNames[i].Data(), tempo.Data()) ;
332 0 : return ;
333 : }
334 0 : rl2->LoadHeader();
335 : }
336 0 : AliPHOSLoader * phosLoader2 = static_cast<AliPHOSLoader*>(rl2->GetLoader("PHOSLoader"));
337 :
338 0 : if(fDigInput){
339 0 : readEvent = static_cast<AliStream*>(fDigInput->GetInputStream(i))->GetCurrentEventNumber() ;
340 0 : }
341 : TClonesArray * digs ;
342 0 : if(AliPHOSSimParam::GetInstance()->IsStreamDigits(i)){ //This is Digits Stream
343 0 : AliInfo(Form("Adding event %d from input stream %d %s %s",
344 : readEvent, i, fInputFileNames[i].Data(), tempo.Data())) ;
345 0 : rl2->GetEvent(readEvent) ;
346 0 : phosLoader2->CleanDigits() ;
347 0 : phosLoader2->LoadDigits("READ") ;
348 0 : digs = phosLoader2->Digits() ;
349 : toMakeNoise=0 ; //Do not add noise, it is already in stream
350 0 : }
351 : else{
352 0 : AliInfo(Form("Adding event %d (SDigits) from input stream %d %s %s",
353 : readEvent, i, fInputFileNames[i].Data(), tempo.Data())) ;
354 0 : rl2->GetEvent(readEvent) ;
355 0 : phosLoader2->CleanSDigits() ;
356 0 : phosLoader2->LoadSDigits("READ") ;
357 0 : digs = phosLoader2->SDigits() ;
358 : }
359 0 : sdigArray->AddAt(digs, i) ;
360 0 : }
361 :
362 : //Find the first crystal with signal
363 : Int_t nextSig = 200000 ;
364 : TClonesArray * sdigits ;
365 16 : for(Int_t i = 0 ; i < fInput ; i++){
366 8 : sdigits = static_cast<TClonesArray *>(sdigArray->At(i)) ;
367 8 : if ( !sdigits->GetEntriesFast() )
368 : continue ;
369 8 : Int_t curNext = static_cast<AliPHOSDigit *>(sdigits->At(0))->GetId() ;
370 4 : if(curNext < nextSig)
371 4 : nextSig = curNext ;
372 4 : }
373 :
374 4 : TArrayI index(fInput) ;
375 4 : index.Reset() ; //Set all indexes to zero
376 :
377 : AliPHOSDigit * digit ;
378 : AliPHOSDigit * curSDigit ;
379 :
380 : // TClonesArray * ticks = new TClonesArray("AliPHOSTick",1000) ;
381 :
382 : //Put Noise contribution
383 : Double_t apdNoise = 0. ;
384 4 : if(toMakeNoise)
385 8 : apdNoise = AliPHOSSimParam::GetInstance()->GetAPDNoise() ;
386 :
387 4 : Int_t relId[4] ;
388 12 : Int_t emcpermod=geom->GetNPhi()*geom->GetNZ();
389 : Int_t idigit= 0;
390 48 : for(Int_t imod=0; imod<5; imod++){
391 20 : if(!isPresent[imod])
392 : continue ;
393 12 : Int_t firstAbsId=imod*emcpermod+1 ;
394 12 : Int_t lastAbsId =(imod+1)*emcpermod ;
395 86040 : for(absID = firstAbsId ; absID <= lastAbsId ; absID++){
396 : //do not add digits to non-existing part of mod4
397 43008 : geom->AbsToRelNumbering(absID,relId) ;
398 43008 : if(relId[0]==4 && relId[2]<33) //This part of module does not exist
399 : continue ;
400 86016 : Float_t noise = gRandom->Gaus(0.,apdNoise) ;
401 172032 : new((*digits)[idigit]) AliPHOSDigit( -1, absID, noise, TimeOfNoise() ) ;
402 : //look if we have to add signal?
403 86016 : digit = static_cast<AliPHOSDigit *>(digits->At(idigit)) ;
404 43008 : idigit++ ;
405 :
406 43008 : if(absID==nextSig){
407 : //Add SDigits from all inputs
408 : // ticks->Clear() ;
409 : // Int_t contrib = 0 ;
410 :
411 : //New Timing model is necessary
412 : // Float_t a = digit->GetEnergy() ;
413 : // Float_t b = TMath::Abs( a / fTimeSignalLength) ;
414 : // //Mark the beginning of the signal
415 : // new((*ticks)[contrib++]) AliPHOSTick(digit->GetTime(),0, b);
416 : // //Mark the end of the signal
417 : // new((*ticks)[contrib++]) AliPHOSTick(digit->GetTime()+fTimeSignalLength, -a, -b);
418 :
419 : // Calculate time as time of the largest digit
420 365 : Float_t time = digit->GetTime() ;
421 365 : Float_t eTime= digit->GetEnergy() ;
422 :
423 : //loop over inputs
424 1460 : for(Int_t i = 0 ; i < fInput ; i++){
425 1460 : if( static_cast<TClonesArray *>(sdigArray->At(i))->GetEntriesFast() > index[i] ){
426 1460 : curSDigit = static_cast<AliPHOSDigit*>(static_cast<TClonesArray *>(sdigArray->At(i))->At(index[i])) ;
427 730 : if(AliPHOSSimParam::GetInstance()->IsStreamDigits(i)){ //This is Digits Stream
428 0 : curSDigit->SetEnergy(Calibrate(curSDigit->GetEnergy(),curSDigit->GetId())) ;
429 0 : curSDigit->SetTime(CalibrateT(curSDigit->GetTime(),curSDigit->GetId())) ;
430 0 : }
431 : }
432 : else
433 : curSDigit = 0 ;
434 : //May be several digits will contribute from the same input
435 1821 : while(curSDigit && curSDigit->GetId() == absID){
436 : //Shift primary to separate primaries belonging different inputs
437 : Int_t primaryoffset ;
438 365 : if(fDigInput)
439 365 : primaryoffset = fDigInput->GetMask(i) ;
440 : else
441 0 : primaryoffset = 10000000*i ;
442 365 : curSDigit->ShiftPrimary(primaryoffset) ;
443 :
444 : //New Timing model is necessary
445 : // a = curSDigit->GetEnergy() ;
446 : // b = a /fTimeSignalLength ;
447 : // new((*ticks)[contrib++]) AliPHOSTick(curSDigit->GetTime(),0, b);
448 : // new((*ticks)[contrib++]) AliPHOSTick(curSDigit->GetTime()+fTimeSignalLength, -a, -b);
449 365 : if(curSDigit->GetEnergy()>eTime){
450 292 : eTime=curSDigit->GetEnergy() ;
451 292 : time=curSDigit->GetTime() ;
452 292 : }
453 365 : *digit += *curSDigit ; //add energies
454 :
455 730 : index[i]++ ;
456 1460 : if( static_cast<TClonesArray *>(sdigArray->At(i))->GetEntriesFast() > index[i] )
457 1444 : curSDigit = static_cast<AliPHOSDigit*>(static_cast<TClonesArray *>(sdigArray->At(i))->At(index[i])) ;
458 : else
459 : curSDigit = 0 ;
460 : }
461 : }
462 :
463 : //calculate and set time
464 : //New Timing model is necessary
465 : // Float_t time = FrontEdgeTime(ticks) ;
466 365 : digit->SetTime(time) ;
467 :
468 : //Find next signal module
469 : nextSig = 200000 ;
470 1460 : for(Int_t i = 0 ; i < fInput ; i++){
471 730 : sdigits = static_cast<TClonesArray *>(sdigArray->At(i)) ;
472 : Int_t curNext = nextSig ;
473 1095 : if(sdigits->GetEntriesFast() > index[i] ){
474 1083 : curNext = static_cast<AliPHOSDigit *>(sdigits->At(index[i]))->GetId() ;
475 361 : }
476 726 : if(curNext < nextSig) nextSig = curNext ;
477 : }
478 365 : }
479 43008 : }
480 12 : }
481 :
482 : Int_t nEMCcreated=idigit ;
483 :
484 : //Apply non-linearity
485 8 : if(AliPHOSSimParam::GetInstance()->IsCellNonlinearityOn()){ //Apply non-lineairyt on cell level
486 8 : const Double_t aNL = AliPHOSSimParam::GetInstance()->GetCellNonLineairyA() ;
487 8 : const Double_t bNL = AliPHOSSimParam::GetInstance()->GetCellNonLineairyB() ;
488 8 : const Double_t cNL = AliPHOSSimParam::GetInstance()->GetCellNonLineairyC() ;
489 86024 : for(Int_t i = 0 ; i < nEMCcreated ; i++){
490 86016 : digit = static_cast<AliPHOSDigit*>( digits->At(i) ) ;
491 43008 : if(digit){ //if there is mod 4, there is a hole
492 43008 : Double_t e= digit->GetEnergy() ;
493 : // version(1) digit->SetEnergy(e*(1+a*TMath::Exp(-e/b))) ;
494 43008 : digit->SetEnergy(e*cNL*(1.+aNL*TMath::Exp(-e*e/2./bNL/bNL))) ; //Better agreement with data...
495 43008 : }
496 : }
497 4 : }
498 :
499 :
500 : //distretize energy if necessary
501 8 : if(AliPHOSSimParam::GetInstance()->IsEDigitizationOn()){
502 0 : Float_t adcW=AliPHOSSimParam::GetInstance()->GetADCchannelW() ;
503 0 : for(Int_t i = 0 ; i < nEMCcreated ; i++){
504 0 : digit = static_cast<AliPHOSDigit*>( digits->At(i) ) ;
505 0 : if(digit)
506 0 : digit->SetEnergy(adcW*ceil(digit->GetEnergy()/adcW)) ;
507 : }
508 0 : }
509 :
510 : //Apply decalibration if necessary
511 86024 : for(Int_t i = 0 ; i < nEMCcreated ; i++){
512 86016 : digit = static_cast<AliPHOSDigit*>( digits->At(i) ) ;
513 43008 : if(digit)
514 43008 : Decalibrate(digit) ;
515 : }
516 :
517 : // ticks->Delete() ;
518 : // delete ticks ;
519 :
520 : //Now CPV digits (different noise and no timing)
521 12 : Int_t cpvpermod = geom->GetNumberOfCPVPadsZ() * geom->GetNumberOfCPVPadsPhi() ;
522 4 : Int_t nEMCtotal=emcpermod*5 ;
523 8 : Float_t cpvNoise = AliPHOSSimParam::GetInstance()->GetCPVNoise() ;
524 48 : for(Int_t imod=0; imod<5; imod++){ //module is present in current geometry
525 20 : if(isCPVpresent[imod]){ //CPV is present in current geometry
526 0 : Int_t firstAbsId=nEMCtotal+imod*cpvpermod+1 ;
527 0 : Int_t lastAbsId =nEMCtotal+(imod+1)*cpvpermod ;
528 0 : for(absID = firstAbsId; absID <= lastAbsId; absID++){
529 0 : Float_t noise = gRandom->Gaus(0., cpvNoise) ;
530 0 : new((*digits)[idigit]) AliPHOSDigit( -1,absID,noise, TimeOfNoise() ) ;
531 0 : idigit++ ;
532 : //look if we have to add signal?
533 0 : if(absID==nextSig){
534 0 : digit = static_cast<AliPHOSDigit *>(digits->At(idigit-1)) ;
535 : //Add SDigits from all inputs
536 0 : for(Int_t i = 0 ; i < fInput ; i++){
537 0 : if( static_cast<TClonesArray *>(sdigArray->At(i))->GetEntriesFast() > index[i] )
538 0 : curSDigit = static_cast<AliPHOSDigit*>( static_cast<TClonesArray *>(sdigArray->At(i))->At(index[i])) ;
539 : else
540 : curSDigit = 0 ;
541 :
542 : //May be several digits will contribute from the same input
543 0 : while(curSDigit && curSDigit->GetId() == absID){
544 : //Shift primary to separate primaries belonging different inputs
545 : Int_t primaryoffset ;
546 0 : if(fDigInput)
547 0 : primaryoffset = fDigInput->GetMask(i) ;
548 : else
549 0 : primaryoffset = 10000000*i ;
550 0 : curSDigit->ShiftPrimary(primaryoffset) ;
551 :
552 : //add energies
553 0 : *digit += *curSDigit ;
554 0 : index[i]++ ;
555 0 : if( static_cast<TClonesArray *>(sdigArray->At(i))->GetEntriesFast() > index[i] )
556 0 : curSDigit = static_cast<AliPHOSDigit*>( static_cast<TClonesArray *>(sdigArray->At(i))->At(index[i]) ) ;
557 : else
558 : curSDigit = 0 ;
559 : }
560 : }
561 :
562 : //Find next signal module
563 : nextSig = 200000 ;
564 0 : for(Int_t i = 0 ; i < fInput ; i++){
565 0 : sdigits = static_cast<TClonesArray *>(sdigArray->At(i)) ;
566 : Int_t curNext = nextSig ;
567 0 : if(sdigits->GetEntriesFast() > index[i] )
568 0 : curNext = static_cast<AliPHOSDigit *>( sdigits->At(index[i]) )->GetId() ;
569 0 : if(curNext < nextSig) nextSig = curNext ;
570 : }
571 :
572 0 : }
573 : }
574 0 : }
575 : }
576 :
577 8 : delete sdigArray ; //We should not delete its contents
578 :
579 : //set amplitudes in bad channels to zero
580 :
581 :
582 :
583 : // for(Int_t i = 0 ; i <digits->GetEntriesFast(); i++){
584 86024 : for(Int_t i = 0 ; i <nEMCcreated; i++){
585 86016 : digit = static_cast<AliPHOSDigit*>( digits->At(i) ) ;
586 43008 : if(digit){
587 43008 : geom->AbsToRelNumbering(digit->GetId(),relId);
588 43008 : if(relId[1] == 0){ // Emc
589 86016 : if(fcdb->IsBadChannelEmc(relId[0],relId[3],relId[2])) digit->SetEnergy(0.);
590 : }
591 43008 : if(relId[1] == -1){ // Cpv
592 0 : if(fcdb->IsBadChannelCpv(relId[0],relId[3],relId[2])) digit->SetEnergy(0.);
593 : }
594 : }
595 : }
596 :
597 : //remove digits below thresholds
598 8 : Float_t emcThreshold = AliPHOSSimParam::GetInstance()->GetEmcDigitsThreshold() ;
599 86024 : for(Int_t i = 0 ; i < nEMCcreated ; i++){
600 86016 : digit = static_cast<AliPHOSDigit*>( digits->At(i) ) ;
601 43008 : if(!digit)
602 : continue ;
603 43008 : if(digit->GetEnergy() < emcThreshold){
604 42884 : digits->RemoveAt(i) ;
605 : continue ;
606 : }
607 :
608 124 : geom->AbsToRelNumbering(digit->GetId(),relId);
609 :
610 : // digit->SetEnergy(TMath::Ceil(digit->GetEnergy())-0.9999) ;
611 :
612 124 : Float_t tres = TimeResolution(digit->GetEnergy()) ;
613 248 : digit->SetTime(gRandom->Gaus(digit->GetTime(), tres) ) ;
614 :
615 124 : fPulse->Reset();
616 248 : fPulse->SetAmplitude(digit->GetEnergy()/
617 124 : fcdb->GetADCchannelEmc(relId[0],relId[3],relId[2]));
618 124 : fPulse->SetTZero(digit->GetTimeR());
619 124 : fPulse->MakeSamples();
620 124 : fPulse->GetSamples(fADCValuesHG, fADCValuesLG) ;
621 124 : Int_t nSamples = fPulse->GetRawFormatTimeBins();
622 124 : digit->SetALTROSamplesHG(nSamples,fADCValuesHG);
623 124 : digit->SetALTROSamplesLG(nSamples,fADCValuesLG);
624 124 : }
625 :
626 4 : Int_t nCPVcreated=digits->GetEntriesFast() ;
627 8 : Float_t cpvDigitThreshold = AliPHOSSimParam::GetInstance()->GetCpvDigitsThreshold() ;
628 8 : for(Int_t i = nEMCcreated; i < nCPVcreated ; i++){
629 0 : if( static_cast<AliPHOSDigit*>(digits->At(i))->GetEnergy() < cpvDigitThreshold )
630 0 : digits->RemoveAt(i) ;
631 : }
632 :
633 4 : digits->Compress() ;
634 4 : Int_t ndigits = digits->GetEntriesFast() ;
635 :
636 : //Set indexes in list of digits and make true digitization of the energy
637 256 : for (Int_t i = 0 ; i < ndigits ; i++) {
638 248 : digit = static_cast<AliPHOSDigit*>( digits->At(i) ) ;
639 124 : digit->SetIndexInList(i) ;
640 124 : if(digit->GetId() > fEmcCrystals){ //digitize CPV only
641 0 : digit->SetAmp(DigitizeCPV(digit->GetEnergy(),digit->GetId()) ) ;
642 0 : }
643 : }
644 :
645 8 : }
646 : //____________________________________________________________________________
647 : Float_t AliPHOSDigitizer::Calibrate(Float_t amp,Int_t absId){
648 : //Apply calibration
649 0 : const AliPHOSGeometry *geom = AliPHOSGeometry::GetInstance() ;
650 :
651 : //Determine rel.position of the cell absolute ID
652 0 : Int_t relId[4];
653 0 : geom->AbsToRelNumbering(absId,relId);
654 0 : Int_t module=relId[0];
655 0 : Int_t row =relId[2];
656 0 : Int_t column=relId[3];
657 0 : if(relId[1]==0){ //This Is EMC
658 0 : Float_t calibration = fcdb->GetADCchannelEmc(module,column,row);
659 0 : return amp*calibration ;
660 : }
661 0 : return 0 ;
662 0 : }
663 : //____________________________________________________________________________
664 : void AliPHOSDigitizer::Decalibrate(AliPHOSDigit *digit)
665 : {
666 : // Decalibrate EMC digit, i.e. change its energy by a factor read from CDB
667 :
668 86016 : const AliPHOSGeometry *geom = AliPHOSGeometry::GetInstance() ;
669 :
670 : //Determine rel.position of the cell absolute ID
671 43008 : Int_t relId[4];
672 43008 : geom->AbsToRelNumbering(digit->GetId(),relId);
673 43008 : Int_t module=relId[0];
674 43008 : Int_t row =relId[2];
675 43008 : Int_t column=relId[3];
676 43008 : if(relId[1]==0){ //This Is EMC
677 43008 : Float_t decalib = fcdb->GetADCchannelEmcDecalib(module,column,row); // O(1)
678 43008 : Float_t calibration = fcdb->GetADCchannelEmc(module,column,row)*decalib;
679 43008 : Float_t energy = digit->GetEnergy()/calibration;
680 43008 : digit->SetEnergy(energy); //Now digit measures E in ADC counts
681 43008 : Float_t time = digit->GetTime() ;
682 43008 : time-=fcdb->GetTimeShiftEmc(module,column,row);
683 43008 : digit->SetTime(time) ;
684 43008 : }
685 43008 : }
686 : //____________________________________________________________________________
687 : Float_t AliPHOSDigitizer::CalibrateT(Float_t time,Int_t absId){
688 : //Apply time calibration
689 0 : const AliPHOSGeometry *geom = AliPHOSGeometry::GetInstance() ;
690 :
691 : //Determine rel.position of the cell absolute ID
692 0 : Int_t relId[4];
693 0 : geom->AbsToRelNumbering(absId,relId);
694 0 : Int_t module=relId[0];
695 0 : Int_t row =relId[2];
696 0 : Int_t column=relId[3];
697 0 : time += fcdb->GetTimeShiftEmc(module,column,row);
698 0 : return time ;
699 0 : }
700 : //____________________________________________________________________________
701 : Int_t AliPHOSDigitizer::DigitizeCPV(Float_t charge, Int_t absId)
702 : {
703 : // Returns digitized value of the CPV charge in a pad absId
704 :
705 0 : const AliPHOSGeometry *geom = AliPHOSGeometry::GetInstance() ;
706 :
707 : //Determine rel.position of the cell absId
708 0 : Int_t relId[4];
709 0 : geom->AbsToRelNumbering(absId,relId);
710 0 : Int_t module=relId[0];
711 0 : Int_t row =relId[2];
712 0 : Int_t column=relId[3];
713 :
714 : Int_t channel = 0;
715 :
716 0 : if(absId > fEmcCrystals){ //digitize CPV only
717 :
718 : //reading calibration data for cell absId.
719 0 : Float_t adcPedestalCpv = fcdb->GetADCpedestalCpv(module,column,row);
720 0 : Float_t adcChanelCpv = fcdb->GetADCchannelCpv( module,column,row);
721 :
722 0 : channel = (Int_t) TMath::Ceil((charge - adcPedestalCpv)/adcChanelCpv) ;
723 0 : Int_t nMax = AliPHOSSimParam::GetInstance()->GetNADCcpv() ;
724 0 : if(channel > nMax ) channel = nMax ;
725 0 : }
726 0 : return channel ;
727 0 : }
728 :
729 : //____________________________________________________________________________
730 : void AliPHOSDigitizer::Digitize(Option_t *option)
731 : {
732 : // Steering method to process digitization for events
733 : // in the range from fFirstEvent to fLastEvent.
734 : // This range is optionally set by SetEventRange().
735 : // if fLastEvent=-1, then process events until the end.
736 : // by default fLastEvent = fFirstEvent (process only one event)
737 :
738 8 : if (!fInit) { // to prevent overwrite existing file
739 0 : AliError(Form("Give a version name different from %s",
740 : fEventFolderName.Data() )) ;
741 0 : return ;
742 : }
743 :
744 4 : if (strstr(option,"print")) {
745 0 : Print();
746 0 : return ;
747 : }
748 :
749 4 : if(strstr(option,"tim"))
750 0 : gBenchmark->Start("PHOSDigitizer");
751 :
752 4 : AliRunLoader* rl = AliRunLoader::GetRunLoader(fEventFolderName) ;
753 4 : AliPHOSLoader * phosLoader = static_cast<AliPHOSLoader*>(rl->GetLoader("PHOSLoader"));
754 :
755 4 : if (fLastEvent == -1)
756 0 : fLastEvent = rl->GetNumberOfEvents() - 1 ;
757 4 : else if (fDigInput)
758 4 : fLastEvent = fFirstEvent ;
759 :
760 4 : Int_t nEvents = fLastEvent - fFirstEvent + 1;
761 :
762 : Int_t ievent ;
763 :
764 16 : for (ievent = fFirstEvent; ievent <= fLastEvent; ievent++) {
765 4 : fEventCounter++ ;
766 :
767 4 : Digitize(ievent) ; //Add prepared SDigits to digits and add the noise
768 :
769 4 : WriteDigits() ;
770 :
771 4 : if(strstr(option,"deb"))
772 0 : PrintDigits(option);
773 :
774 : //increment the total number of Digits per run
775 4 : fDigitsInRun += phosLoader->Digits()->GetEntriesFast() ;
776 : }
777 :
778 4 : if(strstr(option,"tim")){
779 0 : gBenchmark->Stop("PHOSDigitizer");
780 0 : TString message ;
781 0 : message = " took %f seconds for Digitizing %f seconds per event\n" ;
782 0 : AliInfo(Form( message.Data(),
783 : gBenchmark->GetCpuTime("PHOSDigitizer"),
784 : gBenchmark->GetCpuTime("PHOSDigitizer")/nEvents ));
785 0 : }
786 8 : }
787 : //____________________________________________________________________________
788 : Float_t AliPHOSDigitizer::TimeResolution(Float_t e){
789 : //calculate TOF resolution using beam-test resutls
790 248 : Float_t a=AliPHOSSimParam::GetInstance()->GetTOFa() ;
791 124 : Float_t b=AliPHOSSimParam::GetInstance()->GetTOFb() ;
792 124 : return TMath::Sqrt(a*a+b*b/e) ;
793 : }
794 :
795 : ////____________________________________________________________________________
796 : //Float_t AliPHOSDigitizer::FrontEdgeTime(TClonesArray * ticks) const
797 : //{
798 : // // Returns the shortest time among all time ticks
799 : //
800 : // ticks->Sort() ; //Sort in accordance with times of ticks
801 : // TIter it(ticks) ;
802 : // AliPHOSTick * ctick = (AliPHOSTick *) it.Next() ;
803 : // Float_t time = ctick->CrossingTime(fTimeThreshold) ;
804 : //
805 : // AliPHOSTick * t ;
806 : // while((t=(AliPHOSTick*) it.Next())){
807 : // if(t->GetTime() < time) //This tick starts before crossing
808 : // *ctick+=*t ;
809 : // else
810 : // return time ;
811 : //
812 : // time = ctick->CrossingTime(fTimeThreshold) ;
813 : // }
814 : // return time ;
815 : //}
816 :
817 : //____________________________________________________________________________
818 : Bool_t AliPHOSDigitizer::Init()
819 : {
820 : // Makes all memory allocations
821 2 : fInit = kTRUE ;
822 :
823 : AliPHOSGeometry *geom;
824 1 : if (!(geom = AliPHOSGeometry::GetInstance()))
825 0 : geom = AliPHOSGeometry::GetInstance("IHEP","");
826 : // const AliPHOSGeometry *geom = AliPHOSGeometry::GetInstance() ;
827 :
828 1 : fEmcCrystals = geom->GetNModules() * geom->GetNCristalsInModule() ;
829 :
830 1 : fFirstEvent = 0 ;
831 1 : fLastEvent = fFirstEvent ;
832 1 : if (fDigInput)
833 1 : fInput = fDigInput->GetNinputs() ;
834 : else
835 0 : fInput = 1 ;
836 :
837 5 : fInputFileNames = new TString[fInput] ;
838 5 : fEventNames = new TString[fInput] ;
839 1 : fInputFileNames[0] = GetTitle() ;
840 1 : fEventNames[0] = fEventFolderName.Data() ;
841 : Int_t index ;
842 2 : for (index = 1 ; index < fInput ; index++) {
843 0 : fInputFileNames[index] = static_cast<AliStream*>(fDigInput->GetInputStream(index))->GetFileName(0);
844 0 : TString tempo = fDigInput->GetInputFolderName(index) ;
845 0 : fEventNames[index] = tempo.Remove(tempo.Length()-1) ; // strip of the stream number added by fDigInput
846 0 : }
847 :
848 : //to prevent cleaning of this object while GetEvent is called
849 1 : AliRunLoader* rl = AliRunLoader::GetRunLoader(fEventFolderName) ;
850 1 : if(!rl){
851 0 : AliRunLoader::Open(GetTitle(), fEventFolderName) ;
852 0 : }
853 1 : return fInit ;
854 0 : }
855 :
856 : //____________________________________________________________________________
857 : void AliPHOSDigitizer::InitParameters()
858 : {
859 : // Set initial parameters Digitizer
860 :
861 2 : fDigitsInRun = 0 ;
862 1 : SetEventRange(0,-1) ;
863 2 : fPulse = new AliPHOSPulseGenerator();
864 1 : fADCValuesLG = new Int_t[fPulse->GetRawFormatTimeBins()];
865 1 : fADCValuesHG = new Int_t[fPulse->GetRawFormatTimeBins()];
866 :
867 1 : }
868 :
869 : //__________________________________________________________________
870 : void AliPHOSDigitizer::Print(const Option_t *)const
871 : {
872 : // Print Digitizer's parameters
873 0 : AliInfo(Form("\n------------------- %s -------------", GetName() )) ;
874 0 : if( strcmp(fEventFolderName.Data(), "") != 0 ){
875 0 : printf(" Writing Digits to branch with title %s\n", fEventFolderName.Data()) ;
876 :
877 : Int_t nStreams ;
878 0 : if (fDigInput)
879 0 : nStreams = GetNInputStreams() ;
880 : else
881 0 : nStreams = fInput ;
882 :
883 : Int_t index = 0 ;
884 0 : for (index = 0 ; index < nStreams ; index++) {
885 0 : TString tempo(fEventNames[index]) ;
886 0 : tempo += index ;
887 0 : printf ("Adding SDigits from %s \n", fInputFileNames[index].Data()) ;
888 0 : }
889 :
890 : // printf("\nWith following parameters:\n") ;
891 : // printf(" Electronics noise in EMC (fPinNoise) = %f GeV\n", fPinNoise ) ;
892 : // printf(" Threshold in EMC (fEMCDigitThreshold) = %f GeV\n", fEMCDigitThreshold ) ;
893 : // printf(" Noise in CPV (fCPVNoise) = %f aux units\n", fCPVNoise ) ;
894 : // printf(" Threshold in CPV (fCPVDigitThreshold) = %f aux units\n",fCPVDigitThreshold ) ;
895 0 : printf(" ---------------------------------------------------\n") ;
896 0 : }
897 : else
898 0 : AliInfo(Form("AliPHOSDigitizer not initialized" )) ;
899 :
900 0 : }
901 :
902 : //__________________________________________________________________
903 : void AliPHOSDigitizer::PrintDigits(Option_t * option)
904 : {
905 : // Print a table of digits
906 :
907 :
908 0 : AliRunLoader* rl = AliRunLoader::GetRunLoader(fEventFolderName) ;
909 0 : AliPHOSLoader * phosLoader = static_cast<AliPHOSLoader*>(rl->GetLoader("PHOSLoader"));
910 0 : TClonesArray * digits = phosLoader->Digits() ;
911 0 : const AliPHOSGeometry *geom = AliPHOSGeometry::GetInstance() ;
912 :
913 0 : AliInfo(Form("%d", digits->GetEntriesFast())) ;
914 0 : printf("\nevent %d", gAlice->GetEvNumber()) ;
915 0 : printf("\n Number of entries in Digits list %d", digits->GetEntriesFast() ) ;
916 :
917 :
918 0 : if(strstr(option,"all")||strstr(option,"EMC")){
919 : //loop over digits
920 : AliPHOSDigit * digit;
921 0 : printf("\nEMC digits (with primaries):\n") ;
922 0 : printf("\n Id Amplitude Time Index Nprim: Primaries list \n") ;
923 0 : Int_t maxEmc = geom->GetNModules()*geom->GetNCristalsInModule() ;
924 : Int_t index ;
925 0 : for (index = 0 ; (index < digits->GetEntriesFast()) &&
926 0 : (static_cast<AliPHOSDigit *>(digits->At(index))->GetId() <= maxEmc) ; index++) {
927 0 : digit = (AliPHOSDigit * ) digits->At(index) ;
928 0 : if(digit->GetNprimary() == 0)
929 : continue;
930 : // printf("%6d %8d %6.5e %4d %2d :",
931 : // digit->GetId(), digit->GetAmp(), digit->GetTime(), digit->GetIndexInList(), digit->GetNprimary()) ; // YVK
932 0 : printf("%6d %.4f %6.5e %4d %2d :",
933 0 : digit->GetId(), digit->GetEnergy(), digit->GetTime(), digit->GetIndexInList(), digit->GetNprimary()) ;
934 : Int_t iprimary;
935 0 : for (iprimary=0; iprimary<digit->GetNprimary(); iprimary++) {
936 0 : printf("%d ",digit->GetPrimary(iprimary+1) ) ;
937 : }
938 0 : printf("\n") ;
939 0 : }
940 0 : }
941 :
942 0 : if(strstr(option,"all")||strstr(option,"CPV")){
943 :
944 : //loop over CPV digits
945 : AliPHOSDigit * digit;
946 0 : printf("\nCPV digits (with primaries):\n") ;
947 0 : printf("\n Id Amplitude Time Index Nprim: Primaries list \n") ;
948 0 : Int_t maxEmc = geom->GetNModules()*geom->GetNCristalsInModule() ;
949 : Int_t index ;
950 0 : for (index = 0 ; index < digits->GetEntriesFast(); index++) {
951 0 : digit = (AliPHOSDigit * ) digits->At(index) ;
952 0 : if(digit->GetId() > maxEmc){
953 0 : printf("%6d %8d %4d %2d :",
954 0 : digit->GetId(), digit->GetAmp(), digit->GetIndexInList(), digit->GetNprimary()) ;
955 : Int_t iprimary;
956 0 : for (iprimary=0; iprimary<digit->GetNprimary(); iprimary++) {
957 0 : printf("%d ",digit->GetPrimary(iprimary+1) ) ;
958 : }
959 0 : printf("\n") ;
960 0 : }
961 : }
962 0 : }
963 :
964 0 : }
965 :
966 : //__________________________________________________________________
967 : Float_t AliPHOSDigitizer::TimeOfNoise(void) const
968 : { // Calculates the time signal generated by noise
969 : //PH Info("TimeOfNoise", "Change me") ;
970 86016 : return gRandom->Rndm() * 1.28E-5;
971 : }
972 :
973 : //__________________________________________________________________
974 : void AliPHOSDigitizer::Unload()
975 : {
976 :
977 : Int_t i ;
978 12 : for(i = 1 ; i < fInput ; i++){
979 0 : TString tempo(fEventNames[i]) ;
980 0 : tempo += i ;
981 0 : AliRunLoader* rl = AliRunLoader::GetRunLoader(tempo) ;
982 0 : AliPHOSLoader * phosLoader = static_cast<AliPHOSLoader*>(rl->GetLoader("PHOSLoader"));
983 0 : phosLoader->UnloadSDigits() ;
984 0 : }
985 :
986 4 : AliRunLoader* rl = AliRunLoader::GetRunLoader(fEventFolderName) ;
987 4 : AliPHOSLoader * phosLoader = static_cast<AliPHOSLoader*>(rl->GetLoader("PHOSLoader"));
988 4 : phosLoader->UnloadDigits() ;
989 4 : }
990 :
991 : //____________________________________________________________________________
992 : void AliPHOSDigitizer::WriteDigits()
993 : {
994 :
995 : // Makes TreeD in the output file.
996 : // Check if branch already exists:
997 : // if yes, exit without writing: ROOT TTree does not support overwriting/updating of
998 : // already existing branches.
999 : // else creates branch with Digits, named "PHOS", title "...",
1000 : // and branch "AliPHOSDigitizer", with the same title to keep all the parameters
1001 : // and names of files, from which digits are made.
1002 :
1003 8 : AliRunLoader* rl = AliRunLoader::GetRunLoader(fEventFolderName) ;
1004 4 : AliPHOSLoader * phosLoader = static_cast<AliPHOSLoader*>(rl->GetLoader("PHOSLoader"));
1005 :
1006 4 : const TClonesArray * digits = phosLoader->Digits() ;
1007 4 : TTree * treeD = phosLoader->TreeD();
1008 4 : if(!treeD){
1009 4 : phosLoader->MakeTree("D");
1010 4 : treeD = phosLoader->TreeD();
1011 4 : }
1012 :
1013 : // -- create Digits branch
1014 : Int_t bufferSize = 32000 ;
1015 4 : TBranch * digitsBranch = treeD->Branch("PHOS","TClonesArray",&digits,bufferSize);
1016 4 : digitsBranch->SetTitle(fEventFolderName);
1017 4 : digitsBranch->Fill() ;
1018 :
1019 4 : phosLoader->WriteDigits("OVERWRITE");
1020 :
1021 4 : Unload() ;
1022 :
1023 4 : }
|