]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGDQ/dielectron/AliDielectronHistos.cxx
Merge branch 'master' of https://git.cern.ch/reps/AliRoot
[u/mrichter/AliRoot.git] / PWGDQ / dielectron / AliDielectronHistos.cxx
1 /*************************************************************************
2 * Copyright(c) 1998-2009, 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 //
17 // Generic Histogram container with support for groups and filling of groups by passing
18 // a vector of data
19 //
20 // Authors: 
21 //   Jens Wiechula <Jens.Wiechula@cern.ch> 
22 //   Julian Book   <Julian.Book@cern.ch> 
23 // 
24
25 #include <TH1.h>
26 #include <TH1F.h>
27 #include <TH2.h>
28 #include <TH3.h>
29 #include <THnBase.h>
30 #include <THn.h>
31 #include <THnSparse.h>
32 #include <TProfile.h>
33 #include <TProfile2D.h>
34 #include <TProfile3D.h>
35 #include <TCollection.h>
36 #include <THashList.h>
37 #include <TString.h>
38 #include <TObjString.h>
39 #include <TObjArray.h>
40 #include <TFile.h>
41 #include <TError.h>
42 #include <TCanvas.h>
43 #include <TMath.h>
44 #include <TROOT.h>
45 #include <TLegend.h>
46 #include <TKey.h>
47 #include <TAxis.h>
48 #include <TVirtualPS.h>
49 #include <TVectorD.h>
50
51 #include "AliDielectronHelper.h"
52 #include "AliDielectronVarManager.h"
53 #include "AliDielectronHistos.h"
54
55 ClassImp(AliDielectronHistos)
56
57
58 AliDielectronHistos::AliDielectronHistos() :
59 //   TCollection(),
60   TNamed("AliDielectronHistos","Dielectron Histogram Container"),
61   fHistoList(),
62   fList(0x0),
63   fReservedWords(new TString)
64 {
65   //
66   // Default constructor
67   //
68   fHistoList.SetOwner(kTRUE);
69   fHistoList.SetName("Dielectron_Histos");
70 }
71
72 //_____________________________________________________________________________
73 AliDielectronHistos::AliDielectronHistos(const char* name, const char* title) :
74 //   TCollection(),
75   TNamed(name, title),
76   fHistoList(),
77   fList(0x0),
78   fReservedWords(new TString)
79 {
80   //
81   // TNamed constructor
82   //
83   fHistoList.SetOwner(kTRUE);
84   fHistoList.SetName(name);
85 }
86
87 //_____________________________________________________________________________
88 AliDielectronHistos::~AliDielectronHistos()
89 {
90   //
91   // Destructor
92   //
93   fHistoList.Clear();
94   if (fList) fList->Clear();
95   delete fReservedWords;
96 }
97
98 //_____________________________________________________________________________
99 void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
100                                       UInt_t valTypeP,
101                                       Int_t nbinsX, Double_t xmin, Double_t xmax,
102                                       UInt_t valTypeX, Bool_t logBinX, TString option,
103                                       UInt_t valTypeW)
104 {
105   //
106   // Default histogram creation 1D case
107   //
108
109   TVectorD *binLimX=0x0;
110   
111   if (logBinX) {
112     binLimX=AliDielectronHelper::MakeLogBinning(nbinsX, xmin, xmax);
113   } else {
114     binLimX=AliDielectronHelper::MakeLinBinning(nbinsX, xmin, xmax);
115   }
116   UserProfile(histClass,name,title,valTypeP,binLimX,valTypeX,option,valTypeW);
117 }
118
119 //_____________________________________________________________________________
120 void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
121                                       UInt_t valTypeP,
122                                       Int_t nbinsX, Double_t xmin, Double_t xmax,
123                                       Int_t nbinsY, Double_t ymin, Double_t ymax,
124                                       UInt_t valTypeX, UInt_t valTypeY,
125                                       Bool_t logBinX, Bool_t logBinY, TString option,
126                                       UInt_t valTypeW)
127 {
128   //
129   // Default histogram creation 2D case
130   //
131   if (!IsHistogramOk(histClass,name)) return;
132
133   TVectorD *binLimX=0x0;
134   TVectorD *binLimY=0x0;
135   
136   if (logBinX) {
137     binLimX=AliDielectronHelper::MakeLogBinning(nbinsX, xmin, xmax);
138   } else {
139     binLimX=AliDielectronHelper::MakeLinBinning(nbinsX, xmin, xmax);
140   }
141   if (logBinY) {
142     binLimY=AliDielectronHelper::MakeLogBinning(nbinsY, ymin, ymax);
143   } else {
144     binLimY=AliDielectronHelper::MakeLinBinning(nbinsY, ymin, ymax);
145   }
146   UserProfile(histClass,name,title,valTypeP,binLimX,binLimY,valTypeX,valTypeY,option,valTypeW);
147 }
148
149
150 //_____________________________________________________________________________
151 void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
152                                       UInt_t valTypeP,
153                                       Int_t nbinsX, Double_t xmin, Double_t xmax,
154                                       Int_t nbinsY, Double_t ymin, Double_t ymax,
155                                       Int_t nbinsZ, Double_t zmin, Double_t zmax,
156                                       UInt_t valTypeX, UInt_t valTypeY, UInt_t valTypeZ,
157                                       Bool_t logBinX, Bool_t logBinY, Bool_t logBinZ, TString option,
158                                       UInt_t valTypeW)
159 {
160   //
161   // Default histogram creation 3D case
162   //
163   if (!IsHistogramOk(histClass,name)) return;
164
165   TVectorD *binLimX=0x0;
166   TVectorD *binLimY=0x0;
167   TVectorD *binLimZ=0x0;
168   
169   if (logBinX) {
170     binLimX=AliDielectronHelper::MakeLogBinning(nbinsX, xmin, xmax);
171   } else {
172     binLimX=AliDielectronHelper::MakeLinBinning(nbinsX, xmin, xmax);
173   }
174   
175   if (logBinY) {
176     binLimY=AliDielectronHelper::MakeLogBinning(nbinsY, ymin, ymax);
177   } else {
178     binLimY=AliDielectronHelper::MakeLinBinning(nbinsY, ymin, ymax);
179   }
180   
181   if (logBinZ) {
182     binLimZ=AliDielectronHelper::MakeLogBinning(nbinsZ, zmin, zmax);
183   } else {
184     binLimZ=AliDielectronHelper::MakeLinBinning(nbinsZ, zmin, zmax);
185   }
186
187   UserProfile(histClass,name,title,valTypeP,binLimX,binLimY,binLimZ,valTypeX,valTypeY,valTypeZ,option,valTypeW);
188 }
189
190 //_____________________________________________________________________________
191 void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
192                                       UInt_t valTypeP,
193                                       const char* binning,
194                                       UInt_t valTypeX, TString option,
195                                       UInt_t valTypeW)
196 {
197   //
198   // Histogram creation 1D case with arbitraty binning
199   //
200
201   TVectorD *binLimX=AliDielectronHelper::MakeArbitraryBinning(binning);
202   UserProfile(histClass,name,title,valTypeP,binLimX,valTypeX,option,valTypeW);
203 }
204
205 //_____________________________________________________________________________
206 void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
207                                       UInt_t valTypeP,
208                                       const TVectorD * const binsX,
209                                       UInt_t valTypeX/*=kNoAutoFill*/, TString option,
210                                       UInt_t valTypeW)
211 {
212   //
213   // Histogram creation 1D case with arbitraty binning X
214   // the TVectorD is assumed to be surplus after the creation and will be deleted!!!
215   //
216
217   Bool_t isOk=kTRUE;
218   isOk&=IsHistogramOk(histClass,name);
219   isOk&=(binsX!=0x0);
220   TH1 *hist=0x0;
221
222   if (isOk){
223     if(valTypeP==kNoProfile)
224       hist=new TH1F(name,title,binsX->GetNrows()-1,binsX->GetMatrixArray());
225     else {
226       TString opt=""; Double_t pmin=0., pmax=0.;
227       if(!option.IsNull()) {
228         TObjArray *arr=option.Tokenize(";");
229         arr->SetOwner();
230         opt=((TObjString*)arr->At(0))->GetString();
231         if(arr->GetEntriesFast()>1) pmin=(((TObjString*)arr->At(1))->GetString()).Atof();
232         if(arr->GetEntriesFast()>2) pmax=(((TObjString*)arr->At(2))->GetString()).Atof();
233         delete arr;
234       }
235       hist=new TProfile(name,title,binsX->GetNrows()-1,binsX->GetMatrixArray());
236       ((TProfile*)hist)->BuildOptions(pmin,pmax,opt.Data());
237       //      printf(" name %s PROFILE options: pmin %.1f pmax %.1f err %s \n",name,((TProfile*)hist)->GetYmin(),((TProfile*)hist)->GetYmax(),((TProfile*)hist)->GetErrorOption() );
238     }
239
240     // store variales in axes
241     UInt_t valType[20] = {0};
242     valType[0]=valTypeX;     valType[1]=valTypeP;
243     StoreVariables(hist, valType);
244     hist->SetUniqueID(valTypeW); // store weighting variable
245
246     // adapt the name and title of the histogram in case they are empty
247     AdaptNameTitle(hist, histClass);
248
249     Bool_t isReserved=fReservedWords->Contains(histClass);
250     if(valTypeX==kNoAutoFill) hist->SetUniqueID(valTypeX);
251     if (isReserved)
252       UserHistogramReservedWords(histClass, hist, 999);
253     else
254       UserHistogram(histClass, hist, 999);
255   }
256   
257   delete binsX;
258 }
259
260 //_____________________________________________________________________________
261 void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
262                                       UInt_t valTypeP,
263                                       const TVectorD * const binsX, const TVectorD * const binsY,
264                                       UInt_t valTypeX/*=kNoAutoFill*/, UInt_t valTypeY/*=0*/, TString option,
265                                       UInt_t valTypeW)
266 {
267   //
268   // Histogram creation 2D case with arbitraty binning X
269   // the TVectorD is assumed to be surplus after the creation and will be deleted!!!
270   //
271
272   Bool_t isOk=kTRUE;
273   isOk&=IsHistogramOk(histClass,name);
274   isOk&=(binsX!=0x0);
275   isOk&=(binsY!=0x0);
276   TH1 *hist=0x0;
277
278   if (isOk){
279     if(valTypeP==kNoProfile) {
280       hist=new TH2F(name,title,
281                     binsX->GetNrows()-1,binsX->GetMatrixArray(),
282                     binsY->GetNrows()-1,binsY->GetMatrixArray()); 
283     }
284     else  {
285       TString opt=""; Double_t pmin=0., pmax=0.;
286       if(!option.IsNull()) {
287         TObjArray *arr=option.Tokenize(";");
288         arr->SetOwner();
289         opt=((TObjString*)arr->At(0))->GetString();
290         if(arr->GetEntriesFast()>1) pmin=(((TObjString*)arr->At(1))->GetString()).Atof();
291         if(arr->GetEntriesFast()>2) pmax=(((TObjString*)arr->At(2))->GetString()).Atof();
292         delete arr;
293       }
294       hist=new TProfile2D(name,title,
295                           binsX->GetNrows()-1,binsX->GetMatrixArray(),
296                           binsY->GetNrows()-1,binsY->GetMatrixArray());
297       ((TProfile2D*)hist)->BuildOptions(pmin,pmax,opt.Data());
298       //      printf(" name %s PROFILE options: pmin %.1f pmax %.1f err %s \n",name,((TProfile*)hist)->GetYmin(),((TProfile*)hist)->GetYmax(),((TProfile*)hist)->GetErrorOption() );
299     }
300
301     // store variales in axes
302     UInt_t valType[20] = {0};
303     valType[0]=valTypeX;     valType[1]=valTypeY;     valType[2]=valTypeP;
304     StoreVariables(hist, valType);
305     hist->SetUniqueID(valTypeW); // store weighting variable
306
307     // adapt the name and title of the histogram in case they are empty
308     AdaptNameTitle(hist, histClass);
309
310     Bool_t isReserved=fReservedWords->Contains(histClass);
311     if(valTypeX==kNoAutoFill) hist->SetUniqueID(valTypeX);
312     if (isReserved)
313       UserHistogramReservedWords(histClass, hist, 999);
314     else
315       UserHistogram(histClass, hist, 999);
316   }
317   
318   delete binsX;
319   delete binsY;
320   
321 }
322
323 //_____________________________________________________________________________
324 void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
325                                       UInt_t valTypeP,
326                                       const TVectorD * const binsX, const TVectorD * const binsY, const TVectorD * const binsZ,
327                                       UInt_t valTypeX/*=kNoAutoFill*/, UInt_t valTypeY/*=0*/, UInt_t valTypeZ/*=0*/, TString option,
328                                       UInt_t valTypeW)
329 {
330   //
331   // Histogram creation 3D case with arbitraty binning X
332   // the TVectorD is assumed to be surplus after the creation and will be deleted!!!
333   //
334
335   Bool_t isOk=kTRUE;
336   isOk&=IsHistogramOk(histClass,name);
337   isOk&=(binsX!=0x0);
338   isOk&=(binsY!=0x0);
339   isOk&=(binsZ!=0x0);
340   TH1 *hist=0x0;
341
342   if (isOk) {
343     if(valTypeP==kNoProfile) {
344       hist=new TH3F(name,title,
345                     binsX->GetNrows()-1,binsX->GetMatrixArray(),
346                     binsY->GetNrows()-1,binsY->GetMatrixArray(),
347                     binsZ->GetNrows()-1,binsZ->GetMatrixArray());
348     }
349     else {
350       TString opt=""; Double_t pmin=0., pmax=0.;
351       if(!option.IsNull()) {
352         TObjArray *arr=option.Tokenize(";");
353         arr->SetOwner();
354         opt=((TObjString*)arr->At(0))->GetString();
355         if(arr->GetEntriesFast()>1) pmin=(((TObjString*)arr->At(1))->GetString()).Atof();
356         if(arr->GetEntriesFast()>2) pmax=(((TObjString*)arr->At(2))->GetString()).Atof();
357         delete arr;
358       }
359       hist=new TProfile3D(name,title,
360                           binsX->GetNrows()-1,binsX->GetMatrixArray(),
361                           binsY->GetNrows()-1,binsY->GetMatrixArray(),
362                           binsZ->GetNrows()-1,binsZ->GetMatrixArray());
363       ((TProfile3D*)hist)->BuildOptions(pmin,pmax,opt.Data());
364       //      printf(" name %s PROFILE options: pmin %.1f pmax %.1f err %s \n",name,((TProfile*)hist)->GetYmin(),((TProfile*)hist)->GetYmax(),((TProfile*)hist)->GetErrorOption() );
365     }
366
367     // store variales in axes
368     UInt_t valType[20] = {0};
369     valType[0]=valTypeX;     valType[1]=valTypeY;     valType[2]=valTypeZ;     valType[3]=valTypeP;
370     StoreVariables(hist, valType);
371     hist->SetUniqueID(valTypeW); // store weighting variable
372
373     // adapt the name and title of the histogram in case they are empty
374     AdaptNameTitle(hist, histClass);
375
376     Bool_t isReserved=fReservedWords->Contains(histClass);
377     if(valTypeX==kNoAutoFill) hist->SetUniqueID(valTypeX);
378     if (isReserved)
379       UserHistogramReservedWords(histClass, hist, 999);
380     else
381       UserHistogram(histClass, hist, 999);
382   }
383   
384   delete binsX;
385   delete binsY;
386   delete binsZ;
387 }
388
389 //_____________________________________________________________________________
390 void AliDielectronHistos::UserHistogram(const char* histClass, Int_t ndim, Int_t *bins, Double_t *mins, Double_t *maxs, UInt_t *vars, UInt_t valTypeW)
391 {
392   //
393   // Histogram creation 4-n dimension only with linear binning
394   //
395
396   Bool_t isOk=kTRUE;
397   isOk&=(ndim<21 && ndim>3);
398   if(!isOk) { Warning("UserHistogram","Array sizes should be between 3 and 20. Not adding Histogram to '%s'.", histClass); return; }
399
400   // set automatic histo name
401   TString name;
402   for(Int_t iv=0; iv < ndim; iv++)
403     name+=Form("%s_",AliDielectronVarManager::GetValueName(vars[iv]));
404   name.Resize(name.Length()-1);
405
406   isOk&=IsHistogramOk(histClass,name);
407
408   THnD *hist;
409   if (isOk) {
410     hist=new THnD(name.Data(),"", ndim, bins, mins, maxs);
411
412     // store variales in axes
413     StoreVariables(hist, vars);
414     hist->SetUniqueID(valTypeW); // store weighting variable
415
416     Bool_t isReserved=fReservedWords->Contains(histClass);
417     if (isReserved)
418       UserHistogramReservedWords(histClass, hist, 999);
419     else
420       UserHistogram(histClass, hist, 999);
421
422   }
423 }
424
425 //_____________________________________________________________________________
426 void AliDielectronHistos::UserHistogram(const char* histClass, Int_t ndim, TObjArray *limits, UInt_t *vars, UInt_t valTypeW)
427 {
428   //
429   // Histogram creation n>3 dimension only with non-linear binning
430   //
431
432   Bool_t isOk=kTRUE;
433   isOk&=(ndim<21 && ndim>3);
434   if(!isOk) { Warning("UserHistogram","Array sizes should be between 3 and 20. Not adding Histogram to '%s'.", histClass); return; }
435   isOk&=(ndim==limits->GetEntriesFast());
436   if(!isOk) return;
437
438   // set automatic histo name
439   TString name;
440   for(Int_t iv=0; iv < ndim; iv++)
441     name+=Form("%s_",AliDielectronVarManager::GetValueName(vars[iv]));
442   name.Resize(name.Length()-1);
443
444   isOk&=IsHistogramOk(histClass,name);
445
446   THnD *hist;
447   Int_t bins[ndim];
448   if (isOk) {
449     // get number of bins
450     for(Int_t idim=0 ;idim<ndim; idim++) {
451       TVectorD *vec = (TVectorD*) limits->At(idim);
452       bins[idim]=vec->GetNrows()-1;
453     }
454
455     hist=new THnD(name.Data(),"", ndim, bins, 0x0, 0x0);
456
457     // set binning
458     for(Int_t idim=0 ;idim<ndim; idim++) {
459       TVectorD *vec = (TVectorD*) limits->At(idim);
460       hist->SetBinEdges(idim,vec->GetMatrixArray());
461     }
462
463     // store variales in axes
464     StoreVariables(hist, vars);
465     hist->SetUniqueID(valTypeW); // store weighting variable
466
467     Bool_t isReserved=fReservedWords->Contains(histClass);
468     if (isReserved)
469       UserHistogramReservedWords(histClass, hist, 999);
470     else
471       UserHistogram(histClass, hist, 999);
472
473   }
474 }
475
476 //_____________________________________________________________________________
477 void AliDielectronHistos::UserSparse(const char* histClass, Int_t ndim, Int_t *bins, Double_t *mins, Double_t *maxs, UInt_t *vars,
478                                      UInt_t valTypeW)
479 {
480   //
481   // THnSparse creation with linear binning
482   //
483
484   Bool_t isOk=kTRUE;
485
486   // set automatic histo name
487   TString name;
488   for(Int_t iv=0; iv < ndim; iv++)
489     name+=Form("%s_",AliDielectronVarManager::GetValueName(vars[iv]));
490   name.Resize(name.Length()-1);
491
492   isOk&=IsHistogramOk(histClass,name);
493
494   THnSparseD *hist;
495   if (isOk) {
496     hist=new THnSparseD(name.Data(),"", ndim, bins, mins, maxs);
497
498     // store variales in axes
499     StoreVariables(hist, vars);
500     hist->SetUniqueID(valTypeW); // store weighting variable
501
502     Bool_t isReserved=fReservedWords->Contains(histClass);
503     if (isReserved)
504       UserHistogramReservedWords(histClass, hist, 999);
505     else
506       UserHistogram(histClass, hist, 999);
507
508   }
509 }
510
511 //_____________________________________________________________________________
512 void AliDielectronHistos::UserSparse(const char* histClass, Int_t ndim, TObjArray *limits, UInt_t *vars, UInt_t valTypeW)
513 {
514   //
515   // THnSparse creation with non-linear binning
516   //
517
518   Bool_t isOk=kTRUE;
519   isOk&=(ndim==limits->GetEntriesFast());
520   if(!isOk) return;
521
522   // set automatic histo name
523   TString name;
524   for(Int_t iv=0; iv < ndim; iv++)
525     name+=Form("%s_",AliDielectronVarManager::GetValueName(vars[iv]));
526   name.Resize(name.Length()-1);
527
528   isOk&=IsHistogramOk(histClass,name);
529
530   THnSparseD *hist;
531   Int_t bins[ndim];
532   if (isOk) {
533     // get number of bins
534     for(Int_t idim=0 ;idim<ndim; idim++) {
535       TVectorD *vec = (TVectorD*) limits->At(idim);
536       bins[idim]=vec->GetNrows()-1;
537     }
538
539     hist=new THnSparseD(name.Data(),"", ndim, bins, 0x0, 0x0);
540
541     // set binning
542     for(Int_t idim=0 ;idim<ndim; idim++) {
543       TVectorD *vec = (TVectorD*) limits->At(idim);
544       hist->SetBinEdges(idim,vec->GetMatrixArray());
545     }
546
547     // store variales in axes
548     StoreVariables(hist, vars);
549     hist->SetUniqueID(valTypeW); // store weighting variable
550
551     Bool_t isReserved=fReservedWords->Contains(histClass);
552     if (isReserved)
553       UserHistogramReservedWords(histClass, hist, 999);
554     else
555       UserHistogram(histClass, hist, 999);
556
557   }
558 }
559
560 //_____________________________________________________________________________
561 void AliDielectronHistos::UserHistogram(const char* histClass, TObject* hist, UInt_t valTypes)
562 {
563   //
564   // Add any type of user histogram
565   //
566
567   //special case for the calss Pair. where histograms will be created for all pair classes
568   Bool_t isReserved=fReservedWords->Contains(histClass);
569   if (isReserved) {
570     UserHistogramReservedWords(histClass, hist, valTypes);
571     return;
572   }
573
574   if (!IsHistogramOk(histClass,hist->GetName())) return;
575   THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
576   //  hist->SetDirectory(0);
577
578   // store variables axis
579   UInt_t valType[20] = {0};
580   // incase valTypes is given old way of extracting variables
581   if(valTypes!=999) {
582     valType[0]=valTypes%1000;          //last three digits
583     valType[1]=valTypes/1000%1000;     //second last three digits
584     valType[2]=valTypes/1000000%1000;  //third last three digits
585     hist->SetUniqueID(valTypes);
586   }
587   else {
588     // extract variables from axis
589     FillVarArray(hist, valType);
590     StoreVariables(hist, valType);
591     hist->SetUniqueID(valType[19]); // store weighting variable
592   }
593
594   classTable->Add(hist);
595 }
596
597 //_____________________________________________________________________________
598 void AliDielectronHistos::AddClass(const char* histClass)
599 {
600   //
601   // Add a class of histograms
602   // Several classes can be added by separating them by a ';' e.g. 'class1;class2;class3'
603   //
604   TString hists(histClass);
605   TObjArray *arr=hists.Tokenize(";");
606   TIter next(arr);
607   TObject *o=0;
608   while ( (o=next()) ){
609     if (fHistoList.FindObject(o->GetName())){
610       Warning("AddClass","Cannot create class '%s' it already exists.",histClass);
611       continue;
612     }
613     if (fReservedWords->Contains(o->GetName())){
614       Error("AddClass","Pair is a reserved word, please use another name");
615       continue;
616     }
617     THashList *table=new THashList;
618     table->SetOwner(kTRUE);
619     table->SetName(o->GetName());
620     fHistoList.Add(table);
621   }
622   delete arr;
623 }
624
625 //_____________________________________________________________________________
626 void AliDielectronHistos::Fill(const char* histClass, const char* name, Double_t xval)
627 {
628   //
629   // Fill function 1D case
630   //
631   THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
632   TH1* hist=0;
633   if (!classTable || !(hist=(TH1*)classTable->FindObject(name)) ){
634     Warning("Fill","Cannot fill histogram. Either class '%s' or histogram '%s' not existing.",histClass,name);
635     return;
636   }
637   hist->Fill(xval);
638 }
639
640 //_____________________________________________________________________________
641 void AliDielectronHistos::Fill(const char* histClass, const char* name, Double_t xval, Double_t yval)
642 {
643   //
644   // Fill function 2D case
645   //
646   THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
647   TH2* hist=0;
648   if (!classTable || !(hist=(TH2*)classTable->FindObject(name)) ){
649     Warning("UserHistogram","Cannot fill histogram. Either class '%s' or histogram '%s' not existing.",histClass,name);
650     return;
651   }
652   hist->Fill(xval,yval);
653 }
654
655 //_____________________________________________________________________________
656 void AliDielectronHistos::Fill(const char* histClass, const char* name, Double_t xval, Double_t yval, Double_t zval)
657 {
658   //
659   // Fill function 3D case
660   //
661   THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
662   TH3* hist=0;
663   if (!classTable || !(hist=(TH3*)classTable->FindObject(name)) ){
664     Warning("UserHistogram","Cannot fill histogram. Either class '%s' or histogram '%s' not existing.",histClass,name);
665     return;
666   }
667   hist->Fill(xval,yval,zval);
668 }
669
670 //_____________________________________________________________________________
671 void AliDielectronHistos::FillClass(const char* histClass, Int_t nValues, const Double_t *values)
672 {
673   //
674   // Fill class 'histClass' (by name)
675   //
676
677   THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
678   if (!classTable){
679     Warning("FillClass","Cannot fill class '%s' its not defined. nValues %d",histClass,nValues);
680     return;
681   }
682
683   TIter nextHist(classTable);
684   TObject *obj=0;
685   while ( (obj=(TObject*)nextHist()) )  FillValues(obj, values);
686
687   return;
688 }
689
690 //_____________________________________________________________________________
691 // void AliDielectronHistos::FillClass(const char* histClass, const TVectorD &vals)
692 // {
693 //   //
694 //   //
695 //   //
696 //   FillClass(histClass, vals.GetNrows(), vals.GetMatrixArray());
697 // }
698
699 //_____________________________________________________________________________
700 void AliDielectronHistos::UserHistogramReservedWords(const char* histClass, const TObject *hist, UInt_t valTypes)
701 {
702   //
703   // Creation of histogram for all pair types
704   //
705   TString title(hist->GetTitle());
706   // Same Event Like Sign
707   TIter nextClass(&fHistoList);
708   THashList *l=0;
709   while ( (l=static_cast<THashList*>(nextClass())) ){
710     TString name(l->GetName());
711     if (name.Contains(histClass)){
712       TObject *h=hist->Clone();
713       // Tobject has no function SetDirectory, didn't we need this???
714       //      h->SetDirectory(0);
715       ((TH1*)h)->SetTitle(Form("%s %s",title.Data(),l->GetName()));
716
717       UserHistogram(l->GetName(),h,valTypes);
718     }
719   }
720   delete hist;
721 }
722
723 //_____________________________________________________________________________
724 void AliDielectronHistos::DumpToFile(const char* file)
725 {
726   //
727   // Dump the histogram list to a newly created root file
728   //
729   TFile f(file,"recreate");
730   fHistoList.Write(fHistoList.GetName(),TObject::kSingleKey);
731   f.Close();
732 }
733
734 //_____________________________________________________________________________
735 TObject* AliDielectronHistos::GetHist(const char* histClass, const char* name) const
736 {
737   //
738   // return object 'name' in 'histClass'
739   //
740   THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
741   if (!classTable) return 0x0;
742   return classTable->FindObject(name);
743 }
744
745 //_____________________________________________________________________________
746 TH1* AliDielectronHistos::GetHistogram(const char* histClass, const char* name) const
747 {
748   //
749   // return histogram 'name' in 'histClass'
750   //
751   return ((TH1*) GetHist(histClass, name));
752 }
753
754 //_____________________________________________________________________________
755 TObject* AliDielectronHistos::GetHist(const char* cutClass, const char* histClass, const char* name) const
756 {
757   //
758   // return object from list of list of histograms
759   // this function is thought for retrieving histograms if a list of AliDielectronHistos is set
760   //
761   
762   if (!fList) return 0x0;
763   THashList *h=dynamic_cast<THashList*>(fList->FindObject(cutClass));
764   if (!h)return 0x0;
765   THashList *classTable=dynamic_cast<THashList*>(h->FindObject(histClass));
766   if (!classTable) return 0x0;
767   return classTable->FindObject(name);
768 }
769
770 //_____________________________________________________________________________
771 TH1* AliDielectronHistos::GetHistogram(const char* cutClass, const char* histClass, const char* name) const
772 {
773   //
774   // return histogram from list of list of histograms
775   // this function is thought for retrieving histograms if a list of AliDielectronHistos is set
776   //
777   return ((TH1*) GetHist(cutClass, histClass, name));
778 }
779
780 //_____________________________________________________________________________
781 void AliDielectronHistos::Draw(const Option_t* option)
782 {
783   //
784   // Draw histograms
785   //
786
787   TString drawStr(option);
788   TObjArray *arr=drawStr.Tokenize(";");
789   arr->SetOwner();
790   TIter nextOpt(arr);
791
792   TString drawClasses;
793   TObjString *ostr=0x0;
794
795   TString currentOpt;
796   TString testOpt;
797   while ( (ostr=(TObjString*)nextOpt()) ){
798     currentOpt=ostr->GetString();
799     currentOpt.Remove(TString::kBoth,'\t');
800     currentOpt.Remove(TString::kBoth,' ');
801
802     testOpt="classes=";
803     if ( currentOpt.Contains(testOpt.Data()) ){
804       drawClasses=currentOpt(testOpt.Length(),currentOpt.Length());
805     }
806   }
807
808   delete arr;
809   drawStr.ToLower();
810   //optionsfList
811 //   Bool_t same=drawOpt.Contains("same"); //FIXME not yet implemented
812
813   TCanvas *c=0x0;
814   if (gVirtualPS) {
815     if (!gPad){
816       Error("Draw","When writing to a file you have to create a canvas before opening the file!!!");
817       return;
818     }
819     c=gPad->GetCanvas();
820     c->cd();
821 //     c=new TCanvas;
822   }
823   
824   TIter nextClass(&fHistoList);
825   THashList *classTable=0;
826 //   Bool_t first=kTRUE;
827   while ( (classTable=(THashList*)nextClass()) ){
828     //test classes option
829     if (!drawClasses.IsNull() && !drawClasses.Contains(classTable->GetName())) continue;
830     //optimised division
831     Int_t nPads = classTable->GetEntries();
832     Int_t nCols = (Int_t)TMath::Ceil( TMath::Sqrt(nPads) );
833     Int_t nRows = (Int_t)TMath::Ceil( (Double_t)nPads/(Double_t)nCols );
834
835     //create canvas
836     if (!gVirtualPS){
837       TString canvasName;
838       canvasName.Form("c%s_%s",GetName(),classTable->GetName());
839       c=(TCanvas*)gROOT->FindObject(canvasName.Data());
840       if (!c) c=new TCanvas(canvasName.Data(),Form("%s: %s",GetName(),classTable->GetName()));
841       c->Clear();
842     } else {
843 //       if (first){
844 //         first=kFALSE;
845 //         if (nPads>1) gVirtualPS->NewPage();
846 //       } else {
847         if (nPads>1) c->Clear();
848 //       }
849     }
850     if (nCols>1||nRows>1) c->Divide(nCols,nRows);
851     
852     //loop over histograms and draw them
853     TIter nextHist(classTable);
854     Int_t iPad=0;
855     TH1 *h=0;
856     while ( (h=(TH1*)nextHist()) ){
857       TString drawOpt;
858       if ( (h->InheritsFrom(TH2::Class())) ) drawOpt="colz";
859       if (nCols>1||nRows>1) c->cd(++iPad);
860       if ( TMath::Abs(h->GetXaxis()->GetBinWidth(1)-h->GetXaxis()->GetBinWidth(2))>1e-10 ) gPad->SetLogx();
861       if ( TMath::Abs(h->GetYaxis()->GetBinWidth(1)-h->GetYaxis()->GetBinWidth(2))>1e-10 ) gPad->SetLogy();
862       if ( TMath::Abs(h->GetZaxis()->GetBinWidth(1)-h->GetZaxis()->GetBinWidth(2))>1e-10 ) gPad->SetLogz();
863       TString histOpt=h->GetOption();
864       histOpt.ToLower();
865       if (histOpt.Contains("logx")) gPad->SetLogx();
866       if (histOpt.Contains("logy")) gPad->SetLogy();
867       if (histOpt.Contains("logz")) gPad->SetLogz();
868       histOpt.ReplaceAll("logx","");
869       histOpt.ReplaceAll("logy","");
870       histOpt.ReplaceAll("logz","");
871       h->Draw(drawOpt.Data());
872     }
873     if (gVirtualPS) {
874       c->Update();
875     }
876     
877   }
878 //   if (gVirtualPS) delete c;
879 }
880
881 //_____________________________________________________________________________
882 void AliDielectronHistos::Print(const Option_t* option) const
883 {
884   //
885   // Print classes and histograms
886   //
887   TString optString(option);
888
889   if (optString.IsNull()) PrintStructure();
890
891
892
893 }
894
895 //_____________________________________________________________________________
896 void AliDielectronHistos::PrintStructure() const
897 {
898   //
899   // Print classes and histograms in the class to stdout
900   //
901   if (!fList){
902     TIter nextClass(&fHistoList);
903     THashList *classTable=0;
904     while ( (classTable=(THashList*)nextClass()) ){
905       TIter nextHist(classTable);
906       TObject *o=0;
907       printf("+ %s\n",classTable->GetName());
908       while ( (o=nextHist()) )
909         printf("| ->%s\n",o->GetName());
910     }
911   } else {
912     TIter nextCutClass(fList);
913     THashList *cutClass=0x0;
914     while ( (cutClass=(THashList*)nextCutClass()) ) {
915       printf("+ %s\n",cutClass->GetName());
916       TIter nextClass(cutClass);
917       THashList *classTable=0;
918       while ( (classTable=(THashList*)nextClass()) ){
919         TIter nextHist(classTable);
920         TObject *o=0;
921         printf("|  + %s\n",classTable->GetName());
922         while ( (o=nextHist()) )
923           printf("|  | ->%s\n",o->GetName());
924       }
925       
926     }
927   }
928 }
929
930 //_____________________________________________________________________________
931 void AliDielectronHistos::SetHistogramList(THashList &list, Bool_t setOwner/*=kTRUE*/)
932 {
933   //
934   // set histogram classes and histograms to this instance. It will take onwnership!
935   //
936   ResetHistogramList();
937   TString name(GetName());
938   if (name == "AliDielectronHistos") SetName(list.GetName());
939   TIter next(&list);
940   TObject *o;
941   while ( (o=next()) ){
942     fHistoList.Add(o);
943   }
944   if (setOwner){
945     list.SetOwner(kFALSE);
946     fHistoList.SetOwner(kTRUE);
947   } else {
948     fHistoList.SetOwner(kFALSE);
949   }
950 }
951
952 //_____________________________________________________________________________
953 Bool_t AliDielectronHistos::SetCutClass(const char* cutClass)
954 {
955   //
956   // Assign histogram list according to cutClass
957   //
958
959   if (!fList) return kFALSE;
960   ResetHistogramList();
961   THashList *h=dynamic_cast<THashList*>(fList->FindObject(cutClass));
962   if (!h) {
963     Warning("SetCutClass","cutClass '%s' not found", cutClass);
964     return kFALSE;
965   }
966   SetHistogramList(*h,kFALSE);
967   return kTRUE;
968 }
969
970 //_____________________________________________________________________________
971 Bool_t AliDielectronHistos::IsHistogramOk(const char* histClass, const char* name)
972 {
973   //
974   // check whether the histogram class exists and the histogram itself does not exist yet
975   //
976   Bool_t isReserved=fReservedWords->Contains(histClass);
977   if (!fHistoList.FindObject(histClass)&&!isReserved){
978     Warning("IsHistogramOk","Cannot create histogram. Class '%s' not defined. Please create it using AddClass before.",histClass);
979     return kFALSE;
980   }
981   if (GetHist(histClass,name)){
982     Warning("IsHistogramOk","Cannot create histogram '%s' in class '%s': It already exists!",name,histClass);
983     return kFALSE;
984   }
985   return kTRUE;
986 }
987
988 // //_____________________________________________________________________________
989 // TIterator* AliDielectronHistos::MakeIterator(Bool_t dir) const
990 // {
991 //   //
992 //   //
993 //   //
994 //   return new TListIter(&fHistoList, dir);
995 // }
996
997 //_____________________________________________________________________________
998 void AliDielectronHistos::ReadFromFile(const char* file)
999 {
1000   //
1001   // Read histos from file
1002   //
1003   TFile f(file);
1004   TIter nextKey(f.GetListOfKeys());
1005   TKey *key=0;
1006   while ( (key=(TKey*)nextKey()) ){
1007     TObject *o=f.Get(key->GetName());
1008     THashList *list=dynamic_cast<THashList*>(o);
1009     if (!list) continue;
1010     SetHistogramList(*list);
1011     break;
1012   }
1013   f.Close();
1014 }
1015
1016 //_____________________________________________________________________________
1017 void AliDielectronHistos::DrawSame(const char* histName, const Option_t *opt)
1018 {
1019   //
1020   // Draw all histograms with the same name into one canvas
1021   // if option contains 'leg' a legend will be created with the class name as caption
1022   // if option contains 'can' a new canvas is created
1023   //
1024
1025   TString optString(opt);
1026   optString.ToLower();
1027   Bool_t optLeg=optString.Contains("leg");
1028   Bool_t optCan=optString.Contains("can");
1029
1030   TLegend *leg=0;
1031   TCanvas *c=0;
1032   if (optCan){
1033     c=(TCanvas*)gROOT->FindObject(Form("c%s",histName));
1034     if (!c) c=new TCanvas(Form("c%s",histName),Form("All '%s' histograms",histName));
1035     c->Clear();
1036     c->cd();
1037   }
1038
1039   if (optLeg) leg=new TLegend(.8,.3,.99,.9);
1040   
1041   Int_t i=0;
1042   TIter next(&fHistoList);
1043   THashList *classTable=0;
1044   Double_t max=-1e10;
1045   TH1 *hFirst=0x0;
1046   while ( (classTable=(THashList*)next()) ){
1047     if ( TH1 *h=(TH1*)classTable->FindObject(histName) ){
1048       if (i==0) hFirst=h;
1049       h->SetLineColor(i+1);
1050       h->SetMarkerColor(i+1);
1051       h->Draw(i>0?"same":"");
1052       if (leg) leg->AddEntry(h,classTable->GetName(),"lp");
1053       ++i;
1054       max=TMath::Max(max,h->GetMaximum());
1055     }
1056   }
1057   if (leg){
1058     leg->SetFillColor(10);
1059     leg->SetY1(.9-i*.05);
1060     leg->Draw();
1061   }
1062   if (hFirst&&(hFirst->GetYaxis()->GetXmax()<max)){
1063     hFirst->SetMaximum(max);
1064   }
1065 }
1066
1067 //_____________________________________________________________________________
1068 void AliDielectronHistos::SetReservedWords(const char* words)
1069 {
1070   //
1071   // set reserved words
1072   //
1073
1074   (*fReservedWords)=words;
1075 }
1076
1077 //_____________________________________________________________________________
1078 void AliDielectronHistos::StoreVariables(TObject *obj, UInt_t valType[20])
1079 {
1080   //
1081   //
1082   //
1083   if (!obj) return;
1084   if      (obj->InheritsFrom(TH1::Class()))         StoreVariables(static_cast<TH1*>(obj), valType);
1085   else if (obj->InheritsFrom(THnBase::Class()))     StoreVariables(static_cast<THnBase*>(obj), valType);
1086
1087   return;
1088
1089 }
1090
1091
1092 //_____________________________________________________________________________
1093 void AliDielectronHistos::StoreVariables(TH1 *obj, UInt_t valType[20])
1094 {
1095   //
1096   // store variables in the axis (special for TProfile3D)
1097   //
1098
1099   Int_t dim   = obj->GetDimension();
1100
1101   // dimension correction for profiles
1102   if(obj->IsA() == TProfile::Class() || obj->IsA() == TProfile2D::Class() || obj->IsA() == TProfile3D::Class()) {
1103     dim++;
1104   }
1105
1106   switch( dim ) {
1107   case 4:
1108     obj->SetUniqueID(valType[3]); // Tprofile3D variable
1109   case 3:
1110     obj->GetZaxis()->SetUniqueID(valType[2]);
1111   case 2:
1112     obj->GetYaxis()->SetUniqueID(valType[1]);
1113   case 1:
1114     obj->GetXaxis()->SetUniqueID(valType[0]);
1115   }
1116
1117   return;
1118 }
1119
1120 //_____________________________________________________________________________
1121 void AliDielectronHistos::StoreVariables(THnBase *obj, UInt_t valType[20])
1122 {
1123   //
1124   // store variables in the axis
1125   //
1126
1127   Int_t dim = obj->GetNdimensions();
1128
1129   for(Int_t it=0; it<dim; it++) {
1130     obj->GetAxis(it)->SetUniqueID(valType[it]);
1131     obj->GetAxis(it)->SetName(Form("%s", AliDielectronVarManager::GetValueName(valType[it])));
1132     obj->GetAxis(it)->SetTitle(Form("%s %s", AliDielectronVarManager::GetValueLabel(valType[it]), AliDielectronVarManager::GetValueUnit(valType[it])));
1133   }
1134   obj->Sumw2();
1135   return;
1136 }
1137
1138 //_____________________________________________________________________________
1139 void AliDielectronHistos::FillValues(TObject *obj, const Double_t *values)
1140 {
1141   //
1142   //
1143   //
1144   if (!obj) return;
1145   if      (obj->InheritsFrom(TH1::Class()))       FillValues(static_cast<TH1*>(obj), values);
1146   else if (obj->InheritsFrom(THnBase::Class()))   FillValues(static_cast<THnBase*>(obj), values);
1147
1148   return;
1149
1150 }
1151
1152 //_____________________________________________________________________________
1153 void AliDielectronHistos::FillValues(TH1 *obj, const Double_t *values)
1154 {
1155   //
1156   // fill values for TH1 inherted classes
1157   //
1158
1159   Int_t dim   = obj->GetDimension();
1160   Bool_t bprf = kFALSE;
1161   //  UInt_t nValues = (UInt_t) AliDielectronVarManager::kNMaxValues;
1162
1163   UInt_t valueTypes=obj->GetUniqueID();
1164   if (valueTypes==(UInt_t)AliDielectronHistos::kNoAutoFill) return;
1165   Bool_t weight = (valueTypes!=kNoWeights);
1166
1167   if(obj->IsA() == TProfile::Class() || obj->IsA() == TProfile2D::Class() || obj->IsA() == TProfile3D::Class())
1168     bprf=kTRUE;
1169
1170   UInt_t value1=obj->GetXaxis()->GetUniqueID();
1171   UInt_t value2=obj->GetYaxis()->GetUniqueID();
1172   UInt_t value3=obj->GetZaxis()->GetUniqueID();
1173   UInt_t value4=obj->GetUniqueID();            // get profile var stored in the unique ID
1174
1175   // ask for inclusive trigger map variables
1176   if(value1!=AliDielectronVarManager::kTriggerInclONL && value1!=AliDielectronVarManager::kTriggerInclOFF &&
1177      value2!=AliDielectronVarManager::kTriggerInclONL && value2!=AliDielectronVarManager::kTriggerInclOFF &&
1178      value3!=AliDielectronVarManager::kTriggerInclONL && value3!=AliDielectronVarManager::kTriggerInclOFF &&
1179      value4!=AliDielectronVarManager::kTriggerInclONL && value4!=AliDielectronVarManager::kTriggerInclOFF ) {
1180     // no trigger map variable selected
1181     switch ( dim ) {
1182     case 1:
1183       if(!bprf && !weight)     obj->Fill(values[value1]);                 // histograms
1184       else if(!bprf && weight) obj->Fill(values[value1], values[value4]); // weighted histograms
1185       else if(bprf && !weight) ((TProfile*)obj)->Fill(values[value1],values[value2]);   // profiles
1186       else                     ((TProfile*)obj)->Fill(values[value1],values[value2], values[value4]); // weighted profiles
1187       break;
1188     case 2:
1189       if(!bprf && !weight)     obj->Fill(values[value1], values[value2]);                 // histograms
1190       else if(!bprf && weight) ((TH2*)obj)->Fill(values[value1], values[value2], values[value4]); // weighted histograms
1191       else if(bprf && !weight) ((TProfile2D*)obj)->Fill(values[value1], values[value2], values[value3]); // profiles
1192       else                     ((TProfile2D*)obj)->Fill(values[value1], values[value2], values[value3], values[value4]); // weighted profiles
1193       break;
1194     case 3:
1195       if(!bprf && !weight)     ((TH3*)obj)->Fill(values[value1], values[value2], values[value3]);                 // histograms
1196       else if(!bprf && weight) ((TH3*)obj)->Fill(values[value1], values[value2], values[value3], values[value4]); // weighted histograms
1197       else if(bprf && !weight) ((TProfile3D*)obj)->Fill(values[value1], values[value2], values[value3], values[value4]); // profiles
1198       else                     printf(" WARNING: weighting NOT possible yet for TProfile3Ds ! \n");
1199       break;
1200     }
1201   }
1202   else {
1203     // fill inclusive trigger map variables
1204     if(weight) return;
1205     switch ( dim ) {
1206     case 1:
1207       for(Int_t i=0; i<30; i++) { if(TESTBIT((UInt_t)values[value1],i)) obj->Fill(i); }
1208       break;
1209     case 2:
1210       if((value1==AliDielectronVarManager::kTriggerInclOFF && value2==AliDielectronVarManager::kTriggerInclONL) ||
1211          (value1==AliDielectronVarManager::kTriggerInclONL && value2==AliDielectronVarManager::kTriggerInclOFF) ) {
1212         for(Int_t i=0; i<30; i++) {
1213           if((UInt_t)values[value1]==BIT(i)) {
1214             for(Int_t i2=0; i2<30; i2++) {
1215               if((UInt_t)values[value2]==BIT(i2)) {
1216                 obj->Fill(i, i2);
1217               } // bit fired
1218             } //loop 2
1219           }//bit fired
1220         } // loop 1
1221       }
1222       else if(value1==AliDielectronVarManager::kTriggerInclONL || value1==AliDielectronVarManager::kTriggerInclOFF) {
1223         for(Int_t i=0; i<30; i++) { if(TESTBIT((UInt_t)values[value1],i)) obj->Fill(i, values[value2]); }
1224       }
1225       else if(value2==AliDielectronVarManager::kTriggerInclONL || value2==AliDielectronVarManager::kTriggerInclOFF) {
1226         for(Int_t i=0; i<30; i++) { if(TESTBIT((UInt_t)values[value2],i)) obj->Fill(values[value1], i); }
1227       }
1228       else //makes no sense
1229         return;
1230       break;
1231     default: return;
1232     }
1233
1234   } //end: trigger filling
1235
1236
1237   return;
1238 }
1239
1240 //_____________________________________________________________________________
1241 void AliDielectronHistos::FillValues(THnBase *obj, const Double_t *values)
1242 {
1243   //
1244   // fill values for THn inherted classes
1245   //
1246
1247   const Int_t dim   = obj->GetNdimensions();
1248
1249   UInt_t valueTypes=obj->GetUniqueID();
1250   if (valueTypes==(UInt_t)AliDielectronHistos::kNoAutoFill) return;
1251   Bool_t weight = (valueTypes!=kNoWeights);
1252
1253   UInt_t value4=obj->GetUniqueID();            // weight variable
1254
1255   Double_t fill[dim];
1256   for(Int_t it=0; it<dim; it++)   fill[it] = values[obj->GetAxis(it)->GetUniqueID()];
1257   if(!weight) obj->Fill(fill);
1258   else obj->Fill(fill, values[value4]);
1259
1260
1261   return;
1262 }
1263
1264 //_____________________________________________________________________________
1265 void AliDielectronHistos::FillVarArray(TObject *obj, UInt_t *valType)
1266 {
1267   //
1268   // extract variables stored in the axis (special for TProfile3D)
1269   //
1270
1271
1272   if (!obj) return;
1273   //  printf(" fillvararray %s \n",obj->GetName());
1274
1275   if (obj->InheritsFrom(TH1::Class())) {
1276     valType[0]=((TH1*)obj)->GetXaxis()->GetUniqueID();
1277     valType[1]=((TH1*)obj)->GetYaxis()->GetUniqueID();
1278     valType[2]=((TH1*)obj)->GetZaxis()->GetUniqueID();
1279     valType[3]=((TH1*)obj)->GetUniqueID();  // tprofile var stored in unique ID
1280   }
1281   else if (obj->InheritsFrom(THnBase::Class())) {
1282     for(Int_t it=0; it<((THn*)obj)->GetNdimensions(); it++)
1283       valType[it]=((THn*)obj)->GetAxis(it)->GetUniqueID();
1284   }
1285   valType[19]=obj->GetUniqueID(); //weights
1286   return;
1287 }
1288
1289 //_____________________________________________________________________________
1290 void AliDielectronHistos::AdaptNameTitle(TH1 *hist, const char* histClass) {
1291
1292   //
1293   // adapt name and title of the histogram
1294   //
1295
1296   Int_t dim            = hist->GetDimension();
1297   TString currentName  = hist->GetName();
1298   TString currentTitle = hist->GetTitle();
1299
1300
1301   Bool_t bname  = (currentName.IsNull());
1302   Bool_t btitle = (currentTitle.IsNull());
1303   Bool_t bprf   = kFALSE;
1304   if(hist->IsA() == TProfile::Class() || hist->IsA() == TProfile2D::Class() || hist->IsA() == TProfile3D::Class())
1305     bprf=kTRUE;
1306
1307   // tprofile options
1308   Double_t pmin=0., pmax=0.;
1309   TString option = "", calcrange="";
1310   Bool_t bStdOpt=kTRUE;
1311   if(bprf) {
1312     switch( dim ) {
1313     case 3:
1314       option = ((TProfile3D*)hist)->GetErrorOption();
1315       pmin   = ((TProfile3D*)hist)->GetTmin();
1316       pmax   = ((TProfile3D*)hist)->GetTmax();
1317       break;
1318     case 2:
1319       option = ((TProfile2D*)hist)->GetErrorOption();
1320       pmin   = ((TProfile2D*)hist)->GetZmin();
1321       pmax   = ((TProfile2D*)hist)->GetZmax();
1322       break;
1323     case 1:
1324       option = ((TProfile*)hist)->GetErrorOption();
1325       pmin   = ((TProfile*)hist)->GetYmin();
1326       pmax   = ((TProfile*)hist)->GetYmax();
1327       break;
1328     }
1329     if(option.Contains("s",TString::kIgnoreCase)) bStdOpt=kFALSE;
1330     if(pmin!=pmax) calcrange=Form("#cbar_{%+.*f}^{%+.*f}",GetPrecision(pmin),pmin,GetPrecision(pmax),pmax);
1331   }
1332
1333   UInt_t varx = hist->GetXaxis()->GetUniqueID();
1334   UInt_t vary = hist->GetYaxis()->GetUniqueID();
1335   UInt_t varz = hist->GetZaxis()->GetUniqueID();
1336   UInt_t varp = hist->GetUniqueID();
1337   Bool_t weight = (varp!=kNoWeights);
1338
1339   // store titles in the axis
1340   if(btitle) {
1341     switch( dim ) {
1342     case 3:
1343       hist->GetXaxis()->SetNameTitle(AliDielectronVarManager::GetValueName(varx),
1344                                      Form("%s %s",
1345                                       AliDielectronVarManager::GetValueLabel(varx),
1346                                       AliDielectronVarManager::GetValueUnit(varx))
1347                                  );
1348       hist->GetYaxis()->SetNameTitle(AliDielectronVarManager::GetValueName(vary),
1349                                      Form("%s %s",
1350                                       AliDielectronVarManager::GetValueLabel(vary),
1351                                       AliDielectronVarManager::GetValueUnit(vary))
1352                                  );
1353       hist->GetZaxis()->SetNameTitle(AliDielectronVarManager::GetValueName(varz),
1354                                      Form("%s %s",
1355                                       AliDielectronVarManager::GetValueLabel(varz),
1356                                       AliDielectronVarManager::GetValueUnit(varz))
1357                                  );
1358       if(bprf)
1359         hist->SetNameTitle(AliDielectronVarManager::GetValueName(varp),
1360                            Form("%s  %s%s%s%s %s",
1361                             hist->GetTitle(),
1362                             (bStdOpt ? "#LT" : "RMS("),
1363                             AliDielectronVarManager::GetValueLabel(varp),
1364                             (bStdOpt ? "#GT" : ")"),
1365                             calcrange.Data(),
1366                             AliDielectronVarManager::GetValueUnit(varp))
1367                        );
1368       break;
1369     case 2:
1370       hist->GetXaxis()->SetNameTitle(AliDielectronVarManager::GetValueName(varx),
1371                                      Form("%s %s",
1372                                       AliDielectronVarManager::GetValueLabel(varx),
1373                                       AliDielectronVarManager::GetValueUnit(varx))
1374                                  );
1375       hist->GetYaxis()->SetNameTitle(AliDielectronVarManager::GetValueName(vary),
1376                                      Form("%s %s",
1377                                       AliDielectronVarManager::GetValueLabel(vary),
1378                                       AliDielectronVarManager::GetValueUnit(vary))
1379                                  );
1380       hist->GetZaxis()->SetTitle(Form("#%ss",histClass));
1381       if(bprf)
1382         hist->GetZaxis()->SetNameTitle(AliDielectronVarManager::GetValueName(varz),
1383                                        Form("%s%s%s%s %s",
1384                                         (bStdOpt ? "#LT" : "RMS("),
1385                                         AliDielectronVarManager::GetValueLabel(varz),
1386                                         (bStdOpt ? "#GT" : ")"),
1387                                         calcrange.Data(),
1388                                         AliDielectronVarManager::GetValueUnit(varz))
1389                                    );
1390       if(weight) hist->GetZaxis()->SetTitle(Form("%s weighted %s",
1391                                                  AliDielectronVarManager::GetValueLabel(varp),
1392                                                  hist->GetZaxis()->GetTitle() )
1393                                             );
1394
1395       break;
1396     case 1:
1397       hist->GetXaxis()->SetNameTitle(AliDielectronVarManager::GetValueName(varx),
1398                                      Form("%s %s",
1399                                       AliDielectronVarManager::GetValueLabel(varx),
1400                                       AliDielectronVarManager::GetValueUnit(varx))
1401                                  );
1402       hist->GetYaxis()->SetTitle(Form("#%ss",histClass));
1403       if(bprf)
1404         hist->GetYaxis()->SetNameTitle(AliDielectronVarManager::GetValueName(vary),
1405                                        Form("%s%s%s%s %s",
1406                                         (bStdOpt ? "#LT" : "RMS("),
1407                                         AliDielectronVarManager::GetValueLabel(vary), 
1408                                         (bStdOpt ? "#GT" : ")"),
1409                                         calcrange.Data(),
1410                                         AliDielectronVarManager::GetValueUnit(vary))
1411                                    );
1412       if(weight) hist->GetYaxis()->SetTitle(Form("%s weighted %s",
1413                                                  AliDielectronVarManager::GetValueLabel(varp),
1414                                                  hist->GetYaxis()->GetTitle() )
1415                                             );
1416
1417       break;
1418     }
1419
1420     // create an unique name
1421     if(bname)
1422       switch(dim) {
1423       case 3:
1424         currentName+=Form("%s_",AliDielectronVarManager::GetValueName(varx));
1425         currentName+=Form("%s_",AliDielectronVarManager::GetValueName(vary));
1426         currentName+=Form("%s",AliDielectronVarManager::GetValueName(varz));
1427         if(bprf)   currentName+=Form("-%s%s",AliDielectronVarManager::GetValueName(varp),(bStdOpt ? "avg" : "rms"));
1428         if(weight) currentName+=Form("-wght%s",AliDielectronVarManager::GetValueName(varp));
1429         break;
1430       case 2:
1431         currentName+=Form("%s_",AliDielectronVarManager::GetValueName(varx));
1432         currentName+=Form("%s",AliDielectronVarManager::GetValueName(vary));
1433         if(bprf)   currentName+=Form("-%s%s",AliDielectronVarManager::GetValueName(varz),(bStdOpt ? "avg" : "rms"));
1434         if(weight) currentName+=Form("-wght%s",AliDielectronVarManager::GetValueName(varp));
1435         break;
1436       case 1:
1437         currentName+=Form("%s",AliDielectronVarManager::GetValueName(varx));
1438         if(bprf)   currentName+=Form("-%s%s",AliDielectronVarManager::GetValueName(vary),(bStdOpt ? "avg" : "rms"));
1439         if(weight) currentName+=Form("-wght%s",AliDielectronVarManager::GetValueName(varp));
1440         break;
1441       }
1442     // to differentiate btw. leg and pair histos
1443     if(!strcmp(histClass,"Pair")) currentName.Prepend("p");
1444     hist->SetName(currentName.Data());
1445   }
1446
1447 }
1448
1449 Int_t AliDielectronHistos::GetPrecision(Double_t value) {
1450
1451   //
1452   // computes the precision of a double
1453   // usefull for axis ranges etc
1454   //
1455
1456   Bool_t bfnd     = kFALSE;
1457   Int_t precision = 0;
1458   value*=1e6;
1459   while(!bfnd) {
1460     //    printf(" value %f precision %d bfnd %d \n",TMath::Abs(value*TMath::Power(10,precision)), precision, bfnd);
1461     bfnd = ((TMath::Abs(value*TMath::Power(10,precision))/1e6  -  TMath::Floor(TMath::Abs(value*TMath::Power(10,precision))/1e6)) != 0.0
1462             ? kFALSE
1463             : kTRUE);
1464     if(!bfnd) precision++;
1465   }
1466
1467   //  printf("precision for %f found to be %d \n", value, precision);
1468   return precision;
1469
1470 }
1471
1472
1473