Fix warnings
[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 <TObjArray.h>
32 #include <TFile.h>
33 #include <TError.h>
34 #include <TCanvas.h>
35 #include <TMath.h>
36 #include <TROOT.h>
37 #include <TLegend.h>
38 #include <TKey.h>
39 // #include <TVectorD.h>
40
41 #include "AliDielectronHistos.h"
42
43
44 ClassImp(AliDielectronHistos)
45
46
47 AliDielectronHistos::AliDielectronHistos() :
48 //   TCollection(),
49   TNamed("AliDielectronHistos","Dielectron Histogram Container"),
50   fHistoList(),
51   fReservedWords(new TString)
52 {
53   //
54   // Default constructor
55   //
56   fHistoList.SetOwner(kTRUE);
57   fHistoList.SetName("Dielectron_Histos");
58 }
59
60 //_____________________________________________________________________________
61 AliDielectronHistos::AliDielectronHistos(const char* name, const char* title) :
62 //   TCollection(),
63   TNamed(name, title),
64   fHistoList(),
65   fReservedWords(new TString)
66 {
67   //
68   // TNamed constructor
69   //
70   fHistoList.SetOwner(kTRUE);
71   fHistoList.SetName(name);
72 }
73
74 //_____________________________________________________________________________
75 AliDielectronHistos::~AliDielectronHistos()
76 {
77   //
78   // Destructor
79   //
80   fHistoList.Delete();
81   delete fReservedWords;
82 }
83
84 //_____________________________________________________________________________
85 void AliDielectronHistos::UserHistogram(const char* histClass,const char *name, const char* title,
86                                         Int_t nbinsX, Double_t xmin, Double_t xmax,
87                                         UInt_t valTypeX)
88 {
89   //
90   // Default histogram creation 1D case
91   //
92   if (!IsHistogramOk(histClass,name)) return;
93   
94   TH1* hist=new TH1F(name,title,nbinsX,xmin,xmax);
95   Bool_t isReserved=fReservedWords->Contains(histClass);
96   if (isReserved)
97     UserHistogramReservedWords(histClass, hist, valTypeX);
98   else
99     UserHistogram(histClass, hist, valTypeX);
100 }
101
102 //_____________________________________________________________________________
103 void AliDielectronHistos::UserHistogram(const char* histClass,const char *name, const char* title,
104                                         Int_t nbinsX, Double_t xmin, Double_t xmax,
105                                         Int_t nbinsY, Double_t ymin, Double_t ymax,
106                                         UInt_t valTypeX, UInt_t valTypeY)
107 {
108   //
109   // Default histogram creation 2D case
110   //
111   if (!IsHistogramOk(histClass,name)) return;
112
113   TH1* hist=new TH2F(name,title,nbinsX,xmin,xmax,nbinsY,ymin,ymax);
114   Bool_t isReserved=fReservedWords->Contains(histClass);
115   if (isReserved)
116     UserHistogramReservedWords(histClass, hist, valTypeX+100*valTypeY);
117   else
118     UserHistogram(histClass, hist, valTypeX+100*valTypeY);
119 }
120
121
122 //_____________________________________________________________________________
123 void AliDielectronHistos::UserHistogram(const char* histClass,const char *name, const char* title,
124                                         Int_t nbinsX, Double_t xmin, Double_t xmax,
125                                         Int_t nbinsY, Double_t ymin, Double_t ymax,
126                                         Int_t nbinsZ, Double_t zmin, Double_t zmax,
127                                         UInt_t valTypeX, UInt_t valTypeY, UInt_t valTypeZ)
128 {
129   //
130   // Default histogram creation 3D case
131   //
132   if (!IsHistogramOk(histClass,name)) return;
133
134   TH1* hist=new TH3F(name,title,nbinsX,xmin,xmax,nbinsY,ymin,ymax,nbinsZ,zmin,zmax);
135   Bool_t isReserved=fReservedWords->Contains(histClass);
136   if (isReserved)
137     UserHistogramReservedWords(histClass, hist, valTypeX+100*valTypeY+10000*valTypeZ);
138   else
139     UserHistogram(histClass, hist, valTypeX+100*valTypeY+10000*valTypeZ);
140 }
141
142 //_____________________________________________________________________________
143 void AliDielectronHistos::UserHistogram(const char* histClass, TH1* hist, UInt_t valTypes)
144 {
145   //
146   // Add any type of user histogram
147   //
148
149   //special case for the calss Pair. where histograms will be created for all pair classes
150   Bool_t isReserved=fReservedWords->Contains(histClass);
151   if (isReserved) {
152     UserHistogramReservedWords(histClass, hist, valTypes);
153     return;
154   }
155   
156   if (!IsHistogramOk(histClass,hist->GetName())) return;
157   
158   THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
159   hist->SetDirectory(0);
160   hist->SetUniqueID(valTypes);
161   classTable->Add(hist);
162 }
163
164 //_____________________________________________________________________________
165 void AliDielectronHistos::AddClass(const char* histClass)
166 {
167   //
168   // Add a class of histograms
169   // Several classes can be added by separating them by a ';' e.g. 'class1;class2;class3'
170   //
171   TString hists(histClass);
172   TObjArray *arr=hists.Tokenize(";");
173   TIter next(arr);
174   TObject *o=0;
175   while ( (o=next()) ){
176     if (fHistoList.FindObject(o->GetName())){
177       Warning("AddClass","Cannot create class '%s' it already exists.",histClass);
178       continue;
179     }
180     if (fReservedWords->Contains(o->GetName())){
181       Error("AddClass","Pair is a reserved word, please use another name");
182       continue;
183     }
184     THashList *table=new THashList;
185     table->SetOwner(kTRUE);
186     table->SetName(o->GetName());
187     fHistoList.Add(table);
188   }
189   delete arr;
190 }
191
192 //_____________________________________________________________________________
193 void AliDielectronHistos::Fill(const char* histClass, const char* name, Double_t xval)
194 {
195   //
196   // Fill function 1D case
197   //
198   THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
199   TH1* hist=0;
200   if (!classTable || !(hist=(TH1*)classTable->FindObject(name)) ){
201     Warning("Fill","Cannot fill histogram. Either class '%s' or histogram '%s' not existing.",histClass,name);
202     return;
203   }
204   hist->Fill(xval);
205 }
206
207 //_____________________________________________________________________________
208 void AliDielectronHistos::Fill(const char* histClass, const char* name, Double_t xval, Double_t yval)
209 {
210   //
211   // Fill function 2D case
212   //
213   THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
214   TH2* hist=0;
215   if (!classTable || !(hist=(TH2*)classTable->FindObject(name)) ){
216     Warning("UserHistogram","Cannot fill histogram. Either class '%s' or histogram '%s' not existing.",histClass,name);
217     return;
218   }
219   hist->Fill(xval,yval);
220 }
221
222 //_____________________________________________________________________________
223 void AliDielectronHistos::Fill(const char* histClass, const char* name, Double_t xval, Double_t yval, Double_t zval)
224 {
225   //
226   // Fill function 3D case
227   //
228   THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
229   TH3* hist=0;
230   if (!classTable || !(hist=(TH3*)classTable->FindObject(name)) ){
231     Warning("UserHistogram","Cannot fill histogram. Either class '%s' or histogram '%s' not existing.",histClass,name);
232     return;
233   }
234   hist->Fill(xval,yval,zval);
235 }
236
237 //_____________________________________________________________________________
238 void AliDielectronHistos::FillClass(const char* histClass, Int_t nValues, const Double_t *values)
239 {
240   //
241   // Fill class 'histClass' (by name)
242   //
243   
244   THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
245   if (!classTable){
246     Warning("FillClass","Cannot fill class '%s' its not defined.",histClass);
247     return;
248   }
249   
250   TIter nextHist(classTable);
251   TH1 *hist=0;
252   while ( (hist=(TH1*)nextHist()) ){
253     UInt_t valueTypes=hist->GetUniqueID();
254     if (valueTypes==(UInt_t)kNoAutoFill) continue;
255     UInt_t value1=valueTypes%100;        //last two digits
256     UInt_t value2=valueTypes/100%100;    //second last two digits
257     UInt_t value3=valueTypes/10000%100;  //third last two digits
258     if (value1>=(UInt_t)nValues||value2>=(UInt_t)nValues||value3>=(UInt_t)nValues) {
259       Warning("FillClass","One of the values is out of range. Not filling histogram '%s/%s'.", histClass, hist->GetName());
260       continue;
261     }
262     switch (hist->GetDimension()){
263     case 1:
264       hist->Fill(values[value1]);
265       break;
266     case 2:
267       ((TH2*)hist)->Fill(values[value1],values[value2]);
268       break;
269     case 3:
270       ((TH3*)hist)->Fill(values[value1],values[value2],values[value3]);
271       break;
272     }
273   }
274 }
275
276 //_____________________________________________________________________________
277 // void AliDielectronHistos::FillClass(const char* histClass, const TVectorD &vals)
278 // {
279 //   //
280 //   //
281 //   //
282 //   FillClass(histClass, vals.GetNrows(), vals.GetMatrixArray());
283 // }
284
285 //_____________________________________________________________________________
286 void AliDielectronHistos::UserHistogramReservedWords(const char* histClass, TH1 *hist, UInt_t valTypes)
287 {
288   //
289   // Creation of histogram for all pair types
290   //
291   TString title(hist->GetTitle());
292   // Same Event Like Sign
293   TIter nextClass(&fHistoList);
294   THashList *l=0;
295   while ( (l=static_cast<THashList*>(nextClass())) ){
296     TString name(l->GetName());
297     if (name.Contains(histClass)){
298       TH1 *h=static_cast<TH1*>(hist->Clone());
299       h->SetDirectory(0);
300       h->SetTitle(Form("%s %s",title.Data(),l->GetName()));
301       UserHistogram(l->GetName(),h,valTypes);
302     }
303   }
304   delete hist;
305 }
306
307 //_____________________________________________________________________________
308 void AliDielectronHistos::DumpToFile(const char* file)
309 {
310   //
311   // Dump the histogram list to a newly created root file
312   //
313   TFile f(file,"recreate");
314   fHistoList.Write(fHistoList.GetName(),TObject::kSingleKey);
315   f.Close();
316 }
317
318 //_____________________________________________________________________________
319 TH1* AliDielectronHistos::GetHistogram(const char* histClass, const char* name) const
320 {
321   //
322   // return histogram 'name' in 'histClass'
323   //
324   THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
325   if (!classTable) return 0x0;
326   return (TH1*)classTable->FindObject(name);
327 }
328
329 //_____________________________________________________________________________
330 void AliDielectronHistos::Draw(const Option_t* option)
331 {
332   //
333   // Draw histograms
334   //
335
336   TString drawStr(option);
337   drawStr.ToLower();
338   //options
339 //   Bool_t same=drawOpt.Contains("same"); //FIXME not yet implemented
340   
341   TIter nextClass(&fHistoList);
342   THashList *classTable=0;
343   while ( (classTable=(THashList*)nextClass()) ){
344     //optimised division
345     Int_t nPads = classTable->GetEntries();
346     Int_t nCols = (Int_t)TMath::Ceil( TMath::Sqrt(nPads) );
347     Int_t nRows = (Int_t)TMath::Ceil( (Double_t)nPads/(Double_t)nCols );
348
349     //create canvas
350     TString canvasName;
351     canvasName.Form("c%s",classTable->GetName());
352     TCanvas *c=(TCanvas*)gROOT->FindObject(canvasName.Data());
353     if (!c) c=new TCanvas(canvasName.Data(),classTable->GetName());
354     c->Clear();
355     c->Divide(nCols,nRows);
356
357     //loop over histograms and draw them
358     TIter nextHist(classTable);
359     Int_t iPad=0;
360     TH1 *h=0;
361     while ( (h=(TH1*)nextHist()) ){
362       TString drawOpt;
363       if ( (h->InheritsFrom(TH2::Class())) ) drawOpt="colz";
364       c->cd(++iPad);
365       h->Draw(drawOpt.Data());
366     }
367   }
368 }
369
370 //_____________________________________________________________________________
371 void AliDielectronHistos::Print(const Option_t* option) const
372 {
373   //
374   // Print classes and histograms
375   //
376   TString optString(option);
377
378   if (optString.IsNull()) PrintStructure();
379
380
381
382 }
383
384 //_____________________________________________________________________________
385 void AliDielectronHistos::PrintStructure() const
386 {
387   //
388   // Print classes and histograms in the class to stdout
389   //
390   TIter nextClass(&fHistoList);
391   THashList *classTable=0;
392   while ( (classTable=(THashList*)nextClass()) ){
393     TIter nextHist(classTable);
394     TObject *o=0;
395     printf("+ %s\n",classTable->GetName());
396     while ( (o=nextHist()) )
397       printf("| ->%s\n",o->GetName());
398   }
399   
400 }
401
402 //_____________________________________________________________________________
403 void AliDielectronHistos::SetHistogramList(THashList &list)
404 {
405   //
406   // set histogram classes and histograms to this instance. It will take onwnership!
407   //
408   TIter next(&list);
409   TObject *o;
410   while ( (o=next()) ){
411     fHistoList.Add(o);
412   }
413   list.SetOwner(kFALSE);
414   fHistoList.SetOwner(kTRUE);
415 }
416
417 //_____________________________________________________________________________
418 Bool_t AliDielectronHistos::IsHistogramOk(const char* histClass, const char* name)
419 {
420   //
421   // check whether the histogram class exists and the histogram itself does not exist yet
422   //
423   Bool_t isReserved=fReservedWords->Contains(histClass);
424   if (!fHistoList.FindObject(histClass)&&!isReserved){
425     Warning("IsHistogramOk","Cannot create histogram. Class '%s' not defined. Please create it using AddClass before.",histClass);
426     return kFALSE;
427   }
428   if (GetHistogram(histClass,name)){
429     Warning("IsHistogramOk","Cannot create histogram '%s' in class '%s': It already exists!",name,histClass);
430     return kFALSE;
431   }
432   return kTRUE;
433 }
434
435 // //_____________________________________________________________________________
436 // TIterator* AliDielectronHistos::MakeIterator(Bool_t dir) const
437 // {
438 //   //
439 //   //
440 //   //
441 //   return new TListIter(&fHistoList, dir);
442 // }
443
444 //_____________________________________________________________________________
445 void AliDielectronHistos::ReadFromFile(const char* file)
446 {
447   //
448   // Read histos from file
449   //
450   TFile f(file);
451   TIter nextKey(f.GetListOfKeys());
452   TKey *key=0;
453   while ( (key=(TKey*)nextKey()) ){
454     TObject *o=f.Get(key->GetName());
455     THashList *list=dynamic_cast<THashList*>(o);
456     if (!list) continue;
457     SetHistogramList(*list);
458     break;
459   }
460   f.Close();
461 }
462
463 void AliDielectronHistos::DrawSame(const char* histName, const Option_t *opt)
464 {
465   //
466   // Draw all histograms with the same name into one canvas
467   // if option contains 'leg' a legend will be created with the class name as caption
468   // if option contains 'can' a new canvas is created
469   //
470
471   TString optString(opt);
472   optString.ToLower();
473   Bool_t optLeg=optString.Contains("leg");
474   Bool_t optCan=optString.Contains("can");
475
476   TLegend *leg=0;
477   TCanvas *c=0;
478   if (optCan){
479     c=(TCanvas*)gROOT->FindObject(Form("c%s",histName));
480     if (!c) c=new TCanvas(Form("c%s",histName),Form("All '%s' histograms",histName));
481     c->Clear();
482     c->cd();
483   }
484
485   if (optLeg) leg=new TLegend(.8,.3,.99,.9);
486   
487   Int_t i=0;
488   TIter next(&fHistoList);
489   THashList *classTable=0;
490   Double_t max=-1e10;
491   TH1 *hFirst=0x0;
492   while ( (classTable=(THashList*)next()) ){
493     if ( TH1 *h=(TH1*)classTable->FindObject(histName) ){
494       if (i==0) hFirst=h;
495       h->SetLineColor(i+1);
496       h->SetMarkerColor(i+1);
497       h->Draw(i>0?"same":"");
498       if (leg) leg->AddEntry(h,classTable->GetName(),"lp");
499       ++i;
500       max=TMath::Max(max,h->GetMaximum());
501     }
502   }
503   if (leg){
504     leg->SetFillColor(10);
505     leg->SetY1(.9-i*.05);
506     leg->Draw();
507   }
508   if (hFirst&&(hFirst->GetYaxis()->GetXmax()<max)){
509     hFirst->SetMaximum(max);
510   }
511 }
512
513 //_____________________________________________________________________________
514 void AliDielectronHistos::SetReservedWords(const char* words)
515 {
516   //
517   // set reserved words
518   //
519   
520   (*fReservedWords)=words;
521 }
522