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>
22 // Julian Book <Julian.Book@cern.ch>
31 #include <THnSparse.h>
33 #include <TProfile2D.h>
34 #include <TProfile3D.h>
35 #include <TCollection.h>
36 #include <THashList.h>
38 #include <TObjString.h>
39 #include <TObjArray.h>
48 #include <TVirtualPS.h>
51 #include "AliDielectronHelper.h"
52 #include "AliDielectronVarManager.h"
53 #include "AliDielectronHistos.h"
55 ClassImp(AliDielectronHistos)
58 AliDielectronHistos::AliDielectronHistos() :
60 TNamed("AliDielectronHistos","Dielectron Histogram Container"),
63 fReservedWords(new TString)
66 // Default constructor
68 fHistoList.SetOwner(kTRUE);
69 fHistoList.SetName("Dielectron_Histos");
72 //_____________________________________________________________________________
73 AliDielectronHistos::AliDielectronHistos(const char* name, const char* title) :
78 fReservedWords(new TString)
83 fHistoList.SetOwner(kTRUE);
84 fHistoList.SetName(name);
87 //_____________________________________________________________________________
88 AliDielectronHistos::~AliDielectronHistos()
94 if (fList) fList->Clear();
95 delete fReservedWords;
98 //_____________________________________________________________________________
99 void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
101 Int_t nbinsX, Double_t xmin, Double_t xmax,
102 UInt_t valTypeX, Bool_t logBinX, TString option,
106 // Default histogram creation 1D case
109 TVectorD *binLimX=0x0;
112 binLimX=AliDielectronHelper::MakeLogBinning(nbinsX, xmin, xmax);
114 binLimX=AliDielectronHelper::MakeLinBinning(nbinsX, xmin, xmax);
116 UserProfile(histClass,name,title,valTypeP,binLimX,valTypeX,option,valTypeW);
119 //_____________________________________________________________________________
120 void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
122 Int_t nbinsX, Double_t xmin, Double_t xmax,
123 Int_t nbinsY, Double_t ymin, Double_t ymax,
124 UInt_t valTypeX, UInt_t valTypeY,
125 Bool_t logBinX, Bool_t logBinY, TString option,
129 // Default histogram creation 2D case
131 if (!IsHistogramOk(histClass,name)) return;
133 TVectorD *binLimX=0x0;
134 TVectorD *binLimY=0x0;
137 binLimX=AliDielectronHelper::MakeLogBinning(nbinsX, xmin, xmax);
139 binLimX=AliDielectronHelper::MakeLinBinning(nbinsX, xmin, xmax);
142 binLimY=AliDielectronHelper::MakeLogBinning(nbinsY, ymin, ymax);
144 binLimY=AliDielectronHelper::MakeLinBinning(nbinsY, ymin, ymax);
146 UserProfile(histClass,name,title,valTypeP,binLimX,binLimY,valTypeX,valTypeY,option,valTypeW);
150 //_____________________________________________________________________________
151 void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
153 Int_t nbinsX, Double_t xmin, Double_t xmax,
154 Int_t nbinsY, Double_t ymin, Double_t ymax,
155 Int_t nbinsZ, Double_t zmin, Double_t zmax,
156 UInt_t valTypeX, UInt_t valTypeY, UInt_t valTypeZ,
157 Bool_t logBinX, Bool_t logBinY, Bool_t logBinZ, TString option,
161 // Default histogram creation 3D case
163 if (!IsHistogramOk(histClass,name)) return;
165 TVectorD *binLimX=0x0;
166 TVectorD *binLimY=0x0;
167 TVectorD *binLimZ=0x0;
170 binLimX=AliDielectronHelper::MakeLogBinning(nbinsX, xmin, xmax);
172 binLimX=AliDielectronHelper::MakeLinBinning(nbinsX, xmin, xmax);
176 binLimY=AliDielectronHelper::MakeLogBinning(nbinsY, ymin, ymax);
178 binLimY=AliDielectronHelper::MakeLinBinning(nbinsY, ymin, ymax);
182 binLimZ=AliDielectronHelper::MakeLogBinning(nbinsZ, zmin, zmax);
184 binLimZ=AliDielectronHelper::MakeLinBinning(nbinsZ, zmin, zmax);
187 UserProfile(histClass,name,title,valTypeP,binLimX,binLimY,binLimZ,valTypeX,valTypeY,valTypeZ,option,valTypeW);
190 //_____________________________________________________________________________
191 void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
194 UInt_t valTypeX, TString option,
198 // Histogram creation 1D case with arbitraty binning
201 TVectorD *binLimX=AliDielectronHelper::MakeArbitraryBinning(binning);
202 UserProfile(histClass,name,title,valTypeP,binLimX,valTypeX,option,valTypeW);
205 //_____________________________________________________________________________
206 void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
208 const TVectorD * const binsX,
209 UInt_t valTypeX/*=kNoAutoFill*/, TString option,
213 // Histogram creation 1D case with arbitraty binning X
214 // the TVectorD is assumed to be surplus after the creation and will be deleted!!!
218 isOk&=IsHistogramOk(histClass,name);
223 if(valTypeP==kNoProfile)
224 hist=new TH1F(name,title,binsX->GetNrows()-1,binsX->GetMatrixArray());
226 TString opt=""; Double_t pmin=0., pmax=0.;
227 if(!option.IsNull()) {
228 TObjArray *arr=option.Tokenize(";");
230 opt=((TObjString*)arr->At(0))->GetString();
231 if(arr->GetEntriesFast()>1) pmin=(((TObjString*)arr->At(1))->GetString()).Atof();
232 if(arr->GetEntriesFast()>2) pmax=(((TObjString*)arr->At(2))->GetString()).Atof();
235 hist=new TProfile(name,title,binsX->GetNrows()-1,binsX->GetMatrixArray());
236 ((TProfile*)hist)->BuildOptions(pmin,pmax,opt.Data());
237 // printf(" name %s PROFILE options: pmin %.1f pmax %.1f err %s \n",name,((TProfile*)hist)->GetYmin(),((TProfile*)hist)->GetYmax(),((TProfile*)hist)->GetErrorOption() );
240 // store variales in axes
241 UInt_t valType[20] = {0};
242 valType[0]=valTypeX; valType[1]=valTypeP;
243 StoreVariables(hist, valType);
244 hist->SetUniqueID(valTypeW); // store weighting variable
246 // adapt the name and title of the histogram in case they are empty
247 AdaptNameTitle(hist, histClass);
249 Bool_t isReserved=fReservedWords->Contains(histClass);
250 if(valTypeX==kNoAutoFill) hist->SetUniqueID(valTypeX);
252 UserHistogramReservedWords(histClass, hist, 999);
254 UserHistogram(histClass, hist, 999);
260 //_____________________________________________________________________________
261 void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
263 const TVectorD * const binsX, const TVectorD * const binsY,
264 UInt_t valTypeX/*=kNoAutoFill*/, UInt_t valTypeY/*=0*/, TString option,
268 // Histogram creation 2D case with arbitraty binning X
269 // the TVectorD is assumed to be surplus after the creation and will be deleted!!!
273 isOk&=IsHistogramOk(histClass,name);
279 if(valTypeP==kNoProfile) {
280 hist=new TH2F(name,title,
281 binsX->GetNrows()-1,binsX->GetMatrixArray(),
282 binsY->GetNrows()-1,binsY->GetMatrixArray());
285 TString opt=""; Double_t pmin=0., pmax=0.;
286 if(!option.IsNull()) {
287 TObjArray *arr=option.Tokenize(";");
289 opt=((TObjString*)arr->At(0))->GetString();
290 if(arr->GetEntriesFast()>1) pmin=(((TObjString*)arr->At(1))->GetString()).Atof();
291 if(arr->GetEntriesFast()>2) pmax=(((TObjString*)arr->At(2))->GetString()).Atof();
294 hist=new TProfile2D(name,title,
295 binsX->GetNrows()-1,binsX->GetMatrixArray(),
296 binsY->GetNrows()-1,binsY->GetMatrixArray());
297 ((TProfile2D*)hist)->BuildOptions(pmin,pmax,opt.Data());
298 // printf(" name %s PROFILE options: pmin %.1f pmax %.1f err %s \n",name,((TProfile*)hist)->GetYmin(),((TProfile*)hist)->GetYmax(),((TProfile*)hist)->GetErrorOption() );
301 // store variales in axes
302 UInt_t valType[20] = {0};
303 valType[0]=valTypeX; valType[1]=valTypeY; valType[2]=valTypeP;
304 StoreVariables(hist, valType);
305 hist->SetUniqueID(valTypeW); // store weighting variable
307 // adapt the name and title of the histogram in case they are empty
308 AdaptNameTitle(hist, histClass);
310 Bool_t isReserved=fReservedWords->Contains(histClass);
311 if(valTypeX==kNoAutoFill) hist->SetUniqueID(valTypeX);
313 UserHistogramReservedWords(histClass, hist, 999);
315 UserHistogram(histClass, hist, 999);
323 //_____________________________________________________________________________
324 void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
326 const TVectorD * const binsX, const TVectorD * const binsY, const TVectorD * const binsZ,
327 UInt_t valTypeX/*=kNoAutoFill*/, UInt_t valTypeY/*=0*/, UInt_t valTypeZ/*=0*/, TString option,
331 // Histogram creation 3D case with arbitraty binning X
332 // the TVectorD is assumed to be surplus after the creation and will be deleted!!!
336 isOk&=IsHistogramOk(histClass,name);
343 if(valTypeP==kNoProfile) {
344 hist=new TH3F(name,title,
345 binsX->GetNrows()-1,binsX->GetMatrixArray(),
346 binsY->GetNrows()-1,binsY->GetMatrixArray(),
347 binsZ->GetNrows()-1,binsZ->GetMatrixArray());
350 TString opt=""; Double_t pmin=0., pmax=0.;
351 if(!option.IsNull()) {
352 TObjArray *arr=option.Tokenize(";");
354 opt=((TObjString*)arr->At(0))->GetString();
355 if(arr->GetEntriesFast()>1) pmin=(((TObjString*)arr->At(1))->GetString()).Atof();
356 if(arr->GetEntriesFast()>2) pmax=(((TObjString*)arr->At(2))->GetString()).Atof();
359 hist=new TProfile3D(name,title,
360 binsX->GetNrows()-1,binsX->GetMatrixArray(),
361 binsY->GetNrows()-1,binsY->GetMatrixArray(),
362 binsZ->GetNrows()-1,binsZ->GetMatrixArray());
363 ((TProfile3D*)hist)->BuildOptions(pmin,pmax,opt.Data());
364 // printf(" name %s PROFILE options: pmin %.1f pmax %.1f err %s \n",name,((TProfile*)hist)->GetYmin(),((TProfile*)hist)->GetYmax(),((TProfile*)hist)->GetErrorOption() );
367 // store variales in axes
368 UInt_t valType[20] = {0};
369 valType[0]=valTypeX; valType[1]=valTypeY; valType[2]=valTypeZ; valType[3]=valTypeP;
370 StoreVariables(hist, valType);
371 hist->SetUniqueID(valTypeW); // store weighting variable
373 // adapt the name and title of the histogram in case they are empty
374 AdaptNameTitle(hist, histClass);
376 Bool_t isReserved=fReservedWords->Contains(histClass);
377 if(valTypeX==kNoAutoFill) hist->SetUniqueID(valTypeX);
379 UserHistogramReservedWords(histClass, hist, 999);
381 UserHistogram(histClass, hist, 999);
389 //_____________________________________________________________________________
390 void AliDielectronHistos::UserHistogram(const char* histClass, Int_t ndim, Int_t *bins, Double_t *mins, Double_t *maxs, UInt_t *vars, UInt_t valTypeW)
393 // Histogram creation 4-n dimension only with linear binning
397 isOk&=(ndim<21 && ndim>3);
398 if(!isOk) { Warning("UserHistogram","Array sizes should be between 3 and 20. Not adding Histogram to '%s'.", histClass); return; }
400 // set automatic histo name
402 for(Int_t iv=0; iv < ndim; iv++)
403 name+=Form("%s_",AliDielectronVarManager::GetValueName(vars[iv]));
404 name.Resize(name.Length()-1);
406 isOk&=IsHistogramOk(histClass,name);
410 hist=new THnD(name.Data(),"", ndim, bins, mins, maxs);
412 // store variales in axes
413 StoreVariables(hist, vars);
414 hist->SetUniqueID(valTypeW); // store weighting variable
416 Bool_t isReserved=fReservedWords->Contains(histClass);
418 UserHistogramReservedWords(histClass, hist, 999);
420 UserHistogram(histClass, hist, 999);
425 //_____________________________________________________________________________
426 void AliDielectronHistos::UserHistogram(const char* histClass, Int_t ndim, TObjArray *limits, UInt_t *vars, UInt_t valTypeW)
429 // Histogram creation n>3 dimension only with non-linear binning
433 isOk&=(ndim<21 && ndim>3);
434 if(!isOk) { Warning("UserHistogram","Array sizes should be between 3 and 20. Not adding Histogram to '%s'.", histClass); return; }
435 isOk&=(ndim==limits->GetEntriesFast());
438 // set automatic histo name
440 for(Int_t iv=0; iv < ndim; iv++)
441 name+=Form("%s_",AliDielectronVarManager::GetValueName(vars[iv]));
442 name.Resize(name.Length()-1);
444 isOk&=IsHistogramOk(histClass,name);
449 // get number of bins
450 for(Int_t idim=0 ;idim<ndim; idim++) {
451 TVectorD *vec = (TVectorD*) limits->At(idim);
452 bins[idim]=vec->GetNrows()-1;
455 hist=new THnD(name.Data(),"", ndim, bins, 0x0, 0x0);
458 for(Int_t idim=0 ;idim<ndim; idim++) {
459 TVectorD *vec = (TVectorD*) limits->At(idim);
460 hist->SetBinEdges(idim,vec->GetMatrixArray());
463 // store variales in axes
464 StoreVariables(hist, vars);
465 hist->SetUniqueID(valTypeW); // store weighting variable
467 Bool_t isReserved=fReservedWords->Contains(histClass);
469 UserHistogramReservedWords(histClass, hist, 999);
471 UserHistogram(histClass, hist, 999);
476 //_____________________________________________________________________________
477 void AliDielectronHistos::UserSparse(const char* histClass, Int_t ndim, Int_t *bins, Double_t *mins, Double_t *maxs, UInt_t *vars,
481 // THnSparse creation with linear binning
486 // set automatic histo name
488 for(Int_t iv=0; iv < ndim; iv++)
489 name+=Form("%s_",AliDielectronVarManager::GetValueName(vars[iv]));
490 name.Resize(name.Length()-1);
492 isOk&=IsHistogramOk(histClass,name);
496 hist=new THnSparseD(name.Data(),"", ndim, bins, mins, maxs);
498 // store variales in axes
499 StoreVariables(hist, vars);
500 hist->SetUniqueID(valTypeW); // store weighting variable
502 Bool_t isReserved=fReservedWords->Contains(histClass);
504 UserHistogramReservedWords(histClass, hist, 999);
506 UserHistogram(histClass, hist, 999);
511 //_____________________________________________________________________________
512 void AliDielectronHistos::UserSparse(const char* histClass, Int_t ndim, TObjArray *limits, UInt_t *vars, UInt_t valTypeW)
515 // THnSparse creation with non-linear binning
519 isOk&=(ndim==limits->GetEntriesFast());
522 // set automatic histo name
524 for(Int_t iv=0; iv < ndim; iv++)
525 name+=Form("%s_",AliDielectronVarManager::GetValueName(vars[iv]));
526 name.Resize(name.Length()-1);
528 isOk&=IsHistogramOk(histClass,name);
533 // get number of bins
534 for(Int_t idim=0 ;idim<ndim; idim++) {
535 TVectorD *vec = (TVectorD*) limits->At(idim);
536 bins[idim]=vec->GetNrows()-1;
539 hist=new THnSparseD(name.Data(),"", ndim, bins, 0x0, 0x0);
542 for(Int_t idim=0 ;idim<ndim; idim++) {
543 TVectorD *vec = (TVectorD*) limits->At(idim);
544 hist->SetBinEdges(idim,vec->GetMatrixArray());
547 // store variales in axes
548 StoreVariables(hist, vars);
549 hist->SetUniqueID(valTypeW); // store weighting variable
551 Bool_t isReserved=fReservedWords->Contains(histClass);
553 UserHistogramReservedWords(histClass, hist, 999);
555 UserHistogram(histClass, hist, 999);
560 //_____________________________________________________________________________
561 void AliDielectronHistos::UserHistogram(const char* histClass, TObject* hist, UInt_t valTypes)
564 // Add any type of user histogram
567 //special case for the calss Pair. where histograms will be created for all pair classes
568 Bool_t isReserved=fReservedWords->Contains(histClass);
570 UserHistogramReservedWords(histClass, hist, valTypes);
574 if (!IsHistogramOk(histClass,hist->GetName())) return;
575 THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
576 // hist->SetDirectory(0);
578 // store variables axis
579 UInt_t valType[20] = {0};
580 // incase valTypes is given old way of extracting variables
582 valType[0]=valTypes%1000; //last three digits
583 valType[1]=valTypes/1000%1000; //second last three digits
584 valType[2]=valTypes/1000000%1000; //third last three digits
585 hist->SetUniqueID(valTypes);
588 // extract variables from axis
589 FillVarArray(hist, valType);
590 StoreVariables(hist, valType);
591 hist->SetUniqueID(valType[19]); // store weighting variable
594 classTable->Add(hist);
597 //_____________________________________________________________________________
598 void AliDielectronHistos::AddClass(const char* histClass)
601 // Add a class of histograms
602 // Several classes can be added by separating them by a ';' e.g. 'class1;class2;class3'
604 TString hists(histClass);
605 TObjArray *arr=hists.Tokenize(";");
608 while ( (o=next()) ){
609 if (fHistoList.FindObject(o->GetName())){
610 Warning("AddClass","Cannot create class '%s' it already exists.",histClass);
613 if (fReservedWords->Contains(o->GetName())){
614 Error("AddClass","Pair is a reserved word, please use another name");
617 THashList *table=new THashList;
618 table->SetOwner(kTRUE);
619 table->SetName(o->GetName());
620 fHistoList.Add(table);
625 //_____________________________________________________________________________
626 void AliDielectronHistos::Fill(const char* histClass, const char* name, Double_t xval)
629 // Fill function 1D case
631 THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
633 if (!classTable || !(hist=(TH1*)classTable->FindObject(name)) ){
634 Warning("Fill","Cannot fill histogram. Either class '%s' or histogram '%s' not existing.",histClass,name);
640 //_____________________________________________________________________________
641 void AliDielectronHistos::Fill(const char* histClass, const char* name, Double_t xval, Double_t yval)
644 // Fill function 2D case
646 THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
648 if (!classTable || !(hist=(TH2*)classTable->FindObject(name)) ){
649 Warning("UserHistogram","Cannot fill histogram. Either class '%s' or histogram '%s' not existing.",histClass,name);
652 hist->Fill(xval,yval);
655 //_____________________________________________________________________________
656 void AliDielectronHistos::Fill(const char* histClass, const char* name, Double_t xval, Double_t yval, Double_t zval)
659 // Fill function 3D case
661 THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
663 if (!classTable || !(hist=(TH3*)classTable->FindObject(name)) ){
664 Warning("UserHistogram","Cannot fill histogram. Either class '%s' or histogram '%s' not existing.",histClass,name);
667 hist->Fill(xval,yval,zval);
670 //_____________________________________________________________________________
671 void AliDielectronHistos::FillClass(const char* histClass, Int_t nValues, const Double_t *values)
674 // Fill class 'histClass' (by name)
677 THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
679 Warning("FillClass","Cannot fill class '%s' its not defined. nValues %d",histClass,nValues);
683 TIter nextHist(classTable);
685 while ( (obj=(TObject*)nextHist()) ) FillValues(obj, values);
690 //_____________________________________________________________________________
691 // void AliDielectronHistos::FillClass(const char* histClass, const TVectorD &vals)
696 // FillClass(histClass, vals.GetNrows(), vals.GetMatrixArray());
699 //_____________________________________________________________________________
700 void AliDielectronHistos::UserHistogramReservedWords(const char* histClass, const TObject *hist, UInt_t valTypes)
703 // Creation of histogram for all pair types
705 TString title(hist->GetTitle());
706 // Same Event Like Sign
707 TIter nextClass(&fHistoList);
709 while ( (l=static_cast<THashList*>(nextClass())) ){
710 TString name(l->GetName());
711 if (name.Contains(histClass)){
712 TObject *h=hist->Clone();
713 // Tobject has no function SetDirectory, didn't we need this???
714 // h->SetDirectory(0);
715 ((TH1*)h)->SetTitle(Form("%s %s",title.Data(),l->GetName()));
717 UserHistogram(l->GetName(),h,valTypes);
723 //_____________________________________________________________________________
724 void AliDielectronHistos::DumpToFile(const char* file)
727 // Dump the histogram list to a newly created root file
729 TFile f(file,"recreate");
730 fHistoList.Write(fHistoList.GetName(),TObject::kSingleKey);
734 //_____________________________________________________________________________
735 TObject* AliDielectronHistos::GetHist(const char* histClass, const char* name) const
738 // return object 'name' in 'histClass'
740 THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
741 if (!classTable) return 0x0;
742 return classTable->FindObject(name);
745 //_____________________________________________________________________________
746 TH1* AliDielectronHistos::GetHistogram(const char* histClass, const char* name) const
749 // return histogram 'name' in 'histClass'
751 return ((TH1*) GetHist(histClass, name));
754 //_____________________________________________________________________________
755 TObject* AliDielectronHistos::GetHist(const char* cutClass, const char* histClass, const char* name) const
758 // return object from list of list of histograms
759 // this function is thought for retrieving histograms if a list of AliDielectronHistos is set
762 if (!fList) return 0x0;
763 THashList *h=dynamic_cast<THashList*>(fList->FindObject(cutClass));
765 THashList *classTable=dynamic_cast<THashList*>(h->FindObject(histClass));
766 if (!classTable) return 0x0;
767 return classTable->FindObject(name);
770 //_____________________________________________________________________________
771 TH1* AliDielectronHistos::GetHistogram(const char* cutClass, const char* histClass, const char* name) const
774 // return histogram from list of list of histograms
775 // this function is thought for retrieving histograms if a list of AliDielectronHistos is set
777 return ((TH1*) GetHist(cutClass, histClass, name));
780 //_____________________________________________________________________________
781 void AliDielectronHistos::Draw(const Option_t* option)
787 TString drawStr(option);
788 TObjArray *arr=drawStr.Tokenize(";");
793 TObjString *ostr=0x0;
797 while ( (ostr=(TObjString*)nextOpt()) ){
798 currentOpt=ostr->GetString();
799 currentOpt.Remove(TString::kBoth,'\t');
800 currentOpt.Remove(TString::kBoth,' ');
803 if ( currentOpt.Contains(testOpt.Data()) ){
804 drawClasses=currentOpt(testOpt.Length(),currentOpt.Length());
811 // Bool_t same=drawOpt.Contains("same"); //FIXME not yet implemented
816 Error("Draw","When writing to a file you have to create a canvas before opening the file!!!");
824 TIter nextClass(&fHistoList);
825 THashList *classTable=0;
826 // Bool_t first=kTRUE;
827 while ( (classTable=(THashList*)nextClass()) ){
828 //test classes option
829 if (!drawClasses.IsNull() && !drawClasses.Contains(classTable->GetName())) continue;
831 Int_t nPads = classTable->GetEntries();
832 Int_t nCols = (Int_t)TMath::Ceil( TMath::Sqrt(nPads) );
833 Int_t nRows = (Int_t)TMath::Ceil( (Double_t)nPads/(Double_t)nCols );
838 canvasName.Form("c%s_%s",GetName(),classTable->GetName());
839 c=(TCanvas*)gROOT->FindObject(canvasName.Data());
840 if (!c) c=new TCanvas(canvasName.Data(),Form("%s: %s",GetName(),classTable->GetName()));
845 // if (nPads>1) gVirtualPS->NewPage();
847 if (nPads>1) c->Clear();
850 if (nCols>1||nRows>1) c->Divide(nCols,nRows);
852 //loop over histograms and draw them
853 TIter nextHist(classTable);
856 while ( (h=(TH1*)nextHist()) ){
858 if ( (h->InheritsFrom(TH2::Class())) ) drawOpt="colz";
859 if (nCols>1||nRows>1) c->cd(++iPad);
860 if ( TMath::Abs(h->GetXaxis()->GetBinWidth(1)-h->GetXaxis()->GetBinWidth(2))>1e-10 ) gPad->SetLogx();
861 if ( TMath::Abs(h->GetYaxis()->GetBinWidth(1)-h->GetYaxis()->GetBinWidth(2))>1e-10 ) gPad->SetLogy();
862 if ( TMath::Abs(h->GetZaxis()->GetBinWidth(1)-h->GetZaxis()->GetBinWidth(2))>1e-10 ) gPad->SetLogz();
863 TString histOpt=h->GetOption();
865 if (histOpt.Contains("logx")) gPad->SetLogx();
866 if (histOpt.Contains("logy")) gPad->SetLogy();
867 if (histOpt.Contains("logz")) gPad->SetLogz();
868 histOpt.ReplaceAll("logx","");
869 histOpt.ReplaceAll("logy","");
870 histOpt.ReplaceAll("logz","");
871 h->Draw(drawOpt.Data());
878 // if (gVirtualPS) delete c;
881 //_____________________________________________________________________________
882 void AliDielectronHistos::Print(const Option_t* option) const
885 // Print classes and histograms
887 TString optString(option);
889 if (optString.IsNull()) PrintStructure();
895 //_____________________________________________________________________________
896 void AliDielectronHistos::PrintStructure() const
899 // Print classes and histograms in the class to stdout
902 TIter nextClass(&fHistoList);
903 THashList *classTable=0;
904 while ( (classTable=(THashList*)nextClass()) ){
905 TIter nextHist(classTable);
907 printf("+ %s\n",classTable->GetName());
908 while ( (o=nextHist()) )
909 printf("| ->%s\n",o->GetName());
912 TIter nextCutClass(fList);
913 THashList *cutClass=0x0;
914 while ( (cutClass=(THashList*)nextCutClass()) ) {
915 printf("+ %s\n",cutClass->GetName());
916 TIter nextClass(cutClass);
917 THashList *classTable=0;
918 while ( (classTable=(THashList*)nextClass()) ){
919 TIter nextHist(classTable);
921 printf("| + %s\n",classTable->GetName());
922 while ( (o=nextHist()) )
923 printf("| | ->%s\n",o->GetName());
930 //_____________________________________________________________________________
931 void AliDielectronHistos::SetHistogramList(THashList &list, Bool_t setOwner/*=kTRUE*/)
934 // set histogram classes and histograms to this instance. It will take onwnership!
936 ResetHistogramList();
937 TString name(GetName());
938 if (name == "AliDielectronHistos") SetName(list.GetName());
941 while ( (o=next()) ){
945 list.SetOwner(kFALSE);
946 fHistoList.SetOwner(kTRUE);
948 fHistoList.SetOwner(kFALSE);
952 //_____________________________________________________________________________
953 Bool_t AliDielectronHistos::SetCutClass(const char* cutClass)
956 // Assign histogram list according to cutClass
959 if (!fList) return kFALSE;
960 ResetHistogramList();
961 THashList *h=dynamic_cast<THashList*>(fList->FindObject(cutClass));
963 Warning("SetCutClass","cutClass '%s' not found", cutClass);
966 SetHistogramList(*h,kFALSE);
970 //_____________________________________________________________________________
971 Bool_t AliDielectronHistos::IsHistogramOk(const char* histClass, const char* name)
974 // check whether the histogram class exists and the histogram itself does not exist yet
976 Bool_t isReserved=fReservedWords->Contains(histClass);
977 if (!fHistoList.FindObject(histClass)&&!isReserved){
978 Warning("IsHistogramOk","Cannot create histogram. Class '%s' not defined. Please create it using AddClass before.",histClass);
981 if (GetHist(histClass,name)){
982 Warning("IsHistogramOk","Cannot create histogram '%s' in class '%s': It already exists!",name,histClass);
988 // //_____________________________________________________________________________
989 // TIterator* AliDielectronHistos::MakeIterator(Bool_t dir) const
994 // return new TListIter(&fHistoList, dir);
997 //_____________________________________________________________________________
998 void AliDielectronHistos::ReadFromFile(const char* file)
1001 // Read histos from file
1004 TIter nextKey(f.GetListOfKeys());
1006 while ( (key=(TKey*)nextKey()) ){
1007 TObject *o=f.Get(key->GetName());
1008 THashList *list=dynamic_cast<THashList*>(o);
1009 if (!list) continue;
1010 SetHistogramList(*list);
1016 //_____________________________________________________________________________
1017 void AliDielectronHistos::DrawSame(const char* histName, const Option_t *opt)
1020 // Draw all histograms with the same name into one canvas
1021 // if option contains 'leg' a legend will be created with the class name as caption
1022 // if option contains 'can' a new canvas is created
1025 TString optString(opt);
1026 optString.ToLower();
1027 Bool_t optLeg=optString.Contains("leg");
1028 Bool_t optCan=optString.Contains("can");
1033 c=(TCanvas*)gROOT->FindObject(Form("c%s",histName));
1034 if (!c) c=new TCanvas(Form("c%s",histName),Form("All '%s' histograms",histName));
1039 if (optLeg) leg=new TLegend(.8,.3,.99,.9);
1042 TIter next(&fHistoList);
1043 THashList *classTable=0;
1046 while ( (classTable=(THashList*)next()) ){
1047 if ( TH1 *h=(TH1*)classTable->FindObject(histName) ){
1049 h->SetLineColor(i+1);
1050 h->SetMarkerColor(i+1);
1051 h->Draw(i>0?"same":"");
1052 if (leg) leg->AddEntry(h,classTable->GetName(),"lp");
1054 max=TMath::Max(max,h->GetMaximum());
1058 leg->SetFillColor(10);
1059 leg->SetY1(.9-i*.05);
1062 if (hFirst&&(hFirst->GetYaxis()->GetXmax()<max)){
1063 hFirst->SetMaximum(max);
1067 //_____________________________________________________________________________
1068 void AliDielectronHistos::SetReservedWords(const char* words)
1071 // set reserved words
1074 (*fReservedWords)=words;
1077 //_____________________________________________________________________________
1078 void AliDielectronHistos::StoreVariables(TObject *obj, UInt_t valType[20])
1084 if (obj->InheritsFrom(TH1::Class())) StoreVariables(static_cast<TH1*>(obj), valType);
1085 else if (obj->InheritsFrom(THnBase::Class())) StoreVariables(static_cast<THnBase*>(obj), valType);
1092 //_____________________________________________________________________________
1093 void AliDielectronHistos::StoreVariables(TH1 *obj, UInt_t valType[20])
1096 // store variables in the axis (special for TProfile3D)
1099 Int_t dim = obj->GetDimension();
1101 // dimension correction for profiles
1102 if(obj->IsA() == TProfile::Class() || obj->IsA() == TProfile2D::Class() || obj->IsA() == TProfile3D::Class()) {
1108 obj->SetUniqueID(valType[3]); // Tprofile3D variable
1110 obj->GetZaxis()->SetUniqueID(valType[2]);
1112 obj->GetYaxis()->SetUniqueID(valType[1]);
1114 obj->GetXaxis()->SetUniqueID(valType[0]);
1120 //_____________________________________________________________________________
1121 void AliDielectronHistos::StoreVariables(THnBase *obj, UInt_t valType[20])
1124 // store variables in the axis
1127 Int_t dim = obj->GetNdimensions();
1129 for(Int_t it=0; it<dim; it++) {
1130 obj->GetAxis(it)->SetUniqueID(valType[it]);
1131 obj->GetAxis(it)->SetName(Form("%s", AliDielectronVarManager::GetValueName(valType[it])));
1132 obj->GetAxis(it)->SetTitle(Form("%s %s", AliDielectronVarManager::GetValueLabel(valType[it]), AliDielectronVarManager::GetValueUnit(valType[it])));
1138 //_____________________________________________________________________________
1139 void AliDielectronHistos::FillValues(TObject *obj, const Double_t *values)
1145 if (obj->InheritsFrom(TH1::Class())) FillValues(static_cast<TH1*>(obj), values);
1146 else if (obj->InheritsFrom(THnBase::Class())) FillValues(static_cast<THnBase*>(obj), values);
1152 //_____________________________________________________________________________
1153 void AliDielectronHistos::FillValues(TH1 *obj, const Double_t *values)
1156 // fill values for TH1 inherted classes
1159 Int_t dim = obj->GetDimension();
1160 Bool_t bprf = kFALSE;
1161 // UInt_t nValues = (UInt_t) AliDielectronVarManager::kNMaxValues;
1163 UInt_t valueTypes=obj->GetUniqueID();
1164 if (valueTypes==(UInt_t)AliDielectronHistos::kNoAutoFill) return;
1165 Bool_t weight = (valueTypes!=kNoWeights);
1167 if(obj->IsA() == TProfile::Class() || obj->IsA() == TProfile2D::Class() || obj->IsA() == TProfile3D::Class())
1170 UInt_t value1=obj->GetXaxis()->GetUniqueID();
1171 UInt_t value2=obj->GetYaxis()->GetUniqueID();
1172 UInt_t value3=obj->GetZaxis()->GetUniqueID();
1173 UInt_t value4=obj->GetUniqueID(); // get profile var stored in the unique ID
1175 // ask for inclusive trigger map variables
1176 if(value1!=AliDielectronVarManager::kTriggerInclONL && value1!=AliDielectronVarManager::kTriggerInclOFF &&
1177 value2!=AliDielectronVarManager::kTriggerInclONL && value2!=AliDielectronVarManager::kTriggerInclOFF &&
1178 value3!=AliDielectronVarManager::kTriggerInclONL && value3!=AliDielectronVarManager::kTriggerInclOFF &&
1179 value4!=AliDielectronVarManager::kTriggerInclONL && value4!=AliDielectronVarManager::kTriggerInclOFF ) {
1180 // no trigger map variable selected
1183 if(!bprf && !weight) obj->Fill(values[value1]); // histograms
1184 else if(!bprf && weight) obj->Fill(values[value1], values[value4]); // weighted histograms
1185 else if(bprf && !weight) ((TProfile*)obj)->Fill(values[value1],values[value2]); // profiles
1186 else ((TProfile*)obj)->Fill(values[value1],values[value2], values[value4]); // weighted profiles
1189 if(!bprf && !weight) obj->Fill(values[value1], values[value2]); // histograms
1190 else if(!bprf && weight) ((TH2*)obj)->Fill(values[value1], values[value2], values[value4]); // weighted histograms
1191 else if(bprf && !weight) ((TProfile2D*)obj)->Fill(values[value1], values[value2], values[value3]); // profiles
1192 else ((TProfile2D*)obj)->Fill(values[value1], values[value2], values[value3], values[value4]); // weighted profiles
1195 if(!bprf && !weight) ((TH3*)obj)->Fill(values[value1], values[value2], values[value3]); // histograms
1196 else if(!bprf && weight) ((TH3*)obj)->Fill(values[value1], values[value2], values[value3], values[value4]); // weighted histograms
1197 else if(bprf && !weight) ((TProfile3D*)obj)->Fill(values[value1], values[value2], values[value3], values[value4]); // profiles
1198 else printf(" WARNING: weighting NOT possible yet for TProfile3Ds ! \n");
1203 // fill inclusive trigger map variables
1207 for(Int_t i=0; i<30; i++) { if(TESTBIT((UInt_t)values[value1],i)) obj->Fill(i); }
1210 if((value1==AliDielectronVarManager::kTriggerInclOFF && value2==AliDielectronVarManager::kTriggerInclONL) ||
1211 (value1==AliDielectronVarManager::kTriggerInclONL && value2==AliDielectronVarManager::kTriggerInclOFF) ) {
1212 for(Int_t i=0; i<30; i++) {
1213 if((UInt_t)values[value1]==BIT(i)) {
1214 for(Int_t i2=0; i2<30; i2++) {
1215 if((UInt_t)values[value2]==BIT(i2)) {
1222 else if(value1==AliDielectronVarManager::kTriggerInclONL || value1==AliDielectronVarManager::kTriggerInclOFF) {
1223 for(Int_t i=0; i<30; i++) { if(TESTBIT((UInt_t)values[value1],i)) obj->Fill(i, values[value2]); }
1225 else if(value2==AliDielectronVarManager::kTriggerInclONL || value2==AliDielectronVarManager::kTriggerInclOFF) {
1226 for(Int_t i=0; i<30; i++) { if(TESTBIT((UInt_t)values[value2],i)) obj->Fill(values[value1], i); }
1228 else //makes no sense
1234 } //end: trigger filling
1240 //_____________________________________________________________________________
1241 void AliDielectronHistos::FillValues(THnBase *obj, const Double_t *values)
1244 // fill values for THn inherted classes
1247 const Int_t dim = obj->GetNdimensions();
1249 UInt_t valueTypes=obj->GetUniqueID();
1250 if (valueTypes==(UInt_t)AliDielectronHistos::kNoAutoFill) return;
1251 Bool_t weight = (valueTypes!=kNoWeights);
1253 UInt_t value4=obj->GetUniqueID(); // weight variable
1256 for(Int_t it=0; it<dim; it++) fill[it] = values[obj->GetAxis(it)->GetUniqueID()];
1257 if(!weight) obj->Fill(fill);
1258 else obj->Fill(fill, values[value4]);
1264 //_____________________________________________________________________________
1265 void AliDielectronHistos::FillVarArray(TObject *obj, UInt_t *valType)
1268 // extract variables stored in the axis (special for TProfile3D)
1273 // printf(" fillvararray %s \n",obj->GetName());
1275 if (obj->InheritsFrom(TH1::Class())) {
1276 valType[0]=((TH1*)obj)->GetXaxis()->GetUniqueID();
1277 valType[1]=((TH1*)obj)->GetYaxis()->GetUniqueID();
1278 valType[2]=((TH1*)obj)->GetZaxis()->GetUniqueID();
1279 valType[3]=((TH1*)obj)->GetUniqueID(); // tprofile var stored in unique ID
1281 else if (obj->InheritsFrom(THnBase::Class())) {
1282 for(Int_t it=0; it<((THn*)obj)->GetNdimensions(); it++)
1283 valType[it]=((THn*)obj)->GetAxis(it)->GetUniqueID();
1285 valType[19]=obj->GetUniqueID(); //weights
1289 //_____________________________________________________________________________
1290 void AliDielectronHistos::AdaptNameTitle(TH1 *hist, const char* histClass) {
1293 // adapt name and title of the histogram
1296 Int_t dim = hist->GetDimension();
1297 TString currentName = hist->GetName();
1298 TString currentTitle = hist->GetTitle();
1301 Bool_t bname = (currentName.IsNull());
1302 Bool_t btitle = (currentTitle.IsNull());
1303 Bool_t bprf = kFALSE;
1304 if(hist->IsA() == TProfile::Class() || hist->IsA() == TProfile2D::Class() || hist->IsA() == TProfile3D::Class())
1308 Double_t pmin=0., pmax=0.;
1309 TString option = "", calcrange="";
1310 Bool_t bStdOpt=kTRUE;
1314 option = ((TProfile3D*)hist)->GetErrorOption();
1315 pmin = ((TProfile3D*)hist)->GetTmin();
1316 pmax = ((TProfile3D*)hist)->GetTmax();
1319 option = ((TProfile2D*)hist)->GetErrorOption();
1320 pmin = ((TProfile2D*)hist)->GetZmin();
1321 pmax = ((TProfile2D*)hist)->GetZmax();
1324 option = ((TProfile*)hist)->GetErrorOption();
1325 pmin = ((TProfile*)hist)->GetYmin();
1326 pmax = ((TProfile*)hist)->GetYmax();
1329 if(option.Contains("s",TString::kIgnoreCase)) bStdOpt=kFALSE;
1330 if(pmin!=pmax) calcrange=Form("#cbar_{%+.*f}^{%+.*f}",GetPrecision(pmin),pmin,GetPrecision(pmax),pmax);
1333 UInt_t varx = hist->GetXaxis()->GetUniqueID();
1334 UInt_t vary = hist->GetYaxis()->GetUniqueID();
1335 UInt_t varz = hist->GetZaxis()->GetUniqueID();
1336 UInt_t varp = hist->GetUniqueID();
1337 Bool_t weight = (varp!=kNoWeights);
1339 // store titles in the axis
1343 hist->GetXaxis()->SetNameTitle(AliDielectronVarManager::GetValueName(varx),
1345 AliDielectronVarManager::GetValueLabel(varx),
1346 AliDielectronVarManager::GetValueUnit(varx))
1348 hist->GetYaxis()->SetNameTitle(AliDielectronVarManager::GetValueName(vary),
1350 AliDielectronVarManager::GetValueLabel(vary),
1351 AliDielectronVarManager::GetValueUnit(vary))
1353 hist->GetZaxis()->SetNameTitle(AliDielectronVarManager::GetValueName(varz),
1355 AliDielectronVarManager::GetValueLabel(varz),
1356 AliDielectronVarManager::GetValueUnit(varz))
1359 hist->SetNameTitle(AliDielectronVarManager::GetValueName(varp),
1360 Form("%s %s%s%s%s %s",
1362 (bStdOpt ? "#LT" : "RMS("),
1363 AliDielectronVarManager::GetValueLabel(varp),
1364 (bStdOpt ? "#GT" : ")"),
1366 AliDielectronVarManager::GetValueUnit(varp))
1370 hist->GetXaxis()->SetNameTitle(AliDielectronVarManager::GetValueName(varx),
1372 AliDielectronVarManager::GetValueLabel(varx),
1373 AliDielectronVarManager::GetValueUnit(varx))
1375 hist->GetYaxis()->SetNameTitle(AliDielectronVarManager::GetValueName(vary),
1377 AliDielectronVarManager::GetValueLabel(vary),
1378 AliDielectronVarManager::GetValueUnit(vary))
1380 hist->GetZaxis()->SetTitle(Form("#%ss",histClass));
1382 hist->GetZaxis()->SetNameTitle(AliDielectronVarManager::GetValueName(varz),
1384 (bStdOpt ? "#LT" : "RMS("),
1385 AliDielectronVarManager::GetValueLabel(varz),
1386 (bStdOpt ? "#GT" : ")"),
1388 AliDielectronVarManager::GetValueUnit(varz))
1390 if(weight) hist->GetZaxis()->SetTitle(Form("%s weighted %s",
1391 AliDielectronVarManager::GetValueLabel(varp),
1392 hist->GetZaxis()->GetTitle() )
1397 hist->GetXaxis()->SetNameTitle(AliDielectronVarManager::GetValueName(varx),
1399 AliDielectronVarManager::GetValueLabel(varx),
1400 AliDielectronVarManager::GetValueUnit(varx))
1402 hist->GetYaxis()->SetTitle(Form("#%ss",histClass));
1404 hist->GetYaxis()->SetNameTitle(AliDielectronVarManager::GetValueName(vary),
1406 (bStdOpt ? "#LT" : "RMS("),
1407 AliDielectronVarManager::GetValueLabel(vary),
1408 (bStdOpt ? "#GT" : ")"),
1410 AliDielectronVarManager::GetValueUnit(vary))
1412 if(weight) hist->GetYaxis()->SetTitle(Form("%s weighted %s",
1413 AliDielectronVarManager::GetValueLabel(varp),
1414 hist->GetYaxis()->GetTitle() )
1420 // create an unique name
1424 currentName+=Form("%s_",AliDielectronVarManager::GetValueName(varx));
1425 currentName+=Form("%s_",AliDielectronVarManager::GetValueName(vary));
1426 currentName+=Form("%s",AliDielectronVarManager::GetValueName(varz));
1427 if(bprf) currentName+=Form("-%s%s",AliDielectronVarManager::GetValueName(varp),(bStdOpt ? "avg" : "rms"));
1428 if(weight) currentName+=Form("-wght%s",AliDielectronVarManager::GetValueName(varp));
1431 currentName+=Form("%s_",AliDielectronVarManager::GetValueName(varx));
1432 currentName+=Form("%s",AliDielectronVarManager::GetValueName(vary));
1433 if(bprf) currentName+=Form("-%s%s",AliDielectronVarManager::GetValueName(varz),(bStdOpt ? "avg" : "rms"));
1434 if(weight) currentName+=Form("-wght%s",AliDielectronVarManager::GetValueName(varp));
1437 currentName+=Form("%s",AliDielectronVarManager::GetValueName(varx));
1438 if(bprf) currentName+=Form("-%s%s",AliDielectronVarManager::GetValueName(vary),(bStdOpt ? "avg" : "rms"));
1439 if(weight) currentName+=Form("-wght%s",AliDielectronVarManager::GetValueName(varp));
1442 // to differentiate btw. leg and pair histos
1443 if(!strcmp(histClass,"Pair")) currentName.Prepend("p");
1444 hist->SetName(currentName.Data());
1449 Int_t AliDielectronHistos::GetPrecision(Double_t value) {
1452 // computes the precision of a double
1453 // usefull for axis ranges etc
1456 Bool_t bfnd = kFALSE;
1457 Int_t precision = 0;
1460 // printf(" value %f precision %d bfnd %d \n",TMath::Abs(value*TMath::Power(10,precision)), precision, bfnd);
1461 bfnd = ((TMath::Abs(value*TMath::Power(10,precision))/1e6 - TMath::Floor(TMath::Abs(value*TMath::Power(10,precision))/1e6)) != 0.0
1464 if(!bfnd) precision++;
1467 // printf("precision for %f found to be %d \n", value, precision);