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