added reference mult
[u/mrichter/AliRoot.git] / VZERO / AliVZEROReconstructor.cxx
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 ///////////////////////////////////////////////////////////////////////////////
19 ///                                                                          //
20 /// class for VZERO reconstruction                                           //
21 ///                                                                          //
22 ///////////////////////////////////////////////////////////////////////////////
23
24 #include <TH1F.h>
25 #include <TF1.h>
26 #include <TParameter.h>
27
28 #include "AliRunLoader.h"
29 #include "AliRawReader.h"
30 #include "AliGRPObject.h"
31 #include "AliCDBManager.h"
32 #include "AliCDBStorage.h"
33 #include "AliCDBEntry.h"
34 #include "AliVZEROReconstructor.h"
35 #include "AliVZERORawStream.h"
36 #include "AliVZEROConst.h"
37 #include "AliESDEvent.h"
38 #include "AliVZEROTriggerMask.h"
39 #include "AliESDfriend.h"
40 #include "AliESDVZEROfriend.h"
41 #include "AliVZEROdigit.h"
42 #include "AliVZEROCalibData.h"
43 #include "AliRunInfo.h"
44 #include "AliCTPTimeParams.h"
45
46 ClassImp(AliVZEROReconstructor)
47
48 //_____________________________________________________________________________
49 AliVZEROReconstructor:: AliVZEROReconstructor(): AliReconstructor(),
50                         fESDVZERO(0x0),
51                         fESD(0x0),
52                         fESDVZEROfriend(0x0),
53                         fCalibData(NULL),
54                         fTimeSlewing(NULL),
55                         fCollisionMode(0),
56                         fBeamEnergy(0.),
57                         fDigitsArray(0)
58 {
59   // Default constructor  
60   // Get calibration data
61   
62   fCalibData = GetCalibData();
63
64   AliCDBEntry *entry = AliCDBManager::Instance()->Get("GRP/CTP/CTPtiming");
65   if (!entry) AliFatal("CTP timing parameters are not found in OCDB !");
66   AliCTPTimeParams *ctpParams = (AliCTPTimeParams*)entry->GetObject();
67   Float_t l1Delay = (Float_t)ctpParams->GetDelayL1L0()*25.0;
68
69   AliCDBEntry *entry2 = AliCDBManager::Instance()->Get("VZERO/Calib/TimeDelays");
70   if (!entry2) AliFatal("VZERO time delays are not found in OCDB !");
71   TH1F *delays = (TH1F*)entry2->GetObject();
72
73   AliCDBEntry *entry3 = AliCDBManager::Instance()->Get("VZERO/Calib/TimeSlewing");
74   if (!entry3) AliFatal("VZERO time slewing function is not found in OCDB !");
75   fTimeSlewing = (TF1*)entry3->GetObject();
76
77   for(Int_t i = 0 ; i < 64; ++i) {
78     Int_t board = AliVZEROCalibData::GetBoardNumber(i);
79     fTimeOffset[i] = (((Float_t)fCalibData->GetTriggerCountOffset(board)-
80                         (Float_t)fCalibData->GetRollOver(board))*25.0+
81                        fCalibData->GetTimeOffset(i)+
82                        l1Delay+
83                        delays->GetBinContent(i+1)+
84                        kV0Offset);
85   }
86 }
87
88
89 //_____________________________________________________________________________
90 AliVZEROReconstructor& AliVZEROReconstructor::operator = 
91   (const AliVZEROReconstructor& /*reconstructor*/)
92 {
93 // assignment operator
94
95   Fatal("operator =", "assignment operator not implemented");
96   return *this;
97 }
98
99 //_____________________________________________________________________________
100 AliVZEROReconstructor::~AliVZEROReconstructor()
101 {
102 // destructor
103
104    delete fESDVZERO;
105    delete fESDVZEROfriend;
106    delete fDigitsArray;
107 }
108
109 //_____________________________________________________________________________
110 void AliVZEROReconstructor::Init()
111 {
112 // initializer
113
114   fESDVZERO  = new AliESDVZERO;
115   fESDVZEROfriend = new AliESDVZEROfriend;
116   
117   GetCollisionMode();  // fCollisionMode =1 for Pb-Pb simulated data
118 }
119
120 //______________________________________________________________________
121 void AliVZEROReconstructor::ConvertDigits(AliRawReader* rawReader, TTree* digitsTree) const
122 {
123 // converts RAW to digits 
124
125   if (!digitsTree) {
126     AliError("No digits tree!");
127     return;
128   }
129
130   if (!fDigitsArray)
131     fDigitsArray = new TClonesArray("AliVZEROdigit", 64);
132   digitsTree->Branch("VZERODigit", &fDigitsArray);
133
134   fESDVZEROfriend->Reset();
135
136   rawReader->Reset();
137   AliVZERORawStream rawStream(rawReader);
138   if (rawStream.Next()) { 
139      Float_t adc[64]; 
140      Float_t time[64], width[64];  
141      Bool_t BBFlag[64], BGFlag[64], integrator[64];
142      Short_t chargeADC[64][21];
143      for(Int_t i=0; i<64; i++) {
144        Int_t j   =  rawStream.GetOfflineChannel(i);
145        adc[j]    = 0.0;
146        time[j]   = 0.0;
147        width[j]  = 0.0;
148        BBFlag[j] = kFALSE;
149        BGFlag[j] = kFALSE;
150        integrator[j] = kFALSE;
151        // Search for the maximum charge in the train of 21 LHC clocks 
152        // regardless of the integrator which has been operated:
153        Float_t maxadc = 0;
154        Int_t imax = -1;
155        Float_t adcPedSub[21];
156        for(Int_t iClock=0; iClock<21; iClock++){
157          chargeADC[j][iClock] = (Short_t)rawStream.GetPedestal(i,iClock);
158          Bool_t iIntegrator = rawStream.GetIntegratorFlag(i,iClock);
159          Int_t k = j+64*iIntegrator;
160          adcPedSub[iClock] = rawStream.GetPedestal(i,iClock) - fCalibData->GetPedestal(k);
161          if(adcPedSub[iClock] <= GetRecoParam()->GetNSigmaPed()*fCalibData->GetSigma(k)) {
162            adcPedSub[iClock] = 0;
163            continue;
164          }
165          if(iClock < GetRecoParam()->GetStartClock() || iClock > GetRecoParam()->GetEndClock()) continue;
166          if(adcPedSub[iClock] > maxadc) {
167            maxadc = adcPedSub[iClock];
168            imax   = iClock;
169          }
170        }
171
172        AliDebug(2,Form("Channel %d (online), %d (offline)",i,j)); 
173          if (imax != -1) {
174            Int_t start = imax - GetRecoParam()->GetNPreClocks();
175            if (start < 0) start = 0;
176            Int_t end = imax + GetRecoParam()->GetNPostClocks();
177            if (end > 20) end = 20;
178            for(Int_t iClock = start; iClock <= end; iClock++) {
179              if (iClock >= imax) {
180                BBFlag[j] |= rawStream.GetBBFlag(i,iClock);
181                BGFlag[j] |= rawStream.GetBGFlag(i,iClock);
182              }
183              if (iClock == imax)
184                adc[j] += rawStream.GetPedestal(i,iClock);
185              else 
186                adc[j] += adcPedSub[iClock];
187
188              AliDebug(2,Form("clock = %d adc = %f",iClock,rawStream.GetPedestal(i,iClock))); 
189            }
190            // Convert i (FEE channel numbering) to j (aliroot channel numbering)
191
192            integrator[j] =  rawStream.GetIntegratorFlag(i,imax); 
193          }
194
195          Int_t board   = j / 8;
196          time[j]       =  rawStream.GetTime(i)/ (25./256.) * fCalibData->GetTimeResolution(board);
197          width[j]      =  rawStream.GetWidth(i) / 0.4 * fCalibData->GetWidthResolution(board);
198
199          // Filling the esd friend object
200          fESDVZEROfriend->SetBBScalers(j,rawStream.GetBBScalers(i));
201          fESDVZEROfriend->SetBGScalers(j,rawStream.GetBGScalers(i));
202          for (Int_t iBunch = 0; iBunch < AliESDVZEROfriend::kNBunches; iBunch++) {
203              fESDVZEROfriend->SetChargeMB(j,iBunch,rawStream.GetChargeMB(i,iBunch));
204              fESDVZEROfriend->SetIntMBFlag(j,iBunch,rawStream.GetIntMBFlag(i,iBunch));
205              fESDVZEROfriend->SetBBMBFlag(j,iBunch,rawStream.GetBBMBFlag(i,iBunch));
206              fESDVZEROfriend->SetBGMBFlag(j,iBunch,rawStream.GetBGMBFlag(i,iBunch));
207          }
208          for (Int_t iEv = 0; iEv < AliESDVZEROfriend::kNEvOfInt; iEv++) {
209              fESDVZEROfriend->SetPedestal(j,iEv,rawStream.GetPedestal(i,iEv));
210              fESDVZEROfriend->SetIntegratorFlag(j,iEv,rawStream.GetIntegratorFlag(i,iEv));
211              fESDVZEROfriend->SetBBFlag(j,iEv,rawStream.GetBBFlag(i,iEv));
212              fESDVZEROfriend->SetBGFlag(j,iEv,rawStream.GetBGFlag(i,iEv));
213          }
214          fESDVZEROfriend->SetTime(j,time[j]);
215          fESDVZEROfriend->SetWidth(j,width[j]);
216      }  
217
218      // Filling the esd friend object
219      fESDVZEROfriend->SetTriggerInputs(rawStream.GetTriggerInputs());
220      fESDVZEROfriend->SetTriggerInputsMask(rawStream.GetTriggerInputsMask());
221
222      for(Int_t iScaler = 0; iScaler < AliESDVZEROfriend::kNScalers; iScaler++)
223          fESDVZEROfriend->SetTriggerScalers(iScaler,rawStream.GetTriggerScalers(iScaler));
224
225      for(Int_t iBunch = 0; iBunch < AliESDVZEROfriend::kNBunches; iBunch++)
226          fESDVZEROfriend->SetBunchNumbersMB(iBunch,rawStream.GetBunchNumbersMB(iBunch));
227      
228
229      Int_t aBBflagsV0A = 0;
230      Int_t aBBflagsV0C = 0;
231      Int_t aBGflagsV0A = 0;
232      Int_t aBGflagsV0C = 0;
233
234      // Channels(aliroot numbering) will be ordered in the tree
235      for(Int_t iChannel = 0; iChannel < 64; iChannel++) {
236        if(iChannel<32) {
237          if (BBFlag[iChannel]) aBBflagsV0C |= (1 << iChannel);
238          if (BGFlag[iChannel]) aBGflagsV0C |= (1 << iChannel);
239        } else {
240          if (BBFlag[iChannel]) aBBflagsV0A |= (1 << (iChannel-32));
241          if (BGFlag[iChannel]) aBGflagsV0A |= (1 << (iChannel-32));
242        }
243          if(fCalibData->IsChannelDead(iChannel)){
244             adc[iChannel]  = (Float_t) kInvalidADC; 
245             time[iChannel] = (Float_t) kInvalidTime;     
246          }
247          if (adc[iChannel] > 0)
248            new ((*fDigitsArray)[fDigitsArray->GetEntriesFast()])
249              AliVZEROdigit(iChannel, adc[iChannel], time[iChannel],
250                            width[iChannel],integrator[iChannel],
251                            chargeADC[iChannel]);
252         
253      }          
254
255      // Store the BB and BG flags in the digits tree (user info)
256      digitsTree->GetUserInfo()->Add(new TParameter<int>("BBflagsV0A",aBBflagsV0A));
257      digitsTree->GetUserInfo()->Add(new TParameter<int>("BBflagsV0C",aBBflagsV0C));
258      digitsTree->GetUserInfo()->Add(new TParameter<int>("BGflagsV0A",aBGflagsV0A));
259      digitsTree->GetUserInfo()->Add(new TParameter<int>("BGflagsV0C",aBGflagsV0C));
260
261      digitsTree->Fill();
262   }
263
264   fDigitsArray->Clear();
265 }
266
267 //______________________________________________________________________
268 void AliVZEROReconstructor::FillESD(TTree* digitsTree, TTree* /*clustersTree*/,
269                                     AliESDEvent* esd) const
270 {
271 // fills multiplicities to the ESD - pedestal is now subtracted
272     
273   if (!digitsTree) {
274       AliError("No digits tree!");
275       return;
276   }
277
278   TBranch* digitBranch = digitsTree->GetBranch("VZERODigit");
279   digitBranch->SetAddress(&fDigitsArray);
280
281   Float_t   mult[64];  
282   Float_t    adc[64]; 
283   Float_t   time[64]; 
284   Float_t  width[64];
285   Bool_t aBBflag[64];
286   Bool_t aBGflag[64];
287    
288   for (Int_t i=0; i<64; i++){
289        adc[i]    = 0.0;
290        mult[i]   = 0.0;
291        time[i]   = kInvalidTime;
292        width[i]  = 0.0;
293        aBBflag[i] = kFALSE;
294        aBGflag[i] = kFALSE;
295   }
296      
297   Int_t aBBflagsV0A = 0;
298   Int_t aBBflagsV0C = 0;
299   Int_t aBGflagsV0A = 0;
300   Int_t aBGflagsV0C = 0;
301
302   if (digitsTree->GetUserInfo()->FindObject("BBflagsV0A")) {
303     aBBflagsV0A = ((TParameter<int>*)digitsTree->GetUserInfo()->FindObject("BBflagsV0A"))->GetVal();
304   }
305   else
306     AliWarning("V0A beam-beam flags not found in digits tree UserInfo! The flags will not be written to the raw-data stream!");
307
308   if (digitsTree->GetUserInfo()->FindObject("BBflagsV0C")) {
309     aBBflagsV0C = ((TParameter<int>*)digitsTree->GetUserInfo()->FindObject("BBflagsV0C"))->GetVal();
310   }
311   else
312     AliWarning("V0C beam-beam flags not found in digits tree UserInfo! The flags will not be written to the raw-data stream!");
313
314   if (digitsTree->GetUserInfo()->FindObject("BGflagsV0A")) {
315     aBGflagsV0A = ((TParameter<int>*)digitsTree->GetUserInfo()->FindObject("BGflagsV0A"))->GetVal();
316   }
317   else
318     AliWarning("V0A beam-gas flags not found in digits tree UserInfo! The flags will not be written to the raw-data stream!");
319
320   if (digitsTree->GetUserInfo()->FindObject("BGflagsV0C")) {
321     aBGflagsV0C = ((TParameter<int>*)digitsTree->GetUserInfo()->FindObject("BGflagsV0C"))->GetVal();
322   }
323   else
324     AliWarning("V0C beam-gas flags not found in digits tree UserInfo! The flags will not be written to the raw-data stream!");
325   
326
327   Int_t nEntries = (Int_t)digitsTree->GetEntries();
328   for (Int_t e=0; e<nEntries; e++) {
329     digitsTree->GetEvent(e);
330
331     Int_t nDigits = fDigitsArray->GetEntriesFast();
332     
333     for (Int_t d=0; d<nDigits; d++) {    
334         AliVZEROdigit* digit = (AliVZEROdigit*) fDigitsArray->At(d);      
335         Int_t  pmNumber      = digit->PMNumber(); 
336         // Pedestal retrieval and suppression: 
337         Bool_t   integrator  = digit->Integrator();
338         Int_t k = pmNumber+64*integrator;
339         Float_t  pedestal    = fCalibData->GetPedestal(k);
340         adc[pmNumber]   =  digit->ADC() - pedestal; 
341         time[pmNumber]  =  CorrectLeadingTime(pmNumber,digit->Time(),adc[pmNumber]);
342         width[pmNumber] =  digit->Width();
343         if(pmNumber < 32) {
344           aBBflag[pmNumber] = (aBBflagsV0C >> pmNumber) & 0x1;
345           aBGflag[pmNumber] = (aBGflagsV0C >> pmNumber) & 0x1;
346         }
347         else {
348           aBBflag[pmNumber] = (aBBflagsV0A >> (pmNumber-32)) & 0x1;
349           aBGflag[pmNumber] = (aBGflagsV0A >> (pmNumber-32)) & 0x1;
350         }
351
352         if (adc[pmNumber] > 0) AliDebug(1,Form("PM = %d ADC = %f TDC %f    Int %d (%d %d %d %d %d)    %f %f   %f %f    %d %d",pmNumber, adc[pmNumber],digit->Time(),
353                                                integrator,
354                                                digit->ChargeADC(8),digit->ChargeADC(9),digit->ChargeADC(10),
355                                                digit->ChargeADC(11),digit->ChargeADC(12),
356                                                fCalibData->GetPedestal(pmNumber),fCalibData->GetSigma(pmNumber),
357                                                fCalibData->GetPedestal(pmNumber+64),fCalibData->GetSigma(pmNumber+64),
358                                                aBBflag[pmNumber],aBGflag[pmNumber]));
359
360         if(adc[pmNumber] > (fCalibData->GetPedestal(k) + GetRecoParam()->GetNSigmaPed()*fCalibData->GetSigma(k))) {
361             mult[pmNumber] += adc[pmNumber]*fCalibData->GetMIPperADC(pmNumber);
362         }           
363     } // end of loop over digits
364   } // end of loop over events in digits tree
365          
366   fESDVZERO->SetBit(AliESDVZERO::kCorrectedLeadingTime,kTRUE);
367   fESDVZERO->SetMultiplicity(mult);
368   fESDVZERO->SetADC(adc);
369   fESDVZERO->SetTime(time);
370   fESDVZERO->SetWidth(width);
371   fESDVZERO->SetBBFlag(aBBflag);
372   fESDVZERO->SetBGFlag(aBGflag);
373
374   // now fill the V0 decision and channel flags
375   {
376     AliVZEROTriggerMask triggerMask;
377     triggerMask.FillMasks(fESDVZERO, fCalibData, fTimeSlewing);
378   }
379
380   if (esd) { 
381      AliDebug(1, Form("Writing VZERO data to ESD tree"));
382      esd->SetVZEROData(fESDVZERO);
383   }
384
385   if (esd) {
386      AliESDfriend *fr = (AliESDfriend*)esd->FindListObject("AliESDfriend");
387      if (fr) {
388         AliDebug(1, Form("Writing VZERO friend data to ESD tree"));
389         fr->SetVZEROfriend(fESDVZEROfriend);
390     }
391   }
392
393   fDigitsArray->Clear();
394 }
395
396 //_____________________________________________________________________________
397 AliCDBStorage* AliVZEROReconstructor::SetStorage(const char *uri) 
398 {
399 // Sets the storage  
400
401   Bool_t deleteManager = kFALSE;
402   
403   AliCDBManager *manager = AliCDBManager::Instance();
404   AliCDBStorage *defstorage = manager->GetDefaultStorage();
405   
406   if(!defstorage || !(defstorage->Contains("VZERO"))){ 
407      AliWarning("No default storage set or default storage doesn't contain VZERO!");
408      manager->SetDefaultStorage(uri);
409      deleteManager = kTRUE;
410   }
411  
412   AliCDBStorage *storage = manager->GetDefaultStorage();
413
414   if(deleteManager){
415      AliCDBManager::Instance()->UnsetDefaultStorage();
416      defstorage = 0;   // the storage is killed by AliCDBManager::Instance()->Destroy()
417   }
418
419   return storage; 
420 }
421
422 //____________________________________________________________________________
423 void AliVZEROReconstructor::GetCollisionMode()
424 {
425   // Retrieval of collision mode 
426
427   TString beamType = GetRunInfo()->GetBeamType();
428   if(beamType==AliGRPObject::GetInvalidString()){
429      AliError("VZERO cannot retrieve beam type");
430      return;
431   }
432
433   if( (beamType.CompareTo("P-P") ==0)  || (beamType.CompareTo("p-p") ==0) ){
434     fCollisionMode=0;
435   }
436   else if( (beamType.CompareTo("Pb-Pb") ==0)  || (beamType.CompareTo("A-A") ==0) ){
437     fCollisionMode=1;
438   }
439     
440   fBeamEnergy = GetRunInfo()->GetBeamEnergy();
441   if(fBeamEnergy==AliGRPObject::GetInvalidFloat()) {
442      AliError("Missing value for the beam energy ! Using 0");
443      fBeamEnergy = 0.;
444   }
445   
446   AliDebug(1,Form("\n ++++++ Beam type and collision mode retrieved as %s %d @ %1.3f GeV ++++++\n\n",beamType.Data(), fCollisionMode, fBeamEnergy));
447
448 }
449
450 //_____________________________________________________________________________
451 AliVZEROCalibData* AliVZEROReconstructor::GetCalibData() const
452 {
453   // Gets calibration object for VZERO set
454
455   AliCDBManager *man = AliCDBManager::Instance();
456
457   AliCDBEntry *entry=0;
458
459   entry = man->Get("VZERO/Calib/Data");
460
461   AliVZEROCalibData *calibdata = 0;
462
463   if (entry) calibdata = (AliVZEROCalibData*) entry->GetObject();
464   if (!calibdata)  AliFatal("No calibration data from calibration database !");
465
466   return calibdata;
467 }
468
469 Float_t AliVZEROReconstructor::CorrectLeadingTime(Int_t i, Float_t time, Float_t adc) const
470 {
471   // Correct the leading time
472   // for slewing effect and
473   // misalignment of the channels
474   if (time < 1e-6) return kInvalidTime;
475
476   // Channel alignment and general offset subtraction
477   if (i < 32) time -= kV0CDelayCables;
478   time -= fTimeOffset[i];
479
480   // In case of pathological signals
481   if (adc < 1e-6) return time;
482
483   // Slewing correction
484   Float_t thr = fCalibData->GetDiscriThr(i);
485   time -= fTimeSlewing->Eval(adc/thr);
486
487   return time;
488 }