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