Fix for memory leaks in digits TClonesArrays (Matevz)
[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>
9e04c3b6 34
35// --- AliRoot header files ---
36#include "AliVZEROConst.h"
37#include "AliRun.h"
38#include "AliVZERO.h"
39#include "AliVZEROhit.h"
9e04c3b6 40#include "AliRunLoader.h"
41#include "AliLoader.h"
fe0adf2a 42#include "AliGRPObject.h"
9e04c3b6 43#include "AliRunDigitizer.h"
ce7090f5 44#include "AliCDBManager.h"
45#include "AliCDBStorage.h"
46#include "AliCDBEntry.h"
47#include "AliVZEROCalibData.h"
48
9e04c3b6 49#include "AliVZEROdigit.h"
b0d2c2d3 50#include "AliVZERODigitizer.h"
9e04c3b6 51
52ClassImp(AliVZERODigitizer)
53
54 AliVZERODigitizer::AliVZERODigitizer()
fe0adf2a 55 :AliDigitizer(),
56 fCalibData(GetCalibData()),
57 fPhotoCathodeEfficiency(0.18),
58 fPMVoltage(768.0),
59 fPMGain(TMath::Power((fPMVoltage / 112.5) ,7.04277)),
60 fNdigits(0),
61 fDigits(0),
62 fCollisionMode(0),
63 fBeamEnergy(0.)
0b2bea8b 64
9e04c3b6 65{
b0d2c2d3 66 // default constructor
67
0b2bea8b 68// fNdigits = 0;
69// fDigits = 0;
70//
71// fPhotoCathodeEfficiency = 0.18;
72// fPMVoltage = 768.0;
73// fPMGain = TMath::Power((fPMVoltage / 112.5) ,7.04277);
ce7090f5 74
0b2bea8b 75// fCalibData = GetCalibData();
9e04c3b6 76}
77
78//____________________________________________________________________________
79 AliVZERODigitizer::AliVZERODigitizer(AliRunDigitizer* manager)
0b2bea8b 80 :AliDigitizer(manager),
81 fCalibData(GetCalibData()),
82 fPhotoCathodeEfficiency(0.18),
83 fPMVoltage(768.0),
84 fPMGain(TMath::Power((fPMVoltage / 112.5) ,7.04277)),
85 fNdigits(0),
fe0adf2a 86 fDigits(0),
87 fCollisionMode(0),
88 fBeamEnergy(0.)
0b2bea8b 89
9e04c3b6 90{
91 // constructor
92
0b2bea8b 93// fNdigits = 0;
94// fDigits = 0;
95//
96// fPhotoCathodeEfficiency = 0.18;
97// fPMVoltage = 768.0;
98// fPMGain = TMath::Power( (fPMVoltage / 112.5) ,7.04277 );
ce7090f5 99
0b2bea8b 100// fCalibData = GetCalibData();
ce7090f5 101
9e04c3b6 102}
103
104//____________________________________________________________________________
105 AliVZERODigitizer::~AliVZERODigitizer()
106{
107 // destructor
108
109 if (fDigits) {
110 fDigits->Delete();
111 delete fDigits;
b0d2c2d3 112 fDigits=0;
113 }
9e04c3b6 114}
115
b0d2c2d3 116//_____________________________________________________________________________
117Bool_t AliVZERODigitizer::Init()
9e04c3b6 118{
b0d2c2d3 119 // Initialises the digitizer
9e04c3b6 120
b0d2c2d3 121 // Initialises the Digit array
9e04c3b6 122 fDigits = new TClonesArray ("AliVZEROdigit", 1000);
8bd3e27a 123
c61a7285 124 // TGeoHMatrix *im = AliGeomManager::GetMatrix("VZERO/V0C");
125 // im->Print();
fe0adf2a 126
127 GetCollisionMode();
b0d2c2d3 128 return kTRUE;
9e04c3b6 129}
130
131//____________________________________________________________________________
b0d2c2d3 132void AliVZERODigitizer::Exec(Option_t* /*option*/)
ce7090f5 133{
b0d2c2d3 134 // Creates digits from hits
ce7090f5 135
db0db003 136 Float_t map[80]; // 48 values on V0C + 32 on V0A
f25f4990 137// Int_t pmNumber[80];
db0db003 138 Float_t adc[64]; // 32 PMs on V0C + 32 PMs on V0A
8bd3e27a 139 Float_t time[80], time_ref[80], time2[64];
140 Float_t adc_gain[80];
141 Float_t adc_pedestal[64],adc_sigma[64];
ce7090f5 142 fNdigits = 0;
8adc9b44 143 Float_t pmGain_smeared[64];
8bd3e27a 144 Float_t cPM[80];
145
146 // Smearing of the PM tubes intrinsic characteristics
147
148 for(Int_t ii=0; ii<64; ii++) {
8adc9b44 149 pmGain_smeared[ii] = gRandom->Gaus(fPMGain, fPMGain/5); }
8bd3e27a 150
151 // Retrieval of ADC gain values and pedestal information from local CDB
ce7090f5 152 // I use only the first 64th values of the calibration array in CDB
153 // as I have no beam burst structure - odd or even beam burst number
b0d2c2d3 154
ce7090f5 155 // Reminder : We have 16 scintillating cells mounted on 8 PMs
20277079 156 // on Ring 3 and Ring 4 in V0C - added to produce ADC outputs
157 // on these rings...
ce7090f5 158
8bd3e27a 159 for(Int_t i=0; i<16; i++) {
fad64858 160 adc_gain[i] = fCalibData->GetGain(i);
161 cPM[i] = fPhotoCathodeEfficiency * pmGain_smeared[i];
162 }
ce7090f5 163
164 for(Int_t j=16; j<48; j=j+2) {
fad64858 165 Int_t i=(j+17)/2;
166 adc_gain[j] = fCalibData->GetGain(i);
167 adc_gain[j+1] = fCalibData->GetGain(i);
168 cPM[j] = fPhotoCathodeEfficiency * pmGain_smeared[i];
169 cPM[j+1] = fPhotoCathodeEfficiency * pmGain_smeared[i];
170 }
8bd3e27a 171
172 for(Int_t i=48; i<80; i++){
db0db003 173 adc_gain[i] = fCalibData->GetGain(i-16);
fad64858 174 cPM[i] = fPhotoCathodeEfficiency * pmGain_smeared[i-16];
175 };
ce7090f5 176
fad64858 177 for(Int_t i=0; i<64; i++){
178 adc_pedestal[i] = fCalibData->GetPedestal(i);
179 adc_sigma[i] = fCalibData->GetSigma(i);
180 };
8bd3e27a 181
182// for(Int_t i=0; i<64; i++) { printf(" i = %d pedestal = %f sigma = %f \n\n",
183// i, adc_pedestal[i], adc_sigma[i] );}
ce7090f5 184
fad64858 185 AliRunLoader* outRunLoader = AliRunLoader::GetRunLoader(fManager->GetOutputFolderName());
b0d2c2d3 186 if (!outRunLoader) {
187 Error("Exec", "Can not get output Run Loader");
fad64858 188 return;
189 }
ce7090f5 190
b0d2c2d3 191 AliLoader* outLoader = outRunLoader->GetLoader("VZEROLoader");
fad64858 192
b0d2c2d3 193 if (!outLoader) {
194 Error("Exec", "Can not get output VZERO Loader");
fad64858 195 return;
196 }
b0d2c2d3 197
e539620f 198 const char* mode = "update";
199 if(outRunLoader->GetEventNumber() == 0) mode = "recreate";
200 outLoader->LoadDigits(mode);
fad64858 201
b0d2c2d3 202 if (!outLoader->TreeD()) outLoader->MakeTree("D");
203 outLoader->MakeDigitsContainer();
ce7090f5 204 TTree* treeD = outLoader->TreeD();
b0d2c2d3 205 Int_t bufsize = 16000;
206 treeD->Branch("VZERODigit", &fDigits, bufsize);
c299dbe4 207
b0d2c2d3 208 for (Int_t iInput = 0; iInput < fManager->GetNinputs(); iInput++) {
fad64858 209 AliRunLoader* runLoader = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(iInput));
8bd3e27a 210 AliLoader* loader = runLoader->GetLoader("VZEROLoader");
211 if (!loader) {
212 Error("Exec", "Can not get VZERO Loader for input %d", iInput);
fad64858 213 continue;
214 }
ce7090f5 215
8bd3e27a 216 if (!runLoader->GetAliRun()) runLoader->LoadgAlice();
b0d2c2d3 217
8bd3e27a 218 AliVZERO* vzero = (AliVZERO*) runLoader->GetAliRun()->GetDetector("VZERO");
219 if (!vzero) {
220 Error("Exec", "No VZERO detector for input %d", iInput);
fad64858 221 continue;
222 }
9e04c3b6 223
8bd3e27a 224 loader->LoadHits();
225 TTree* treeH = loader->TreeH();
226 if (!treeH) {
227 Error("Exec", "Cannot get TreeH for input %d", iInput);
fad64858 228 continue;
229 }
c299dbe4 230
8bd3e27a 231 for(Int_t i=0; i<80; i++) {map[i] = 0; time[i] = 0.0;}
fe0adf2a 232
8bd3e27a 233 TClonesArray* hits = vzero->Hits();
9e04c3b6 234
b0d2c2d3 235// Now makes Digits from hits
fe0adf2a 236
8bd3e27a 237 Int_t nTracks = (Int_t) treeH->GetEntries();
238 for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
239 for (Int_t i=0; i<80; i++) {time_ref[i] = 999999.0;}
240 vzero->ResetHits();
241 treeH->GetEvent(iTrack);
242 Int_t nHits = hits->GetEntriesFast();
243 for (Int_t iHit = 0; iHit < nHits; iHit++) {
fad64858 244 AliVZEROhit* hit = (AliVZEROhit *)hits->UncheckedAt(iHit);
245 Int_t nPhot = hit->Nphot();
246 Int_t cell = hit->Cell();
db0db003 247 map[cell] += Float_t(nPhot);
fad64858 248 Float_t dt_scintillator = gRandom->Gaus(0,0.7);
249 Float_t t = dt_scintillator + 1e9*hit->Tof();
250 if (t > 0.0) {
251 if(t < time_ref[cell]) time_ref[cell] = t;
252 time[cell] = TMath::Min(t,time_ref[cell]);
253 }
8bd3e27a 254 } // hit loop
255 } // track loop
b0d2c2d3 256
8bd3e27a 257 loader->UnloadHits();
b0d2c2d3 258
259 } // input loop
20277079 260
261// Now builds the scintillator cell response (80 cells i.e. 80 responses)
841137ce 262
20277079 263 for (Int_t i=0; i<80; i++) {
8adc9b44 264 Float_t q1 = Float_t ( map[i] )* cPM[i] * kQe;
265 Float_t noise = gRandom->Gaus(10.5,3.22);
266 Float_t pmResponse = q1/kC*TMath::Power(ktheta/kthau,1/(1-ktheta/kthau))
8bd3e27a 267 + noise*1e-3;
fe0adf2a 268 if(fCollisionMode >0) adc_gain[i] = adc_gain[i]/70.0; // reduce dynamics in Ion Collision Mode
db0db003 269 map[i] = pmResponse * adc_gain[i];
fe0adf2a 270 Float_t MIP = 1.0/fCalibData->GetMIPperADC(GetPMNumber(i));
271 if(fCollisionMode >0) MIP=2.0;
272// printf("cell = %d, ADC = %d, TDC = %f \n",i,map[i], time[i]*10.0 );
db0db003 273 if(map[i] > (MIP/2.) )
274 {map[i] = gRandom->Gaus(map[i], (MIP/6.) );}
8adc9b44 275 }
c299dbe4 276
8bd3e27a 277// Now transforms 80 cell responses into 64 photomultiplier responses
278// Also adds the ADC pedestals taken out of the calibration data base
20277079 279
8bd3e27a 280 for (Int_t j=0; j<16; j++){
db0db003 281 adc[j] = map [j] + gRandom->Gaus(adc_pedestal[j], adc_sigma[j]);
20277079 282 time2[j]= time[j];}
283
284 for (Int_t j=48; j<80; j++){
db0db003 285 adc[j-16] = map [j] + gRandom->Gaus(adc_pedestal[j-16],adc_sigma[j-16]);
8bd3e27a 286 time2[j-16]= time[j]; }
20277079 287
288 for (Int_t j=0; j<16; j++){
db0db003 289 adc[16+j] = map [16+2*j]+ map [16+2*j+1] + gRandom->Gaus(adc_pedestal[16+j], adc_sigma[16+j]);
c299dbe4 290 Float_t min_time = TMath::Min(time [16+2*j],time [16+2*j+1]);
291 time2[16+j] = min_time;
8bd3e27a 292 if(min_time==0.0){time2[16+j]=TMath::Max(time[16+2*j],time[16+2*j+1]);}
c299dbe4 293 }
294
295
20277079 296// Now add digits to the digit Tree
297
298 for (Int_t i=0; i<64; i++) {
299 if(adc[i] > 0) {
fad64858 300// printf(" Event, cell, adc, tof = %d %d %d %d\n",
301// outRunLoader->GetEventNumber(),i, adc[i], Int_t((time2[i]*10.0) +0.5));
8bd3e27a 302// multiply by 10 to have 100 ps per channel :
fad64858 303
db0db003 304 AddDigit(i, adc[i], (time2[i]*10.0) ) ;
fad64858 305 }
20277079 306 }
b0d2c2d3 307 treeD->Fill();
308 outLoader->WriteDigits("OVERWRITE");
309 outLoader->UnloadDigits();
310 ResetDigit();
9e04c3b6 311}
312
313//____________________________________________________________________________
db0db003 314void AliVZERODigitizer::AddDigit(Int_t PMnumber, Float_t adc, Float_t time)
9e04c3b6 315 {
316
317// Adds Digit
318
319 TClonesArray &ldigits = *fDigits;
fad64858 320 Bool_t integrator;
321 if (((Int_t) gRandom->Uniform(2))<1) integrator = kFALSE;
322 else integrator = kTRUE;
323
324 new(ldigits[fNdigits++]) AliVZEROdigit(PMnumber,adc,time,0,kFALSE,kFALSE,integrator);
325
9e04c3b6 326}
327//____________________________________________________________________________
328void AliVZERODigitizer::ResetDigit()
329{
fe0adf2a 330
9e04c3b6 331// Clears Digits
fe0adf2a 332
9e04c3b6 333 fNdigits = 0;
b0d2c2d3 334 if (fDigits) fDigits->Delete();
9e04c3b6 335}
ce7090f5 336
337//____________________________________________________________________________
fe0adf2a 338void AliVZERODigitizer::GetCollisionMode()
339{
340// Retrieves the collision mode from GRP data
341
342// Initialization of the GRP entry
343
344 Int_t run = AliCDBManager::Instance()->GetRun();
345
346// printf("\n ++++++ Run Number retrieved as %d \n",run);
347
348 AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/GRP/Data",run);
349 AliGRPObject* grpData = 0x0;
350
351 if(entry){
352 TMap* m = dynamic_cast<TMap*>(entry->GetObject()); // old GRP entry
353 if(m){
354 m->Print();
355 grpData = new AliGRPObject();
356 grpData->ReadValuesFromMap(m);
357 }
358 else{
359 grpData = dynamic_cast<AliGRPObject*>(entry->GetObject()); // new GRP entry
360 entry->SetOwner(0);
361 }
362 AliCDBManager::Instance()->UnloadFromCache("GRP/GRP/Data");
363 }
364
365 if(!grpData) AliError("No GRP entry found in OCDB!");
366
367// Retrieval of collision mode
368
369 TString beamType = grpData->GetBeamType();
370 if(beamType==AliGRPObject::GetInvalidString()){
371 AliError("GRP/GRP/Data entry: missing value for the beam type !");
372 AliError("\t VZERO cannot retrieve beam type\n");
373 return;
374 }
375
376 if( (beamType.CompareTo("P-P") ==0) || (beamType.CompareTo("p-p") ==0) ){
377 fCollisionMode=0;
378 }
379 else if( (beamType.CompareTo("Pb-Pb") ==0) || (beamType.CompareTo("A-A") ==0) ){
380 fCollisionMode=1;
381 }
382
383 fBeamEnergy = grpData->GetBeamEnergy();
384 if(fBeamEnergy==AliGRPObject::GetInvalidFloat()) {
385 AliError("GRP/GRP/Data entry: missing value for the beam energy ! Using 0");
386 fBeamEnergy = 0.;
387 }
388
389// printf("\n ++++++ Beam type and collision mode retrieved as %s %d @ %1.3f GeV ++++++\n\n",beamType.Data(), fCollisionMode, fBeamEnergy);
390
391}
392
393//____________________________________________________________________________
ce7090f5 394AliVZEROCalibData* AliVZERODigitizer::GetCalibData() const
395
396{
c0b82b5a 397 AliCDBManager *man = AliCDBManager::Instance();
ce7090f5 398
c0b82b5a 399 AliCDBEntry *entry=0;
ce7090f5 400
c0b82b5a 401 entry = man->Get("VZERO/Calib/Data");
402
df791951 403// if(!entry){
404// AliWarning("Load of calibration data from default storage failed!");
405// AliWarning("Calibration data will be loaded from local storage ($ALICE_ROOT)");
406// Int_t runNumber = man->GetRun();
162637e4 407// entry = man->GetStorage("local://$ALICE_ROOT/OCDB")
df791951 408// ->Get("VZERO/Calib/Data",runNumber);
409//
410// }
c0b82b5a 411
412 // Retrieval of data in directory VZERO/Calib/Data:
ce7090f5 413
ce7090f5 414
c0b82b5a 415 AliVZEROCalibData *calibdata = 0;
ce7090f5 416
c0b82b5a 417 if (entry) calibdata = (AliVZEROCalibData*) entry->GetObject();
df791951 418 if (!calibdata) AliFatal("No calibration data from calibration database !");
ce7090f5 419
c0b82b5a 420 return calibdata;
ce7090f5 421
422}
423
8adc9b44 424//____________________________________________________________________________
425Int_t AliVZERODigitizer::GetPMNumber(Int_t cell) const
426
427{
428
429 Int_t pmNumber[80] = { 0, 1, 2, 3, 4, 5, 6, 7,
430 8, 9, 10, 11, 12, 13, 14, 15,
431 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23,
432 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31,
433 32, 33, 34, 35, 36, 37, 38, 39,
434 40, 41, 42, 43, 44, 45, 46, 47,
435 48, 49, 50, 51, 52, 53, 54, 55,
436 56, 57, 58, 59, 60, 61, 62, 63 };
437
438 return pmNumber[cell];
439}
440
441