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