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