]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ZDC/AliZDCReconstructor.cxx
Read all the coeff. from energy calib. object
[u/mrichter/AliRoot.git] / ZDC / AliZDCReconstructor.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 ZDC reconstruction      **************      //
21 //                  Author: Chiara.Oppedisano@to.infn.it                     //
22 //                                                                           //
23 // NOTATIONS ADOPTED TO IDENTIFY DETECTORS (used in different ages!):        //
24 //   (ZN1,ZP1) or (ZNC, ZPC) or RIGHT refers to side C (RB26)                //
25 //   (ZN2,ZP2) or (ZNA, ZPA) or LEFT refers to side A (RB24)                 //
26 //                                                                           //
27 ///////////////////////////////////////////////////////////////////////////////
28
29
30 #include <TH2F.h>
31 #include <TH1D.h>
32 #include <TAxis.h>
33 #include <TMap.h>
34
35 #include "AliRawReader.h"
36 #include "AliESDEvent.h"
37 #include "AliESDZDC.h"
38 #include "AliZDCDigit.h"
39 #include "AliZDCRawStream.h"
40 #include "AliZDCReco.h"
41 #include "AliZDCReconstructor.h"
42 #include "AliZDCPedestals.h"
43 #include "AliZDCEnCalib.h"
44 #include "AliZDCTowerCalib.h"
45 #include "AliZDCRecoParam.h"
46 #include "AliZDCRecoParampp.h"
47 #include "AliZDCRecoParamPbPb.h"
48 #include "AliRunInfo.h"
49
50
51 ClassImp(AliZDCReconstructor)
52 AliZDCRecoParam *AliZDCReconstructor::fRecoParam=0;  //reconstruction parameters
53
54 //_____________________________________________________________________________
55 AliZDCReconstructor:: AliZDCReconstructor() :
56   fPedData(GetPedestalData()),
57   fEnCalibData(GetEnergyCalibData()),
58   fTowCalibData(GetTowerCalibData()),
59   fRecoMode(0),
60   fBeamEnergy(0.),
61   fNRun(0),
62   fIsCalibrationMB(kFALSE),
63   fPedSubMode(0),
64   fSignalThreshold(7)
65 {
66   // **** Default constructor
67 }
68
69
70 //_____________________________________________________________________________
71 AliZDCReconstructor::~AliZDCReconstructor()
72 {
73 // destructor
74 //   if(fRecoParam)    delete fRecoParam;
75    if(fPedData)      delete fPedData;    
76    if(fEnCalibData)  delete fEnCalibData;
77    if(fTowCalibData) delete fTowCalibData;
78 }
79
80 //____________________________________________________________________________
81 void AliZDCReconstructor::Init()
82 {
83   // Setting reconstruction mode
84   // Getting beam type and beam energy from GRP calibration object
85   
86   TString runType = GetRunInfo()->GetRunType();
87   if((runType.CompareTo("CALIBRATION_MB")) == 0){
88     fIsCalibrationMB = kTRUE;
89   }
90     
91   TString beamType = GetRunInfo()->GetBeamType();
92   // This is a temporary solution to allow reconstruction in tests without beam
93   if(((beamType.CompareTo("UNKNOWN"))==0) && ((runType.CompareTo("PHYSICS")) == 0)){
94     fRecoMode=1;
95   }
96   /*else if((beamType.CompareTo("UNKNOWN"))==0){
97     AliError("\t UNKNOWN beam type\n");
98     return;
99   }*/
100
101   if(((beamType.CompareTo("pp"))==0) || ((beamType.CompareTo("p-p"))==0)
102      ||((beamType.CompareTo("PP"))==0) || ((beamType.CompareTo("P-P"))==0)){
103     fRecoMode=1;
104   }
105   else if((beamType.CompareTo("A-A")) == 0){
106     fRecoMode=2;
107   }
108     
109   fBeamEnergy = GetRunInfo()->GetBeamEnergy();
110   if(fBeamEnergy==0.) AliWarning(" Beam energy value missing -> E_beam = 0");
111     
112   if(fIsCalibrationMB==kFALSE)  
113     printf("\n\n ***** ZDC reconstruction initialized for %s @ %1.0f GeV *****\n\n",beamType.Data(), fBeamEnergy);
114   
115 }
116
117 //_____________________________________________________________________________
118 void AliZDCReconstructor::Reconstruct(TTree* digitsTree, TTree* clustersTree) const
119 {
120   // *** Local ZDC reconstruction for digits
121   // Works on the current event
122     
123   // Retrieving calibration data  
124   // Parameters for mean value pedestal subtraction
125   int const kNch = 24;
126   Float_t meanPed[2*kNch];    
127   for(Int_t jj=0; jj<2*kNch; jj++) meanPed[jj] = fPedData->GetMeanPed(jj);
128   // Parameters pedestal subtraction through correlation with out-of-time signals
129   Float_t corrCoeff0[2*kNch], corrCoeff1[2*kNch];
130   for(Int_t jj=0; jj<2*kNch; jj++){
131      corrCoeff0[jj] = fPedData->GetPedCorrCoeff0(jj);
132      corrCoeff1[jj] = fPedData->GetPedCorrCoeff1(jj);
133   }
134
135   // get digits
136   AliZDCDigit digit;
137   AliZDCDigit* pdigit = &digit;
138   digitsTree->SetBranchAddress("ZDC", &pdigit);
139   //printf("\n\t # of digits in tree: %d\n",(Int_t) digitsTree->GetEntries());
140
141   // loop over digits
142   Float_t tZN1Corr[10], tZP1Corr[10], tZN2Corr[10], tZP2Corr[10]; 
143   Float_t dZEM1Corr[2], dZEM2Corr[2], sPMRef1[2], sPMRef2[2]; 
144   for(Int_t i=0; i<10; i++){
145      tZN1Corr[i] = tZP1Corr[i] = tZN2Corr[i] = tZP2Corr[i] = 0.;
146      if(i<2) dZEM1Corr[i] = dZEM2Corr[i] = sPMRef1[i] = sPMRef2[i] = 0.;
147   }  
148   
149   Int_t digNentries = digitsTree->GetEntries();
150   Float_t ootDigi[kNch];
151   // -- Reading out-of-time signals (last kNch entries) for current event
152   if(fPedSubMode==1){
153     for(Int_t iDigit=kNch; iDigit<digNentries; iDigit++){
154        ootDigi[iDigit] = digitsTree->GetEntry(iDigit);
155     }
156   }
157   
158   for(Int_t iDigit=0; iDigit<(digNentries/2); iDigit++) {
159    digitsTree->GetEntry(iDigit);
160    if (!pdigit) continue;
161    //  
162    Int_t det = digit.GetSector(0);
163    Int_t quad = digit.GetSector(1);
164    Int_t pedindex = -1;
165    Float_t ped2SubHg=0., ped2SubLg=0.;
166    if(quad!=5){
167      if(det==1)      pedindex = quad;
168      else if(det==2) pedindex = quad+5;
169      else if(det==3) pedindex = quad+9;
170      else if(det==4) pedindex = quad+12;
171      else if(det==5) pedindex = quad+17;
172    }
173    else pedindex = (det-1)/3+22;
174    //
175    if(fPedSubMode==0){
176      ped2SubHg = meanPed[pedindex];
177      ped2SubLg = meanPed[pedindex+kNch];
178    }
179    else if(fPedSubMode==1){
180      ped2SubHg = corrCoeff1[pedindex]*ootDigi[pedindex]+corrCoeff0[pedindex];
181      ped2SubLg = corrCoeff1[pedindex+kNch]*ootDigi[pedindex+kNch]+corrCoeff0[pedindex+kNch];
182    }
183       
184    if(quad != 5){ // ZDC (not reference PTMs!)
185     if(det == 1){ // *** ZNC
186        tZN1Corr[quad] = (Float_t) (digit.GetADCValue(0)-ped2SubHg);
187        tZN1Corr[quad+5] = (Float_t) (digit.GetADCValue(1)-ped2SubLg);
188        if(tZN1Corr[quad]<0.) tZN1Corr[quad] = 0.;
189        if(tZN1Corr[quad+5]<0.) tZN1Corr[quad+5] = 0.;
190     }
191     else if(det == 2){ // *** ZP1
192        tZP1Corr[quad] = (Float_t) (digit.GetADCValue(0)-ped2SubHg);
193        tZP1Corr[quad+5] = (Float_t) (digit.GetADCValue(1)-ped2SubLg);
194        if(tZP1Corr[quad]<0.) tZP1Corr[quad] = 0.;
195        if(tZP1Corr[quad+5]<0.) tZP1Corr[quad+5] = 0.;
196     }
197     else if(det == 3){
198        if(quad == 1){       // *** ZEM1  
199          dZEM1Corr[0] += (Float_t) (digit.GetADCValue(0)-ped2SubHg); 
200          dZEM1Corr[1] += (Float_t) (digit.GetADCValue(1)-ped2SubLg); 
201          if(dZEM1Corr[0]<0.) dZEM1Corr[0] = 0.;
202          if(dZEM1Corr[1]<0.) dZEM1Corr[1] = 0.;
203        }
204        else if(quad == 2){  // *** ZEM2
205          dZEM2Corr[0] += (Float_t) (digit.GetADCValue(0)-ped2SubHg); 
206          dZEM2Corr[1] += (Float_t) (digit.GetADCValue(1)-ped2SubLg); 
207          if(dZEM2Corr[0]<0.) dZEM2Corr[0] = 0.;
208          if(dZEM2Corr[1]<0.) dZEM2Corr[1] = 0.;
209        }
210     }
211     else if(det == 4){  // *** ZN2
212        tZN2Corr[quad] = (Float_t) (digit.GetADCValue(0)-ped2SubHg);
213        tZN2Corr[quad+5] = (Float_t) (digit.GetADCValue(1)-ped2SubLg);
214        if(tZN2Corr[quad]<0.) tZN2Corr[quad] = 0.;
215        if(tZN2Corr[quad+5]<0.) tZN2Corr[quad+5] = 0.;
216    }
217     else if(det == 5){  // *** ZP2 
218        tZP2Corr[quad] = (Float_t) (digit.GetADCValue(0)-ped2SubHg);
219        tZP2Corr[quad+5] = (Float_t) (digit.GetADCValue(1)-ped2SubLg);
220        if(tZP2Corr[quad]<0.) tZP2Corr[quad] = 0.;
221        if(tZP2Corr[quad+5]<0.) tZP2Corr[quad+5] = 0.;
222     }
223    }
224    else{ // Reference PMs
225      if(det == 1){
226        sPMRef1[0] = (Float_t) (digit.GetADCValue(0)-ped2SubHg);
227        sPMRef1[1] = (Float_t) (digit.GetADCValue(1)-ped2SubLg);
228        // Ch. debug
229        if(sPMRef1[0]<0.) sPMRef1[0] = 0.;
230        if(sPMRef2[1]<0.) sPMRef1[1] = 0.;
231      }
232      else if(det == 4){
233        sPMRef2[0] = (Float_t) (digit.GetADCValue(0)-ped2SubHg);
234        sPMRef2[1] = (Float_t) (digit.GetADCValue(1)-ped2SubLg);
235        // Ch. debug
236        if(sPMRef2[0]<0.) sPMRef2[0] = 0.;
237        if(sPMRef2[1]<0.) sPMRef2[1] = 0.;
238      }
239    }
240
241    // Ch. debug
242    /*printf("AliZDCReconstructor: digit #%d det %d quad %d pedHG %1.0f pedLG %1.0f\n",
243          iDigit, det, quad, ped2SubHg, ped2SubLg);
244    printf(" -> pedindex %d\n", pedindex);
245    printf("   HGChain -> RawDig %d DigCorr %1.2f", 
246         digit.GetADCValue(0), digit.GetADCValue(0)-ped2SubHg); 
247    printf("   LGChain -> RawDig %d DigCorr %1.2f\n", 
248         digit.GetADCValue(1), digit.GetADCValue(1)-ped2SubLg);*/ 
249    
250   }//digits loop
251  
252   UInt_t counts[32];
253   for(Int_t jj=0; jj<32; jj++) counts[jj]=0;
254   
255   Int_t  evQualityBlock[4] = {1,0,0,0};
256   Int_t  triggerBlock[4] = {0,0,0,0};
257   Int_t  chBlock[3] = {0,0,0};
258   UInt_t puBits=0;
259   
260   // reconstruct the event
261   if(fRecoMode==1)
262     ReconstructEventpp(clustersTree, tZN1Corr, tZP1Corr, tZN2Corr, tZP2Corr, 
263       dZEM1Corr, dZEM2Corr, sPMRef1, sPMRef2, 
264       kFALSE, counts, 
265       evQualityBlock,  triggerBlock,  chBlock, puBits);
266   else if(fRecoMode==2)
267     ReconstructEventPbPb(clustersTree, tZN1Corr, tZP1Corr, tZN2Corr, tZP2Corr, 
268       dZEM1Corr, dZEM2Corr, sPMRef1, sPMRef2, 
269       kFALSE, counts, 
270       evQualityBlock,  triggerBlock,  chBlock, puBits);
271 }
272
273 //_____________________________________________________________________________
274 void AliZDCReconstructor::Reconstruct(AliRawReader* rawReader, TTree* clustersTree) const
275 {
276   // *** ZDC raw data reconstruction
277   // Works on the current event
278   
279   // Retrieving calibration data  
280   // Parameters for pedestal subtraction
281   int const kNch = 24;
282   Float_t meanPed[2*kNch];    
283   for(Int_t jj=0; jj<2*kNch; jj++) meanPed[jj] = fPedData->GetMeanPed(jj);
284   // Parameters pedestal subtraction through correlation with out-of-time signals
285   Float_t corrCoeff0[2*kNch], corrCoeff1[2*kNch];
286   for(Int_t jj=0; jj<2*kNch; jj++){
287      corrCoeff0[jj] =  fPedData->GetPedCorrCoeff0(jj);
288      corrCoeff1[jj] =  fPedData->GetPedCorrCoeff1(jj);
289   }
290
291   Int_t adcZN1[5], adcZN1oot[5], adcZN1lg[5], adcZN1ootlg[5];
292   Int_t adcZP1[5], adcZP1oot[5], adcZP1lg[5], adcZP1ootlg[5];
293   Int_t adcZN2[5], adcZN2oot[5], adcZN2lg[5], adcZN2ootlg[5];
294   Int_t adcZP2[5], adcZP2oot[5], adcZP2lg[5], adcZP2ootlg[5];
295   Int_t adcZEM[2], adcZEMoot[2], adcZEMlg[2], adcZEMootlg[2];
296   Int_t pmRef[2], pmRefoot[2], pmReflg[2], pmRefootlg[2];
297   for(Int_t ich=0; ich<5; ich++){
298     adcZN1[ich] = adcZN1oot[ich] = adcZN1lg[ich] = adcZN1ootlg[ich] = 0;
299     adcZP1[ich] = adcZP1oot[ich] = adcZP1lg[ich] = adcZP1ootlg[ich] = 0;
300     adcZN2[ich] = adcZN2oot[ich] = adcZN2lg[ich] = adcZN2ootlg[ich] = 0;
301     adcZP2[ich] = adcZP2oot[ich] = adcZP2lg[ich] = adcZP2ootlg[ich] = 0;
302     if(ich<2){
303       adcZEM[ich] = adcZEMoot[ich] = adcZEMlg[ich] = adcZEMootlg[ich] = 0;
304       pmRef[ich] = pmRefoot[ich] = pmReflg[ich] = pmRefootlg[ich] = 0;
305     }
306   }
307   
308   Float_t tZN1Corr[10], tZP1Corr[10], tZN2Corr[10], tZP2Corr[10]; 
309   Float_t dZEM1Corr[2], dZEM2Corr[2], sPMRef1[2], sPMRef2[2]; 
310   for(Int_t i=0; i<10; i++){
311      tZN1Corr[i] = tZP1Corr[i] = tZN2Corr[i] = tZP2Corr[i] = 0.;
312      if(i<2) dZEM1Corr[i] = dZEM2Corr[i] = sPMRef1[i] = sPMRef2[i] = 0.;
313   }  
314
315   Bool_t isScalerOn=kFALSE;
316   Int_t jsc=0;
317   UInt_t scalerData[32];        
318   for(Int_t k=0; k<32; k++) scalerData[k]=0;
319   
320   Int_t  evQualityBlock[4] = {1,0,0,0};
321   Int_t  triggerBlock[4] = {0,0,0,0};
322   Int_t  chBlock[3] = {0,0,0};
323   UInt_t puBits=0;
324
325   //fNRun = (Int_t) rawReader->GetRunNumber();
326   Int_t kFirstADCGeo=0, kLastADCGeo=3, kScalerGeo=8, kPUGeo=29;
327   //Int_t kTrigScales=30, kTrigHistory=31;
328
329   // loop over raw data
330   rawReader->Reset();
331   AliZDCRawStream rawData(rawReader);
332   while(rawData.Next()){
333    
334    // ***************************** Reading ADCs
335    if((rawData.GetADCModule()>=kFirstADCGeo) && (rawData.GetADCModule()<=kLastADCGeo)){    
336     //printf(" **** Reading ADC raw data from module %d **** \n",rawData.GetADCModule());
337     //
338     if((rawData.IsADCDataWord()) && (rawData.GetNChannelsOn()<48))    chBlock[0] = kTRUE;
339     if((rawData.IsADCDataWord()) && (rawData.IsOverflow() == kTRUE))  chBlock[1] = kTRUE;
340     if((rawData.IsADCDataWord()) && (rawData.IsUnderflow() == kTRUE)) chBlock[2] = kTRUE;
341     if((rawData.IsADCDataWord()) && (rawData.IsADCEventGood() == kTRUE)) evQualityBlock[0] = kTRUE;
342     
343     if((rawData.IsADCDataWord()) && (rawData.IsUnderflow()==kFALSE) 
344         && (rawData.IsOverflow()==kFALSE) && (rawData.IsADCEventGood()==kTRUE)){
345      
346       Int_t adcMod = rawData.GetADCModule();
347       Int_t det = rawData.GetSector(0);
348       Int_t quad = rawData.GetSector(1);
349       Int_t gain = rawData.GetADCGain();
350       Int_t pedindex=0;
351       //
352       // Mean pedestal value subtraction -------------------------------------------------------
353       if(fPedSubMode == 0){
354        // Not interested in o.o.t. signals (ADC modules 2, 3)
355        if(adcMod == 2 || adcMod == 3) continue;
356        //
357        if(quad != 5){ // ZDCs (not reference PTMs)
358         if(det == 1){    
359           pedindex = quad;
360           if(gain == 0) tZN1Corr[quad]  += (Float_t) (rawData.GetADCValue()-meanPed[pedindex]); 
361           else tZN1Corr[quad+5]  += (Float_t) (rawData.GetADCValue()-meanPed[pedindex+kNch]); 
362         }
363         else if(det == 2){ 
364           pedindex = quad+5;
365           if(gain == 0) tZP1Corr[quad]  += (Float_t) (rawData.GetADCValue()-meanPed[pedindex]); 
366           else tZP1Corr[quad+5]  += (Float_t) (rawData.GetADCValue()-meanPed[pedindex+kNch]); 
367         }
368         else if(det == 3){ 
369           pedindex = quad+9;
370           if(quad==1){     
371             if(gain == 0) dZEM1Corr[0] += (Float_t) (rawData.GetADCValue()-meanPed[pedindex]); 
372             else dZEM1Corr[1] += (Float_t) (rawData.GetADCValue()-meanPed[pedindex+kNch]); 
373           }
374           else if(quad==2){ 
375             if(gain == 0) dZEM2Corr[0] += (Float_t) (rawData.GetADCValue()-meanPed[pedindex]); 
376             else dZEM2Corr[1] += (Float_t) (rawData.GetADCValue()-meanPed[pedindex+kNch]); 
377           }
378         }
379         else if(det == 4){       
380           pedindex = quad+12;
381           if(gain == 0) tZN2Corr[quad]  += (Float_t) (rawData.GetADCValue()-meanPed[pedindex]); 
382           else tZN2Corr[quad+5]  += (Float_t) (rawData.GetADCValue()-meanPed[pedindex+kNch]); 
383         }
384         else if(det == 5){
385           pedindex = quad+17;
386           if(gain == 0) tZP2Corr[quad]  += (Float_t) (rawData.GetADCValue()-meanPed[pedindex]); 
387           else tZP2Corr[quad+5]  += (Float_t) (rawData.GetADCValue()-meanPed[pedindex+kNch]); 
388         }
389        }
390        else{ // reference PM
391          pedindex = (det-1)/3 + 22;
392          if(det == 1){
393            if(gain==0) sPMRef1[0] += (Float_t) (rawData.GetADCValue()-meanPed[pedindex]);
394          else sPMRef1[1] += (Float_t) (rawData.GetADCValue()-meanPed[pedindex+kNch]);
395          }
396          else if(det == 4){
397            if(gain==0) sPMRef2[0] += (Float_t) (rawData.GetADCValue()-meanPed[pedindex]);
398            else sPMRef2[1] += (Float_t) (rawData.GetADCValue()-meanPed[pedindex+kNch]);
399          }
400        }
401        // Ch. debug
402        /*if(gain==0){
403          printf(" AliZDCReconstructor: det %d quad %d res %d -> Pedestal[%d] %1.0f", 
404            det,quad,gain, pedindex, meanPed[pedindex]);
405          printf("   RawADC %d ADCCorr %1.0f\n", 
406            rawData.GetADCValue(), rawData.GetADCValue()-meanPed[pedindex]);
407        }*/ 
408       }// mean pedestal subtraction
409       // Pedestal subtraction from correlation ------------------------------------------------
410       else if(fPedSubMode == 1){
411        // In time signals
412        if(adcMod==0 || adcMod==1){
413          if(quad != 5){ // signals from ZDCs
414            if(det == 1){
415              if(gain==0) adcZN1[quad] = rawData.GetADCValue();
416              else adcZN1lg[quad] = rawData.GetADCValue();
417            }
418            else if(det == 2){
419              if(gain==0) adcZP1[quad] = rawData.GetADCValue();
420              else adcZP1lg[quad] = rawData.GetADCValue();
421            }
422            else if(det == 3){
423              if(gain==0) adcZEM[quad-1] = rawData.GetADCValue();
424              else adcZEMlg[quad-1] = rawData.GetADCValue();
425            }
426            else if(det == 4){
427              if(gain==0) adcZN2[quad] = rawData.GetADCValue();
428              else adcZN2lg[quad] = rawData.GetADCValue();
429            }
430            else if(det == 5){
431              if(gain==0) adcZP2[quad] = rawData.GetADCValue();
432              else adcZP2lg[quad] = rawData.GetADCValue();
433            }
434          }
435          else{ // signals from reference PM
436             if(gain==0) pmRef[quad-1] = rawData.GetADCValue();
437             else pmReflg[quad-1] = rawData.GetADCValue();
438          }
439        }
440        // Out-of-time pedestals
441        else if(adcMod==2 || adcMod==3){
442          if(quad != 5){ // signals from ZDCs
443            if(det == 1){
444              if(gain==0) adcZN1oot[quad] = rawData.GetADCValue();
445              else adcZN1ootlg[quad] = rawData.GetADCValue();
446            }
447            else if(det == 2){
448              if(gain==0) adcZP1oot[quad] = rawData.GetADCValue();
449              else adcZP1ootlg[quad] = rawData.GetADCValue();
450            }
451            else if(det == 3){
452              if(gain==0) adcZEMoot[quad-1] = rawData.GetADCValue();
453              else adcZEMootlg[quad-1] = rawData.GetADCValue();
454            }
455            else if(det == 4){
456              if(gain==0) adcZN2oot[quad] = rawData.GetADCValue();
457              else adcZN2ootlg[quad] = rawData.GetADCValue();
458            }
459            else if(det == 5){
460              if(gain==0) adcZP2oot[quad] = rawData.GetADCValue();
461              else adcZP2ootlg[quad] = rawData.GetADCValue();
462            }
463          }
464          else{ // signals from reference PM
465             if(gain==0) pmRefoot[quad-1] = rawData.GetADCValue();
466             else pmRefootlg[quad-1] = rawData.GetADCValue();
467          }
468        }
469       } // pedestal subtraction from correlation
470       // Ch. debug
471       /*printf("\t AliZDCReconstructor: det %d quad %d res %d -> Ped[%d] = %1.0f\n", 
472         det,quad,gain, pedindex, meanPed[pedindex]);*/
473     }//IsADCDataWord
474    }// ADC DATA
475    // ***************************** Reading Scaler
476    else if(rawData.GetADCModule()==kScalerGeo){
477      if(rawData.IsScHeaderRead()==kTRUE && rawData.IsScEventGood()==kTRUE){
478        isScalerOn = kTRUE;
479        scalerData[jsc] = rawData.GetTriggerCount();
480        jsc++;
481      }
482    }// VME SCALER DATA
483    // ***************************** Reading PU
484    else if(rawData.GetADCModule()==kPUGeo){
485      puBits = rawData.GetDetectorPattern();
486    }
487     // ***************************** Reading trigger history
488    else if(rawData.IstriggerHistoryWord()==kTRUE){
489      triggerBlock[0] = rawData.IsCPTInputEMDTrigger();
490      triggerBlock[1] = rawData.IsCPTInputSemiCentralTrigger();
491      triggerBlock[2] = rawData.IsCPTInputCentralTrigger();
492      triggerBlock[3] = rawData.IsCPTInputMBTrigger();
493    }
494   
495   }//loop on raw data
496   
497   if(fPedSubMode==1){
498     for(Int_t t=0; t<5; t++){
499        tZN1Corr[t] = adcZN1[t] - (corrCoeff1[t]*adcZN1oot[t]+corrCoeff0[t]);
500        tZN1Corr[t+5] = adcZN1lg[t] - (corrCoeff1[t+kNch]*adcZN1ootlg[t]+corrCoeff0[t+kNch]);
501        //
502        tZP1Corr[t] = adcZP1[t] - (corrCoeff1[t+5]*adcZP1oot[t]+corrCoeff0[t+5]);
503        tZP1Corr[t+5] = adcZP1lg[t] - (corrCoeff1[t+5+kNch]*adcZP1ootlg[t]+corrCoeff0[t+5+kNch]);
504        //
505        tZN2Corr[t] = adcZN2[t] - (corrCoeff1[t+12]*adcZN2oot[t]+corrCoeff0[t+12]);
506        tZN2Corr[t+5] = adcZN2lg[t] - (corrCoeff1[t+12+kNch]*adcZN2ootlg[t]+corrCoeff0[t+12+kNch]);
507        //
508        tZP2Corr[t] = adcZP2[t] - (corrCoeff1[t+17]*adcZP2oot[t]+corrCoeff0[t+17]);
509        tZP2Corr[t+5] = adcZP2lg[t] - (corrCoeff1[t+17+kNch]*adcZP2ootlg[t]+corrCoeff0[t+17+kNch]);
510        // 0---------0 Ch. debug 0---------0
511 /*       printf("\n\n ---------- Debug of pedestal subtraction from correlation ----------\n");
512        printf("\tCorrCoeff0\tCorrCoeff1\n");
513        printf(" ZN1 %d\t%1.0f\t%1.0f\n",t,corrCoeff0[t],corrCoeff1[t]);
514        printf(" ZN1lg %d\t%1.0f\t%1.0f\n",t+kNch,corrCoeff0[t+kNch],corrCoeff1[t+kNch]);
515        printf(" ZP1 %d\t%1.0f\t%1.0f\n",t+5,corrCoeff0[t+5],corrCoeff1[t+5]);
516        printf(" ZP1lg %d\t%1.0f\t%1.0f\n",t+5+kNch,corrCoeff0[t+5+kNch],corrCoeff1[t+5+kNch]);
517        printf(" ZN2 %d\t%1.0f\t%1.0f\n",t+12,corrCoeff0[t+12],corrCoeff1[t+12]);
518        printf(" ZN2lg %d\t%1.0f\t%1.0f\n",t+12+kNch,corrCoeff0[t+12+kNch],corrCoeff1[t+12+kNch]);
519        printf(" ZP2 %d\t%1.0f\t%1.0f\n",t+17,corrCoeff0[t+17],corrCoeff1[t+17]);
520        printf(" ZP2lg %d\t%1.0f\t%1.0f\n",t+17+kNch,corrCoeff0[t+17+kNch],corrCoeff1[t+17+kNch]);
521        
522        printf("ZN1 ->  rawADC %d\tpedestal%1.2f\tcorrADC%1.2f\n",
523                 adcZN1[t],(corrCoeff1[t]*adcZN1oot[t]+corrCoeff0[t]),tZN1Corr[t]);
524        printf(" lg ->  rawADC %d\tpedestal%1.2f\tcorrADC%1.2f\n",
525                 adcZN1lg[t],(corrCoeff1[t+kNch]*adcZN1ootlg[t]+corrCoeff0[t+kNch]),tZN1Corr[t+5]);
526        //
527        printf("ZP1 ->  rawADC %d\tpedestal%1.2f\tcorrADC%1.2f\n",
528                 adcZP1[t],(corrCoeff1[t+5]*adcZP1oot[t]+corrCoeff0[t+5]),tZP1Corr[t]);
529        printf(" lg ->  rawADC %d\tpedestal%1.2f\tcorrADC%1.2f\n",
530                 adcZP1lg[t],(corrCoeff1[t+5+kNch]*adcZP1ootlg[t]+corrCoeff0[t+5+kNch]),tZP1Corr[t+5]);
531        //
532        printf("ZN2 ->  rawADC %d\tpedestal%1.2f\tcorrADC%1.2f\n",
533                 adcZN2[t],(corrCoeff1[t+12]*adcZN2oot[t]+corrCoeff0[t+12]),tZN2Corr[t]);
534        printf(" lg ->  rawADC %d\tpedestal%1.2f\tcorrADC%1.2f\n",
535                 adcZN2lg[t],(corrCoeff1[t+12+kNch]*adcZN2ootlg[t]+corrCoeff0[t+12+kNch]),tZN2Corr[t+5]);
536        //
537        printf("ZP2 ->  rawADC %d\tpedestal%1.2f\tcorrADC%1.2f\n",
538                 adcZP2[t],(corrCoeff1[t+17]*adcZP2oot[t]+corrCoeff0[t+17]),tZP2Corr[t]);
539        printf(" lg ->  rawADC %d\tpedestal%1.2f\tcorrADC%1.2f\n",
540                 adcZP2lg[t],(corrCoeff1[t+17+kNch]*adcZP2ootlg[t]+corrCoeff0[t+17+kNch]),tZP2Corr[t+5]);
541 */
542     }
543     dZEM1Corr[0] = adcZEM[0]   - (corrCoeff1[9]*adcZEMoot[0]+corrCoeff0[9]);
544     dZEM1Corr[1] = adcZEMlg[0] - (corrCoeff1[9+kNch]*adcZEMootlg[0]+corrCoeff0[9+kNch]);
545     dZEM2Corr[0] = adcZEM[1]   - (corrCoeff1[10]*adcZEMoot[1]+corrCoeff0[10]);
546     dZEM2Corr[1] = adcZEMlg[1] - (corrCoeff1[10+kNch]*adcZEMootlg[1]+corrCoeff0[10+kNch]);
547     //
548     sPMRef1[0] = pmRef[0]   - (corrCoeff1[22]*pmRefoot[0]+corrCoeff0[22]);
549     sPMRef1[1] = pmReflg[0] - (corrCoeff1[22+kNch]*pmRefootlg[0]+corrCoeff0[22+kNch]);
550     sPMRef2[0] = pmRef[0]   - (corrCoeff1[23]*pmRefoot[1]+corrCoeff0[23]);
551     sPMRef2[1] = pmReflg[0] - (corrCoeff1[23+kNch]*pmRefootlg[1]+corrCoeff0[23+kNch]);
552   }
553     
554   if(fRecoMode==1) // p-p data
555     ReconstructEventpp(clustersTree, tZN1Corr, tZP1Corr, tZN2Corr, tZP2Corr, 
556       dZEM1Corr, dZEM2Corr, sPMRef1, sPMRef2, 
557       isScalerOn, scalerData, 
558       evQualityBlock, triggerBlock, chBlock, puBits);
559   else if(fRecoMode==2) // Pb-Pb data
560     ReconstructEventPbPb(clustersTree, tZN1Corr, tZP1Corr, tZN2Corr, tZP2Corr, 
561       dZEM1Corr, dZEM2Corr, sPMRef1, sPMRef2, 
562       isScalerOn, scalerData, 
563       evQualityBlock, triggerBlock, chBlock, puBits);
564 }
565
566 //_____________________________________________________________________________
567 void AliZDCReconstructor::ReconstructEventpp(TTree *clustersTree, Float_t* corrADCZN1, 
568         Float_t* corrADCZP1, Float_t* corrADCZN2, Float_t* corrADCZP2,
569         Float_t* corrADCZEM1, Float_t* corrADCZEM2, Float_t* sPMRef1, Float_t* sPMRef2,
570         Bool_t isScalerOn, UInt_t* scaler, 
571         Int_t* evQualityBlock, Int_t* triggerBlock, Int_t* chBlock, UInt_t puBits) const
572 {
573   // ****************** Reconstruct one event ******************
574   
575   // CH. debug
576   /*printf("\n*************************************************\n");
577   printf(" ReconstructEventpp -> values after pedestal subtraction:\n");
578   printf(" ADCZN1 [%1.2f %1.2f %1.2f %1.2f %1.2f]\n",
579         corrADCZN1[0],corrADCZN1[1],corrADCZN1[2],corrADCZN1[3],corrADCZN1[4]);
580   printf(" ADCZP1 [%1.2f %1.2f %1.2f %1.2f %1.2f]\n",
581         corrADCZP1[0],corrADCZP1[1],corrADCZP1[2],corrADCZP1[3],corrADCZP1[4]);
582   printf(" ADCZN2 [%1.2f %1.2f %1.2f %1.2f %1.2f]\n",
583         corrADCZN2[0],corrADCZN2[1],corrADCZN2[2],corrADCZN2[3],corrADCZN2[4]);
584   printf(" ADCZP2 [%1.2f %1.2f %1.2f %1.2f %1.2f]\n",
585         corrADCZP2[0],corrADCZP2[1],corrADCZP2[2],corrADCZP2[3],corrADCZP2[4]);
586   printf(" ADCZEM1 [%1.2f] ADCZEM2 [%1.2f] \n",corrADCZEM1[0],corrADCZEM2[0]);
587   printf("*************************************************\n");*/
588     
589   // ---------------------- Setting reco flags for ESD
590   UInt_t rFlags[32];
591   for(Int_t ifl=0; ifl<32; ifl++) rFlags[ifl]=0;
592   
593   if(evQualityBlock[0] == 1) rFlags[31] = 0x0;
594   else rFlags[31] = 0x1;
595   //
596   if(evQualityBlock[1] == 1) rFlags[30] = 0x1;
597   if(evQualityBlock[2] == 1) rFlags[29] = 0x1;
598   if(evQualityBlock[3] == 1) rFlags[28] = 0x1;
599
600   if(triggerBlock[0] == 1) rFlags[27] = 0x1;
601   if(triggerBlock[1] == 1) rFlags[26] = 0x1;
602   if(triggerBlock[2] == 1) rFlags[25] = 0x1;
603   if(triggerBlock[3] == 1) rFlags[24] = 0x1;
604   
605   if(chBlock[0] == 1) rFlags[18] = 0x1;
606   if(chBlock[1] == 1) rFlags[17] = 0x1;
607   if(chBlock[2] == 1) rFlags[16] = 0x1;
608   
609   
610   rFlags[13] = puBits & 0x00000020;
611   rFlags[12] = puBits & 0x00000010;
612   rFlags[11] = puBits & 0x00000080;
613   rFlags[10] = puBits & 0x00000040;
614   rFlags[9]  = puBits & 0x00000020;
615   rFlags[8]  = puBits & 0x00000010;
616   
617   if(corrADCZP1[0]>fSignalThreshold)  rFlags[5] = 0x1;
618   if(corrADCZN1[0]>fSignalThreshold)  rFlags[4] = 0x1;
619   if(corrADCZEM2[0]>fSignalThreshold) rFlags[3] = 0x1;
620   if(corrADCZEM1[0]>fSignalThreshold) rFlags[2] = 0x1;
621   if(corrADCZP2[0]>fSignalThreshold)  rFlags[1] = 0x1;
622   if(corrADCZN2[0]>fSignalThreshold)  rFlags[0] = 0x1;
623
624   UInt_t recoFlag = rFlags[31] << 31 | rFlags[30] << 30 | rFlags[29] << 29 | rFlags[28] << 28 |
625              rFlags[27] << 27 | rFlags[26] << 26 | rFlags[25] << 25 | rFlags[24] << 24 |
626              0x0 << 23 | 0x0 << 22 | 0x0 << 21 | 0x0 << 20 |
627              0x0 << 19 | rFlags[18] << 18 |  rFlags[17] << 17 |  rFlags[16] << 16 |
628              0x0 << 15 | 0x0 << 14 | rFlags[13] << 13 | rFlags[12] << 12 | 
629              rFlags[11] << 11 |rFlags[10] << 10 | rFlags[9] << 9 | rFlags[8] << 8 |
630              0x0 << 7 | 0x0 << 6 | rFlags[5] << 5 | rFlags[4] << 4 | 
631              rFlags[3] << 3 | rFlags[2] << 2 | rFlags[1] << 1 | rFlags[0];
632   // --------------------------------------------------
633
634   // ******     Retrieving calibration data 
635   // --- Equalization coefficients ---------------------------------------------
636   Float_t equalCoeffZN1[5], equalCoeffZP1[5], equalCoeffZN2[5], equalCoeffZP2[5];
637   for(Int_t ji=0; ji<5; ji++){
638      equalCoeffZN1[ji] = fTowCalibData->GetZN1EqualCoeff(ji);
639      equalCoeffZP1[ji] = fTowCalibData->GetZP1EqualCoeff(ji); 
640      equalCoeffZN2[ji] = fTowCalibData->GetZN2EqualCoeff(ji); 
641      equalCoeffZP2[ji] = fTowCalibData->GetZP2EqualCoeff(ji); 
642   }
643   // --- Energy calibration factors ------------------------------------
644   Float_t calibEne[4];
645   // **** Energy calibration coefficient set to 1 
646   // **** (no trivial way to calibrate in p-p runs)
647   for(Int_t ij=0; ij<6; ij++) calibEne[ij] = fEnCalibData->GetEnCalib(ij);
648   
649   // ******     Equalization of detector responses
650   Float_t equalTowZN1[10], equalTowZN2[10], equalTowZP1[10], equalTowZP2[10];
651   for(Int_t gi=0; gi<10; gi++){
652      if(gi<5){
653        equalTowZN1[gi] = corrADCZN1[gi]*equalCoeffZN1[gi];
654        equalTowZP1[gi] = corrADCZP1[gi]*equalCoeffZP1[gi];
655        equalTowZN2[gi] = corrADCZN2[gi]*equalCoeffZN2[gi];
656        equalTowZP2[gi] = corrADCZP2[gi]*equalCoeffZP2[gi];
657      }
658      else{
659        equalTowZN1[gi] = corrADCZN1[gi]*equalCoeffZN1[gi-5];
660        equalTowZP1[gi] = corrADCZP1[gi]*equalCoeffZP1[gi-5];
661        equalTowZN2[gi] = corrADCZN2[gi]*equalCoeffZN2[gi-5];
662        equalTowZP2[gi] = corrADCZP2[gi]*equalCoeffZP2[gi-5];
663      }
664   }
665   // Ch. debug
666   /*printf("\n ------------- EQUALIZATION -------------\n");
667   printf(" ADCZN1 [%1.2f %1.2f %1.2f %1.2f %1.2f]\n",
668         equalTowZN1[0],equalTowZN1[1],equalTowZN1[2],equalTowZN1[3],equalTowZN1[4]);
669   printf(" ADCZP1 [%1.2f %1.2f %1.2f %1.2f %1.2f]\n",
670         equalTowZP1[0],equalTowZP1[1],equalTowZP1[2],equalTowZP1[3],equalTowZP1[4]);
671   printf(" ADCZN2 [%1.2f %1.2f %1.2f %1.2f %1.2f]\n",
672         equalTowZN2[0],equalTowZN2[1],equalTowZN2[2],equalTowZN2[3],equalTowZN2[4]);
673   printf(" ADCZP2 [%1.2f %1.2f %1.2f %1.2f %1.2f]\n",
674         equalTowZP2[0],equalTowZP2[1],equalTowZP2[2],equalTowZP2[3],equalTowZP2[4]);
675   printf(" ----------------------------------------\n");*/
676   
677   // ******     Summed response for hadronic calorimeter (SUMMED and then CALIBRATED!)
678   Float_t calibSumZN1[]={0,0}, calibSumZN2[]={0,0}, calibSumZP1[]={0,0}, calibSumZP2[]={0,0};
679   for(Int_t gi=0; gi<5; gi++){
680        calibSumZN1[0] += equalTowZN1[gi];
681        calibSumZP1[0] += equalTowZP1[gi];
682        calibSumZN2[0] += equalTowZN2[gi];
683        calibSumZP2[0] += equalTowZP2[gi];
684        //
685        calibSumZN1[1] += equalTowZN1[gi+5];
686        calibSumZP1[1] += equalTowZP1[gi+5];
687        calibSumZN2[1] += equalTowZN2[gi+5];
688        calibSumZP2[1] += equalTowZP2[gi+5];
689   }
690   // High gain chain
691   calibSumZN1[0] = calibSumZN1[0]*calibEne[0];
692   calibSumZP1[0] = calibSumZP1[0]*calibEne[1];
693   calibSumZN2[0] = calibSumZN2[0]*calibEne[2];
694   calibSumZP2[0] = calibSumZP2[0]*calibEne[3];
695   // Low gain chain
696   calibSumZN1[1] = calibSumZN1[1]*calibEne[0];
697   calibSumZP1[1] = calibSumZP1[1]*calibEne[1];
698   calibSumZN2[1] = calibSumZN2[1]*calibEne[2];
699   calibSumZP2[1] = calibSumZP2[1]*calibEne[3];
700   
701   // ******     Energy calibration of detector responses
702   Float_t calibTowZN1[10], calibTowZN2[10], calibTowZP1[10], calibTowZP2[10];
703   for(Int_t gi=0; gi<5; gi++){
704      // High gain chain
705      calibTowZN1[gi] = equalTowZN1[gi]*calibEne[0];
706      calibTowZP1[gi] = equalTowZP1[gi]*calibEne[1];
707      calibTowZN2[gi] = equalTowZN2[gi]*calibEne[2];
708      calibTowZP2[gi] = equalTowZP2[gi]*calibEne[3];
709      // Low gain chain
710      calibTowZN1[gi+5] = equalTowZN1[gi+5]*calibEne[0];
711      calibTowZP1[gi+5] = equalTowZP1[gi+5]*calibEne[1];
712      calibTowZN2[gi+5] = equalTowZN2[gi+5]*calibEne[2];
713      calibTowZP2[gi+5] = equalTowZP2[gi+5]*calibEne[3];
714   }
715   //
716   Float_t sumZEM[]={0,0}, calibZEM1[]={0,0}, calibZEM2[]={0,0};
717   calibZEM1[0] = corrADCZEM1[0]*calibEne[5];
718   calibZEM1[1] = corrADCZEM1[1]*calibEne[5];
719   calibZEM2[0] = corrADCZEM2[0]*calibEne[5];
720   calibZEM2[1] = corrADCZEM2[1]*calibEne[5];
721   for(Int_t k=0; k<2; k++) sumZEM[k] = calibZEM1[k] + calibZEM2[k];
722   // Ch. debug
723   /*printf("\n ------------- CALIBRATION -------------\n");
724   printf(" ADCZN1 [%1.2f %1.2f %1.2f %1.2f %1.2f]\n",
725         calibTowZN1[0],calibTowZN1[1],calibTowZN1[2],calibTowZN1[3],calibTowZN1[4]);
726   printf(" ADCZP1 [%1.2f %1.2f %1.2f %1.2f %1.2f]\n",
727         calibTowZP1[0],calibTowZP1[1],calibTowZP1[2],calibTowZP1[3],calibTowZP1[4]);
728   printf(" ADCZN2 [%1.2f %1.2f %1.2f %1.2f %1.2f]\n",
729         calibTowZN2[0],calibTowZN2[1],calibTowZN2[2],calibTowZN2[3],calibTowZN2[4]);
730   printf(" ADCZP2 [%1.2f %1.2f %1.2f %1.2f %1.2f]\n",
731         calibTowZP2[0],calibTowZP2[1],calibTowZP2[2],calibTowZP2[3],calibTowZP2[4]);
732   printf(" ADCZEM1 [%1.2f] ADCZEM2 [%1.2f] \n",calibZEM1[0],calibZEM2[0]);
733   printf(" ----------------------------------------\n");*/
734   
735   //  ******    No. of spectator and participants nucleons
736   //  Variables calculated to comply with ESD structure
737   //  *** N.B. -> They have a meaning only in Pb-Pb!!!!!!!!!!!!
738   Int_t nDetSpecNLeft=0, nDetSpecPLeft=0, nDetSpecNRight=0, nDetSpecPRight=0;
739   Int_t nGenSpec=0, nGenSpecLeft=0, nGenSpecRight=0;
740   Int_t nPart=0, nPartTotLeft=0, nPartTotRight=0;
741   Double_t impPar=0., impPar1=0., impPar2=0.;
742   
743   // create the output tree
744   AliZDCReco* reco = new AliZDCReco(calibSumZN1, calibSumZP1, calibSumZN2, calibSumZP2, 
745                    calibTowZN1, calibTowZP1, calibTowZN2, calibTowZP2, 
746                    calibZEM1, calibZEM2, sPMRef1, sPMRef2,
747                    nDetSpecNLeft, nDetSpecPLeft, nDetSpecNRight, nDetSpecPRight, 
748                    nGenSpec, nGenSpecLeft, nGenSpecRight, 
749                    nPart, nPartTotLeft, nPartTotRight, 
750                    impPar, impPar1, impPar2,
751                    recoFlag, isScalerOn, scaler);
752                   
753   const Int_t kBufferSize = 4000;
754   clustersTree->Branch("ZDC", "AliZDCReco", &reco, kBufferSize);
755   // write the output tree
756   clustersTree->Fill();
757 }
758
759 //_____________________________________________________________________________
760 void AliZDCReconstructor::ReconstructEventPbPb(TTree *clustersTree, 
761         Float_t* corrADCZN1, Float_t* corrADCZP1, Float_t* corrADCZN2, Float_t* corrADCZP2,
762         Float_t* corrADCZEM1, Float_t* corrADCZEM2, Float_t* sPMRef1, Float_t* sPMRef2,
763         Bool_t isScalerOn, UInt_t* scaler, 
764         Int_t* evQualityBlock, Int_t* triggerBlock, Int_t* chBlock, UInt_t puBits) const
765 {
766   // ****************** Reconstruct one event ******************
767   // ---------------------- Setting reco flags for ESD
768   UInt_t rFlags[32];
769   for(Int_t ifl=0; ifl<32; ifl++) rFlags[ifl]=0;
770   
771   if(evQualityBlock[0] == 1) rFlags[31] = 0x0;
772   else rFlags[31] = 0x1;
773   //
774   if(evQualityBlock[1] == 1) rFlags[30] = 0x1;
775   if(evQualityBlock[2] == 1) rFlags[29] = 0x1;
776   if(evQualityBlock[3] == 1) rFlags[28] = 0x1;
777
778   if(triggerBlock[0] == 1) rFlags[27] = 0x1;
779   if(triggerBlock[1] == 1) rFlags[26] = 0x1;
780   if(triggerBlock[2] == 1) rFlags[25] = 0x1;
781   if(triggerBlock[3] == 1) rFlags[24] = 0x1;
782   
783   if(chBlock[0] == 1) rFlags[18] = 0x1;
784   if(chBlock[1] == 1) rFlags[17] = 0x1;
785   if(chBlock[2] == 1) rFlags[16] = 0x1;
786   
787   rFlags[13] = puBits & 0x00000020;
788   rFlags[12] = puBits & 0x00000010;
789   rFlags[11] = puBits & 0x00000080;
790   rFlags[10] = puBits & 0x00000040;
791   rFlags[9]  = puBits & 0x00000020;
792   rFlags[8]  = puBits & 0x00000010;  
793   
794   if(corrADCZP1[0]>fSignalThreshold)  rFlags[5] = 0x1;
795   if(corrADCZN1[0]>fSignalThreshold)  rFlags[4] = 0x1;
796   if(corrADCZEM2[0]>fSignalThreshold) rFlags[3] = 0x1;
797   if(corrADCZEM1[0]>fSignalThreshold) rFlags[2] = 0x1;
798   if(corrADCZP2[0]>fSignalThreshold)  rFlags[1] = 0x1;
799   if(corrADCZN2[0]>fSignalThreshold)  rFlags[0] = 0x1;
800
801   UInt_t recoFlag = rFlags[31] << 31 | rFlags[30] << 30 | rFlags[29] << 29 | rFlags[28] << 28 |
802              rFlags[27] << 27 | rFlags[26] << 26 | rFlags[25] << 25 | rFlags[24] << 24 |
803              0x0 << 23 | 0x0 << 22 | 0x0 << 21 | 0x0 << 20 |
804              0x0 << 19 | rFlags[18] << 18 |  rFlags[17] << 17 |  rFlags[16] << 16 |
805              0x0 << 15 | 0x0 << 14 | rFlags[13] << 13 | rFlags[12] << 12 | 
806              rFlags[11] << 11 |rFlags[10] << 10 | rFlags[9] << 9 | rFlags[8] << 8 |
807              0x0 << 7 | 0x0 << 6 | rFlags[5] << 5 | rFlags[4] << 4 | 
808              rFlags[3] << 3 | rFlags[2] << 2 | rFlags[1] << 1 | rFlags[0];
809   // --------------------------------------------------
810   
811
812   // ******     Retrieving calibration data 
813   // --- Equalization coefficients ---------------------------------------------
814   Float_t equalCoeffZN1[5], equalCoeffZP1[5], equalCoeffZN2[5], equalCoeffZP2[5];
815   for(Int_t ji=0; ji<5; ji++){
816      equalCoeffZN1[ji] = fTowCalibData->GetZN1EqualCoeff(ji);
817      equalCoeffZP1[ji] = fTowCalibData->GetZP1EqualCoeff(ji); 
818      equalCoeffZN2[ji] = fTowCalibData->GetZN2EqualCoeff(ji); 
819      equalCoeffZP2[ji] = fTowCalibData->GetZP2EqualCoeff(ji); 
820   }
821   // --- Energy calibration factors ------------------------------------
822   Float_t valFromOCDB[6], calibEne[6];
823   for(Int_t ij=0; ij<6; ij++){
824     valFromOCDB[ij] = fEnCalibData->GetEnCalib(ij);
825     if(ij<4){
826       if(valFromOCDB[ij]!=0) calibEne[ij] = fBeamEnergy/valFromOCDB[ij];
827       else AliWarning(" Value from OCDB for E calibration = 0 !!!\n");
828     } 
829     else calibEne[ij] = valFromOCDB[ij];
830   }
831   
832   // ******     Equalization of detector responses
833   Float_t equalTowZN1[10], equalTowZN2[10], equalTowZP1[10], equalTowZP2[10];
834   for(Int_t gi=0; gi<10; gi++){
835      if(gi<5){
836        equalTowZN1[gi] = corrADCZN1[gi]*equalCoeffZN1[gi];
837        equalTowZP1[gi] = corrADCZP1[gi]*equalCoeffZP1[gi];
838        equalTowZN2[gi] = corrADCZN2[gi]*equalCoeffZN2[gi];
839        equalTowZP2[gi] = corrADCZP2[gi]*equalCoeffZP2[gi];
840      }
841      else{
842        equalTowZN1[gi] = corrADCZN1[gi]*equalCoeffZN1[gi-5];
843        equalTowZP1[gi] = corrADCZP1[gi]*equalCoeffZP1[gi-5];
844        equalTowZN2[gi] = corrADCZN2[gi]*equalCoeffZN2[gi-5];
845        equalTowZP2[gi] = corrADCZP2[gi]*equalCoeffZP2[gi-5];
846      }
847   }
848   
849   // ******     Summed response for hadronic calorimeter (SUMMED and then CALIBRATED!)
850   Float_t calibSumZN1[]={0,0}, calibSumZN2[]={0,0}, calibSumZP1[]={0,0}, calibSumZP2[]={0,0};
851   for(Int_t gi=0; gi<5; gi++){
852        calibSumZN1[0] += equalTowZN1[gi];
853        calibSumZP1[0] += equalTowZP1[gi];
854        calibSumZN2[0] += equalTowZN2[gi];
855        calibSumZP2[0] += equalTowZP2[gi];
856        //
857        calibSumZN1[1] += equalTowZN1[gi+5];
858        calibSumZP1[1] += equalTowZP1[gi+5];
859        calibSumZN2[1] += equalTowZN2[gi+5];
860        calibSumZP2[1] += equalTowZP2[gi+5];
861   }
862   // High gain chain
863   calibSumZN1[0] = calibSumZN1[0]*calibEne[0]*8.;
864   calibSumZP1[0] = calibSumZP1[0]*calibEne[1]*8.;
865   calibSumZN2[0] = calibSumZN2[0]*calibEne[2]*8.;
866   calibSumZP2[0] = calibSumZP2[0]*calibEne[3]*8.;
867   // Low gain chain
868   calibSumZN1[1] = calibSumZN1[1]*calibEne[0];
869   calibSumZP1[1] = calibSumZP1[1]*calibEne[1];
870   calibSumZN2[1] = calibSumZN2[1]*calibEne[2];
871   calibSumZP2[1] = calibSumZP2[1]*calibEne[3];
872   //
873   Float_t sumZEM[]={0,0}, calibZEM1[]={0,0}, calibZEM2[]={0,0};
874   calibZEM1[0] = corrADCZEM1[0]*calibEne[5]*8.;
875   calibZEM1[1] = corrADCZEM1[1]*calibEne[5];
876   calibZEM2[0] = corrADCZEM2[0]*calibEne[5]*8.;
877   calibZEM2[1] = corrADCZEM2[1]*calibEne[5];
878   for(Int_t k=0; k<2; k++) sumZEM[k] = calibZEM1[k] + calibZEM2[k];
879     
880   // ******     Energy calibration of detector responses
881   Float_t calibTowZN1[10], calibTowZN2[10], calibTowZP1[10], calibTowZP2[10];
882   for(Int_t gi=0; gi<5; gi++){
883      // High gain chain
884      calibTowZN1[gi] = equalTowZN1[gi]*calibEne[0]*8.;
885      calibTowZP1[gi] = equalTowZP1[gi]*calibEne[1]*8.;
886      calibTowZN2[gi] = equalTowZN2[gi]*calibEne[2]*8.;
887      calibTowZP2[gi] = equalTowZP2[gi]*calibEne[3]*8.;
888      // Low gain chain
889      calibTowZN1[gi+5] = equalTowZN1[gi+5]*calibEne[0];
890      calibTowZP1[gi+5] = equalTowZP1[gi+5]*calibEne[1];
891      calibTowZN2[gi+5] = equalTowZN2[gi+5]*calibEne[2];
892      calibTowZP2[gi+5] = equalTowZP2[gi+5]*calibEne[3];
893   }
894   
895   //  ******    Number of detected spectator nucleons
896   Int_t nDetSpecNLeft=0, nDetSpecPLeft=0, nDetSpecNRight=0, nDetSpecPRight=0;
897   if(fBeamEnergy!=0){
898     nDetSpecNLeft = (Int_t) (calibSumZN1[0]/fBeamEnergy);
899     nDetSpecPLeft = (Int_t) (calibSumZP1[0]/fBeamEnergy);
900     nDetSpecNRight = (Int_t) (calibSumZN2[0]/fBeamEnergy);
901     nDetSpecPRight = (Int_t) (calibSumZP2[0]/fBeamEnergy);
902   }
903   else AliWarning(" ATTENTION!!! fBeamEnergy=0 -> N_spec will be ZERO!!! \n");
904   /*printf("\n\t AliZDCReconstructor -> nDetSpecNLeft %d, nDetSpecPLeft %d,"
905     " nDetSpecNRight %d, nDetSpecPRight %d\n",nDetSpecNLeft, nDetSpecPLeft, 
906     nDetSpecNRight, nDetSpecPRight);*/
907   
908   Int_t nGenSpec=0, nGenSpecA=0, nGenSpecC=0;
909   Int_t nPart=0, nPartA=0, nPartC=0;
910   Double_t b=0., bA=0., bC=0.;
911   
912   if(fIsCalibrationMB == kFALSE){
913     // ******   Reconstruction parameters ------------------ 
914     // Ch. debug
915     //fRecoParam->Print("");
916     //
917  
918     if (!fRecoParam) fRecoParam = const_cast<AliZDCRecoParam*>(GetRecoParam()); 
919  
920     TH2F *hZDCvsZEM  = fRecoParam->GethZDCvsZEM();
921     TH2F *hZDCCvsZEM = fRecoParam->GethZDCCvsZEM();
922     TH2F *hZDCAvsZEM = fRecoParam->GethZDCAvsZEM();
923     TH1D *hNpartDist = fRecoParam->GethNpartDist();
924     TH1D *hbDist = fRecoParam->GethbDist();    
925     Float_t ClkCenter = fRecoParam->GetClkCenter();
926     //
927     Double_t xHighEdge = hZDCvsZEM->GetXaxis()->GetXmax();
928     Double_t origin = xHighEdge*ClkCenter;
929     // Ch. debug
930     //printf("\n\n  xHighEdge %1.2f, origin %1.4f \n", xHighEdge, origin);
931     //
932     // ====> Summed ZDC info (sideA+side C)
933     TF1 *line = new TF1("line","[0]*x+[1]",0.,xHighEdge);
934     Float_t y = (calibSumZN1[0]+calibSumZP1[0]+calibSumZN2[0]+calibSumZP2[0])/1000.;
935     Float_t x = (calibZEM1[0]+calibZEM2[0])/1000.;
936     line->SetParameter(0, y/(x-origin));
937     line->SetParameter(1, -origin*y/(x-origin));
938     // Ch. debug
939     //printf("  ***************** Summed ZDC info (sideA+side C) \n");
940     //printf("  E_{ZEM} %1.4f, E_{ZDC} %1.2f, TF1: %1.2f*x + %1.2f   ", x, y,y/(x-origin),-origin*y/(x-origin));
941     //
942     Double_t countPerc=0;
943     Double_t xBinCenter=0, yBinCenter=0;
944     for(Int_t nbinx=1; nbinx<=hZDCvsZEM->GetNbinsX(); nbinx++){
945       for(Int_t nbiny=1; nbiny<=hZDCvsZEM->GetNbinsY(); nbiny++){
946          xBinCenter = hZDCvsZEM->GetXaxis()->GetBinCenter(nbinx);
947          yBinCenter = hZDCvsZEM->GetYaxis()->GetBinCenter(nbiny);
948          //
949          if(line->GetParameter(0)>0){
950            if(yBinCenter < (line->GetParameter(0)*xBinCenter + line->GetParameter(1))){
951              countPerc += hZDCvsZEM->GetBinContent(nbinx,nbiny);
952              // Ch. debug
953              /*printf(" xBinCenter  %1.3f, yBinCenter %1.0f,  countPerc %1.0f\n", 
954                 xBinCenter, yBinCenter, countPerc);*/
955            }
956          }
957          else{
958            if(yBinCenter > (line->GetParameter(0)*xBinCenter + line->GetParameter(1))){
959              countPerc += hZDCvsZEM->GetBinContent(nbinx,nbiny);
960              // Ch. debug
961              /*printf(" xBinCenter  %1.3f, yBinCenter %1.0f,  countPerc %1.0f\n", 
962                 xBinCenter, yBinCenter, countPerc);*/
963            }
964          }
965       }
966     }
967     //
968     Double_t xSecPerc = 0.;
969     if(hZDCvsZEM->GetEntries()!=0){ 
970       xSecPerc = countPerc/hZDCvsZEM->GetEntries();
971     }
972     else{
973       AliWarning("  Histogram hZDCvsZEM from OCDB has no entries!!!");
974     }
975     // Ch. debug
976     //printf("  xSecPerc %1.4f  \n", xSecPerc);
977
978     // ====> side C
979     TF1 *lineC = new TF1("lineC","[0]*x+[1]",0.,xHighEdge);
980     Float_t yC = (calibSumZN1[0]+calibSumZP1[0])/1000.;
981     lineC->SetParameter(0, yC/(x-origin));
982     lineC->SetParameter(1, -origin*yC/(x-origin));
983     // Ch. debug
984     //printf("  ***************** Side C \n");
985     //printf("  E_{ZEM} %1.4f, E_{ZDCC} %1.2f, TF1: %1.2f*x + %1.2f   ", x, yC,yC/(x-origin),-origin*yC/(x-origin));
986     //
987     Double_t countPercC=0;
988     Double_t xBinCenterC=0, yBinCenterC=0;
989     for(Int_t nbinx=1; nbinx<=hZDCCvsZEM->GetNbinsX(); nbinx++){
990       for(Int_t nbiny=1; nbiny<=hZDCCvsZEM->GetNbinsY(); nbiny++){
991          xBinCenterC = hZDCCvsZEM->GetXaxis()->GetBinCenter(nbinx);
992          yBinCenterC = hZDCCvsZEM->GetYaxis()->GetBinCenter(nbiny);
993          if(lineC->GetParameter(0)>0){
994            if(yBinCenterC < (lineC->GetParameter(0)*xBinCenterC + lineC->GetParameter(1))){
995              countPercC += hZDCCvsZEM->GetBinContent(nbinx,nbiny);
996            }
997          }
998          else{
999            if(yBinCenterC > (lineC->GetParameter(0)*xBinCenterC + lineC->GetParameter(1))){
1000              countPercC += hZDCCvsZEM->GetBinContent(nbinx,nbiny);
1001            }
1002          }
1003       }
1004     }
1005     //
1006     Double_t xSecPercC = 0.;
1007     if(hZDCCvsZEM->GetEntries()!=0){ 
1008       xSecPercC = countPercC/hZDCCvsZEM->GetEntries();
1009     }
1010     else{
1011       AliWarning("  Histogram hZDCCvsZEM from OCDB has no entries!!!");
1012     }
1013     // Ch. debug
1014     //printf("  xSecPercC %1.4f  \n", xSecPercC);
1015     
1016     // ====> side A
1017     TF1 *lineA = new TF1("lineA","[0]*x+[1]",0.,xHighEdge);
1018     Float_t yA = (calibSumZN2[0]+calibSumZP2[0])/1000.;
1019     lineA->SetParameter(0, yA/(x-origin));
1020     lineA->SetParameter(1, -origin*yA/(x-origin));
1021     //
1022     // Ch. debug
1023     //printf("  ***************** Side A \n");
1024     //printf("  E_{ZEM} %1.4f, E_{ZDCA} %1.2f, TF1: %1.2f*x + %1.2f   ", x, yA,yA/(x-origin),-origin*yA/(x-origin));
1025     //
1026     Double_t countPercA=0;
1027     Double_t xBinCenterA=0, yBinCenterA=0;
1028     for(Int_t nbinx=1; nbinx<=hZDCAvsZEM->GetNbinsX(); nbinx++){
1029       for(Int_t nbiny=1; nbiny<=hZDCAvsZEM->GetNbinsY(); nbiny++){
1030          xBinCenterA = hZDCAvsZEM->GetXaxis()->GetBinCenter(nbinx);
1031          yBinCenterA = hZDCAvsZEM->GetYaxis()->GetBinCenter(nbiny);
1032          if(lineA->GetParameter(0)>0){
1033            if(yBinCenterA < (lineA->GetParameter(0)*xBinCenterA + lineA->GetParameter(1))){
1034              countPercA += hZDCAvsZEM->GetBinContent(nbinx,nbiny);
1035            }
1036          }
1037          else{
1038            if(yBinCenterA > (lineA->GetParameter(0)*xBinCenterA + lineA->GetParameter(1))){
1039              countPercA += hZDCAvsZEM->GetBinContent(nbinx,nbiny);
1040            }
1041          }
1042       }
1043     }
1044     //
1045     Double_t xSecPercA = 0.;
1046     if(hZDCAvsZEM->GetEntries()!=0){ 
1047       xSecPercA = countPercA/hZDCAvsZEM->GetEntries();
1048     }
1049     else{
1050       AliWarning("  Histogram hZDCAvsZEM from OCDB has no entries!!!");
1051     }
1052     // Ch. debug
1053     //printf("  xSecPercA %1.4f  \n", xSecPercA);
1054     
1055     //  ******    Number of participants (from E_ZDC vs. E_ZEM correlation)
1056     Double_t nPartFrac=0., nPartFracC=0., nPartFracA=0.;
1057     for(Int_t npbin=1; npbin<hNpartDist->GetNbinsX(); npbin++){
1058       nPartFrac += (hNpartDist->GetBinContent(npbin))/(hNpartDist->GetEntries());
1059       if((1.-nPartFrac) < xSecPerc){
1060         nPart = (Int_t) hNpartDist->GetBinLowEdge(npbin);
1061         // Ch. debug
1062         //printf("  ***************** Summed ZDC info (sideA+side C) \n");
1063         //printf("  nPartFrac %1.4f, nPart %d\n", nPartFrac, nPart);
1064         break;
1065       }
1066     }
1067     if(nPart<0) nPart=0;
1068     //
1069     for(Int_t npbin=1; npbin<hNpartDist->GetNbinsX(); npbin++){
1070       nPartFracC += (hNpartDist->GetBinContent(npbin))/(hNpartDist->GetEntries());
1071       if((1.-nPartFracC) < xSecPercC){
1072         nPartC = (Int_t) hNpartDist->GetBinLowEdge(npbin);
1073         // Ch. debug
1074         //printf("  ***************** Side C \n");
1075         //printf("  nPartFracC %1.4f, nPartC %d\n", nPartFracC, nPartC);
1076         break;
1077     }
1078     }
1079     if(nPartC<0) nPartC=0;
1080     //
1081     for(Int_t npbin=1; npbin<hNpartDist->GetNbinsX(); npbin++){
1082       nPartFracA += (hNpartDist->GetBinContent(npbin))/(hNpartDist->GetEntries());
1083       if((1.-nPartFracA) < xSecPercA){
1084         nPartA = (Int_t) hNpartDist->GetBinLowEdge(npbin);
1085         // Ch. debug
1086         //printf("  ***************** Side A \n");
1087         //printf("  nPartFracA %1.4f, nPartA %d\n\n", nPartFracA, nPartA);
1088         break;
1089       }
1090     }
1091     if(nPartA<0) nPartA=0;
1092     
1093     //  ******    Impact parameter (from E_ZDC vs. E_ZEM correlation)
1094     Double_t bFrac=0., bFracC=0., bFracA=0.;
1095     for(Int_t ibbin=1; ibbin<hbDist->GetNbinsX(); ibbin++){
1096       bFrac += (hbDist->GetBinContent(ibbin))/(hbDist->GetEntries());
1097       if((1.-bFrac) < xSecPerc){
1098         b = hbDist->GetBinLowEdge(ibbin);
1099         break;
1100       }
1101     }
1102     //
1103     for(Int_t ibbin=1; ibbin<hbDist->GetNbinsX(); ibbin++){
1104       bFracC += (hbDist->GetBinContent(ibbin))/(hbDist->GetEntries());
1105       if((1.-bFracC) < xSecPercC){
1106         bC = hbDist->GetBinLowEdge(ibbin);
1107         break;
1108       }
1109     }
1110     //
1111     for(Int_t ibbin=1; ibbin<hbDist->GetNbinsX(); ibbin++){
1112       bFracA += (hbDist->GetBinContent(ibbin))/(hNpartDist->GetEntries());
1113       if((1.-bFracA) < xSecPercA){
1114         bA = hbDist->GetBinLowEdge(ibbin);
1115         break;
1116       }
1117     }
1118
1119     //  ******  Number of spectator nucleons 
1120     nGenSpec = 416 - nPart;
1121     nGenSpecC = 416 - nPartC;
1122     nGenSpecA = 416 - nPartA;
1123     if(nGenSpec>416) nGenSpec=416; if(nGenSpec<0) nGenSpec=0;
1124     if(nGenSpecC>416) nGenSpecC=416; if(nGenSpecC<0) nGenSpecC=0;
1125     if(nGenSpecA>416) nGenSpecA=416; if(nGenSpecA<0) nGenSpecA=0;
1126   
1127     //  Ch. debug
1128     /*printf("\n\t AliZDCReconstructor -> calibSumZN1[0] %1.0f, calibSumZP1[0] %1.0f,"
1129         "  calibSumZN2[0] %1.0f, calibSumZP2[0] %1.0f, corrADCZEMHG %1.0f\n", 
1130         calibSumZN1[0],calibSumZP1[0],calibSumZN2[0],calibSumZP2[0],corrADCZEMHG);
1131     printf("\t AliZDCReconstructor -> nGenSpecLeft %d nGenSpecRight %d\n", 
1132         nGenSpecLeft, nGenSpecRight);
1133     printf("\t AliZDCReconstructor ->  NpartL %d,  NpartR %d,  b %1.2f fm\n\n",nPartTotLeft, nPartTotRight, impPar);
1134     */
1135   
1136     delete lineC;  delete lineA;
1137
1138   } // ONLY IF fIsCalibrationMB==kFALSE
1139   
1140   AliZDCReco* reco = new AliZDCReco(calibSumZN1, calibSumZP1, calibSumZN2, calibSumZP2, 
1141                   calibTowZN1, calibTowZP1, calibTowZN2, calibTowZP2, 
1142                   calibZEM1, calibZEM2, sPMRef1, sPMRef2,
1143                   nDetSpecNLeft, nDetSpecPLeft, nDetSpecNRight, nDetSpecPRight, 
1144                   nGenSpec, nGenSpecA, nGenSpecC, 
1145                   nPart, nPartA, nPartC, b, bA, bC,
1146                   recoFlag, isScalerOn, scaler);
1147                     
1148   const Int_t kBufferSize = 4000;
1149   clustersTree->Branch("ZDC", "AliZDCReco", &reco, kBufferSize);
1150   //reco->Print("");
1151   // write the output tree
1152   clustersTree->Fill();
1153 }
1154
1155 //_____________________________________________________________________________
1156 void AliZDCReconstructor::BuildRecoParam(Float_t ZDCC, Float_t ZDCA, Float_t ZEM) const
1157 {
1158   // Calculate RecoParam object for Pb-Pb data
1159   (fRecoParam->GethZDCvsZEM())->Fill(ZDCC+ZDCA, ZEM);
1160   (fRecoParam->GethZDCCvsZEM())->Fill(ZDCC, ZEM);
1161   (fRecoParam->GethZDCAvsZEM())->Fill(ZDCA, ZEM);
1162  
1163 }
1164
1165 //_____________________________________________________________________________
1166 void AliZDCReconstructor::FillZDCintoESD(TTree *clustersTree, AliESDEvent* esd) const
1167 {
1168   // fill energies and number of participants to the ESD
1169
1170   AliZDCReco reco;
1171   AliZDCReco* preco = &reco;
1172   clustersTree->SetBranchAddress("ZDC", &preco);
1173
1174   clustersTree->GetEntry(0);
1175   //
1176   AliESDZDC * esdzdc = esd->GetESDZDC();
1177   Float_t tZN1Ene[5], tZN2Ene[5], tZP1Ene[5], tZP2Ene[5];
1178   Float_t tZN1EneLR[5], tZN2EneLR[5], tZP1EneLR[5], tZP2EneLR[5];
1179   for(Int_t i=0; i<5; i++){
1180      tZN1Ene[i] = reco.GetZN1HREnTow(i);
1181      tZN2Ene[i] = reco.GetZN2HREnTow(i);
1182      tZP1Ene[i] = reco.GetZP1HREnTow(i);
1183      tZP2Ene[i] = reco.GetZP2HREnTow(i);
1184      //
1185      tZN1EneLR[i] = reco.GetZN1LREnTow(i);
1186      tZN2EneLR[i] = reco.GetZN2LREnTow(i);
1187      tZP1EneLR[i] = reco.GetZP1LREnTow(i);
1188      tZP2EneLR[i] = reco.GetZP2LREnTow(i);
1189   }
1190   //
1191   esdzdc->SetZN1TowerEnergy(tZN1Ene);
1192   esdzdc->SetZN2TowerEnergy(tZN2Ene);
1193   esdzdc->SetZP1TowerEnergy(tZP1Ene);
1194   esdzdc->SetZP2TowerEnergy(tZP2Ene);
1195   //
1196   esdzdc->SetZN1TowerEnergyLR(tZN1EneLR);
1197   esdzdc->SetZN2TowerEnergyLR(tZN2EneLR);
1198   esdzdc->SetZP1TowerEnergyLR(tZP1EneLR);
1199   esdzdc->SetZP2TowerEnergyLR(tZP2EneLR);
1200   // 
1201   Int_t nPart  = reco.GetNParticipants();
1202   Int_t nPartA = reco.GetNPartSideA();
1203   Int_t nPartC = reco.GetNPartSideC();
1204   Double_t b  = reco.GetImpParameter();
1205   Double_t bA = reco.GetImpParSideA();
1206   Double_t bC = reco.GetImpParSideC();
1207   UInt_t recoFlag = reco.GetRecoFlag();
1208   //
1209   esd->SetZDC(reco.GetZN1HREnergy(), reco.GetZP1HREnergy(), reco.GetZEM1HRsignal(), 
1210               reco.GetZEM2HRsignal(), reco.GetZN2HREnergy(), reco.GetZP2HREnergy(), 
1211               nPart, nPartA, nPartC, b, bA, bC, recoFlag);
1212   
1213   // Writing ZDC scaler for cross section calculation
1214   // ONLY IF the scaler has been read during the event
1215   if(reco.IsScalerOn()==kTRUE){
1216     UInt_t counts[32];
1217     for(Int_t jk=0; jk<32; jk++) counts[jk] = reco.GetZDCScaler(jk);
1218     esd->SetZDCScaler(counts);
1219   }
1220 }
1221
1222 //_____________________________________________________________________________
1223 AliCDBStorage* AliZDCReconstructor::SetStorage(const char *uri) 
1224 {
1225   // Setting the storage
1226
1227   Bool_t deleteManager = kFALSE;
1228   
1229   AliCDBManager *manager = AliCDBManager::Instance();
1230   AliCDBStorage *defstorage = manager->GetDefaultStorage();
1231   
1232   if(!defstorage || !(defstorage->Contains("ZDC"))){ 
1233      AliWarning("No default storage set or default storage doesn't contain ZDC!");
1234      manager->SetDefaultStorage(uri);
1235      deleteManager = kTRUE;
1236   }
1237  
1238   AliCDBStorage *storage = manager->GetDefaultStorage();
1239
1240   if(deleteManager){
1241     AliCDBManager::Instance()->UnsetDefaultStorage();
1242     defstorage = 0;   // the storage is killed by AliCDBManager::Instance()->Destroy()
1243   }
1244
1245   return storage; 
1246 }
1247
1248 //_____________________________________________________________________________
1249 AliZDCPedestals* AliZDCReconstructor::GetPedestalData() const
1250 {
1251
1252   // Getting pedestal calibration object for ZDC set
1253
1254   AliCDBEntry  *entry = AliCDBManager::Instance()->Get("ZDC/Calib/Pedestals");
1255   if(!entry) AliFatal("No calibration data loaded!");
1256   entry->SetOwner(kFALSE);
1257
1258   AliZDCPedestals *calibdata = dynamic_cast<AliZDCPedestals*>  (entry->GetObject());
1259   if(!calibdata)  AliFatal("Wrong calibration object in calibration  file!");
1260
1261   return calibdata;
1262 }
1263
1264 //_____________________________________________________________________________
1265 AliZDCEnCalib* AliZDCReconstructor::GetEnergyCalibData() const
1266 {
1267
1268   // Getting energy and equalization calibration object for ZDC set
1269
1270   AliCDBEntry  *entry = AliCDBManager::Instance()->Get("ZDC/Calib/EnergyCalib");
1271   if(!entry) AliFatal("No calibration data loaded!");  
1272   entry->SetOwner(kFALSE);
1273
1274   AliZDCEnCalib *calibdata = dynamic_cast<AliZDCEnCalib*> (entry->GetObject());
1275   if(!calibdata)  AliFatal("Wrong calibration object in calibration  file!");
1276
1277   return calibdata;
1278 }
1279
1280 //_____________________________________________________________________________
1281 AliZDCTowerCalib* AliZDCReconstructor::GetTowerCalibData() const
1282 {
1283
1284   // Getting energy and equalization calibration object for ZDC set
1285
1286   AliCDBEntry  *entry = AliCDBManager::Instance()->Get("ZDC/Calib/TowerCalib");
1287   if(!entry) AliFatal("No calibration data loaded!");  
1288   entry->SetOwner(kFALSE);
1289
1290   AliZDCTowerCalib *calibdata = dynamic_cast<AliZDCTowerCalib*> (entry->GetObject());
1291   if(!calibdata)  AliFatal("Wrong calibration object in calibration  file!");
1292
1293   return calibdata;
1294 }
1295
1296 //_____________________________________________________________________________
1297 AliZDCRecoParampp* AliZDCReconstructor::GetppRecoParamFromOCDB() const
1298 {
1299
1300   // Getting reconstruction parameters from OCDB
1301
1302   AliCDBEntry  *entry = AliCDBManager::Instance()->Get("ZDC/Calib/RecoParampp");
1303   if(!entry) AliFatal("No RecoParam data found in OCDB!");  
1304   
1305   AliZDCRecoParampp *param = dynamic_cast<AliZDCRecoParampp*> (entry->GetObject());
1306   if(!param)  AliFatal("No RecoParam object in OCDB entry!");
1307   
1308   return param;
1309
1310 }
1311
1312 //_____________________________________________________________________________
1313 AliZDCRecoParamPbPb* AliZDCReconstructor::GetPbPbRecoParamFromOCDB() const
1314 {
1315
1316   // Getting reconstruction parameters from OCDB
1317
1318   AliCDBEntry  *entry = AliCDBManager::Instance()->Get("ZDC/Calib/RecoParamPbPb");
1319   if(!entry) AliFatal("No RecoParam data found in OCDB!");  
1320   
1321   AliZDCRecoParamPbPb *param = dynamic_cast<AliZDCRecoParamPbPb*> (entry->GetObject());
1322   if(!param)  AliFatal("No RecoParam object in OCDB entry!");
1323   
1324   return param;
1325
1326 }