AliRsnReader:
[u/mrichter/AliRoot.git] / OCDB / EMCAL / Calib / AliEMCALPi0Calibration.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-2007, 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 /* History of svn commits:
16  *
17  * $Log$
18  *
19  */
20
21 //_________________________________________________________________________
22 //    This is analysis task for doing EMCAL pi0 calibration
23 //--  Authors: Aleksei Pavlinov (WSU) 
24 //--  Feb 17, 2007 - Sep 11, 2007
25 //--  Pi0 calibration
26 //--  Recalibration, linearity, shower profile
27 //--  May 2008 - move to AliAnalysisTaskSE
28 //--  You should load next library before running:
29 //    root [0] gSystem->Load("libANALYSIS");
30 //    root [1] gSystem->Load("libANALYSISalice");
31 //    root [2] gSystem->Load("libEMCALcalib");
32 //_________________________________________________________________________
33
34 #include "AliEMCALPi0Calibration.h"
35 #include "AliEMCALFolder.h"
36 #include "AliEMCALSuperModule.h"
37 #include "AliEMCALCell.h"
38 #include "AliEMCALCellInfo.h"
39 #include "AliEMCALPi0SelectionParam.h"
40 #include "AliEMCALHistoUtilities.h"
41 #include "AliEMCALCalibCoefs.h"
42 #include "AliEMCALGeometry.h"
43 #include "AliLog.h"
44 #include "AliESD.h"
45 #include "AliEMCALRecPoint.h"
46 #include "AliRunLoader.h"
47 #include "AliStack.h"
48 #include "AliEMCALDigit.h"
49 #include "AliESDEvent.h"
50
51 #include <iostream>
52 #include <iomanip>
53 #include <fstream>
54 #include <cassert>
55 #include <map>
56 #include <string>
57
58 #include <TROOT.h>
59 #include <TStyle.h>
60 #include <TSystem.h>
61 #include <TCanvas.h>
62 #include <TVector3.h>
63 #include <TLorentzVector.h>
64 #include <TParticle.h>
65 #include <TChain.h>
66 #include <TFile.h>
67 #include <TH1F.h>
68 #include <TH1D.h>
69 #include <TH2F.h>
70 #include <TF1.h>
71 #include <TMath.h>
72 #include <TBrowser.h>
73 #include <TList.h>
74 #include <TCanvas.h>
75 #include <TLine.h>
76 #include <TObjString.h>
77 #include <TArrayI.h>
78 #include <TGraphErrors.h>
79 #include <TLegend.h>
80 #include <TLegendEntry.h>
81 #include <TNtuple.h>
82
83 using namespace std;
84
85 typedef  AliEMCALHistoUtilities u;
86
87 AliEMCALGeometry* AliEMCALPi0Calibration::fgEmcalGeo=0;
88 Int_t             AliEMCALPi0Calibration::fgNmaxCell = 4*12*24*11;
89
90 Double_t AliEMCALPi0Calibration::fgDistEff = 3.;
91 Double_t AliEMCALPi0Calibration::fgW0      = 4.5;
92 Double_t AliEMCALPi0Calibration::fgSlopePhiShift = 0.01; // ?? just guess
93
94 AliEMCALFolder* AliEMCALPi0Calibration::fgEMCAL = 0;
95 AliEMCALFolder* AliEMCALPi0Calibration::fgEMCALOld = 0;
96
97 const Char_t **AliEMCALPi0Calibration::fgAnaOpt=0;
98 Int_t AliEMCALPi0Calibration::fgNanaOpt = 0; 
99 enum keyOpt{
100   kCORR1,
101   kRECALIB,
102   kIDEAL,
103   kPI0,
104   kGAMMA,
105   kKINE,
106   kPROF,
107   kFIT,
108  //-- 
109   kEND
110 };
111
112 // Enumeration variables
113 // enum {kUndefined=-1, kLed=0, kBeam=1};
114 // enum {kPatchResponse=0, kClusterResponse=1};
115 // enum {kSkip=0,  kSaveToMemory=1};
116
117 ClassImp(AliEMCALPi0Calibration)
118
119 AliEMCALPi0Calibration::AliEMCALPi0Calibration() :
120   AliAnalysisTaskSE(),
121   fPmom(0),
122   fChain(0),
123   fLofHistsPC(0),
124   fLofHistsRP(0),
125   fLKineVsRP(0),
126   fLShowerProfile(0),
127   fCellsInfo(0),
128   fEmcalPool(0),
129   fRunOpts(0),
130   fArrOpts(0),
131   fKeyOpts(0)
132
133   // Default constructor - for reading 
134 }
135
136 AliEMCALPi0Calibration::AliEMCALPi0Calibration(const char* name) :
137   AliAnalysisTaskSE(name),
138   fPmom(0),
139   fChain(0),
140   fLofHistsPC(0),
141   fLofHistsRP(0),
142   fLKineVsRP(0),
143   fLShowerProfile(0),
144   fCellsInfo(0),
145   fEmcalPool(0),
146   fRunOpts(0),
147   fArrOpts(0),
148   fKeyOpts(0)
149 {
150   //
151   // Constructor. Initialization of pointers
152   //
153   const Char_t *anaOpt[]={
154   "CORR1",   // GetCorrectedEnergyForGamma1(Double_t eRec);
155   "RECALIB",
156   "IDEAL",
157   "PI0",
158   "GAMMA",
159   "KINE",   // reading kine file
160   "PROF",   // Shower profile: phi direction now
161   "FIT"     // define parameters : deff, w0 and phislope
162   };
163   
164   fgNanaOpt = sizeof(anaOpt) / sizeof(Char_t*); 
165   fgAnaOpt = new const Char_t*[fgNanaOpt];
166   for(int i=0; i<fgNanaOpt; i++) fgAnaOpt[i] = anaOpt[i];
167 }
168
169 //AliEMCALPi0Calibration::AliEMCALPi0Calibration(const AliAnalysisTaskSE& obj) :
170 //  AliAnalysisTaskSE(),
171 //  fPmom(0),
172 //  fChain(0),
173 //  fLofHistsPC(0),
174 //  fLofHistsRP(0),
175 //  fLKineVsRP(0),
176 //  fLShowerProfile(0),
177 //  fCellsInfo(0),
178 //  fEmcalPool(0),
179 //  fRunOpts(0),
180 //  fArrOpts(0),
181 //  fKeyOpts(0)
182 //{ 
183 //  // Copy constructor - unused
184 //}
185 //
186 //AliEMCALPi0Calibration& AliEMCALPi0Calibration::operator=(const AliAnalysisTaskSE& other)
187 //{ 
188 //  // Assignment
189 // 
190 //  return *this;
191 //}
192
193 AliEMCALPi0Calibration::~AliEMCALPi0Calibration()
194 {
195   //
196   // Destructor
197   //
198
199   // histograms are in the output list and deleted when the output
200   // list is deleted by the TSelector dtor
201 }
202
203 void AliEMCALPi0Calibration::InitStructure(Int_t it)
204 {
205   //
206   // Initialize the common structure of selector
207   //
208   fgEmcalGeo = AliEMCALGeometry::GetInstance("EMCAL_COMPLETE"); // initialize geometry just once
209   fCellsInfo = AliEMCALCellInfo::GetTableForGeometry(fgEmcalGeo);
210
211   if(fRunOpts.Length()>0) CheckRunOpts();
212
213   Int_t key = 0;
214   if(GetKeyOptsValue(kGAMMA)) key = 1;
215   fLofHistsRP = DefineHistsOfRP("RP", fPmom, key);
216   fLofHistsPC = DefineHistsOfRP("PseudoCl", fPmom);
217
218   fEmcalPool = new TFolder("PoolOfEMCAL","");
219   if(it <= 1) {
220     fgEMCAL     = new AliEMCALFolder(it); // folder for first itteration   
221     fEmcalPool->Add(fgEMCAL);
222   }
223   //if(it<=0) SetName("GammaSel"); // For convinience
224   //else      SetName("Pi0Sel");
225   if(GetKeyOptsValue(kKINE)) fLKineVsRP = DefineHistsOfKineVsRP("KineVsRP",fPmom, key);
226   if(GetKeyOptsValue(kPROF)) fLShowerProfile = DefineHistsForShowerProfile("ProfY", fPmom);
227 }
228
229 void AliEMCALPi0Calibration::CheckRunOpts()
230 {
231   // Check run options
232   fRunOpts.ToUpper();
233   int nopt = u::ParseString(fRunOpts, fArrOpts);
234   printf("<I> AliEMCALPi0Calibration::CheckRunOpts() analyze %i(%i) options : fgNanaOpt %i\n", 
235          nopt, fArrOpts.GetEntries(), fgNanaOpt);  
236   if(nopt <=0) return;
237
238   fKeyOpts = new TArrayI(fgNanaOpt);
239   for(Int_t i=0; i<fgNanaOpt; i++) (*fKeyOpts)[i] = 0;
240
241   for(Int_t i=0; i<fArrOpts.GetEntries(); i++ ) {
242     TObjString *o = (TObjString*)fArrOpts.At(i); 
243
244     TString runOpt = o->String();
245     Int_t indj=-1;
246
247     for(Int_t j=0; j<fgNanaOpt; j++) {
248       TString opt = fgAnaOpt[j];
249       if(runOpt.Contains(opt,TString::kIgnoreCase)) {
250         indj = j;
251         break;
252       }
253     }
254     if(indj<0) {
255       printf("<E> option |%s| unavailable **\n", 
256       runOpt.Data());
257       assert(0);
258     } else {
259       (*fKeyOpts)[indj] = 1;
260       printf("<I> option |%s| is valid : number %i : |%s| \n", 
261              runOpt.Data(), indj, fgAnaOpt[indj]);
262     }
263   }
264 }
265
266 Int_t AliEMCALPi0Calibration::GetKeyOptsValue(Int_t key)
267 {
268   // Oct 14, 2007
269   static Int_t val=0;
270   val = 0;
271   if(fKeyOpts && key>=0 && key<fKeyOpts->GetSize()) {
272     val = fKeyOpts->At(key);
273   }
274   // printf(" key %i : val %i : opt %s \n", key, val, fgAnaOpt[key]);
275   return val;
276 }
277
278 void AliEMCALPi0Calibration::UserExec(const Option_t* /* */)
279 {
280   AliESDEvent * esd = dynamic_cast<AliESDEvent *>(InputEvent());
281
282   if (!esd)
283   {
284     AliDebug(AliLog::kError, "ESD branch not available");
285     return;
286   }
287   
288   static AliEMCALPi0SelectionParRec* rPar = GetEmcalFolder()->GetPi0SelectionParRow(0);
289
290   static Int_t nEmcalClusters, indOfFirstEmcalRP, nEmcalRP,nEmcalPseudoClusters;
291   nEmcalClusters    = esd->GetNumberOfEMCALClusters();
292   indOfFirstEmcalRP = esd->GetFirstEMCALCluster();
293   u::FillH1(fLofHistsRP, 1, double(indOfFirstEmcalRP));
294
295   static AliRunLoader* rl = 0;
296   static Int_t nev = 0; // Temporary - 0nly for reading one file now !!
297   
298   static AliESDCaloCluster *cl = 0; 
299   nEmcalRP = nEmcalPseudoClusters = 0;
300   TList *l=0;
301   double eDigi=0;   
302
303   TClonesArray lvM1("TLorentzVector", 100);  // for convenience; 100 is enough now 
304   TArrayI      indLv(100);                   // index of RP
305
306   static TLorentzVector v, vcl;
307   int nrp = 0; // # of RP for gg analysis
308   static Double_t erec=0., ecorr=0.0;
309   for(int i=indOfFirstEmcalRP; i<indOfFirstEmcalRP+nEmcalClusters; i++) {
310     cl = esd->GetCaloCluster(i);
311     if(cl->GetClusterType() == AliESDCaloCluster::kEMCALPseudoCluster) {
312       nEmcalPseudoClusters++;
313       l = fLofHistsPC;
314     } else if(cl->GetClusterType() == AliESDCaloCluster::kEMCALClusterv1){
315       nEmcalRP++;
316       if(fgEMCAL->GetIterationNumber()>1||GetKeyOptsValue(kIDEAL)||GetKeyOptsValue(kRECALIB)||GetKeyOptsValue(kFIT)) {
317         AliEMCALRecPoint *rp=0;
318         if(GetKeyOptsValue(kFIT) == kFALSE) fgDistEff = -1.; // No fitting ; Sep 4, 2007
319         if(GetKeyOptsValue(kIDEAL)) {
320           rp = AliEMCALFolder::GetRecPoint(cl, fgEMCAL->GetCCFirst(), 0, fLofHistsRP, fgDistEff, fgW0, fgSlopePhiShift);
321         } else {
322           rp = AliEMCALFolder::GetRecPoint(cl, fgEMCAL->GetCCFirst(), fgEMCAL->GetCCIn(), fLofHistsRP, fgDistEff, fgW0, fgSlopePhiShift);
323         }
324         if(GetKeyOptsValue(kPROF)) {
325           FillHistsForShowerProfile( GetListShowerProfile(), rp, GetCellsInfo());
326         }
327         //if(rp->GetPointEnergy()>=rPar->fEOfRpMin && u::GetLorentzVectorFromRecPoint(v, rp)) {
328         if(u::GetLorentzVectorFromRecPoint(v, rp)) { // comparing with RP
329           if(GetKeyOptsValue(kCORR1)) {
330             erec  = v.Rho();
331             ecorr = u::GetCorrectedEnergyForGamma1(erec);
332             v.SetRho(ecorr);
333             v.SetE(ecorr); // This is gamma
334             //printf("<1> erec %f | ecorr %f \n", erec, ecorr);
335           }
336           new(lvM1[nrp]) TLorentzVector(v);
337           indLv[nrp] = i;
338           nrp++;
339           // Conroling of recalibration
340           u::GetLorentzVectorFromESDCluster(vcl, cl);
341           u::FillH1(fLofHistsRP, 11, vcl.P()-v.P());
342           u::FillH1(fLofHistsRP, 12, TMath::RadToDeg()*(vcl.Theta()-v.Theta()));
343           u::FillH1(fLofHistsRP, 13, TMath::RadToDeg()*(vcl.Phi()-v.Phi()));
344
345           u::FillH1(fLofHistsRP, 16, v.P());
346           u::FillH2(fLofHistsRP, 17, vcl.P(), vcl.P()-v.P());
347           l = 0; // no filling
348           if(GetKeyOptsValue(kIDEAL) || GetKeyOptsValue(kRECALIB)) l = fLofHistsRP;
349         }
350         if(rp) delete rp;
351       } else { // first iteration
352         //        if(cl->E()>=rPar->fEOfRpMin && u::GetLorentzVectorFromESDCluster(v, cl)) {
353         if(u::GetLorentzVectorFromESDCluster(v, cl)) { // comparing with RP
354         // cut 0.4 GeV may be high ! 
355           if(GetKeyOptsValue(kCORR1)) {
356             erec  = v.Rho();
357             ecorr = u::GetCorrectedEnergyForGamma1(erec);
358             v.SetRho(ecorr);
359             v.SetE(ecorr); // This is gamma now
360             // printf("<2> erec %f | ecorr %f \n", erec, ecorr);
361             // printf("    v.Rho()  %f \n", v.Rho());
362           }
363           new(lvM1[nrp]) TLorentzVector(v);
364           indLv[nrp] = i;
365           nrp++;
366           l = fLofHistsRP;
367         }
368       }
369       
370     } else {
371       printf(" wrong cluster type : %i\n", cl->GetClusterType());
372       assert(0);
373     }
374     u::FillH1(l, 2, double(cl->GetClusterType()));
375
376     u::FillH1(l, 3, double(cl->GetNumberOfDigits()));  
377     u::FillH1(l, 4, double(cl->E()));  
378     // Cycle on digits (towers)
379     Short_t *digiAmpl  = cl->GetDigitAmplitude()->GetArray();
380     Short_t *digiTime  = cl->GetDigitTime()->GetArray();
381     Short_t *digiAbsId = cl->GetDigitIndex()->GetArray();
382     for(int id=0; id<cl->GetNumberOfDigits(); id++) {
383       eDigi = double(digiAmpl[id]) / 500.; // See AliEMCALClusterizerv1
384       //      if(eDigi <= 0.0) { // sometimes it is happen
385       //if(eDigi > 10.0 && cl->GetClusterType() == AliESDCaloCluster::kEMCALClusterv1) {
386       // printf(" %i digiAmpl %i : %f \n", id, int(digiAmpl[id]), eDigi);
387       //}
388       u::FillH1(l, 5, eDigi);
389       u::FillH1(l, 6, double(digiTime[id]));
390       u::FillH1(l, 7, double(digiAbsId[id]));
391       if(int(digiAbsId[id]) >= fgNmaxCell) {
392         printf(" id %i :  digiAbsId[id] %i (%i) : %s \n", 
393                id, int(digiAbsId[id]), fgNmaxCell, l->GetName());
394       }
395     }
396   }
397   u::FillH1(fLofHistsRP, 0, double(nEmcalRP));
398   u::FillH1(fLofHistsPC, 0, double(nEmcalPseudoClusters));
399
400   static TLorentzVector *lv1=0, *lv2=0, lgg;
401   for(int i1=0; i1<nrp; i1++){
402     lv1 = (TLorentzVector*)lvM1.At(i1);
403     u::FillH1(fLofHistsRP, 18, lv1->P());
404   }
405   static Double_t mgg, pgg;
406   mgg = pgg = 0.;
407   nrp = lvM1.GetEntriesFast(); 
408   if(nrp >= 2) {
409     // eff.mass analysis
410     for(int i1=0; i1<nrp-1; i1++){
411       lv1 = (TLorentzVector*)lvM1.At(i1);
412       for(int i2=i1+1; i2<nrp; i2++){
413         lv2 = (TLorentzVector*)lvM1.At(i2);
414         lgg = (*lv1) + (*lv2);
415         mgg = lgg.M();  // eff.mass
416         pgg = lgg.P();  // momentum
417         u::FillH1(fLofHistsRP, 8, mgg);
418  
419         if((mgg>=rPar->fMassGGMin && mgg<=rPar->fMassGGMax)) {// pi0 candidates
420           if((pgg>=rPar->fMomPi0Min && pgg>=rPar->fMomPi0Min)) {
421             if(fgEMCAL && fgEMCAL->GetIterationNumber()>=1) {
422               fgEMCAL->FillPi0Candidate(mgg,esd->GetCaloCluster(indLv[i1]),esd->GetCaloCluster(indLv[i2]));
423               u::FillH1(fLofHistsRP, 9, pgg); 
424               u::FillH1(fLofHistsRP,10, lv1->P());
425               u::FillH1(fLofHistsRP,10, lv2->P());
426             }
427           }
428         }
429       }
430     }
431   }
432
433   //  static Int_t fileNumber = 0;
434   static TString curFileName;
435   //  if(GetKeyOptsValue(kKINE) && nev<fChain->GetEntries()) {
436   if(GetKeyOptsValue(kKINE)) {
437   // Get galice.root file in current directory
438     if(nev%1000==0) {
439       printf(" current file |%s|\n", fChain->GetCurrentFile()->GetName());
440       curFileName = fChain->GetCurrentFile()->GetName();
441       curFileName.ReplaceAll("AliESDs.","galice."); 
442     }
443     rl = u::InitKinematics(nev, curFileName.Data());
444   // Compare kineamtics vs EMCal clusters
445     FillHistsOfKineVsRP(fLKineVsRP, rl, lvM1);
446   }
447
448   lvM1.Delete();
449
450   if(nEmcalClusters != (nEmcalRP+nEmcalPseudoClusters))
451     Info("Process","nEmcalClusters %i : RP %i + PC %i ",nEmcalClusters, nEmcalRP, nEmcalPseudoClusters); 
452
453   nev++;
454
455   return;
456 }
457
458 //
459 TList *AliEMCALPi0Calibration::DefineHistsOfRP(const char *name,Double_t p,Int_t keyOpt)
460 {
461   //
462   // Define histogramms of rec.points
463   //
464   printf("<I> DefineHistsOfRP :%s : p %f : keyOpt %i \n", name, p, keyOpt);
465   Double_t adcChannelEC = 0.0153; // ~15mev per adc count
466   Double_t xma = p*1.4, xmi=0.0, step=0.0, xmic=xmi, xmac = xma;
467   if(xma<0) xma = 20.;
468   Int_t nmax=1000, scale=4, nmaxc = nmax;
469
470   gROOT->cd();
471   TH1::AddDirectory(1);
472   new TH1F("00_EmcalMultiplicity", "multiplicity of EMCAL  ", 201, -0.5, 200.5); // real and pseudo
473   new TH1F("01_IndexOfFirstEmcal", "index of first emcal rec.points ", 201, -0.5, 200.5);
474
475   new TH1F("02_NumberOf", "number of  ", 6, -0.5, 5.5);
476   new TH1F("03_NumberOfDigitsIn", "number of digits(towers) in rec.points ", 101, -0.5, 100.5);
477
478   if(keyOpt==1 && p>0.1) {
479     if   (p>=100.)  scale=12;
480     else if(p>=50.) scale=10;
481     else if(p>=30.) scale=8;  
482     xma = p + scale*(0.15*TMath::Sqrt(p));
483     xmi = p - scale*(0.15*TMath::Sqrt(p));
484     step = (xma-xmi)/nmax;
485   }
486
487   if(step < 0.0153) {
488     nmax = int((xma-xmi) / adcChannelEC)+1;
489     xma =  xmi + adcChannelEC*nmax;
490   } 
491   new TH1F("04_EnergyOf", "energy of ", nmax, xmi, xma);
492   nmaxc = nmax; xmic=xmi; xmac = xma;
493
494   nmax = 10000;
495   xmi  = adcChannelEC/2.; xma = xmi + adcChannelEC*nmax;
496   // All energy(momentum) unit is GeV if don't notice
497   new TH1F("05_DigitEnergyIn", "digit energy in ", nmaxc, xmic, xmac);
498   new TH1F("06_DigitTimeIn", "digit time in 10ps(0.01ns) ", 1000, 0.0, 3.e+3); // ns/100 = 10 ps
499   new TH1F("07_DigitAbsIdIn", "digit abs id in ", fgNmaxCell, -0.5, double(fgNmaxCell)-0.5);
500   new TH1F("08_EffMass", "effective mass of #gamma,#gamma(m_{#pi^{0}}=134.9766 MeV)", 100, 0.0, 0.5);
501   new TH1F("09_MomOfPi0Candidate", "momentum of #pi^{0} candidates (0.085 <mgg<0.185)", 600, 0.0, 30.0);
502   new TH1F("10_MomOfRpPi0Candidate", "momentum of RP for #pi^{0} candidates (0.085 <mgg<0.185)", 600, 0.0, 30.0);
503   // Recalibration staf
504   Double_t pmax=11., dpmax=0.20;
505   if(p>0.1) {
506     pmax=p*1.2;
507     dpmax *= p;
508   }
509   new TH1F("11_MomClESD-RpRecalib", "difference of momentum cl(ESD) - rp(Recalib)", 100, -.01, dpmax);
510   new TH1F("12_ThetaClESD-RpRecalib", "difference of #theta cl(ESD) - rp(Recalib) in degree", 100, -0.05, +0.05);
511   new TH1F("13_PhiClESD-RpRecalib", "difference of #phi cl(ESD) - rp(Recalib) in degree ", 100, -0.05, +0.05);
512   // Digi
513   new TH1F("14_EDigiRecalib", "energy of digits after recalibration", 2000, 0.0, 20.);
514   //  AliEMCALGeometry* g = AliEMCALGeometry::GetInstance();
515   new TH1F("15_AbsIdRecalib", "abs Id of digits after recalibration", fgEmcalGeo->GetNCells(),-0.5,Double_t(fgEmcalGeo->GetNCells())-0.5);
516   new TH1F("16_EnergyOfRecalibRp_", "energy of recalibrated rec.points", nmaxc, xmic, xmac); // Jul 12, 2007
517   new TH2F("17_ShiftRecalib_", "E(clESD) - E(recalib)", 110,0.0, pmax, 50,0.0,dpmax); // Jul 13, 2007
518   
519   // Corrected staff
520   new TH1F("18_EnergyOfCorrectedLV", "energy of corrected LV", nmaxc, xmic, xmac);
521
522   TString st = Form("ListOfHists%s_P=%5.1f",name,p);
523   st.ReplaceAll(" ","");
524   TList *l = u::MoveHistsToList(st.Data(), kFALSE);
525   st = Form("%s_P=%5.1f",name,p);
526   st.ReplaceAll(" ","");
527   u::AddToNameAndTitleToList(l, st.Data(), st.Data());
528
529   return l;
530 }
531
532 TList* AliEMCALPi0Calibration::DefineHistsOfKineVsRP(const char *name,  Double_t p, Int_t keyOpt)
533 {
534   //
535   // Define histogramms for comparing a initial kinematics with rec.points
536   //
537  printf("<I>  DefineHistsOfKineVsRP :%s : p %f : keyOpt %i \n", name, p, keyOpt);
538
539   gROOT->cd();
540   TH1::AddDirectory(1);
541   new TH1F("00_hVx",Form("Vx of primary vertex"), 100, -5., +5.);   // 00
542   new TH1F("01_hVy",Form("Vy of primary vertex"), 100, -5., +5.);   // 01
543   new TH1F("02_hVz",Form("Vz of primary vertex"), 100, -50., +50.); // 02
544
545   //  Double_t adcChannelEC = 0.0153; // ~15mev per adc count
546   Double_t xma = p*1.4, xmi=0.0, sig=0.15*TMath::Sqrt(p);
547   //  Double_t step=0.0, xmic=xmi, xmac = xma;
548   if(xma<0) xma = 20.;
549   //Int_t nmax=1000;
550   // scale=4, nmaxc = nmax;
551
552   new TH1F("03_hGidPrimar", "Geant Id of primary particle ", 101, 0.5, 100.5);   // 03
553   new TH1F("04_hPmomPrim","momentum of primary particle", 100, xmi, xma);        // 04
554   new TH1F("05_hEtaPrim","#eta of primary particle ", 200, -1., 1.);             // 05
555   new TH1F("06_hPhiPrim","#phi of primary particle ", 63*2, 0.0,TMath::Pi()*2.); // 06
556   new TH1F("07_hThetaPrim","#theta of primary particle", 63, 0.0,TMath::Pi());   // 07 
557   new TH1F("08_hPhiPrimInDegree","#phi of primary particle in degree", 120, 75.0, 195.0);  // 08
558   new TH1F("09_hThetaPrimInDegree","#theta of primary particle in degree", 90, 45., 135.); // 09
559
560   // Particle vs cluster
561   new TH1F("10_hE(P)-E(RP)"," E(p) - E(RP) ", 100, -10.*sig, 10.*sig);   // 10
562
563   new TH1F("11_hPvsRpAngleInDegree","angle between P and RP (in degree)", 110, 0.0, 1.0); // 11
564   double dphi=0.5; // for fitting
565   new TH1F("12_hPvsRpDPhiInDegree","dif(#phi) between P and RP (in degree)", 100, -dphi, dphi); // 12
566   new TH1F("13_hPvsRpDThetaInDegree","dif(#theta) between P and RP (in degree)", 100, -0.5, 0.5); // 13
567
568   new TH1F("14_hPvsRpDPhiInDegree","dif(#phi) between P and RP (in degree) right part of SM", 100, -dphi, +dphi); // 14
569   new TH1F("15_hPvsRpDPhiInDegree","dif(#phi) between P and RP (in degree) left part of SM", 100, -dphi, dphi); // 15
570
571   new TH1F("16_hPvsRpDThetaInDegree","dif(#theta) between P and RP (even index)", 100, -0.5, 0.5); // 16
572   new TH1F("17_hPvsRpDThetaInDegree","dif(#theta) between P and RP (odd  index)", 100, -0.5, 0.5); // 17
573
574   TString st = Form("ListOfHists%s_P=%5.1f",name,p);
575   st.ReplaceAll(" ","");
576   TList *l = u::MoveHistsToList(st.Data(), kFALSE);
577   st = Form("%s_P=%5.1f",name,p);
578   st.ReplaceAll(" ","");
579   u::AddToNameAndTitleToList(l, st.Data(), st.Data());
580   return l;
581 }
582
583 TList *AliEMCALPi0Calibration::DefineHistsForShowerProfile(const char *name, Double_t p)
584 {
585   // Aug 1, 2007 - shower profile business as in testbeam analysis
586   //               Phi direction here is Y direction in testbeam 
587   printf("<I> DefineHistsForShowerProfile: %s : p %f \n", 
588   name, p);
589
590   gROOT->cd();
591   TH1::AddDirectory(1);
592
593   // Cell unit
594   new TH1F("00_hPHiMean"," mean in #phi direction ", 24*10, 0.0, 24.);
595   new TH1F("01_hPHiLog"," mean with log in #phi direction ", 24*10, 0.0, 24.);
596   new TH2F("02_XmeanVsXlog", "xmean vs xlog", 240,0.0, 24.,240,0.0, 24.);
597   new TH2F("03_XmeanVsXlog", "xmean vs xlog (system of cell with max energy, first half on #eta)", 
598   50,-0.5,+0.5, 100,-1.,+1.);
599   new TH2F("04_XmeanVsXlog", "xmean vs xlog (system of cell with max energy, second half on #eta)", 
600   50,-0.5,+0.5, 100,-1.,+1.);
601
602   new TH2F("05_PhiShowerProfile", " #phi shower profile - cumulative distribution",
603   6*25,-3.,3., 201, -0.0025, 1.0025);   // 00; x direction in cell unit
604
605   TString st = Form("L%s_P=%5.1f",name,p);
606   st.ReplaceAll(" ","");
607   TList *l = u::MoveHistsToList(st.Data(), kFALSE);
608   st = Form("%s_P=%5.1f",name,p);
609   st.ReplaceAll(" ","");
610   u::AddToNameAndTitleToList(l, st.Data(), st.Data());
611
612   return l;
613 }
614
615 void AliEMCALPi0Calibration::FillHistsOfKineVsRP(TList *l, AliRunLoader* rl,  TClonesArray &lvM)
616 {
617   //
618   // lvM - array of TLorentzVector's which was cretaef from AliESDCaloCluster's
619   //
620
621   if(l==0 || rl==0) return;
622
623   // TNtuple for qucik analysis
624   static TNtuple *nt=0;
625   if(nt==0) {
626     gROOT->cd();
627     Int_t bsize = int(1.e+7);
628     nt = new TNtuple("angle","angle ntuple for quick analysis",
629     "dPhi:dTheta:phiP:thetaP", bsize);
630     gROOT->GetListOfBrowsables()->Add(nt);
631   }
632   static AliStack* st=0;
633   static TParticle *p=0;
634   static Int_t gid=0, ic=0, pdg=0, i=0;
635   gid = ic = pdg = 0;
636
637   st = rl->Stack();
638   if(st == 0) return;
639   // first primary particle
640   p = st->Particle(0);
641   if(p == 0) return;
642
643   u::FillH1(l, ic++, p->Vx());
644   u::FillH1(l, ic++, p->Vy());
645   u::FillH1(l, ic++, p->Vz());
646
647   pdg = p->GetPdgCode();
648   //gid = gMC->IdFromPDG(pdg); // gMc should be defined
649
650   u::FillH1(l, ic++, Double_t(gid));
651   u::FillH1(l, ic++, p->P());
652   u::FillH1(l, ic++, p->Eta());
653   u::FillH1(l, ic++, TVector2::Phi_0_2pi(p->Phi()) );
654   u::FillH1(l, ic++, p->Theta());
655   // In degree
656   u::FillH1(l, ic++, TVector2::Phi_0_2pi(p->Phi())*TMath::RadToDeg());
657   u::FillH1(l, ic++, p->Theta()*TMath::RadToDeg()); // 09
658
659   if(lvM.GetEntriesFast() == 0) return;
660   //
661   // Initial kinematics vs Calo clusters
662   //
663   static TLorentzVector *lv = 0, lvp;
664   lvp.SetPxPyPzE(p->Px(),p->Py(),p->Pz(),p->Energy()); // Particle 
665
666   Double_t angle = 0.0, angleMin = 180.0, eDiff=0.0, dPhi=0., dTheta=0., phiP=0.0, thetaP=0.0;
667   Int_t indMin = 0;
668   phiP   = lvp.Phi() * TMath::RadToDeg();
669   if (phiP<81. || phiP>99.)  return;     // cut phi boundaries
670   thetaP = lvp.Theta() * TMath::RadToDeg();
671   if (thetaP<56. || thetaP>89.)  return; // cut theta boundaries
672
673   for(i=0; i<lvM.GetEntriesFast(); i++) {
674     lv = (TLorentzVector*)lvM.At(i);
675     angle = lv->Angle(lvp.Vect())*TMath::RadToDeg();
676     if(angleMin > angle) {
677       angleMin = angle;
678       indMin   = i;
679     }
680   }
681   lv = (TLorentzVector*)lvM.At(indMin);
682   eDiff   = lvp.E() - lv->E();
683   u::FillH1(l, ic++, eDiff); 
684
685   dPhi    = TVector2::Phi_mpi_pi(lvp.Phi()-lv->Phi())*TMath::RadToDeg();
686   dTheta  = TVector2::Phi_mpi_pi(lvp.Theta()-lv->Theta())*TMath::RadToDeg();
687   u::FillH1(l, ic++, angleMin);
688   u::FillH1(l, ic++, dPhi); 
689   u::FillH1(l, ic++, dTheta); 
690
691   if       (phiP>=81. && phiP<=90.) {
692     u::FillH1(l, 14, dPhi); 
693   } else if(phiP> 90. && phiP<=99.) {
694     u::FillH1(l, 15, dPhi); 
695   }
696   // Unfinished - have to get absid of digit with max energy 
697   u::FillH1(l, 16, dTheta); 
698   u::FillH1(l, 17, dTheta); 
699   if(nt) {
700     nt->Fill(dPhi,dTheta,phiP,thetaP);
701     /*
702      tv__tree = (TTree *) gROOT->FindObject("angle");
703      tv__tree->Draw("dPhi:phiP","abs(dPhi)<0.5","", 9182, 0);
704      tv__tree->Draw("dTheta:thetaP","abs(dTheta)<0.5","", 9182, 0);
705      */
706   }
707 }
708
709 void AliEMCALPi0Calibration::FillHistsForShowerProfile
710 (TList *l, AliEMCALRecPoint *rp, AliEMCALCellInfo * t)
711 {
712   // Aug 1, 2007
713   if(l==0 || rp==0 || t==0) return;
714   // --
715   static Double_t xmean=0., xlog=0.;
716   static AliEMCALCellIndexes rMax;
717   static Int_t phiSize;
718
719   if(rp->GetPointEnergy() < 1.0) return;
720   //if(rp->GetPointEnergy() > 8.0) return; // discard merged clusters for pi0 case
721
722   EvalLocalPhiPosition(1.,  rp, t, xmean, phiSize, rMax);
723   if(phiSize == 0) return; // just one row in cell directions
724
725   EvalLocalPhiPosition(5.5, rp, t, xlog, phiSize, rMax);
726   if(rMax.fIPhi>1.5&&rMax.fIPhi<21.5 && rMax.fIEta>1.5&&rMax.fIEta<46.5) { 
727     u::FillH1(l, 0, xmean); 
728     u::FillH1(l, 1, xlog); 
729     u::FillH2(l, 2, xlog, xmean);
730     // Select two central modules
731     if((rMax.fIPhim==5 || rMax.fIPhim==6)){
732     // Transition to system of cell with max energy
733       xmean -= (double(rMax.fIPhi)+0.5);  
734       xlog  -= (double(rMax.fIPhi)+0.5);  
735       if(rMax.fIEtam>=2 && rMax.fIEtam<=12){ // approximatively first half on eta 
736         u::FillH2(l, 3, xlog, xmean);
737       } else {// approximatively second half on eta 
738         u::FillH2(l, 4, xlog, xmean);
739       }
740     }
741   }
742 }
743
744 void   AliEMCALPi0Calibration::EvalLocalPhiPosition(const Double_t wlog, const AliEMCALRecPoint *rp, const AliEMCALCellInfo* t, Double_t &xcog, Int_t &phiSize, AliEMCALCellIndexes &rMax)
745 {
746   // wlog = 1 - usual center of gravity; >1 - with logarithmic weight.
747   // digits - array of digits
748   // t      - 
749   //==
750   // xcog - position of center of gravity in cell unit 
751   if(wlog<1.0 || rp==0 || t==0) return;
752   xcog = 0;
753
754   static Double_t wtot=0., w=0., edigi=0., e=0., edigiMax=0.;
755   static Int_t absid = 0, phiMin=0, phiMax=0;
756   static AliEMCALCellIndexes* r=0;
757
758   e = rp->GetPointEnergy();
759   wtot = 0.0;
760   edigiMax=0.;
761
762   phiMin = 23; phiMax = 0;
763   for(Int_t iDigit=0; iDigit<rp->GetMultiplicity(); iDigit++) {
764     absid = rp->GetAbsId()[iDigit];
765     edigi = rp->GetEnergiesList()[iDigit];
766     if(wlog > 1.0)  w = TMath::Max( 0., wlog + TMath::Log(edigi/e));
767     else            w = edigi; // just energy
768
769     r     = t->GetTable(absid);
770     xcog += w*(Double_t(r->fIPhi) + 0.5);
771     wtot += w;
772     if(edigi > edigiMax) {
773       edigiMax = edigi;
774       rMax = (*r);
775     }
776     if(phiMin > r->fIPhi) phiMin = r->fIPhi; 
777     if(phiMax < r->fIPhi) phiMax = r->fIPhi; 
778   }
779   xcog /= wtot;
780   phiSize = phiMax - phiMin;
781   //  printf("phiSize %i \n", phiSize); 
782 }
783 /* unused now
784 TList *AliEMCALPi0Calibration::DefineHistsOfTowers(const char *name)
785 {
786   //
787   // ESD: towers information was saved to pseudo clusters
788   // 
789   gROOT->cd();
790   TH1::AddDirectory(1);
791   new TH1F("00_EmcalMultiplicity", "multiplicity of EMCAL  ", 201, -0.5, 200.5); // number of pseudo RP
792
793   new TH1F("01_EnergyOf", "energy of ", 1000, 0.0, 100.);
794
795   TList *l = u::MoveHistsToList(Form("ListOfHists%s",name, " - ESD"), kFALSE);
796   u::AddToNameAndTitleToList(l, name, name);
797
798   return l;
799 }
800 */
801
802 void AliEMCALPi0Calibration::FitEffMassHist()
803 {
804   TH1* h = (TH1*)fLofHistsRP->At(8);
805   AliEMCALCell::FitHist(h, GetName(), "draw");
806 }
807
808 void AliEMCALPi0Calibration::PrintInfo()
809 {
810   // Service routine
811   printf("\n %i Entrie(s) | Option(s) |%s| \n", GetOptsArray().GetEntries(), fRunOpts.Data());  
812   for(int i=0; i<fgNanaOpt; i++) {
813     if(GetKeyOptsValue(i)) printf(" %i |%s| \n", i, fgAnaOpt[i]);
814   }
815
816   TList *l[2] = {fLofHistsPC, fLofHistsRP};
817   printf("\n");
818   for(int i=0; i<2; i++){
819     TH1F *h = (TH1F*)l[i]->At(2);
820     printf(" %s \t: %i \n", h->GetTitle(), int(h->GetEntries()));
821   }
822   printf(" fgDistEff %f fgW0 %f fgSlopePhiShift %f \n", fgDistEff, fgW0, fgSlopePhiShift);
823 }
824
825 void  AliEMCALPi0Calibration::SetMomentum(Double_t p) 
826 { // Jul 9, 2007
827   fPmom = p;
828   //  SetName(Form("%s_p_%f5.1", GetName(), p));
829 }
830
831
832 AliEMCALFolder*  AliEMCALPi0Calibration::CreateEmcalFolder(const Int_t it)
833 {
834   //
835   // Create emcal folder for iteration number it
836   //
837   AliEMCALFolder* newFolder = new AliEMCALFolder(it); // folder for iteration #it   
838   if(it>1) {
839     fgEMCALOld = fgEMCAL; 
840     AliEMCALCalibCoefs* tabOldOut = fgEMCALOld->GetCCOut();
841     AliEMCALCalibCoefs* tabNewIn = new AliEMCALCalibCoefs(*tabOldOut);
842     tabNewIn->SetName(AliEMCALFolder::GetCCinName().Data());
843     newFolder->Add(tabNewIn);
844   } 
845   fEmcalPool->Add(newFolder);
846   fgEMCAL = newFolder;
847
848   return fgEMCAL;
849 }
850
851 AliEMCALFolder* AliEMCALPi0Calibration::GetEmcalOldFolder(const Int_t nsm)
852 {
853   // Return emcal folder with number nsm
854   AliEMCALFolder* folder=0;
855   if(fEmcalPool) folder =  (AliEMCALFolder*)fEmcalPool->FindObject(Form("EMCAL_%2.2i",nsm));
856   return folder;
857 }
858
859
860 void AliEMCALPi0Calibration::SetEmcalFolder(AliEMCALFolder* folder)
861 {
862   fgEMCAL = folder;
863   fEmcalPool->Add(fgEMCAL);
864 }
865
866 void AliEMCALPi0Calibration::SetEmcalOldFolder(AliEMCALFolder* folder)
867 {
868   fgEMCALOld = folder;
869   fEmcalPool->Add(fgEMCALOld);
870 }
871
872 void AliEMCALPi0Calibration::Browse(TBrowser* b)
873 {
874   // What we see at browser
875   // if(esd)        b->Add(esd);
876   if(fChain)      b->Add(fChain);
877   if(fEmcalPool)  b->Add(fEmcalPool);
878   if(fgEmcalGeo) b->Add(fgEmcalGeo);
879   if(fCellsInfo)  b->Add(fCellsInfo);
880   //
881   if(fLofHistsPC) b->Add(fLofHistsPC);
882   if(fLofHistsRP) b->Add(fLofHistsRP);
883   if(fLKineVsRP)  b->Add(fLKineVsRP);
884   if(fLShowerProfile) b->Add(fLShowerProfile);
885   //  if(u) b->Add(u);
886 }
887
888 Bool_t AliEMCALPi0Calibration::IsFolder() const
889 {
890   if(fLofHistsRP || fEmcalPool) return kTRUE;
891   return kFALSE;
892 }
893
894 void AliEMCALPi0Calibration::Save(Int_t ver, const char *optIO)
895
896   // Aug 3, 2007
897   // Save selector to file
898   TString dir("/home/pavlinov/ALICE/SHISHKEBAB/RF/CALIB/"); // Root directory for saving
899   TString nf=dir;
900   if(GetKeyOptsValue(kPROF)) {
901     nf += "PROF/PROFILE_";
902     nf += ver;
903     nf += ".root";
904     TFile f(nf.Data(), optIO);
905     if(f.IsOpen()) {
906       this->Write();
907       f.Close();
908       printf("<I> Save selectort to file |%s| : optIO %s \n",nf.Data(), optIO);
909     } else {
910       printf("<W> File %s exits ! Increase version : ver %i !\n", nf.Data(), ver);
911     }
912   } else {
913     printf("No PROF option -> no saving now !\n");
914   }
915 }
916
917 AliEMCALPi0Calibration* AliEMCALPi0Calibration::ReadSelector(const char* nf)
918 {
919   // Read selector to file
920   AliEMCALPi0Calibration* selector=0;
921
922   TH1::AddDirectory(0);
923   TFile f(nf,"READ");
924   if(f.IsOpen()) {
925     TObject *o = f.Get("AliEMCALPi0Calibration");
926     if(o) selector = dynamic_cast<AliEMCALPi0Calibration *>(o);
927   }
928   // printf("<I> read selector %p : file |%s| \n", selector, nf);
929   return selector;
930 }
931
932 void AliEMCALPi0Calibration::ReadAllEmcalFolders()
933 {
934   // Oct 14, 2007
935   if(fEmcalPool==0) {
936     fEmcalPool = new TFolder("PoolOfEMCAL","");
937     for(Int_t it=1; it<=10; it++){
938       AliEMCALFolder* fold = AliEMCALFolder::ReadFolder(Form("EMCALFOLDER_It%i_fit.root",it), "READ");
939       //      AliEMCALFolder* fold = AliEMCALFolder::Read(Form("EMCALFOLDER_It%i_fit.root",it), "READ");
940       if(fold) fEmcalPool->Add(fold);
941     }
942   }
943 }
944
945 void AliEMCALPi0Calibration::PictVsIterNumber(const Int_t ind, const Int_t nsm)
946 {
947   // Jun 27, 2007 - unfinished; which picture is the best
948   if(ind<0 || ind>5) return;
949   gROOT->cd();
950   TH1::AddDirectory(1);
951
952   Int_t itMax = 10, it=0;
953   map <int, const char*> indName;
954   indName[0] = "eff.mass";
955   indName[3] = "mass of #pi_{0}";
956   indName[4] = "resolution of #pi_{0}";
957   indName[5] = "chi^{2}/ndf";
958
959   TH1F *hout = new TH1F(indName[ind], indName[ind], itMax, 0.5, double(itMax)+0.5); 
960    
961   TH1::AddDirectory(0);
962   Double_t content, error;
963   TList* col = (TList*)fEmcalPool->GetListOfFolders();
964   for(Int_t i=0; i<col->GetSize(); i++) { // cycle on EMCAL folders
965     AliEMCALFolder* folder = static_cast<AliEMCALFolder*>(col->At(i));
966     if(folder==0) continue;
967     it = folder->GetIterationNumber();
968
969     AliEMCALSuperModule* sm = folder->GetSuperModule(nsm);
970     if(sm==0) continue;
971
972     TList* l = sm->GetHists();
973     if(l==0) continue;
974
975     TH1F *hin = (TH1F*)l->At(ind);
976     if(hin==0) continue;
977
978     if(ind !=0 ) {
979       content = hin->GetMean();
980       error   = hin->GetRMS();
981     } else {
982       sm->FitEffMassHist();
983       TF1 *f = (TF1*)hin->GetListOfFunctions()->At(0);
984       content = error = -1.;
985       if(f) {
986         //        content = f->GetParameter(1);
987         //error   = f->GetParameter(2);
988         content = f->GetParameter(2);
989         error   = f->GetParError(2);
990       }
991     }
992
993     if(content > 0.0) {
994       hout->SetBinContent(it, content);
995       hout->SetBinError(it, error);
996       printf(" it %i content %f +/- %f \n", it, content, error);
997     }
998   }
999
1000   u::DrawHist(hout,2);
1001   hout->SetMinimum(0.0);
1002
1003 }
1004
1005 TH1F* AliEMCALPi0Calibration::FitHistOfRecPointEnergy(const char *opt)
1006 {
1007   // Fit hist of rec.point energy
1008   TH1::AddDirectory(0);
1009
1010   TString sopt(opt);
1011   sopt.ToUpper();
1012
1013   Int_t ind = 4, ind2 = 16;
1014   if(GetKeyOptsValue(kIDEAL)) {
1015     ind  = 16; // Jul 12, 2007
1016     ind2 =  4;
1017   } else if(GetKeyOptsValue(kCORR1)) {
1018     ind  = 18;
1019     ind2 =  4;
1020   }
1021   TH1F *hold = (TH1F*)fLofHistsRP->At(ind), *h=0;
1022   if(hold == 0) return 0;
1023   if(hold->GetEntries() <10.) return hold;
1024
1025   if(sopt.Contains("CLONE")) {
1026     TString newName(Form("C_%s",hold->GetName()));
1027     h = (TH1F*)hold->Clone(newName.Data());
1028     printf(" Clone hist %s -> |%s|%s| \n",hold->GetName(),h->GetName(),h->GetTitle()); 
1029   } else {
1030     h = hold;
1031   }
1032   TH1F* h2 = (TH1F*)fLofHistsRP->At(ind2);
1033
1034   Double_t xmax = h->GetXaxis()->GetXmax(), xmin = 0.4*xmax;;
1035   TF1 *g = u::Gausi("fRecPointE", xmin, xmax, h);
1036   g->SetLineColor(kRed);
1037   gStyle->SetOptFit(111);
1038
1039   h->Fit(g,"N","", xmin, xmax);
1040   printf(" (1) xmin %f : xmax %f \n", xmin, xmax);
1041
1042   xmin = g->GetParameter(1) - 4.*g->GetParameter(2);
1043   xmax = g->GetParameter(1) + 4.*g->GetParameter(2);
1044   h->Fit(g,"Q+","", xmin, xmax);
1045   u::DrawHist(h2,1, 1, "same",2);
1046   printf(" (2) xmin %f : xmax %f \n", xmin, xmax);
1047
1048   return h;
1049 }
1050
1051 TCanvas *AliEMCALPi0Calibration::Linearity(TList *l, int ifun)
1052
1053   // Jul 10, 2007
1054   // Draw picture of EMCal linearity 
1055   if(l==0) {
1056     printf("<E> AliEMCALPi0Calibration::Linearity :TList is zero ! Bye ! \n");
1057     return 0;
1058   }
1059   Double_t p[9]={0.5, 1., 3., 5., 10., 20., 30., 50., 100.}, ep[9];
1060   // see macro rHits.C ->defineSampleFraction
1061   TH1F* hErecOverEin = new TH1F("hErecOverEin","Ratio E_{rec}/E_{#gamma} vs E_{#gamma}", 101,0.5,101.5);
1062   // Fill hist
1063   TArrayD invRat(9), eInvRat(9), erec(9),derec(9), residual(9);
1064   TArrayD res(9), eres(9); // resolution
1065   Int_t np=9;
1066   for(Int_t var=0; var<9; var++){
1067     TH1F *h = (TH1F*)l->At(var);
1068     TF1  *f = (TF1*)h->GetListOfFunctions()->At(0);
1069     Double_t  mean = f->GetParameter(1);
1070     Double_t emean = f->GetParError(1);
1071
1072     Int_t bin = hErecOverEin->FindBin(p[var]);
1073     hErecOverEin->SetBinContent(bin, mean/p[var]);
1074     hErecOverEin->SetBinError(bin,  emean/p[var]); 
1075     //
1076     invRat[var]  = p[var]/mean;
1077     eInvRat[var] = emean/p[var]*invRat[var];
1078     erec[var]    = mean;
1079     derec[var]   = emean;
1080     // Resolution in %
1081     res[var]  = 100.*f->GetParameter(2)/p[var];
1082     eres[var] = 100.*f->GetParError(2)/p[var];
1083     ep[var] = 0.0;
1084   }
1085
1086   TCanvas *c = new TCanvas("Linearity","Linearity", 20,20, 700, 500);
1087   gStyle->SetOptStat(0);
1088   if(0) { // E(rec) / E(gamma)
1089     u::DrawHist(hErecOverEin,2);
1090     hErecOverEin->SetMinimum(0.984);
1091     hErecOverEin->SetMaximum(1.001);
1092   }
1093   Int_t markerColor=1;
1094   const char *fun="", *optFit="";
1095   TF1 *f = 0;
1096   if(0) {
1097     if(ifun==-5) {
1098       fun = "fun5"; optFit="R+";
1099       f = new TF1(fun,"([0]*(x-7.5)*(x-7.5))*exp([1]+[2]*x+[3]*x*x)+1.", 0.0, 100.);
1100       f->FixParameter(0, 1.95380e-05);
1101       //      f->SetParameter(0, 1.95380e-05);
1102       //      f->SetParameter(1, 1.0);
1103     } else if(ifun==-4) {
1104       fun = "fun4"; optFit="R+";
1105       f = new TF1(fun,"([0]*(x-7.5)*(x-7.5))*([1]+[2]*abs(x)+[3]*(x-[4])*(x-[4]))+1.", 0.0, 100.);
1106       f->FixParameter(0, 1.95380e-05);
1107       f->SetParameter(4, 50.);
1108       //      f = new TF1(fun,"exp(([0]+[1]*x)*(x-[2])*(x-[3]))", 0.0, 100.);
1109       //f = new TF1(fun,"([0]+[1]*x)*(x-[2])*(x-[3])", 0.0, 100.);
1110       //f->SetParameter(0, 1.);
1111       //f->SetParameter(1, 1.);
1112
1113       //      f->SetParameter(2, 5.);
1114       //f->SetParLimits(2, 3.,8.);
1115       //f->SetParameter(3, 10.);
1116       //f->SetParLimits(3, 9.,15.);
1117       //f->SetParameter(2, 2.e-4);
1118     } else if(ifun==-3) {
1119       fun = "fun3"; optFit="R+";
1120       f = new TF1(fun,"[0]+[1]*x+[2]*x*x+[3]*x*x*x", 0.0, 11.);
1121     } else if(ifun==-2) {
1122       fun = "fun2"; optFit="R+";
1123
1124       /*
1125       f = new TF1(fun,"[0]*(x-7.5)+[1]*(x-7.5)*(x-7.5)+[2]", 0.0, 10.1); 
1126       f->SetParameter(0, 5.98727e-04);
1127       f->SetParameter(1, 2.12045e-04);
1128       f->SetParameter(2, 1.);
1129       */
1130       f = new TF1(fun,"[0]+[1]*x+[2]*x*x", 9.0, 100.1); 
1131     } else if(ifun==-1) {
1132       fun = "fun0"; optFit="R+";
1133       f = new TF1(fun,"[0]", 0.0, 100.1); 
1134     } else if(ifun>=2) {
1135       fun = Form("pol%i",ifun); 
1136       optFit="+";
1137     }
1138     TGraphErrors *gr = u::DrawGraphErrors(np, erec.GetArray(),invRat.GetArray(),derec.GetArray(),eInvRat.GetArray(),
1139    //    markerColor,21+markerColor,"AP", " Ratio E_{#gamma}/E_{Rec} ", "E_{Rec}  ","   E_{#gamma}/E_{Rec}",
1140  markerColor,21+markerColor,"AP", " Ratio E_{#gamma}/E_{Rec}^{corr} ", "E_{Rec}^{corr}  ","   E_{#gamma}/E_{Rec}^{corr}",
1141                                           ifun, optFit, fun);
1142     gr->GetHistogram()->SetAxisRange(0.0,100.);
1143     //    double xmi=0.999, xma=1.017;
1144     double xmi=0.995, xma=1.005;
1145     gr->GetHistogram()->SetMaximum(xma);
1146     gr->GetHistogram()->SetMinimum(xmi);
1147     gr->GetHistogram()->SetTitleOffset(1.4,"y");
1148     if(ifun==0) {
1149       f = new TF1("fres", "AliEMCALHistoUtilities::EnergyCorrectionForGamma1(x)", 0., 101.); 
1150       f->Draw("same");
1151     }
1152   }
1153   TLine *line = new TLine(0.0,1.0, 100.,1.0);
1154   line->Draw();
1155
1156   if(0) {
1157     c->Clear();
1158     for(int i=0; i<9; i++) {
1159       residual[i] =  100.*(invRat[i] - u::GetCorrectionCoefficientForGamma1(erec[i])); // in percent
1160       printf(" erec %f : residual %5.3f \n", erec[i], residual[i]);
1161     }
1162     markerColor = 2;
1163     TGraphErrors *gr2=u::DrawGraphErrors(np, erec.GetArray(),residual.GetArray(),derec.GetArray(),eInvRat.GetArray(),
1164                   markerColor,21+markerColor,"AP"," residual in %, rec.point level", "E_{Rec}  ","  residual in %",
1165     -1, "", 0);
1166     gr2->GetHistogram()->SetAxisRange(0.0,100.);
1167     gr2->GetHistogram()->SetMaximum(0.2);
1168     gr2->GetHistogram()->SetMinimum(-0.1);
1169     line = new TLine(0.0,0.0, 101.,0.0);
1170     line->Draw();
1171     //TLatex *lat = 
1172         u::Lat("linearity better 0.2% after correction",20., 0.15, 12, 0.06, 1); 
1173     //if(lat); //For what is this?, commented due to compilation warnings
1174   }
1175   if(1) {
1176     TString latexName;
1177     c->Clear();
1178     gStyle->SetOptFit(111);
1179     markerColor = 1;
1180     ifun        = -11;
1181     f = u::GetResolutionFunction("FRES2", latexName);  
1182     f->SetNpx(10000);
1183     f->SetLineColor(kBlack);
1184
1185     TGraphErrors *gr3=u::DrawGraphErrors(np, p,res.GetArray(), ep, eres.GetArray(),
1186     markerColor,21+markerColor,"AP"," resolution in %, rec.point level","E_{#gamma} "," resolution in %",
1187                                          ifun, "+", f->GetName());
1188     gr3->GetHistogram()->SetAxisRange(0.0,101.);
1189     gr3->GetHistogram()->SetMaximum(14.);
1190     gr3->GetHistogram()->SetMinimum(0.0);
1191     gr3->SetMarkerSize(1.5);
1192
1193     //TLatex *lat = 
1194         u::Lat(latexName.Data(),82., 11., 12, 0.06, 1);
1195     //if(lat); //For what is this?, commented due to compilation warnings
1196     // Exp. data
1197     TF1 *fexp = new TF1(*f);
1198     fexp->SetName("fexp");
1199     fexp->SetParameter(0, 2.168);
1200     fexp->SetParameter(1, 8.818);
1201     fexp->SetLineWidth(1);
1202     fexp->SetLineColor(kRed);
1203     fexp->SetLineStyle(1);
1204     fexp->Draw("same");
1205
1206     TLegend *leg = new TLegend(0.21,0.36, 0.68,0.82);
1207     leg->AddEntry(gr3,  "MC data", "P");
1208     leg->AddEntry(f,    "fit of MC data", "L");
1209     TLegendEntry *ent3 = leg->AddEntry(fexp, "#splitline{fit of exp.data}{FNAL, Nov 2005}", "L");
1210     ent3->SetTextColor(fexp->GetLineColor());
1211     leg->Draw();
1212   }
1213   c->Update();
1214
1215   return c;
1216 }
1217
1218 TCanvas *AliEMCALPi0Calibration::DrawKineVsRP(TList *l)
1219
1220   //Jul 25, 2007
1221   if(l==0) {
1222     printf("<W> AliEMCALPi0Calibration::DrawKineVsRP : TList is zero ! \n");
1223     return 0;
1224   }
1225   TCanvas *c = new TCanvas("KineVsRP","KineVsRP", 20,20, 700, 500);
1226   gStyle->SetOptStat(1110);
1227   c->Divide(2,2);
1228
1229   c->cd(1);
1230   TH1F* h1 = (TH1F*)l->At(10);
1231   u::DrawHist(h1,2);
1232
1233   c->cd(2);
1234   TH1F* h2 = (TH1F*)l->At(11);
1235   u::DrawHist(h2,2);
1236
1237   c->cd(3);
1238   TH1F* h3 = (TH1F*)l->At(12);
1239   u::DrawHist(h3,2);
1240   u::DrawHist((TH1F*)l->At(14), 1,kRed,"same");
1241   u::DrawHist((TH1F*)l->At(15), 1,kGreen,"same");
1242
1243   c->cd(4);
1244   TH1F* h4 = (TH1F*)l->At(13);
1245   u::DrawHist(h4, 2);
1246   u::DrawHist((TH1F*)l->At(16), 1,kRed,"same");
1247   u::DrawHist((TH1F*)l->At(17), 1,kGreen,"same");
1248
1249   /*
1250   TH1F* h2 = (TH1F*)l->At(11);
1251   u::DrawHist(h2,2);
1252   */
1253
1254   c->Update();
1255   return c;
1256 }
1257
1258 TCanvas* AliEMCALPi0Calibration::DrawMeanVsLog(TH2F *h2)
1259 {
1260   // h - input histogramm : mean vds log coordinates 
1261   if(h2==0) return 0;
1262
1263   TCanvas *c = new TCanvas("KineVsRP","KineVsRP", 20,20, 700, 500);
1264
1265   TH1F *hid1 = new TH1F("h1","h1 title ", h2->GetNbinsX(), 
1266   h2->GetXaxis()->GetXmin(), h2->GetXaxis()->GetXmax());  
1267
1268   gROOT->cd();
1269   TH1::AddDirectory(1);
1270   TString newName;
1271   for(int ix=1; ix<=h2->GetNbinsX();ix++) {
1272     newName = "hd_"; newName += ix;
1273     TH1D *hd = h2->ProjectionY(newName.Data(),ix,ix);
1274     if(hd->Integral()>=4.) {
1275       //      lhd->Add(hd);
1276       hid1->SetBinContent(ix, hd->GetMean());
1277       hid1->SetBinError(ix, hd->GetRMS());
1278     }
1279   }
1280   TF1 *f1 = new TF1("fcg", "0.5*TMath::SinH(x/[0])/TMath::SinH(0.5/[0])", -0.5, 0.5);
1281   f1->SetParameter(0,0.13);
1282   f1->SetLineColor(kRed);
1283   f1->SetLineWidth(1);
1284
1285   gStyle->SetOptStat(0);
1286   gStyle->SetOptFit(111);
1287   hid1->Fit(f1,"R+");
1288
1289   u::DrawHist(hid1,2);
1290
1291 //u::DrawHist(h2,2);
1292
1293   c->Update();
1294   return c;
1295 }
1296
1297 TCanvas* AliEMCALPi0Calibration::DrawPhiEtaAnglesDistribution(const char* gn)
1298
1299   // Aug 6, 2007
1300   // Proper geometry should be defined already 
1301   // dTheta distibution has two peaks which coresponding different cells inside module ! 
1302
1303   TCanvas *c = new TCanvas("Geometry","Geometry", 20,20, 700, 500);
1304   c->Divide(2,2);
1305
1306   if(fgEmcalGeo==0) fgEmcalGeo = AliEMCALGeometry::GetInstance(gn);
1307
1308   gROOT->cd();
1309   TH1::AddDirectory(1);
1310   TH1F *hDtheta  = new TH1F("hDtheta","#Delta#theta in one SM", 60, -2.0, +1.0); // in degree
1311   TH2F *hDtheta2 = new TH2F("hDtheta2","#Delta#theta vs fIEta of cell", 48, -0.5, 47.5, 60,-2.0,+1.0);
1312
1313   TH1F *hDphi  = new TH1F("hDphi","#Delta#ph in one SM", 2000, -10.0, +10.0); // in degree
1314
1315   TVector3 vg3;
1316   AliEMCALCellInfo* t = GetCellsInfo();
1317   Double_t thetaCell=0., thetaModule=0.;
1318   Double_t phiCell=0., dphi=0.;
1319
1320   for(int absid=0; absid<12*24*4; absid++){
1321     AliEMCALCellIndexes *r = t->GetTable(absid);
1322     fgEmcalGeo->GetGlobal(absid, vg3);
1323
1324     thetaCell   = vg3.Theta()*TMath::RadToDeg();
1325     thetaModule = 90. - 1.5*r->fIEtam;
1326     hDtheta->Fill(thetaCell - thetaModule);
1327     hDtheta2->Fill(double(r->fIEta), thetaCell - thetaModule);
1328
1329     phiCell   = vg3.Phi()*TMath::RadToDeg();
1330     dphi      = phiCell - 90.;
1331     hDphi->Fill(dphi);
1332   }
1333
1334   c->cd(1);
1335   u::DrawHist(hDtheta,2);
1336   c->cd(2);
1337   u::DrawHist(hDtheta2,2);
1338   c->cd(3);
1339   u::DrawHist(hDphi,2);
1340
1341   c->Update();
1342   return c;
1343 }
1344
1345 TCanvas* AliEMCALPi0Calibration::DrawDeffVsEnergy()
1346 {
1347   // Aug 31, 2007 - obsolete
1348   Double_t p[]={0.5, 1.0, 3., 5., 10., 20.,30.,50.,100.};
1349   Double_t ep[]={0., 0., 0., 0., 0., 0., 0., 0., 0.};
1350   // 2 pars
1351   Double_t  deff[]={9.07515, 10.0835, 11.2032, 11.4229, 12.3578, 13.0332, 13.3281, 13.7910, 14.3319};
1352   Double_t edeff[]={2.69645e-03, 3.52180e-03, 4.19236e-02, 1.21201e-01, 1.58886e-01, 3.96680e-01, 3.29985e-02, 1.17113e-01, 5.22763e-01};
1353   //
1354   Double_t w0[]={3.44679e+00, 3.82714e+00, 4.15035e+0, 4.36650e+00, 4.51511e+00, 4.65590, 4.63289e+00, 4.66568, 4.68125};
1355   Double_t ew0[]={7.58982e-01, 1.26420e-02, 2.36129e-10, 1.21201e-01, 2.12999e-01, 7.95650e-02, 6.15307e-03, 1.88803e-01, 5.18022e-05};
1356   int np=sizeof(p)/sizeof(Double_t);
1357   printf("<I> AliEMCALPi0Calibration::DrawDeffVsEnergy() | np %i \n", np);
1358
1359   TCanvas *c = new TCanvas("Deff","Deff", 20,20, 700, 500);
1360   c->Divide(2,1);
1361
1362   Int_t markerColor=1;
1363   c->cd(1);
1364   //TF1 *fdeff= new TF1("fdeff","[0]+[1]*log(x)",0.4, 100.4);
1365   //if(fdeff); //For what is this?, commented due to compilation warnings
1366   TGraphErrors *gr = u::DrawGraphErrors(np, p,deff, ep, edeff,
1367     markerColor,21+markerColor,"AP"," D_{eff} vs E_{#gamma} ","E_{#gamma}         "," D_{eff} in cm ",
1368                                         -1, "", 0);
1369   //                                    -1, "+", fdeff->GetName());
1370   gr->GetHistogram()->SetMaximum(15.);
1371   gPad->SetLogx(1);
1372
1373   c->cd(2);
1374   TGraphErrors *gr2 = u::DrawGraphErrors(np, p,w0, ep, ew0,
1375     markerColor,21+markerColor,"AP"," w_{0} vs E_{#gamma} ","E_{#gamma}         "," w_{0}    ",
1376     -1, "", 0);
1377
1378   gr2->GetHistogram()->SetMaximum(5.);
1379   gPad->SetLogx(1); 
1380
1381   c->Update();
1382   return c;
1383 }
1384
1385 TCanvas* AliEMCALPi0Calibration::DrawDeffVsEnergy2(const char *opt)
1386 {
1387   // Aug 28, 2008 - read pars and pars errors from files
1388   Double_t p[]={0.5, 1.0, 3., 5., 10., 20.,30.,50.,100.};
1389   Double_t ep[]={0., 0., 0., 0., 0., 0., 0., 0., 0.};
1390   // 2 pars
1391   Double_t deff[9], edeff[9], w0[9], ew0[9]; // max size now 
1392   TString sopt(opt);
1393
1394   int np = sizeof(p)/sizeof(Double_t);
1395   printf("<I> AliEMCALPi0Calibration::DrawDeffVsEnergy2() | np %i \n", np);
1396   ReadParsDeffAndW0("/data/r22b/ALICE/CALIB/FIT/", deff, edeff, w0, ew0, 1);
1397
1398   TCanvas *c = new TCanvas("Deff","Deff", 20,20, 700, 500);
1399   c->Divide(2,1);
1400
1401   TF1 *fdeff = 0, *fw0 = 0;
1402   TString optFit(""), funName("");
1403   if(sopt.Contains("fit1")) {
1404     fdeff= new TF1("fdeff","[0]+[1]*log(x)",0.1, 101.);
1405     fdeff->SetLineColor(kRed);
1406     fdeff->SetLineWidth(1);
1407
1408     /* good description - "[0]/(1.+exp([1]*x))"
1409    1  p0           4.82208e+00   9.93617e-04  -0.00000e+00   7.16648e-06
1410    2  p1          -7.79655e-01   4.07500e-03  -0.00000e+00   2.01009e-03
1411       better description - "[0]/(1.+exp([1]*(x-[2])))" (like the Woods-Saxon potential)
1412    1  p0           4.83713e+00   1.00437e-03  -6.98984e-10   4.90371e-07
1413    2  p1          -2.77970e-01   3.35587e-03  -1.79239e-09   2.67312e-07
1414    3  p2           4.41116e+00   8.72191e-02   1.82791e-04   1.55643e-05
1415      */
1416     fw0= new TF1("fw0","[0]/(1.+exp([1]*(x+[2])))",0.1, 101.);
1417     fw0->SetLineColor(kRed);
1418     fw0->SetLineWidth(1);
1419     fw0->SetParameter(0, 4.8);
1420     fw0->SetParameter(1, -2.77970e-01);
1421     fw0->SetParameter(2,  4.41116);
1422     optFit = "+";
1423   }
1424   if(fdeff) funName =  fdeff->GetName();
1425
1426   Int_t markerColor=1;
1427   c->cd(1);
1428   gStyle->SetOptFit(111);
1429   TGraphErrors *gr = u::DrawGraphErrors(np, p,deff, ep, edeff,
1430     markerColor,21+markerColor,"AP"," D_{eff} vs E_{#gamma} ","E_{#gamma}         "," D_{eff} in cm ",
1431                                         -1, optFit.Data(), funName.Data());
1432   gr->GetHistogram()->SetMaximum(15.);
1433   gPad->SetLogx(1);
1434   TLegend *leg1 = new TLegend(0.12,0.76, 0.70,0.90);
1435   TLegendEntry *le1 = leg1->AddEntry(fdeff, Form("%s",fdeff->GetTitle()), "lp");
1436   //TLegendEntry *le1 = leg1->AddEntry(fdeff, Form("%4.2f+%4.2f*log(E_{#gamma})",
1437   //fdeff->GetParameter(0),fdeff->GetParameter(1)), "lp");
1438   le1->SetTextColor(fdeff->GetLineColor());
1439   leg1->Draw();
1440
1441   c->cd(2);
1442   gStyle->SetOptFit(111);
1443   if(fw0) funName =  fw0->GetName();
1444   TGraphErrors *gr2 = u::DrawGraphErrors(np, p,w0, ep, ew0,
1445     markerColor,21+markerColor,"AP"," w_{0} vs E_{#gamma} ","E_{#gamma}         "," w_{0}    ",
1446                                         -1, optFit.Data(), funName.Data());
1447
1448   gr2->GetHistogram()->SetMaximum(5.);
1449
1450   TLegend *leg2 = new TLegend(0.17,0.6, 0.99,0.72);
1451   TLegendEntry *le2 = leg2->AddEntry(fw0, Form("%s",fw0->GetTitle()), "lp");
1452   //TLegendEntry *le2 = leg2->AddEntry(fw0, Form("#frac{%4.2f}{1.+exp(%4.2f*(x+%4.2f)}",
1453   //fw0->GetParameter(0),fw0->GetParameter(1),fw0->GetParameter(2)), "lp");
1454   le2->SetTextColor(fw0->GetLineColor());
1455   leg2->Draw();
1456   //gPad->SetLogx(1); 
1457
1458   c->Update();
1459   return c;
1460 }
1461
1462 void AliEMCALPi0Calibration::ReadParsDeffAndW0
1463 (const char *dirName, double *deff, double *edeff, double *w0, double *ew0, const Int_t pri)
1464 {
1465   // read pars and W0
1466   int strategy = 0, itmp=0;
1467   char line[100];
1468   for(int var=11; var<=19; var++){
1469     int ind = var -11;
1470     ifstream fin;
1471     TString fname = Form("%s/fitVar%iStrategy%i.txt", dirName, var, strategy);
1472     //printf(" open file %s \n", fname.Data());
1473     fin.open(fname.Data());
1474    
1475     for(int i=1; i<=2; i++) { // skip to lines
1476       fin.getline(line,100).eof();
1477       if(pri>=2) printf("%s \n", line);
1478     }
1479
1480     fin >> itmp >> deff[ind] >> edeff[ind];
1481     fin >> itmp >> w0[ind]   >> ew0[ind];
1482     if(pri>=1) 
1483     printf(" %i def %f+/-%f : def %f+/-%f\n", ind, deff[ind],edeff[ind],w0[ind],ew0[ind]); 
1484     fin.getline(line,100).eof(); // skip last line
1485     fin.close();
1486   }
1487 }
1488
1489 TCanvas* AliEMCALPi0Calibration::DrawSpaceResolution()
1490 {
1491   // Sep 4, 2007;
1492   // Space resolution vs optimised space resolution
1493   Double_t p[]={0.5, 1.0, 3., 5., 10., 20.,30.,50.,100.};
1494   Double_t ep[]={0., 0., 0., 0., 0., 0., 0., 0., 0.};
1495   Double_t  spAng[]={0.1877, 0.1351, 0.08144, 0.06331, 0.05384, 0.04876, 0.04706, 0.04656, 0.04726};
1496   Double_t rmsSpAng[]={0.1033, 0.07685, 0.05235, 0.03992, 0.04012, 0.04257, 0.03472, 0.02814, 0.02784};
1497   Double_t  spAngOpt[]={0.1733, 0.1311, 0.07961, 0.06401, 0.05347, 0.04618, 0.04288, 0.04, 0.03802};
1498   Double_t rmsSpAngOpt[]={0.09476, 0.07472, 0.05011, 0.04242, 0.04075, 0.04304, 0.03545, 0.02744, 0.02593};
1499
1500   int np=sizeof(p)/sizeof(Double_t);
1501   printf("<I> AliEMCALPi0Calibration::DrawSpaceResolution() | np %i \n", np);
1502
1503   Double_t* eSpAng    = new Double_t[np];
1504   Double_t* eSpAngOpt = new Double_t[np];
1505   Double_t cc=TMath::Sqrt(8000.), cc2 = 1000.*TMath::DegToRad();
1506   for(int i=0; i<np; i++){
1507     spAng[i]       *= cc2;
1508     rmsSpAng[i]    *= cc2;
1509     spAngOpt[i]    *= cc2;
1510     rmsSpAngOpt[i] *= cc2;
1511
1512     eSpAng[i]    = spAng[i]/cc;
1513     eSpAngOpt[i] = spAngOpt[i]/cc;
1514   }
1515
1516   TCanvas *c = new TCanvas("Deff","Deff", 20,20, 700, 500);
1517   //c->Divide(2,1);
1518
1519   c->cd(1);
1520   gStyle->SetOptFit(111);
1521
1522   TGraphErrors *gr = u::DrawGraphErrors(np, p,spAng, ep, eSpAng,
1523   kBlack, 21,"AP","Angle resolution (mrad) vs E_{#gamma} ","E_{#gamma}       "," anlgle resolution (mrad) ",
1524                                         -1, "", 0);
1525   gr->GetHistogram()->SetMaximum(4.);
1526   gr->GetHistogram()->SetMinimum(0.6);
1527   gPad->SetLogx(1);
1528   gPad->SetLogy(1);
1529
1530   TF1 *fang = new TF1("fang","[0]+[1]/sqrt(x)",0.1, 101.);
1531   fang->SetLineColor(kRed);
1532   fang->SetLineWidth(1);
1533
1534   TGraphErrors *gr2 = u::DrawGraphErrors(np, p,spAngOpt, ep, eSpAngOpt,
1535   kRed,22,"P"," space vs E_{#gamma} ","E_{#gamma}         "," anlgle resolution (mrad) ",
1536                                          -1, "+", fang->GetName());
1537   TLegend *leg1 = new TLegend(0.40,0.57, 0.92,0.87);
1538   TLegendEntry *le1 = leg1->AddEntry(gr, "Initial angle resolution", "p");
1539   le1->SetTextColor(gr->GetLineColor());
1540
1541   TLegendEntry *le2 = leg1->AddEntry(gr2, "Optimized angle resolution", "p");
1542   le2->SetTextColor(gr2->GetLineColor());
1543
1544   TLegendEntry *le3 = leg1->AddEntry(fang, 
1545   Form("%3.2f+#frac{%4.2f}{#sqrt{E}}",fang->GetParameter(0),fang->GetParameter(1)), "lp");
1546   le3->SetTextColor(fang->GetLineColor());
1547
1548   leg1->Draw();
1549
1550   c->Update();
1551
1552   return c;
1553 }
1554
1555 void AliEMCALPi0Calibration::ResetAllListOfHists()
1556 {
1557   // Reset all list of hits
1558   u::ResetListOfHists(fLofHistsPC);
1559   u::ResetListOfHists(fLofHistsRP);
1560   u::ResetListOfHists(fLKineVsRP);
1561   u::ResetListOfHists(fLShowerProfile);
1562 }
1563
1564 void AliEMCALPi0Calibration::ReloadChain(Long64_t entry)
1565
1566   // Oct 14, 2007 - unused now
1567   if(fChain) {
1568     fChain->LoadTree(entry);
1569   }
1570 }
1571
1572 void AliEMCALPi0Calibration::GetInitialParsForFit(const Int_t var, Double_t &deff, Double_t &w0, Double_t &phislope, const int phiCase)
1573 {
1574   //  int phiCase=0; // 0 or 1
1575   phislope = 0.001;
1576   if(var==11)         { // stay here
1577     deff = 9.07515;
1578     w0   = 3.44679;
1579   }  else if(var==12) {
1580     deff = 1.00835e+01;
1581     w0   = 3.82714e+00;
1582   }  else if(var==13) {
1583     deff = 1.12032e+01;
1584     w0   = 4.15035e+00;
1585   }  else if(var==14) {
1586     deff = 1.14229e+01;
1587     w0   = 4.36650;
1588   }  else if(var==15) {
1589     deff = 1.21361e+01; 
1590     w0   = 4.72875;
1591   }  else if(var==16) {
1592     deff = 1.28096e+01;
1593     w0   = 4.81753e+00;
1594   }  else if(var==17) {
1595     deff = 1.33281e+01; 
1596     w0   = 4.63289e+00;
1597   }  else if(var==18) {
1598     deff = 1.37910e+01; 
1599     w0   = 4.66568;
1600   }  else if(var==19) {// Aug 15, 2007
1601     switch (phiCase) {
1602     case 0: // phislope was defined than deff and w0 were fixed
1603       deff = 1.43319e+01;
1604       w0   = 4.69279;
1605       phislope = 2.41419e-04;
1606       break;
1607     case 1: // all parameters free
1608       deff = 1.46327e+01;
1609       w0   = 4.68125;
1610       phislope = 8.95559e-04;
1611       break;
1612     }
1613   } else { 
1614     printf("<E> var % i -> no definition ! \n", var);
1615     assert(0);
1616   }
1617   printf("<I> AliEMCALPi0Calibration::GetInitialParForFit()\n deff %f w0 %f phislope %f \n", 
1618          deff,w0, phislope);
1619 }