]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGDQ/dielectron/AliDielectronHistos.cxx
o update dielectron package
[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 <TProfile.h>
30 #include <TProfile2D.h>
31 #include <TProfile3D.h>
32 #include <TCollection.h>
33 #include <THashList.h>
34 #include <TString.h>
35 #include <TObjString.h>
36 #include <TObjArray.h>
37 #include <TFile.h>
38 #include <TError.h>
39 #include <TCanvas.h>
40 #include <TMath.h>
41 #include <TROOT.h>
42 #include <TLegend.h>
43 #include <TKey.h>
44 #include <TAxis.h>
45 #include <TVirtualPS.h>
46 #include <TVectorD.h>
47
48 #include "AliDielectronHelper.h"
49 #include "AliDielectronHistos.h"
50
51
52 ClassImp(AliDielectronHistos)
53
54
55 AliDielectronHistos::AliDielectronHistos() :
56 //   TCollection(),
57   TNamed("AliDielectronHistos","Dielectron Histogram Container"),
58   fHistoList(),
59   fList(0x0),
60   fReservedWords(new TString)
61 {
62   //
63   // Default constructor
64   //
65   fHistoList.SetOwner(kTRUE);
66   fHistoList.SetName("Dielectron_Histos");
67 }
68
69 //_____________________________________________________________________________
70 AliDielectronHistos::AliDielectronHistos(const char* name, const char* title) :
71 //   TCollection(),
72   TNamed(name, title),
73   fHistoList(),
74   fList(0x0),
75   fReservedWords(new TString)
76 {
77   //
78   // TNamed constructor
79   //
80   fHistoList.SetOwner(kTRUE);
81   fHistoList.SetName(name);
82 }
83
84 //_____________________________________________________________________________
85 AliDielectronHistos::~AliDielectronHistos()
86 {
87   //
88   // Destructor
89   //
90   fHistoList.Clear();
91   if (fList) fList->Clear();
92   delete fReservedWords;
93 }
94
95 //_____________________________________________________________________________
96 void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
97                                       UInt_t valTypeP,
98                                       Int_t nbinsX, Double_t xmin, Double_t xmax,
99                                       UInt_t valTypeX, Bool_t logBinX)
100 {
101   //
102   // Default histogram creation 1D case
103   //
104
105   TVectorD *binLimX=0x0;
106   
107   if (logBinX) {
108     binLimX=AliDielectronHelper::MakeLogBinning(nbinsX, xmin, xmax);
109   } else {
110     binLimX=AliDielectronHelper::MakeLinBinning(nbinsX, xmin, xmax);
111   }
112   UserProfile(histClass,name,title,valTypeP,binLimX,valTypeX);
113 }
114
115 //_____________________________________________________________________________
116 void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
117                                       UInt_t valTypeP,
118                                       Int_t nbinsX, Double_t xmin, Double_t xmax,
119                                       Int_t nbinsY, Double_t ymin, Double_t ymax,
120                                       UInt_t valTypeX, UInt_t valTypeY,
121                                       Bool_t logBinX, Bool_t logBinY)
122 {
123   //
124   // Default histogram creation 2D case
125   //
126   if (!IsHistogramOk(histClass,name)) return;
127
128   TVectorD *binLimX=0x0;
129   TVectorD *binLimY=0x0;
130   
131   if (logBinX) {
132     binLimX=AliDielectronHelper::MakeLogBinning(nbinsX, xmin, xmax);
133   } else {
134     binLimX=AliDielectronHelper::MakeLinBinning(nbinsX, xmin, xmax);
135   }
136   if (logBinY) {
137     binLimY=AliDielectronHelper::MakeLogBinning(nbinsY, ymin, ymax);
138   } else {
139     binLimY=AliDielectronHelper::MakeLinBinning(nbinsY, ymin, ymax);
140   }
141   UserProfile(histClass,name,title,valTypeP,binLimX,binLimY,valTypeX,valTypeY);
142 }
143
144
145 //_____________________________________________________________________________
146 void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
147                                       UInt_t valTypeP,
148                                       Int_t nbinsX, Double_t xmin, Double_t xmax,
149                                       Int_t nbinsY, Double_t ymin, Double_t ymax,
150                                       Int_t nbinsZ, Double_t zmin, Double_t zmax,
151                                       UInt_t valTypeX, UInt_t valTypeY, UInt_t valTypeZ,
152                                       Bool_t logBinX, Bool_t logBinY, Bool_t logBinZ)
153 {
154   //
155   // Default histogram creation 3D case
156   //
157   if (!IsHistogramOk(histClass,name)) return;
158
159   TVectorD *binLimX=0x0;
160   TVectorD *binLimY=0x0;
161   TVectorD *binLimZ=0x0;
162   
163   if (logBinX) {
164     binLimX=AliDielectronHelper::MakeLogBinning(nbinsX, xmin, xmax);
165   } else {
166     binLimX=AliDielectronHelper::MakeLinBinning(nbinsX, xmin, xmax);
167   }
168   
169   if (logBinY) {
170     binLimY=AliDielectronHelper::MakeLogBinning(nbinsY, ymin, ymax);
171   } else {
172     binLimY=AliDielectronHelper::MakeLinBinning(nbinsY, ymin, ymax);
173   }
174   
175   if (logBinZ) {
176     binLimZ=AliDielectronHelper::MakeLogBinning(nbinsZ, zmin, zmax);
177   } else {
178     binLimZ=AliDielectronHelper::MakeLinBinning(nbinsZ, zmin, zmax);
179   }
180
181   UserProfile(histClass,name,title,valTypeP,binLimX,binLimY,binLimZ,valTypeX,valTypeY,valTypeZ);
182 }
183
184 //_____________________________________________________________________________
185 void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
186                                       UInt_t valTypeP,
187                                       const char* binning,
188                                       UInt_t valTypeX)
189 {
190   //
191   // Histogram creation 1D case with arbitraty binning
192   //
193
194   TVectorD *binLimX=AliDielectronHelper::MakeArbitraryBinning(binning);
195   UserProfile(histClass,name,title,valTypeP,binLimX,valTypeX);
196 }
197
198 //_____________________________________________________________________________
199 void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
200                                       UInt_t valTypeP,
201                                       const TVectorD * const binsX,
202                                       UInt_t valTypeX/*=kNoAutoFill*/)
203 {
204   //
205   // Histogram creation 1D case with arbitraty binning X
206   // the TVectorD is assumed to be surplus after the creation and will be deleted!!!
207   //
208
209   Bool_t isOk=kTRUE;
210   isOk&=IsHistogramOk(histClass,name);
211   isOk&=(binsX!=0x0);
212   TH1 *hist=0x0;
213   
214   if (isOk){
215     if(valTypeP==999)
216       hist=new TH1F(name,title,binsX->GetNrows()-1,binsX->GetMatrixArray());
217     else {
218       hist=new TProfile(name,title,binsX->GetNrows()-1,binsX->GetMatrixArray());
219     }
220
221     // store var for profile in fBits
222     StoreVarForProfile(hist,valTypeP);
223
224     Bool_t isReserved=fReservedWords->Contains(histClass);
225     UInt_t uniqueID = valTypeX;
226     if(valTypeP!=999) uniqueID |= 0x80000000; // set last bit to 1 (for profiles only)
227     if (isReserved)
228       UserHistogramReservedWords(histClass, hist, uniqueID);
229     else
230       UserHistogram(histClass, hist, uniqueID);
231   }
232   
233   delete binsX;
234 }
235
236 //_____________________________________________________________________________
237 void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
238                                       UInt_t valTypeP,
239                                       const TVectorD * const binsX, const TVectorD * const binsY,
240                                       UInt_t valTypeX/*=kNoAutoFill*/, UInt_t valTypeY/*=0*/)
241 {
242   //
243   // Histogram creation 2D case with arbitraty binning X
244   // the TVectorD is assumed to be surplus after the creation and will be deleted!!!
245   //
246
247   Bool_t isOk=kTRUE;
248   isOk&=IsHistogramOk(histClass,name);
249   isOk&=(binsX!=0x0);
250   isOk&=(binsY!=0x0);
251   TH1 *hist=0x0;
252
253   if (isOk){
254     if(valTypeP==999) {
255       hist=new TH2F(name,title,
256                     binsX->GetNrows()-1,binsX->GetMatrixArray(),
257                     binsY->GetNrows()-1,binsY->GetMatrixArray()); 
258     }
259     else 
260       hist=new TProfile2D(name,title,
261                           binsX->GetNrows()-1,binsX->GetMatrixArray(),
262                           binsY->GetNrows()-1,binsY->GetMatrixArray());
263     
264     // store var for profile in fBits
265     StoreVarForProfile(hist,valTypeP);
266
267     Bool_t isReserved=fReservedWords->Contains(histClass);
268     // switched from 2 digits encoding to 3 digits
269     UInt_t uniqueID = valTypeX+1000*valTypeY;
270     if(valTypeP!=999) uniqueID |= 0x80000000; // set last bit to 1 (for profiles only)
271
272     if (isReserved)
273       UserHistogramReservedWords(histClass, hist, uniqueID);
274     else
275       UserHistogram(histClass, hist, uniqueID);
276   }
277   
278   delete binsX;
279   delete binsY;
280   
281 }
282
283 //_____________________________________________________________________________
284 void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
285                                       UInt_t valTypeP,
286                                       const TVectorD * const binsX, const TVectorD * const binsY, const TVectorD * const binsZ,
287                                       UInt_t valTypeX/*=kNoAutoFill*/, UInt_t valTypeY/*=0*/, UInt_t valTypeZ/*=0*/)
288 {
289   //
290   // Histogram creation 3D case with arbitraty binning X
291   // the TVectorD is assumed to be surplus after the creation and will be deleted!!!
292   //
293
294   Bool_t isOk=kTRUE;
295   isOk&=IsHistogramOk(histClass,name);
296   isOk&=(binsX!=0x0);
297   isOk&=(binsY!=0x0);
298   isOk&=(binsZ!=0x0);
299   TH1 *hist=0x0;
300   
301   if (isOk){
302     if(valTypeP==999)
303       hist=new TH3F(name,title,
304                     binsX->GetNrows()-1,binsX->GetMatrixArray(),
305                     binsY->GetNrows()-1,binsY->GetMatrixArray(),
306                     binsZ->GetNrows()-1,binsZ->GetMatrixArray());
307     else
308       hist=new TProfile3D(name,title,
309                           binsX->GetNrows()-1,binsX->GetMatrixArray(),
310                           binsY->GetNrows()-1,binsY->GetMatrixArray(),
311                           binsZ->GetNrows()-1,binsZ->GetMatrixArray());
312     
313     // store var for profile in fBits
314     StoreVarForProfile(hist,valTypeP);
315     
316     Bool_t isReserved=fReservedWords->Contains(histClass);
317     // switched from 2 digits encoding to 3 digits
318     UInt_t uniqueID = valTypeX+1000*valTypeY+1000000*valTypeZ;
319     if(valTypeP!=999) uniqueID |= 0x80000000; // set last bit to 1 (for profiles only)
320
321     if (isReserved)
322       UserHistogramReservedWords(histClass, hist, uniqueID);
323     else
324       UserHistogram(histClass, hist, uniqueID);
325   }
326   
327   delete binsX;
328   delete binsY;
329   delete binsZ;
330 }
331
332 //_____________________________________________________________________________
333 void AliDielectronHistos::UserHistogram(const char* histClass, TH1* hist, UInt_t valTypes)
334 {
335   //
336   // Add any type of user histogram
337   //
338
339   //special case for the calss Pair. where histograms will be created for all pair classes
340   Bool_t isReserved=fReservedWords->Contains(histClass);
341   if (isReserved) {
342     UserHistogramReservedWords(histClass, hist, valTypes);
343     return;
344   }
345   
346   if (!IsHistogramOk(histClass,hist->GetName())) return;
347   
348   THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
349   hist->SetDirectory(0);
350   hist->SetUniqueID(valTypes);
351
352   classTable->Add(hist);
353 }
354
355 //_____________________________________________________________________________
356 void AliDielectronHistos::AddClass(const char* histClass)
357 {
358   //
359   // Add a class of histograms
360   // Several classes can be added by separating them by a ';' e.g. 'class1;class2;class3'
361   //
362   TString hists(histClass);
363   TObjArray *arr=hists.Tokenize(";");
364   TIter next(arr);
365   TObject *o=0;
366   while ( (o=next()) ){
367     if (fHistoList.FindObject(o->GetName())){
368       Warning("AddClass","Cannot create class '%s' it already exists.",histClass);
369       continue;
370     }
371     if (fReservedWords->Contains(o->GetName())){
372       Error("AddClass","Pair is a reserved word, please use another name");
373       continue;
374     }
375     THashList *table=new THashList;
376     table->SetOwner(kTRUE);
377     table->SetName(o->GetName());
378     fHistoList.Add(table);
379   }
380   delete arr;
381 }
382
383 //_____________________________________________________________________________
384 void AliDielectronHistos::Fill(const char* histClass, const char* name, Double_t xval)
385 {
386   //
387   // Fill function 1D case
388   //
389   THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
390   TH1* hist=0;
391   if (!classTable || !(hist=(TH1*)classTable->FindObject(name)) ){
392     Warning("Fill","Cannot fill histogram. Either class '%s' or histogram '%s' not existing.",histClass,name);
393     return;
394   }
395   hist->Fill(xval);
396 }
397
398 //_____________________________________________________________________________
399 void AliDielectronHistos::Fill(const char* histClass, const char* name, Double_t xval, Double_t yval)
400 {
401   //
402   // Fill function 2D case
403   //
404   THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
405   TH2* hist=0;
406   if (!classTable || !(hist=(TH2*)classTable->FindObject(name)) ){
407     Warning("UserHistogram","Cannot fill histogram. Either class '%s' or histogram '%s' not existing.",histClass,name);
408     return;
409   }
410   hist->Fill(xval,yval);
411 }
412
413 //_____________________________________________________________________________
414 void AliDielectronHistos::Fill(const char* histClass, const char* name, Double_t xval, Double_t yval, Double_t zval)
415 {
416   //
417   // Fill function 3D case
418   //
419   THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
420   TH3* hist=0;
421   if (!classTable || !(hist=(TH3*)classTable->FindObject(name)) ){
422     Warning("UserHistogram","Cannot fill histogram. Either class '%s' or histogram '%s' not existing.",histClass,name);
423     return;
424   }
425   hist->Fill(xval,yval,zval);
426 }
427
428 //_____________________________________________________________________________
429 void AliDielectronHistos::FillClass(const char* histClass, Int_t nValues, const Double_t *values)
430 {
431   //
432   // Fill class 'histClass' (by name)
433   //  
434   
435   THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
436   if (!classTable){
437     Warning("FillClass","Cannot fill class '%s' its not defined.",histClass);
438     return;
439   }
440   
441   TIter nextHist(classTable);
442   TH1 *hist=0;
443   while ( (hist=(TH1*)nextHist()) ){
444     UInt_t value4=hist->TestBits(0x00ffffff)>>14;     // get profile var stored in fBits
445     UInt_t valueTypes=hist->GetUniqueID()&0x7fffffff; // ignore "boolean" bit for profiles
446     
447     if (valueTypes==(UInt_t)kNoAutoFill) continue;
448     UInt_t value1=valueTypes%1000;          //last three digits
449     UInt_t value2=valueTypes/1000%1000;     //second last three digits
450     UInt_t value3=valueTypes/1000000%1000;  //third last three digits
451     
452     if (value1>=(UInt_t)nValues||value2>=(UInt_t)nValues||value3>=(UInt_t)nValues||(value4>=(UInt_t)nValues && value4!=999)) {
453       Warning("FillClass","One of the values is out of range. Not filling Histogram '%s/%s'.", histClass, hist->GetName());
454       continue;
455     }
456     switch (hist->GetDimension()){
457     case 1:
458       if(value4==999) hist->Fill(values[value1]);                    // histograms
459       else ((TProfile*)hist)->Fill(values[value1],values[value4]);   // profiles
460       break;
461     case 2:
462       if(value4==999) ((TH2*)hist)->Fill(values[value1],values[value2]);
463       else ((TProfile2D*)hist)->Fill(values[value1],values[value2],values[value4]);
464       break;
465     case 3:
466       if(value4==999) ((TH3*)hist)->Fill(values[value1],values[value2],values[value3]);
467       else ((TProfile3D*)hist)->Fill(values[value1],values[value2],values[value3],values[value4]);
468       break;
469     }
470   }
471 }
472
473 //_____________________________________________________________________________
474 // void AliDielectronHistos::FillClass(const char* histClass, const TVectorD &vals)
475 // {
476 //   //
477 //   //
478 //   //
479 //   FillClass(histClass, vals.GetNrows(), vals.GetMatrixArray());
480 // }
481
482 //_____________________________________________________________________________
483 void AliDielectronHistos::UserHistogramReservedWords(const char* histClass, const TH1 *hist, UInt_t valTypes)
484 {
485   //
486   // Creation of histogram for all pair types
487   //
488   TString title(hist->GetTitle());
489   // Same Event Like Sign
490   TIter nextClass(&fHistoList);
491   THashList *l=0;
492   while ( (l=static_cast<THashList*>(nextClass())) ){
493     TString name(l->GetName());
494     if (name.Contains(histClass)){
495       TH1 *h=static_cast<TH1*>(hist->Clone());
496       h->SetDirectory(0);
497       h->SetTitle(Form("%s %s",title.Data(),l->GetName()));
498
499       UserHistogram(l->GetName(),h,valTypes);
500     }
501   }
502   delete hist;
503 }
504
505 //_____________________________________________________________________________
506 void AliDielectronHistos::DumpToFile(const char* file)
507 {
508   //
509   // Dump the histogram list to a newly created root file
510   //
511   TFile f(file,"recreate");
512   fHistoList.Write(fHistoList.GetName(),TObject::kSingleKey);
513   f.Close();
514 }
515
516 //_____________________________________________________________________________
517 TH1* AliDielectronHistos::GetHistogram(const char* histClass, const char* name) const
518 {
519   //
520   // return histogram 'name' in 'histClass'
521   //
522   THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
523   if (!classTable) return 0x0;
524   return (TH1*)classTable->FindObject(name);
525 }
526
527 //_____________________________________________________________________________
528 TH1* AliDielectronHistos::GetHistogram(const char* cutClass, const char* histClass, const char* name) const
529 {
530   //
531   // return histogram from list of list of histograms
532   // this function is thought for retrieving histograms if a list of AliDielectronHistos is set
533   //
534   
535   if (!fList) return 0x0;
536   THashList *h=dynamic_cast<THashList*>(fList->FindObject(cutClass));
537   if (!h)return 0x0;
538   THashList *classTable=dynamic_cast<THashList*>(h->FindObject(histClass));
539   if (!classTable) return 0x0;
540   return (TH1*)classTable->FindObject(name);
541 }
542
543 //_____________________________________________________________________________
544 void AliDielectronHistos::Draw(const Option_t* option)
545 {
546   //
547   // Draw histograms
548   //
549
550   TString drawStr(option);
551   TObjArray *arr=drawStr.Tokenize(";");
552   arr->SetOwner();
553   TIter nextOpt(arr);
554
555   TString drawClasses;
556   TObjString *ostr=0x0;
557
558   TString currentOpt;
559   TString testOpt;
560   while ( (ostr=(TObjString*)nextOpt()) ){
561     currentOpt=ostr->GetString();
562     currentOpt.Remove(TString::kBoth,'\t');
563     currentOpt.Remove(TString::kBoth,' ');
564
565     testOpt="classes=";
566     if ( currentOpt.Contains(testOpt.Data()) ){
567       drawClasses=currentOpt(testOpt.Length(),currentOpt.Length());
568     }
569   }
570
571   delete arr;
572   drawStr.ToLower();
573   //optionsfList
574 //   Bool_t same=drawOpt.Contains("same"); //FIXME not yet implemented
575
576   TCanvas *c=0x0;
577   if (gVirtualPS) {
578     if (!gPad){
579       Error("Draw","When writing to a file you have to create a canvas before opening the file!!!");
580       return;
581     }
582     c=gPad->GetCanvas();
583     c->cd();
584 //     c=new TCanvas;
585   }
586   
587   TIter nextClass(&fHistoList);
588   THashList *classTable=0;
589 //   Bool_t first=kTRUE;
590   while ( (classTable=(THashList*)nextClass()) ){
591     //test classes option
592     if (!drawClasses.IsNull() && !drawClasses.Contains(classTable->GetName())) continue;
593     //optimised division
594     Int_t nPads = classTable->GetEntries();
595     Int_t nCols = (Int_t)TMath::Ceil( TMath::Sqrt(nPads) );
596     Int_t nRows = (Int_t)TMath::Ceil( (Double_t)nPads/(Double_t)nCols );
597
598     //create canvas
599     if (!gVirtualPS){
600       TString canvasName;
601       canvasName.Form("c%s_%s",GetName(),classTable->GetName());
602       c=(TCanvas*)gROOT->FindObject(canvasName.Data());
603       if (!c) c=new TCanvas(canvasName.Data(),Form("%s: %s",GetName(),classTable->GetName()));
604       c->Clear();
605     } else {
606 //       if (first){
607 //         first=kFALSE;
608 //         if (nPads>1) gVirtualPS->NewPage();
609 //       } else {
610         if (nPads>1) c->Clear();
611 //       }
612     }
613     if (nCols>1||nRows>1) c->Divide(nCols,nRows);
614     
615     //loop over histograms and draw them
616     TIter nextHist(classTable);
617     Int_t iPad=0;
618     TH1 *h=0;
619     while ( (h=(TH1*)nextHist()) ){
620       TString drawOpt;
621       if ( (h->InheritsFrom(TH2::Class())) ) drawOpt="colz";
622       if (nCols>1||nRows>1) c->cd(++iPad);
623       if ( TMath::Abs(h->GetXaxis()->GetBinWidth(1)-h->GetXaxis()->GetBinWidth(2))>1e-10 ) gPad->SetLogx();
624       if ( TMath::Abs(h->GetYaxis()->GetBinWidth(1)-h->GetYaxis()->GetBinWidth(2))>1e-10 ) gPad->SetLogy();
625       if ( TMath::Abs(h->GetZaxis()->GetBinWidth(1)-h->GetZaxis()->GetBinWidth(2))>1e-10 ) gPad->SetLogz();
626       TString histOpt=h->GetOption();
627       histOpt.ToLower();
628       if (histOpt.Contains("logx")) gPad->SetLogx();
629       if (histOpt.Contains("logy")) gPad->SetLogy();
630       if (histOpt.Contains("logz")) gPad->SetLogz();
631       histOpt.ReplaceAll("logx","");
632       histOpt.ReplaceAll("logy","");
633       histOpt.ReplaceAll("logz","");
634       h->Draw(drawOpt.Data());
635     }
636     if (gVirtualPS) {
637       c->Update();
638     }
639     
640   }
641 //   if (gVirtualPS) delete c;
642 }
643
644 //_____________________________________________________________________________
645 void AliDielectronHistos::Print(const Option_t* option) const
646 {
647   //
648   // Print classes and histograms
649   //
650   TString optString(option);
651
652   if (optString.IsNull()) PrintStructure();
653
654
655
656 }
657
658 //_____________________________________________________________________________
659 void AliDielectronHistos::PrintStructure() const
660 {
661   //
662   // Print classes and histograms in the class to stdout
663   //
664   if (!fList){
665     TIter nextClass(&fHistoList);
666     THashList *classTable=0;
667     while ( (classTable=(THashList*)nextClass()) ){
668       TIter nextHist(classTable);
669       TObject *o=0;
670       printf("+ %s\n",classTable->GetName());
671       while ( (o=nextHist()) )
672         printf("| ->%s\n",o->GetName());
673     }
674   } else {
675     TIter nextCutClass(fList);
676     THashList *cutClass=0x0;
677     while ( (cutClass=(THashList*)nextCutClass()) ) {
678       printf("+ %s\n",cutClass->GetName());
679       TIter nextClass(cutClass);
680       THashList *classTable=0;
681       while ( (classTable=(THashList*)nextClass()) ){
682         TIter nextHist(classTable);
683         TObject *o=0;
684         printf("|  + %s\n",classTable->GetName());
685         while ( (o=nextHist()) )
686           printf("|  | ->%s\n",o->GetName());
687       }
688       
689     }
690   }
691 }
692
693 //_____________________________________________________________________________
694 void AliDielectronHistos::SetHistogramList(THashList &list, Bool_t setOwner/*=kTRUE*/)
695 {
696   //
697   // set histogram classes and histograms to this instance. It will take onwnership!
698   //
699   ResetHistogramList();
700   TString name(GetName());
701   if (name == "AliDielectronHistos") SetName(list.GetName());
702   TIter next(&list);
703   TObject *o;
704   while ( (o=next()) ){
705     fHistoList.Add(o);
706   }
707   if (setOwner){
708     list.SetOwner(kFALSE);
709     fHistoList.SetOwner(kTRUE);
710   } else {
711     fHistoList.SetOwner(kFALSE);
712   }
713 }
714
715 //_____________________________________________________________________________
716 Bool_t AliDielectronHistos::SetCutClass(const char* cutClass)
717 {
718   //
719   // Assign histogram list according to cutClass
720   //
721
722   if (!fList) return kFALSE;
723   ResetHistogramList();
724   THashList *h=dynamic_cast<THashList*>(fList->FindObject(cutClass));
725   if (!h) {
726     Warning("SetCutClass","cutClass '%s' not found", cutClass);
727     return kFALSE;
728   }
729   SetHistogramList(*h,kFALSE);
730   return kTRUE;
731 }
732
733 //_____________________________________________________________________________
734 Bool_t AliDielectronHistos::IsHistogramOk(const char* histClass, const char* name)
735 {
736   //
737   // check whether the histogram class exists and the histogram itself does not exist yet
738   //
739   Bool_t isReserved=fReservedWords->Contains(histClass);
740   if (!fHistoList.FindObject(histClass)&&!isReserved){
741     Warning("IsHistogramOk","Cannot create histogram. Class '%s' not defined. Please create it using AddClass before.",histClass);
742     return kFALSE;
743   }
744   if (GetHistogram(histClass,name)){
745     Warning("IsHistogramOk","Cannot create histogram '%s' in class '%s': It already exists!",name,histClass);
746     return kFALSE;
747   }
748   return kTRUE;
749 }
750
751 // //_____________________________________________________________________________
752 // TIterator* AliDielectronHistos::MakeIterator(Bool_t dir) const
753 // {
754 //   //
755 //   //
756 //   //
757 //   return new TListIter(&fHistoList, dir);
758 // }
759
760 //_____________________________________________________________________________
761 void AliDielectronHistos::ReadFromFile(const char* file)
762 {
763   //
764   // Read histos from file
765   //
766   TFile f(file);
767   TIter nextKey(f.GetListOfKeys());
768   TKey *key=0;
769   while ( (key=(TKey*)nextKey()) ){
770     TObject *o=f.Get(key->GetName());
771     THashList *list=dynamic_cast<THashList*>(o);
772     if (!list) continue;
773     SetHistogramList(*list);
774     break;
775   }
776   f.Close();
777 }
778
779 //_____________________________________________________________________________
780 void AliDielectronHistos::DrawSame(const char* histName, const Option_t *opt)
781 {
782   //
783   // Draw all histograms with the same name into one canvas
784   // if option contains 'leg' a legend will be created with the class name as caption
785   // if option contains 'can' a new canvas is created
786   //
787
788   TString optString(opt);
789   optString.ToLower();
790   Bool_t optLeg=optString.Contains("leg");
791   Bool_t optCan=optString.Contains("can");
792
793   TLegend *leg=0;
794   TCanvas *c=0;
795   if (optCan){
796     c=(TCanvas*)gROOT->FindObject(Form("c%s",histName));
797     if (!c) c=new TCanvas(Form("c%s",histName),Form("All '%s' histograms",histName));
798     c->Clear();
799     c->cd();
800   }
801
802   if (optLeg) leg=new TLegend(.8,.3,.99,.9);
803   
804   Int_t i=0;
805   TIter next(&fHistoList);
806   THashList *classTable=0;
807   Double_t max=-1e10;
808   TH1 *hFirst=0x0;
809   while ( (classTable=(THashList*)next()) ){
810     if ( TH1 *h=(TH1*)classTable->FindObject(histName) ){
811       if (i==0) hFirst=h;
812       h->SetLineColor(i+1);
813       h->SetMarkerColor(i+1);
814       h->Draw(i>0?"same":"");
815       if (leg) leg->AddEntry(h,classTable->GetName(),"lp");
816       ++i;
817       max=TMath::Max(max,h->GetMaximum());
818     }
819   }
820   if (leg){
821     leg->SetFillColor(10);
822     leg->SetY1(.9-i*.05);
823     leg->Draw();
824   }
825   if (hFirst&&(hFirst->GetYaxis()->GetXmax()<max)){
826     hFirst->SetMaximum(max);
827   }
828 }
829
830 //_____________________________________________________________________________
831 void AliDielectronHistos::SetReservedWords(const char* words)
832 {
833   //
834   // set reserved words
835   //
836   
837   (*fReservedWords)=words;
838 }
839
840 //_____________________________________________________________________________
841 void AliDielectronHistos::StoreVarForProfile(TObject *obj, UInt_t valType)
842 {
843   //
844   // store var for TProfiles in TObject::fBits [14-23]
845   //
846   
847   for(UInt_t i=14; i < sizeof(UInt_t)*8; i++) {
848     if(TESTBIT(valType,i-14)) {
849       obj->SetBit(1<<i,kTRUE);
850     }
851   }
852
853   return;
854 }
855
856