1 /*************************************************************************
2 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
17 // Generic Histogram container with support for groups and filling of groups by passing
21 // Jens Wiechula <Jens.Wiechula@cern.ch>
28 #include <TCollection.h>
29 #include <THashList.h>
31 #include <TObjString.h>
32 #include <TObjArray.h>
41 #include <TVirtualPS.h>
44 #include "AliDielectronHelper.h"
45 #include "AliDielectronHistos.h"
48 ClassImp(AliDielectronHistos)
51 AliDielectronHistos::AliDielectronHistos() :
53 TNamed("AliDielectronHistos","Dielectron Histogram Container"),
56 fReservedWords(new TString)
59 // Default constructor
61 fHistoList.SetOwner(kTRUE);
62 fHistoList.SetName("Dielectron_Histos");
65 //_____________________________________________________________________________
66 AliDielectronHistos::AliDielectronHistos(const char* name, const char* title) :
71 fReservedWords(new TString)
76 fHistoList.SetOwner(kTRUE);
77 fHistoList.SetName(name);
80 //_____________________________________________________________________________
81 AliDielectronHistos::~AliDielectronHistos()
87 if (fList) fList->Clear();
88 delete fReservedWords;
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)
97 // Default histogram creation 1D case
100 TVectorD *binLimX=0x0;
103 binLimX=AliDielectronHelper::MakeLogBinning(nbinsX, xmin, xmax);
105 binLimX=AliDielectronHelper::MakeLinBinning(nbinsX, xmin, xmax);
108 UserHistogram(histClass,name,title,binLimX,valTypeX);
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)
119 // Default histogram creation 2D case
121 if (!IsHistogramOk(histClass,name)) return;
123 TVectorD *binLimX=0x0;
124 TVectorD *binLimY=0x0;
127 binLimX=AliDielectronHelper::MakeLogBinning(nbinsX, xmin, xmax);
129 binLimX=AliDielectronHelper::MakeLinBinning(nbinsX, xmin, xmax);
132 binLimY=AliDielectronHelper::MakeLogBinning(nbinsY, ymin, ymax);
134 binLimY=AliDielectronHelper::MakeLinBinning(nbinsY, ymin, ymax);
137 UserHistogram(histClass,name,title,binLimX,binLimY,valTypeX,valTypeY);
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)
150 // Default histogram creation 3D case
152 if (!IsHistogramOk(histClass,name)) return;
154 TVectorD *binLimX=0x0;
155 TVectorD *binLimY=0x0;
156 TVectorD *binLimZ=0x0;
159 binLimX=AliDielectronHelper::MakeLogBinning(nbinsX, xmin, xmax);
161 binLimX=AliDielectronHelper::MakeLinBinning(nbinsX, xmin, xmax);
165 binLimY=AliDielectronHelper::MakeLogBinning(nbinsY, ymin, ymax);
167 binLimY=AliDielectronHelper::MakeLinBinning(nbinsY, ymin, ymax);
171 binLimZ=AliDielectronHelper::MakeLogBinning(nbinsZ, zmin, zmax);
173 binLimZ=AliDielectronHelper::MakeLinBinning(nbinsZ, zmin, zmax);
176 UserHistogram(histClass,name,title,binLimX,binLimY,binLimZ,valTypeX,valTypeY,valTypeZ);
179 //_____________________________________________________________________________
180 void AliDielectronHistos::UserHistogram(const char* histClass,const char *name, const char* title,
185 // Histogram creation 1D case with arbitraty binning
188 TVectorD *binLimX=AliDielectronHelper::MakeArbitraryBinning(binning);
189 UserHistogram(histClass,name,title,binLimX,valTypeX);
192 //_____________________________________________________________________________
193 void AliDielectronHistos::UserHistogram(const char* histClass,const char *name, const char* title,
194 const TVectorD * const binsX,
195 UInt_t valTypeX/*=kNoAutoFill*/)
198 // Histogram creation 1D case with arbitraty binning X
199 // the TVectorD is assumed to be surplus after the creation and will be deleted!!!
203 isOk&=IsHistogramOk(histClass,name);
207 TH1* hist=new TH1F(name,title,binsX->GetNrows()-1,binsX->GetMatrixArray());
209 Bool_t isReserved=fReservedWords->Contains(histClass);
211 UserHistogramReservedWords(histClass, hist, valTypeX);
213 UserHistogram(histClass, hist, valTypeX);
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*/)
225 // Histogram creation 1D case with arbitraty binning X
226 // the TVectorD is assumed to be surplus after the creation and will be deleted!!!
230 isOk&=IsHistogramOk(histClass,name);
235 TH1* hist=new TH2F(name,title,
236 binsX->GetNrows()-1,binsX->GetMatrixArray(),
237 binsY->GetNrows()-1,binsY->GetMatrixArray());
239 Bool_t isReserved=fReservedWords->Contains(histClass);
241 UserHistogramReservedWords(histClass, hist, valTypeX+100*valTypeY);
243 UserHistogram(histClass, hist, valTypeX+100*valTypeY);
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*/)
257 // Histogram creation 1D case with arbitraty binning X
258 // the TVectorD is assumed to be surplus after the creation and will be deleted!!!
262 isOk&=IsHistogramOk(histClass,name);
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());
273 Bool_t isReserved=fReservedWords->Contains(histClass);
275 UserHistogramReservedWords(histClass, hist, valTypeX+100*valTypeY+10000*valTypeZ);
277 UserHistogram(histClass, hist, valTypeX+100*valTypeY+10000*valTypeZ);
285 //_____________________________________________________________________________
286 void AliDielectronHistos::UserHistogram(const char* histClass, TH1* hist, UInt_t valTypes)
289 // Add any type of user histogram
292 //special case for the calss Pair. where histograms will be created for all pair classes
293 Bool_t isReserved=fReservedWords->Contains(histClass);
295 UserHistogramReservedWords(histClass, hist, valTypes);
299 if (!IsHistogramOk(histClass,hist->GetName())) return;
301 THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
302 hist->SetDirectory(0);
303 hist->SetUniqueID(valTypes);
304 classTable->Add(hist);
307 //_____________________________________________________________________________
308 void AliDielectronHistos::AddClass(const char* histClass)
311 // Add a class of histograms
312 // Several classes can be added by separating them by a ';' e.g. 'class1;class2;class3'
314 TString hists(histClass);
315 TObjArray *arr=hists.Tokenize(";");
318 while ( (o=next()) ){
319 if (fHistoList.FindObject(o->GetName())){
320 Warning("AddClass","Cannot create class '%s' it already exists.",histClass);
323 if (fReservedWords->Contains(o->GetName())){
324 Error("AddClass","Pair is a reserved word, please use another name");
327 THashList *table=new THashList;
328 table->SetOwner(kTRUE);
329 table->SetName(o->GetName());
330 fHistoList.Add(table);
335 //_____________________________________________________________________________
336 void AliDielectronHistos::Fill(const char* histClass, const char* name, Double_t xval)
339 // Fill function 1D case
341 THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
343 if (!classTable || !(hist=(TH1*)classTable->FindObject(name)) ){
344 Warning("Fill","Cannot fill histogram. Either class '%s' or histogram '%s' not existing.",histClass,name);
350 //_____________________________________________________________________________
351 void AliDielectronHistos::Fill(const char* histClass, const char* name, Double_t xval, Double_t yval)
354 // Fill function 2D case
356 THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
358 if (!classTable || !(hist=(TH2*)classTable->FindObject(name)) ){
359 Warning("UserHistogram","Cannot fill histogram. Either class '%s' or histogram '%s' not existing.",histClass,name);
362 hist->Fill(xval,yval);
365 //_____________________________________________________________________________
366 void AliDielectronHistos::Fill(const char* histClass, const char* name, Double_t xval, Double_t yval, Double_t zval)
369 // Fill function 3D case
371 THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
373 if (!classTable || !(hist=(TH3*)classTable->FindObject(name)) ){
374 Warning("UserHistogram","Cannot fill histogram. Either class '%s' or histogram '%s' not existing.",histClass,name);
377 hist->Fill(xval,yval,zval);
380 //_____________________________________________________________________________
381 void AliDielectronHistos::FillClass(const char* histClass, Int_t nValues, const Double_t *values)
384 // Fill class 'histClass' (by name)
387 THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
389 Warning("FillClass","Cannot fill class '%s' its not defined.",histClass);
393 TIter nextHist(classTable);
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());
405 switch (hist->GetDimension()){
407 hist->Fill(values[value1]);
410 ((TH2*)hist)->Fill(values[value1],values[value2]);
413 ((TH3*)hist)->Fill(values[value1],values[value2],values[value3]);
419 //_____________________________________________________________________________
420 // void AliDielectronHistos::FillClass(const char* histClass, const TVectorD &vals)
425 // FillClass(histClass, vals.GetNrows(), vals.GetMatrixArray());
428 //_____________________________________________________________________________
429 void AliDielectronHistos::UserHistogramReservedWords(const char* histClass, const TH1 *hist, UInt_t valTypes)
432 // Creation of histogram for all pair types
434 TString title(hist->GetTitle());
435 // Same Event Like Sign
436 TIter nextClass(&fHistoList);
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());
443 h->SetTitle(Form("%s %s",title.Data(),l->GetName()));
444 UserHistogram(l->GetName(),h,valTypes);
450 //_____________________________________________________________________________
451 void AliDielectronHistos::DumpToFile(const char* file)
454 // Dump the histogram list to a newly created root file
456 TFile f(file,"recreate");
457 fHistoList.Write(fHistoList.GetName(),TObject::kSingleKey);
461 //_____________________________________________________________________________
462 TH1* AliDielectronHistos::GetHistogram(const char* histClass, const char* name) const
465 // return histogram 'name' in 'histClass'
467 THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
468 if (!classTable) return 0x0;
469 return (TH1*)classTable->FindObject(name);
472 //_____________________________________________________________________________
473 TH1* AliDielectronHistos::GetHistogram(const char* cutClass, const char* histClass, const char* name) const
476 // return histogram from list of list of histograms
477 // this function is thought for retrieving histograms if a list of AliDielectronHistos is set
480 if (!fList) return 0x0;
481 THashList *h=dynamic_cast<THashList*>(fList->FindObject(cutClass));
483 THashList *classTable=dynamic_cast<THashList*>(h->FindObject(histClass));
484 if (!classTable) return 0x0;
485 return (TH1*)classTable->FindObject(name);
488 //_____________________________________________________________________________
489 void AliDielectronHistos::Draw(const Option_t* option)
495 TString drawStr(option);
496 TObjArray *arr=drawStr.Tokenize(";");
501 TObjString *ostr=0x0;
505 while ( (ostr=(TObjString*)nextOpt()) ){
506 currentOpt=ostr->GetString();
507 currentOpt.Remove(TString::kBoth,'\t');
508 currentOpt.Remove(TString::kBoth,' ');
511 if ( currentOpt.Contains(testOpt.Data()) ){
512 drawClasses=currentOpt(testOpt.Length(),currentOpt.Length());
519 // Bool_t same=drawOpt.Contains("same"); //FIXME not yet implemented
524 Error("Draw","When writing to a file you have to create a canvas before opening the file!!!");
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;
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 );
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()));
553 // if (nPads>1) gVirtualPS->NewPage();
555 if (nPads>1) c->Clear();
558 if (nCols>1||nRows>1) c->Divide(nCols,nRows);
560 //loop over histograms and draw them
561 TIter nextHist(classTable);
564 while ( (h=(TH1*)nextHist()) ){
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();
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());
586 // if (gVirtualPS) delete c;
589 //_____________________________________________________________________________
590 void AliDielectronHistos::Print(const Option_t* option) const
593 // Print classes and histograms
595 TString optString(option);
597 if (optString.IsNull()) PrintStructure();
603 //_____________________________________________________________________________
604 void AliDielectronHistos::PrintStructure() const
607 // Print classes and histograms in the class to stdout
610 TIter nextClass(&fHistoList);
611 THashList *classTable=0;
612 while ( (classTable=(THashList*)nextClass()) ){
613 TIter nextHist(classTable);
615 printf("+ %s\n",classTable->GetName());
616 while ( (o=nextHist()) )
617 printf("| ->%s\n",o->GetName());
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);
629 printf("| + %s\n",classTable->GetName());
630 while ( (o=nextHist()) )
631 printf("| | ->%s\n",o->GetName());
638 //_____________________________________________________________________________
639 void AliDielectronHistos::SetHistogramList(THashList &list, Bool_t setOwner/*=kTRUE*/)
642 // set histogram classes and histograms to this instance. It will take onwnership!
644 ResetHistogramList();
645 TString name(GetName());
646 if (name == "AliDielectronHistos") SetName(list.GetName());
649 while ( (o=next()) ){
653 list.SetOwner(kFALSE);
654 fHistoList.SetOwner(kTRUE);
656 fHistoList.SetOwner(kFALSE);
660 //_____________________________________________________________________________
661 Bool_t AliDielectronHistos::SetCutClass(const char* cutClass)
664 // Assign histogram list according to cutClass
667 if (!fList) return kFALSE;
668 ResetHistogramList();
669 THashList *h=dynamic_cast<THashList*>(fList->FindObject(cutClass));
671 Warning("SetCutClass","cutClass '%s' not found", cutClass);
674 SetHistogramList(*h,kFALSE);
678 //_____________________________________________________________________________
679 Bool_t AliDielectronHistos::IsHistogramOk(const char* histClass, const char* name)
682 // check whether the histogram class exists and the histogram itself does not exist yet
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);
689 if (GetHistogram(histClass,name)){
690 Warning("IsHistogramOk","Cannot create histogram '%s' in class '%s': It already exists!",name,histClass);
696 // //_____________________________________________________________________________
697 // TIterator* AliDielectronHistos::MakeIterator(Bool_t dir) const
702 // return new TListIter(&fHistoList, dir);
705 //_____________________________________________________________________________
706 void AliDielectronHistos::ReadFromFile(const char* file)
709 // Read histos from file
712 TIter nextKey(f.GetListOfKeys());
714 while ( (key=(TKey*)nextKey()) ){
715 TObject *o=f.Get(key->GetName());
716 THashList *list=dynamic_cast<THashList*>(o);
718 SetHistogramList(*list);
724 //_____________________________________________________________________________
725 void AliDielectronHistos::DrawSame(const char* histName, const Option_t *opt)
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
733 TString optString(opt);
735 Bool_t optLeg=optString.Contains("leg");
736 Bool_t optCan=optString.Contains("can");
741 c=(TCanvas*)gROOT->FindObject(Form("c%s",histName));
742 if (!c) c=new TCanvas(Form("c%s",histName),Form("All '%s' histograms",histName));
747 if (optLeg) leg=new TLegend(.8,.3,.99,.9);
750 TIter next(&fHistoList);
751 THashList *classTable=0;
754 while ( (classTable=(THashList*)next()) ){
755 if ( TH1 *h=(TH1*)classTable->FindObject(histName) ){
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");
762 max=TMath::Max(max,h->GetMaximum());
766 leg->SetFillColor(10);
767 leg->SetY1(.9-i*.05);
770 if (hFirst&&(hFirst->GetYaxis()->GetXmax()<max)){
771 hFirst->SetMaximum(max);
775 //_____________________________________________________________________________
776 void AliDielectronHistos::SetReservedWords(const char* words)
779 // set reserved words
782 (*fReservedWords)=words;