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 ///_________________________________________________________________________
20 /// This class constructs Digits out of Hits
24 // --- Standard library ---
26 // --- ROOT system ---
30 #include <TGeoManager.h>
31 #include <TGeoPhysicalNode.h>
32 #include <AliGeomManager.h>
35 // --- AliRoot header files ---
36 #include "AliVZEROConst.h"
39 #include "AliVZEROhit.h"
40 #include "AliRunLoader.h"
41 #include "AliLoader.h"
42 #include "AliGRPObject.h"
43 #include "AliRunDigitizer.h"
44 #include "AliCDBManager.h"
45 #include "AliCDBStorage.h"
46 #include "AliCDBEntry.h"
47 #include "AliVZEROCalibData.h"
49 #include "AliVZEROdigit.h"
50 #include "AliVZERODigitizer.h"
52 ClassImp(AliVZERODigitizer)
54 AliVZERODigitizer::AliVZERODigitizer()
56 fCalibData(GetCalibData()),
57 fPhotoCathodeEfficiency(0.18),
59 fPMGain(TMath::Power((fPMVoltage / 112.5) ,7.04277)),
66 // default constructor
71 // fPhotoCathodeEfficiency = 0.18;
72 // fPMVoltage = 768.0;
73 // fPMGain = TMath::Power((fPMVoltage / 112.5) ,7.04277);
75 // fCalibData = GetCalibData();
78 //____________________________________________________________________________
79 AliVZERODigitizer::AliVZERODigitizer(AliRunDigitizer* manager)
80 :AliDigitizer(manager),
81 fCalibData(GetCalibData()),
82 fPhotoCathodeEfficiency(0.18),
84 fPMGain(TMath::Power((fPMVoltage / 112.5) ,7.04277)),
96 // fPhotoCathodeEfficiency = 0.18;
97 // fPMVoltage = 768.0;
98 // fPMGain = TMath::Power( (fPMVoltage / 112.5) ,7.04277 );
100 // fCalibData = GetCalibData();
104 //____________________________________________________________________________
105 AliVZERODigitizer::~AliVZERODigitizer()
116 //_____________________________________________________________________________
117 Bool_t AliVZERODigitizer::Init()
119 // Initialises the digitizer
121 // Initialises the Digit array
122 fDigits = new TClonesArray ("AliVZEROdigit", 1000);
124 // TGeoHMatrix *im = AliGeomManager::GetMatrix("VZERO/V0C");
131 //____________________________________________________________________________
132 void AliVZERODigitizer::Exec(Option_t* /*option*/)
134 // Creates digits from hits
136 Int_t map[80]; // 48 values on V0C + 32 on V0A
137 // Int_t pmNumber[80];
138 Int_t adc[64]; // 32 PMs on V0C + 32 PMs on V0A
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];
143 Float_t pmGain_smeared[64];
146 // Smearing of the PM tubes intrinsic characteristics
148 for(Int_t ii=0; ii<64; ii++) {
149 pmGain_smeared[ii] = gRandom->Gaus(fPMGain, fPMGain/5); }
151 // Retrieval of ADC gain values and pedestal information from local CDB
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
155 // Reminder : We have 16 scintillating cells mounted on 8 PMs
156 // on Ring 3 and Ring 4 in V0C - added to produce ADC outputs
159 for(Int_t i=0; i<16; i++) {
160 adc_gain[i] = fCalibData->GetGain(i);
161 cPM[i] = fPhotoCathodeEfficiency * pmGain_smeared[i];}
163 for(Int_t j=16; j<48; j=j+2) {
165 adc_gain[j] = fCalibData->GetGain(i);
166 adc_gain[j+1] = fCalibData->GetGain(i);
167 cPM[j] = fPhotoCathodeEfficiency * pmGain_smeared[i];
168 cPM[j+1] = fPhotoCathodeEfficiency * pmGain_smeared[i]; }
170 for(Int_t i=48; i<80; i++){
171 adc_gain[i] = fCalibData->GetGain(i-16);
172 cPM[i] = fPhotoCathodeEfficiency * pmGain_smeared[i-16];};
174 for(Int_t i=0; i<64; i++){ adc_pedestal[i] = fCalibData->GetPedestal(i);
175 adc_sigma[i] = fCalibData->GetSigma(i); };
177 // for(Int_t i=0; i<64; i++) { printf(" i = %d pedestal = %f sigma = %f \n\n",
178 // i, adc_pedestal[i], adc_sigma[i] );}
180 AliRunLoader* outRunLoader =
181 AliRunLoader::GetRunLoader(fManager->GetOutputFolderName());
183 Error("Exec", "Can not get output Run Loader");
186 AliLoader* outLoader = outRunLoader->GetLoader("VZEROLoader");
188 Error("Exec", "Can not get output VZERO Loader");
191 const char* mode = "update";
192 if(outRunLoader->GetEventNumber() == 0) mode = "recreate";
193 outLoader->LoadDigits(mode);
194 if (!outLoader->TreeD()) outLoader->MakeTree("D");
195 outLoader->MakeDigitsContainer();
196 TTree* treeD = outLoader->TreeD();
197 Int_t bufsize = 16000;
198 treeD->Branch("VZERODigit", &fDigits, bufsize);
200 for (Int_t iInput = 0; iInput < fManager->GetNinputs(); iInput++) {
201 AliRunLoader* runLoader =
202 AliRunLoader::GetRunLoader(fManager->GetInputFolderName(iInput));
203 AliLoader* loader = runLoader->GetLoader("VZEROLoader");
205 Error("Exec", "Can not get VZERO Loader for input %d", iInput);
208 if (!runLoader->GetAliRun()) runLoader->LoadgAlice();
210 AliVZERO* vzero = (AliVZERO*) runLoader->GetAliRun()->GetDetector("VZERO");
212 Error("Exec", "No VZERO detector for input %d", iInput);
216 TTree* treeH = loader->TreeH();
218 Error("Exec", "Cannot get TreeH for input %d", iInput);
221 for(Int_t i=0; i<80; i++) {map[i] = 0; time[i] = 0.0;}
223 TClonesArray* hits = vzero->Hits();
225 // Now makes Digits from hits
227 Int_t nTracks = (Int_t) treeH->GetEntries();
228 for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
229 for (Int_t i=0; i<80; i++) {time_ref[i] = 999999.0;}
231 treeH->GetEvent(iTrack);
232 Int_t nHits = hits->GetEntriesFast();
233 for (Int_t iHit = 0; iHit < nHits; iHit++) {
234 AliVZEROhit* hit = (AliVZEROhit *)hits->UncheckedAt(iHit);
235 Int_t nPhot = hit->Nphot();
236 Int_t cell = hit->Cell();
238 Float_t dt_scintillator = gRandom->Gaus(0,0.7);
239 Float_t t = dt_scintillator + 1e9*hit->Tof();
241 if(t < time_ref[cell]) time_ref[cell] = t;
242 time[cell] = TMath::Min(t,time_ref[cell]); }
246 loader->UnloadHits();
250 // Now builds the scintillator cell response (80 cells i.e. 80 responses)
252 for (Int_t i=0; i<80; i++) {
253 Float_t q1 = Float_t ( map[i] )* cPM[i] * kQe;
254 Float_t noise = gRandom->Gaus(10.5,3.22);
255 Float_t pmResponse = q1/kC*TMath::Power(ktheta/kthau,1/(1-ktheta/kthau))
257 if(fCollisionMode >0) adc_gain[i] = adc_gain[i]/70.0; // reduce dynamics in Ion Collision Mode
258 map[i] = Int_t( pmResponse * adc_gain[i]);
259 Float_t MIP = 1.0/fCalibData->GetMIPperADC(GetPMNumber(i));
260 if(fCollisionMode >0) MIP=2.0;
261 // printf("cell = %d, ADC = %d, TDC = %f \n",i,map[i], time[i]*10.0 );
262 if(map[i] > (int(( MIP/2 ) + 0.5)) )
263 {map[i] = Int_t(gRandom->Gaus(map[i], (int(( MIP/6 ) + 0.5)) ));}
266 // Now transforms 80 cell responses into 64 photomultiplier responses
267 // Also adds the ADC pedestals taken out of the calibration data base
269 for (Int_t j=0; j<16; j++){
270 adc[j] = static_cast<Int_t>(map [j] + gRandom->Gaus(adc_pedestal[j], adc_sigma[j]));
273 for (Int_t j=48; j<80; j++){
274 adc[j-16] = static_cast<Int_t>(map [j]
275 + gRandom->Gaus(adc_pedestal[j-16],adc_sigma[j-16]));
276 time2[j-16]= time[j]; }
278 for (Int_t j=0; j<16; j++){
279 adc[16+j] = static_cast<Int_t>(map [16+2*j]+ map [16+2*j+1]
280 + gRandom->Gaus(adc_pedestal[16+j], adc_sigma[16+j]));
281 Float_t min_time = TMath::Min(time [16+2*j],time [16+2*j+1]);
282 time2[16+j] = min_time;
283 if(min_time==0.0){time2[16+j]=TMath::Max(time[16+2*j],time[16+2*j+1]);}
287 // Now add digits to the digit Tree
289 for (Int_t i=0; i<64; i++) {
291 // printf(" Event, cell, adc, tof = %d %d %d %f\n",
292 // outRunLoader->GetEventNumber(),i, map[i], time2[i]*10.0);
293 // multiply by 10 to have 100 ps per channel :
294 AddDigit(i, adc[i], Int_t((time2[i]*10.0) +0.5)) ;}
298 outLoader->WriteDigits("OVERWRITE");
299 outLoader->UnloadDigits();
303 //____________________________________________________________________________
304 void AliVZERODigitizer::AddDigit(Int_t PMnumber, Int_t adc, Int_t time)
309 TClonesArray &ldigits = *fDigits;
310 new(ldigits[fNdigits++]) AliVZEROdigit(PMnumber,adc,time);
312 //____________________________________________________________________________
313 void AliVZERODigitizer::ResetDigit()
319 if (fDigits) fDigits->Delete();
322 //____________________________________________________________________________
323 void AliVZERODigitizer::GetCollisionMode()
325 // Retrieves the collision mode from GRP data
327 // Initialization of the GRP entry
329 Int_t run = AliCDBManager::Instance()->GetRun();
331 // printf("\n ++++++ Run Number retrieved as %d \n",run);
333 AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/GRP/Data",run);
334 AliGRPObject* grpData = 0x0;
337 TMap* m = dynamic_cast<TMap*>(entry->GetObject()); // old GRP entry
340 grpData = new AliGRPObject();
341 grpData->ReadValuesFromMap(m);
344 grpData = dynamic_cast<AliGRPObject*>(entry->GetObject()); // new GRP entry
347 AliCDBManager::Instance()->UnloadFromCache("GRP/GRP/Data");
350 if(!grpData) AliError("No GRP entry found in OCDB!");
352 // Retrieval of collision mode
354 TString beamType = grpData->GetBeamType();
355 if(beamType==AliGRPObject::GetInvalidString()){
356 AliError("GRP/GRP/Data entry: missing value for the beam type !");
357 AliError("\t VZERO cannot retrieve beam type\n");
361 if( (beamType.CompareTo("P-P") ==0) || (beamType.CompareTo("p-p") ==0) ){
364 else if( (beamType.CompareTo("Pb-Pb") ==0) || (beamType.CompareTo("A-A") ==0) ){
368 fBeamEnergy = grpData->GetBeamEnergy();
369 if(fBeamEnergy==AliGRPObject::GetInvalidFloat()) {
370 AliError("GRP/GRP/Data entry: missing value for the beam energy ! Using 0");
374 // printf("\n ++++++ Beam type and collision mode retrieved as %s %d @ %1.3f GeV ++++++\n\n",beamType.Data(), fCollisionMode, fBeamEnergy);
378 //____________________________________________________________________________
379 AliVZEROCalibData* AliVZERODigitizer::GetCalibData() const
382 AliCDBManager *man = AliCDBManager::Instance();
384 AliCDBEntry *entry=0;
386 entry = man->Get("VZERO/Calib/Data");
389 // AliWarning("Load of calibration data from default storage failed!");
390 // AliWarning("Calibration data will be loaded from local storage ($ALICE_ROOT)");
391 // Int_t runNumber = man->GetRun();
392 // entry = man->GetStorage("local://$ALICE_ROOT/OCDB")
393 // ->Get("VZERO/Calib/Data",runNumber);
397 // Retrieval of data in directory VZERO/Calib/Data:
400 AliVZEROCalibData *calibdata = 0;
402 if (entry) calibdata = (AliVZEROCalibData*) entry->GetObject();
403 if (!calibdata) AliFatal("No calibration data from calibration database !");
409 //____________________________________________________________________________
410 Int_t AliVZERODigitizer::GetPMNumber(Int_t cell) const
414 Int_t pmNumber[80] = { 0, 1, 2, 3, 4, 5, 6, 7,
415 8, 9, 10, 11, 12, 13, 14, 15,
416 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23,
417 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31,
418 32, 33, 34, 35, 36, 37, 38, 39,
419 40, 41, 42, 43, 44, 45, 46, 47,
420 48, 49, 50, 51, 52, 53, 54, 55,
421 56, 57, 58, 59, 60, 61, 62, 63 };
423 return pmNumber[cell];