Complete reshuffling of the digitization code. Now VZERO has operational direct Hits...
[u/mrichter/AliRoot.git] / VZERO / AliVZERODigitizer.cxx
CommitLineData
9e04c3b6 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
090026bf 16/* $Id$ */
17
b0d2c2d3 18///_________________________________________________________________________
19///
20/// This class constructs Digits out of Hits
21///
22///
9e04c3b6 23
24// --- Standard library ---
9e04c3b6 25
26// --- ROOT system ---
090026bf 27#include <TMath.h>
9e04c3b6 28#include <TTree.h>
fe0adf2a 29#include <TMap.h>
8bd3e27a 30#include <TGeoManager.h>
31#include <TGeoPhysicalNode.h>
32#include <AliGeomManager.h>
e939a978 33#include <TRandom.h>
9672d66e 34#include <TF1.h>
4e2652e8 35#include <TH1F.h>
9e04c3b6 36
37// --- AliRoot header files ---
9e04c3b6 38#include "AliRun.h"
39#include "AliVZERO.h"
40#include "AliVZEROhit.h"
9e04c3b6 41#include "AliRunLoader.h"
42#include "AliLoader.h"
fe0adf2a 43#include "AliGRPObject.h"
9e04c3b6 44#include "AliRunDigitizer.h"
ce7090f5 45#include "AliCDBManager.h"
46#include "AliCDBStorage.h"
47#include "AliCDBEntry.h"
48#include "AliVZEROCalibData.h"
4e2652e8 49#include "AliCTPTimeParams.h"
9e04c3b6 50#include "AliVZEROdigit.h"
b0d2c2d3 51#include "AliVZERODigitizer.h"
72da5ce8 52#include "AliVZEROSDigit.h"
9e04c3b6 53
54ClassImp(AliVZERODigitizer)
55
56 AliVZERODigitizer::AliVZERODigitizer()
fe0adf2a 57 :AliDigitizer(),
58 fCalibData(GetCalibData()),
59 fPhotoCathodeEfficiency(0.18),
fe0adf2a 60 fNdigits(0),
61 fDigits(0),
4e2652e8 62 fSignalShape(NULL),
63 fPMResponse(NULL),
72da5ce8 64 fSinglePhESpectrum(NULL),
65 fEvenOrOdd(kFALSE),
66 fTask(kHits2Digits),
67 fVZERO(NULL)
9e04c3b6 68{
b0d2c2d3 69 // default constructor
72da5ce8 70 // Initialize OCDB and containers used in the digitization
b0d2c2d3 71
72da5ce8 72 Init();
73}
4e2652e8 74
72da5ce8 75//____________________________________________________________________________
76 AliVZERODigitizer::AliVZERODigitizer(AliVZERO *vzero, DigiTask_t task)
77 :AliDigitizer(),
78 fCalibData(GetCalibData()),
79 fPhotoCathodeEfficiency(0.18),
80 fNdigits(0),
81 fDigits(0),
82 fSignalShape(NULL),
83 fPMResponse(NULL),
84 fSinglePhESpectrum(NULL),
85 fEvenOrOdd(kFALSE),
86 fTask(task),
87 fVZERO(vzero)
88{
89 // constructor
90 // Initialize OCDB and containers used in the digitization
4e2652e8 91
72da5ce8 92 Init();
9e04c3b6 93}
72da5ce8 94
9e04c3b6 95//____________________________________________________________________________
96 AliVZERODigitizer::AliVZERODigitizer(AliRunDigitizer* manager)
0b2bea8b 97 :AliDigitizer(manager),
98 fCalibData(GetCalibData()),
99 fPhotoCathodeEfficiency(0.18),
0b2bea8b 100 fNdigits(0),
fe0adf2a 101 fDigits(0),
4e2652e8 102 fSignalShape(NULL),
103 fPMResponse(NULL),
72da5ce8 104 fSinglePhESpectrum(NULL),
105 fEvenOrOdd(kFALSE),
106 fTask(kHits2Digits),
107 fVZERO(NULL)
9e04c3b6 108{
109 // constructor
4e2652e8 110 // Initialize OCDB and containers used in the digitization
72da5ce8 111
112 Init();
113}
114
115//____________________________________________________________________________
116 AliVZERODigitizer::~AliVZERODigitizer()
117{
118 // destructor
9e04c3b6 119
72da5ce8 120 if (fDigits) {
121 fDigits->Delete();
122 delete fDigits;
123 fDigits=0;
124 }
125
126 if (fSignalShape) {
127 delete fSignalShape;
128 fSignalShape = NULL;
129 }
130 if (fPMResponse) {
131 delete fPMResponse;
132 fPMResponse = NULL;
133 }
134 if (fSinglePhESpectrum) {
135 delete fSinglePhESpectrum;
136 fSinglePhESpectrum = NULL;
137 }
138
139 for(Int_t i = 0 ; i < 64; ++i) {
140 if (fTime[i]) delete [] fTime[i];
141 }
142}
143
144//_____________________________________________________________________________
145Bool_t AliVZERODigitizer::Init()
146{
147 // Initialises the digitizer
148 // Initialize OCDB and containers used in the digitization
149
150 // check if the digitizer was already initialized
151 if (fSignalShape) return kTRUE;
152
9672d66e 153 fSignalShape = new TF1("VZEROSignalShape",this,&AliVZERODigitizer::SignalShape,0,200,6,"AliVZERODigitizer","SignalShape");
4e2652e8 154 // fSignalShape->SetParameters(0,1.57345e1,-4.25603e-1,2.9,6.40982,3.69339e-01);
81db2705 155 // fSignalShape->SetParameters(1.34330e+00,1.13007e+02,-4.95705e-01,
156 // 3.68911e+00,1.01040e+00, 3.94675e-01);
157 fSignalShape->SetParameters(-1.07335e+00,2.16002e+01,-1.26133e-01,
158 1.41619e+00,5.50334e-01,3.86111e-01);
4e2652e8 159 fPMResponse = new TF1("VZEROPMResponse",this,&AliVZERODigitizer::PMResponse,-kPMRespTime,2.*kPMRespTime,0,"AliVZERODigitizer","PMResponse");
160 fSinglePhESpectrum = new TF1("VZEROSinglePhESpectrum",this,&AliVZERODigitizer::SinglePhESpectrum,0,20,0,"AliVZERODigitizer","SinglePhESpectrum");
ce7090f5 161
4e2652e8 162 // Now get the CTP L0->L1 delay
163 AliCDBEntry *entry = AliCDBManager::Instance()->Get("GRP/CTP/CTPtiming");
164 if (!entry) AliFatal("CTP timing parameters are not found in OCDB !");
165 AliCTPTimeParams *ctpParams = (AliCTPTimeParams*)entry->GetObject();
166 Float_t l1Delay = (Float_t)ctpParams->GetDelayL1L0()*25.0;
167
168 AliCDBEntry *entry2 = AliCDBManager::Instance()->Get("VZERO/Calib/TimeDelays");
169 if (!entry2) AliFatal("VZERO time delays are not found in OCDB !");
170 TH1F *delays = (TH1F*)entry2->GetObject();
171
172 for(Int_t i = 0 ; i < 64; ++i) {
173
174 for(Int_t j = 0; j < kNClocks; ++j) fAdc[i][j] = 0;
175 fLeadingTime[i] = fTimeWidth[i] = 0;
176
177 fPmGain[i] = fCalibData->GetGain(i);
178
179 fAdcPedestal[i][0] = fCalibData->GetPedestal(i);
180 fAdcSigma[i][0] = fCalibData->GetSigma(i);
181 fAdcPedestal[i][1] = fCalibData->GetPedestal(i+64);
182 fAdcSigma[i][1] = fCalibData->GetSigma(i+64);
183
51980118 184 Int_t board = AliVZEROCalibData::GetBoardNumber(i);
4e2652e8 185 fNBins[i] = TMath::Nint(((Float_t)(fCalibData->GetMatchWindow(board)+1)*25.0+
186 (Float_t)kMaxTDCWidth*fCalibData->GetWidthResolution(board))/
187 fCalibData->GetTimeResolution(board));
188 fNBinsLT[i] = TMath::Nint(((Float_t)(fCalibData->GetMatchWindow(board)+1)*25.0)/
189 fCalibData->GetTimeResolution(board));
190 fBinSize[i] = fCalibData->GetTimeResolution(board);
191 fHptdcOffset[i] = (((Float_t)fCalibData->GetTriggerCountOffset(board)-
192 (Float_t)fCalibData->GetRollOver(board))*25.0+
193 fCalibData->GetTimeOffset(i)+
194 l1Delay+
195 delays->GetBinContent(i+1)+
196 kV0Offset);
197
198 fTime[i] = new Float_t[fNBins[i]];
199 memset(fTime[i],0,fNBins[i]*sizeof(Float_t));
200 }
72da5ce8 201
202 return kTRUE;
9e04c3b6 203}
9672d66e 204
72da5ce8 205//____________________________________________________________________________
206void AliVZERODigitizer::Exec(Option_t* /*option*/)
207{
208 // Creates digits from hits
209 fNdigits = 0;
210
211 if (fVZERO && !fManager) {
212 AliLoader *loader = fVZERO->GetLoader();
213 if (!loader) {
214 AliError("Can not get VZERO Loader via AliVZERO object!");
215 return;
216 }
217 AliRunLoader* runLoader = AliRunLoader::Instance();
218 for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); ++iEvent) {
219 runLoader->GetEvent(iEvent);
220 if (fTask == kHits2Digits) {
221 DigitizeHits();
222 DigitizeSDigits();
223 WriteDigits(loader);
224 }
225 else {
226 DigitizeHits();
227 WriteSDigits(loader);
228 }
229 }
4e2652e8 230 }
72da5ce8 231 else if (fManager) {
232 ReadSDigits();
233 DigitizeSDigits();
234 AliRunLoader *currentLoader = AliRunLoader::GetRunLoader(fManager->GetOutputFolderName());
235 AliLoader *loader = currentLoader->GetLoader("VZEROLoader");
236 if (!loader) {
237 AliError("Cannot get VZERO Loader via RunDigitizer!");
238 return;
239 }
240 WriteDigits(loader);
4e2652e8 241 }
72da5ce8 242 else {
243 AliFatal("Invalid digitization task! Exiting!");
4e2652e8 244 }
9e04c3b6 245}
246
72da5ce8 247//____________________________________________________________________________
248void AliVZERODigitizer::AddDigit(Int_t pmnumber, Float_t time, Float_t width, Bool_t integrator, Short_t *chargeADC, Int_t *labels)
249 {
250
251// Adds Digit
252
253 TClonesArray &ldigits = *fDigits;
254
255 new(ldigits[fNdigits++]) AliVZEROdigit(pmnumber,time,width,integrator,chargeADC,labels);
256
257}
258//____________________________________________________________________________
259void AliVZERODigitizer::AddSDigit(Int_t pmnumber, Int_t nbins, Float_t *charges, Int_t *labels)
260 {
261
262// Adds SDigit
263
264 TClonesArray &ldigits = *fDigits;
265
266 new(ldigits[fNdigits++]) AliVZEROSDigit(pmnumber,nbins,charges,labels);
267
268}
269//____________________________________________________________________________
270void AliVZERODigitizer::ResetDigits()
9e04c3b6 271{
9e04c3b6 272
72da5ce8 273// Clears Digits
274
275 fNdigits = 0;
276 if (fDigits) fDigits->Clear();
9e04c3b6 277}
278
279//____________________________________________________________________________
72da5ce8 280AliVZEROCalibData* AliVZERODigitizer::GetCalibData() const
281
282{
283 AliCDBManager *man = AliCDBManager::Instance();
284
285 AliCDBEntry *entry=0;
286
287 entry = man->Get("VZERO/Calib/Data");
288
289// if(!entry){
290// AliWarning("Load of calibration data from default storage failed!");
291// AliWarning("Calibration data will be loaded from local storage ($ALICE_ROOT)");
292// Int_t runNumber = man->GetRun();
293// entry = man->GetStorage("local://$ALICE_ROOT/OCDB")
294// ->Get("VZERO/Calib/Data",runNumber);
295//
296// }
297
298 // Retrieval of data in directory VZERO/Calib/Data:
299
300
301 AliVZEROCalibData *calibdata = 0;
302
303 if (entry) calibdata = (AliVZEROCalibData*) entry->GetObject();
304 if (!calibdata) AliFatal("No calibration data from calibration database !");
305
306 return calibdata;
307
308}
309
310double AliVZERODigitizer::SignalShape(double *x, double *par)
311{
312 // this function simulates the time
313 // of arrival of the photons at the
314 // photocathode
315 Double_t xx = x[0];
316 if (xx <= par[0]) return 0;
317 Double_t a = 1./TMath::Power((xx-par[0])/par[1],1./par[2]);
318 if (xx <= par[3]) return a;
319 Double_t b = 1./TMath::Power((xx-par[3])/par[4],1./par[5]);
320 Double_t f = a*b/(a+b);
321 AliDebug(100,Form("x=%f func=%f",xx,f));
322 return f;
323}
324
325double AliVZERODigitizer::PMResponse(double *x, double * /* par */)
326{
327 // this function describes the
328 // PM time response to a single
329 // photoelectron
330 Double_t xx = x[0]+kPMRespTime;
331 return xx*xx*TMath::Exp(-xx*xx/(kPMRespTime*kPMRespTime));
332}
333
334double AliVZERODigitizer::SinglePhESpectrum(double *x, double * /* par */)
335{
336 // this function describes the
337 // PM amplitude response to a single
338 // photoelectron
339 Double_t xx = x[0];
340 if (xx < 0) return 0;
341 return (TMath::Poisson(xx,kPMNbOfSecElec)+kPMTransparency*TMath::Poisson(xx,1.0));
342}
343
344Int_t AliVZERODigitizer::Cell2Pmt(Int_t cell) const
345{
346 // The method maps the scintillator
347 // indexes to the PM ones
348 if (cell < 0 || cell >= 80) {
349 AliError(Form("Wrong VZERO cell index %d",cell));
350 return -1;
351 }
352 if (cell < 16) return cell;
353 if (cell < 48) return 8 + cell/2;
354 return cell - 16;
355}
356
357void AliVZERODigitizer::DigitizeHits()
358{
359 // Digitize the hits to the level of
360 // SDigits (fTime arrays)
4e2652e8 361
362 for(Int_t i = 0 ; i < 64; ++i) {
363 memset(fTime[i],0,fNBins[i]*sizeof(Float_t));
72da5ce8 364 fLabels[i][0] = fLabels[i][1] = fLabels[i][2] = -1;
fad64858 365 }
4e2652e8 366 Float_t integral = fPMResponse->Integral(-kPMRespTime,2.*kPMRespTime);
367 Float_t meansPhE = fSinglePhESpectrum->Mean(0,20);
368
72da5ce8 369 AliLoader* loader = fVZERO->GetLoader();
8bd3e27a 370 if (!loader) {
72da5ce8 371 AliError("Can not get VZERO Loader!");
372 return;
373 }
8bd3e27a 374 loader->LoadHits();
375 TTree* treeH = loader->TreeH();
376 if (!treeH) {
72da5ce8 377 AliError("Cannot get TreeH!");
378 return;
379 }
380 TClonesArray* hits = fVZERO->Hits();
4e2652e8 381
382 // Float_t lightYieldCorr[64] = {0.00707,0.00517,0.00520,0.00537,0.00735,0.00537,0.00733,0.00605,0.00778,0.00749,0.00701,0.00755,0.00732,0.00617,0.00669,0.00525,0.00752,0.00820,0.00797,0.01107,0.01080,0.00889,0.00880,0.01712,0.00866,0.00701,0.00811,0.00602,0.00879,0.00821,0.00861,0.01433,0.00061,0.00032,0.00099,0.00061,0.00034,0.00046,0.00031,0.00122,0.00155,0.00091,0.00032,0.00096,0.00120,0.00067,0.00113,0.00060,0.00158,0.00136,0.00340,0.00066,0.00076,0.00119,0.00129,0.00147,0.00137,0.00117,0.00088,0.00164,0.00128,0.00081,0.00121,0.00250};
383 Float_t lightYieldCorr[64] = {0.01173,0.00874,0.00878,0.00886,0.01151,0.00925,0.01167,0.00983,0.01181,0.01243,0.01115,0.01220,0.01228,0.01053,0.01021,0.00930,0.01270,0.01411,0.01316,0.01894,0.01923,0.01860,0.01738,0.00305,0.01584,0.01251,0.01344,0.00310,0.01302,0.01266,0.01407,0.00338,0.00089,0.00100,0.00130,0.00081,0.00052,0.01230,0.00059,0.02452,0.02980,0.00137,0.01421,0.00116,0.00141,0.00092,0.02480,0.00096,0.00182,0.00174,0.00218,0.00106,0.00116,0.00160,0.00162,0.03097,0.00194,0.00171,0.00132,0.00239,0.00173,0.00118,0.00163,0.00262};
b0d2c2d3 384// Now makes Digits from hits
8bd3e27a 385 Int_t nTracks = (Int_t) treeH->GetEntries();
386 for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
72da5ce8 387 fVZERO->ResetHits();
8bd3e27a 388 treeH->GetEvent(iTrack);
389 Int_t nHits = hits->GetEntriesFast();
390 for (Int_t iHit = 0; iHit < nHits; iHit++) {
4e2652e8 391 AliVZEROhit* hit = (AliVZEROhit *)hits->UncheckedAt(iHit);
392 Int_t nPhot = hit->Nphot();
393 Int_t cell = hit->Cell();
394 Int_t pmt = Cell2Pmt(cell);
30c4ff64 395 Int_t trackLabel = hit->GetTrack();
396 for(Int_t l = 0; l < 3; ++l) {
72da5ce8 397 if (fLabels[pmt][l] < 0) {
398 fLabels[pmt][l] = trackLabel;
30c4ff64 399 break;
400 }
401 }
4e2652e8 402 Float_t dt_scintillator = gRandom->Gaus(0,kIntTimeRes);
403 Float_t t = dt_scintillator + 1e9*hit->Tof();
404 if (pmt < 32) t += kV0CDelayCables;
405 t += fHptdcOffset[pmt];
406 Int_t nPhE;
407 Float_t prob = lightYieldCorr[pmt]*fPhotoCathodeEfficiency; // Optical losses included!
408 if (nPhot > 100)
d0ff6548 409 nPhE = (Int_t)gRandom->Gaus(prob*Float_t(nPhot)+0.5,
410 sqrt(Float_t(nPhot)*prob*(1.-prob)));
4e2652e8 411 else
412 nPhE = gRandom->Binomial(nPhot,prob);
413 Float_t charge = TMath::Qe()*fPmGain[pmt]*fBinSize[pmt]/integral;
414 for (Int_t iPhE = 0; iPhE < nPhE; ++iPhE) {
415 Float_t tPhE = t + fSignalShape->GetRandom(0,fBinSize[pmt]*Float_t(fNBins[pmt]));
416 Float_t gainVar = fSinglePhESpectrum->GetRandom(0,20)/meansPhE;
417 Int_t firstBin = TMath::Max(0,(Int_t)((tPhE-kPMRespTime)/fBinSize[pmt]));
418 Int_t lastBin = TMath::Min(fNBins[pmt]-1,(Int_t)((tPhE+2.*kPMRespTime)/fBinSize[pmt]));
419 for(Int_t iBin = firstBin; iBin <= lastBin; ++iBin) {
420 Float_t tempT = fBinSize[pmt]*(0.5+iBin)-tPhE;
421 fTime[pmt][iBin] += gainVar*charge*fPMResponse->Eval(tempT);
422 }
423 } // ph.e. loop
424 } // hit loop
425 } // track loop
8bd3e27a 426 loader->UnloadHits();
72da5ce8 427}
428
429
430void AliVZERODigitizer::DigitizeSDigits()
431{
432 // Digitize the fTime arrays (SDigits) to the level of
433 // Digits (fAdc arrays)
434 for(Int_t i = 0 ; i < 64; ++i) {
435 for(Int_t j = 0; j < kNClocks; ++j) fAdc[i][j] = 0;
436 fLeadingTime[i] = fTimeWidth[i] = 0;
437 }
4e2652e8 438
439 Float_t maximum = 0.9*fSignalShape->GetMaximum(0,200); // Not exact, one needs to do this on the convoluted
440 Float_t integral2 = fSignalShape->Integral(0,200); // function. Anyway the effect is small <10% on the 2.5 ADC thr
441 for (Int_t ipmt = 0; ipmt < 64; ++ipmt) {
442 Float_t thr = fCalibData->GetDiscriThr(ipmt)*kChargePerADC*maximum*fBinSize[ipmt]/integral2;
443 Bool_t ltFound = kFALSE, ttFound = kFALSE;
444 for (Int_t iBin = 0; iBin < fNBins[ipmt]; ++iBin) {
b6fd9c4a 445 Float_t t = fBinSize[ipmt]*Float_t(iBin);
4e2652e8 446 if (fTime[ipmt][iBin] > thr) {
447 if (!ltFound && (iBin < fNBinsLT[ipmt])) {
448 ltFound = kTRUE;
449 fLeadingTime[ipmt] = t;
450 }
451 }
452 else {
453 if (ltFound) {
454 if (!ttFound) {
455 ttFound = kTRUE;
456 fTimeWidth[ipmt] = t - fLeadingTime[ipmt];
457 }
458 }
459 }
d0ff6548 460 Float_t tadc = t - kClockOffset - fCalibData->GetTimeOffset(ipmt);
461 Int_t clock = kNClocks/2 - Int_t(tadc/25.0);
4e2652e8 462 if (clock >= 0 && clock < kNClocks)
463 fAdc[ipmt][clock] += fTime[ipmt][iBin]/kChargePerADC;
464 }
51980118 465 Int_t board = AliVZEROCalibData::GetBoardNumber(ipmt);
4e2652e8 466 if (ltFound && ttFound) {
467 fTimeWidth[ipmt] = fCalibData->GetWidthResolution(board)*
468 Float_t(Int_t(fTimeWidth[ipmt]/fCalibData->GetWidthResolution(board)));
469 if (fTimeWidth[ipmt] < Float_t(kMinTDCWidth)*fCalibData->GetWidthResolution(board))
470 fTimeWidth[ipmt] = Float_t(kMinTDCWidth)*fCalibData->GetWidthResolution(board);
471 if (fTimeWidth[ipmt] > Float_t(kMaxTDCWidth)*fCalibData->GetWidthResolution(board))
472 fTimeWidth[ipmt] = Float_t(kMaxTDCWidth)*fCalibData->GetWidthResolution(board);
473 }
474 }
b0d2c2d3 475
72da5ce8 476 fEvenOrOdd = gRandom->Integer(2);
4e2652e8 477 for (Int_t j=0; j<64; ++j){
478 for (Int_t iClock = 0; iClock < kNClocks; ++iClock) {
72da5ce8 479 Int_t integrator = (iClock + fEvenOrOdd) % 2;
4e2652e8 480 fAdc[j][iClock] += gRandom->Gaus(fAdcPedestal[j][integrator], fAdcSigma[j][integrator]);
481 }
482 }
20277079 483
72da5ce8 484}
485
486void AliVZERODigitizer::WriteDigits(AliLoader *loader)
487{
488 // Take fAdc arrays filled by the previous
489 // method and produce and add digits to the digit Tree
490
491 loader->LoadDigits("UPDATE");
4e2652e8 492
72da5ce8 493 if (!loader->TreeD()) loader->MakeTree("D");
494 loader->MakeDigitsContainer();
495 TTree* treeD = loader->TreeD();
496 DigitsArray();
497 treeD->Branch("VZERODigit", &fDigits);
498
30c4ff64 499 Short_t *chargeADC = new Short_t[kNClocks];
4e2652e8 500 for (Int_t i=0; i<64; i++) {
30c4ff64 501 for (Int_t j = 0; j < kNClocks; ++j) {
4e2652e8 502 Int_t tempadc = Int_t(fAdc[i][j]);
503 if (tempadc > 1023) tempadc = 1023;
30c4ff64 504 chargeADC[j] = tempadc;
4e2652e8 505 }
72da5ce8 506 AddDigit(i, fLeadingTime[i], fTimeWidth[i], Bool_t((10+fEvenOrOdd)%2), chargeADC, fLabels[i]);
4e2652e8 507 }
30c4ff64 508 delete [] chargeADC;
4e2652e8 509
b0d2c2d3 510 treeD->Fill();
72da5ce8 511 loader->WriteDigits("OVERWRITE");
512 loader->UnloadDigits();
513 ResetDigits();
9e04c3b6 514}
515
72da5ce8 516void AliVZERODigitizer::WriteSDigits(AliLoader *loader)
9e04c3b6 517{
72da5ce8 518 // Take fTime arrays filled by the previous
519 // method and produce and add sdigits to the sdigit Tree
fe0adf2a 520
72da5ce8 521 loader->LoadSDigits("UPDATE");
fe0adf2a 522
72da5ce8 523 if (!loader->TreeS()) loader->MakeTree("S");
524 loader->MakeSDigitsContainer();
525 TTree* treeS = loader->TreeS();
526 SDigitsArray();
527 treeS->Branch("VZEROSDigit", &fDigits);
528
529 for (Int_t ipmt = 0; ipmt < 64; ++ipmt) {
530 AddSDigit(ipmt,fNBins[ipmt],fTime[ipmt],fLabels[ipmt]);
531 }
ce7090f5 532
72da5ce8 533 treeS->Fill();
534 loader->WriteSDigits("OVERWRITE");
535 loader->UnloadSDigits();
536 ResetDigits();
537}
ce7090f5 538
72da5ce8 539void AliVZERODigitizer::ReadSDigits()
ce7090f5 540{
72da5ce8 541 // Read SDigits which are then to precessed
542 // in the following method
543 for(Int_t i = 0 ; i < 64; ++i) {
544 memset(fTime[i],0,fNBins[i]*sizeof(Float_t));
545 fLabels[i][0] = fLabels[i][1] = fLabels[i][2] = -1;
546 }
ce7090f5 547
72da5ce8 548 // Loop over input files
549 Int_t nFiles= fManager->GetNinputs();
550 for (Int_t inputFile = 0; inputFile < nFiles; inputFile++) {
551 // Get the current loader
552 AliRunLoader* currentLoader =
553 AliRunLoader::GetRunLoader(fManager->GetInputFolderName(inputFile));
ce7090f5 554
72da5ce8 555 AliLoader *loader = currentLoader->GetLoader("VZEROLoader");
556 loader->LoadSDigits("READ");
557
558 // Get the tree of summable digits
559 TTree* sdigitsTree = loader->TreeS();
560 if (!sdigitsTree) {
561 AliError("No sdigit tree from manager");
562 continue;
563 }
ce7090f5 564
72da5ce8 565 // Get the branch
566 TBranch* sdigitsBranch = sdigitsTree->GetBranch("VZEROSDigit");
567 if (!sdigitsBranch) {
568 AliError("Failed to get sdigit branch");
569 return;
570 }
4e2652e8 571
72da5ce8 572 // Set the branch address
573 TClonesArray *sdigitsArray = NULL;
574 sdigitsBranch->SetAddress(&sdigitsArray);
575
576 // Sum contributions from the sdigits
577 // Get number of entries in the tree
578 Int_t nentries = Int_t(sdigitsBranch->GetEntries());
579 for (Int_t entry = 0; entry < nentries; ++entry) {
580 sdigitsBranch->GetEntry(entry);
581 // Get the number of sdigits
582 Int_t nsdigits = sdigitsArray->GetEntries();
583 for (Int_t sdigit = 0; sdigit < nsdigits; sdigit++) {
584 AliVZEROSDigit* sDigit = static_cast<AliVZEROSDigit*>(sdigitsArray->UncheckedAt(sdigit));
585 Int_t pmNumber = sDigit->PMNumber();
586 Int_t nbins = sDigit->GetNBins();
587 if (nbins != fNBins[pmNumber]) {
588 AliError(Form("Incompatible number of bins between digitizer (%d) and sdigit (%d) for PM %d! Skipping sdigit!",
589 fNBins[pmNumber],nbins,pmNumber));
590 continue;
591 }
592 // Sum the charges
593 Float_t *charges = sDigit->GetCharges();
594 for(Int_t iBin = 0; iBin < nbins; ++iBin) fTime[pmNumber][iBin] += charges[iBin];
595 // and the labels
596 Int_t *labels = sDigit->GetTracks();
597 Int_t j = 0;
598 for(Int_t i = 0; i < 3; ++i) {
599 if (fLabels[pmNumber][i] < 0) {
600 if (labels[j] < 0) break;
601 fLabels[pmNumber][i] = labels[j];
602 j++;
603 }
604 }
605 }
606 }
607 loader->UnloadSDigits();
608 }
4e2652e8 609}
610
72da5ce8 611//____________________________________________________________________
612TClonesArray*
613AliVZERODigitizer::DigitsArray()
4e2652e8 614{
72da5ce8 615 // Initialize digit array if not already and
616 // return pointer to it.
617 if (!fDigits) {
618 fDigits = new TClonesArray("AliVZEROdigit", 64);
619 fNdigits = 0;
620 }
621 return fDigits;
4e2652e8 622}
623
72da5ce8 624//____________________________________________________________________
625TClonesArray*
626AliVZERODigitizer::SDigitsArray()
4e2652e8 627{
72da5ce8 628 // Initialize sdigit array if not already and
629 // return pointer to it.
630 if (!fDigits) {
631 fDigits = new TClonesArray("AliVZEROSDigit", 64);
632 fNdigits = 0;
4e2652e8 633 }
72da5ce8 634 return fDigits;
4e2652e8 635}