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