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 **************************************************************************/
16 ///////////////////////////////////////////////////////////////////////////
17 // Dielectron Correction framework draw helper //
31 ///////////////////////////////////////////////////////////////////////////
33 #include <TSeqCollection.h>
34 #include <TObjArray.h>
39 #include <TVirtualPS.h>
42 #include <TObjString.h>
51 #include <AliCFEffGrid.h>
55 #include "AliDielectronCFdraw.h"
57 ClassImp(AliDielectronCFdraw)
59 AliDielectronCFdraw::AliDielectronCFdraw() :
70 //________________________________________________________________
71 AliDielectronCFdraw::AliDielectronCFdraw(const char*name, const char* title) :
83 //________________________________________________________________
84 AliDielectronCFdraw::AliDielectronCFdraw(AliCFContainer *cont) :
85 TNamed(cont->GetName(), cont->GetTitle()),
87 fEffGrid(new AliCFEffGrid("eff","eff",*cont)),
91 // directly set the CF container
96 //________________________________________________________________
97 AliDielectronCFdraw::AliDielectronCFdraw(const char* filename) :
104 // get CF container(s) from file 'filename'
106 SetCFContainers(filename);
109 //________________________________________________________________
110 void AliDielectronCFdraw::SetCFContainers(const TSeqCollection *arr)
113 // Merge CF Container out of several containers
120 while ( (o=next()) ){
121 AliCFContainer *cf=dynamic_cast<AliCFContainer*>(o);
123 nstep+=cf->GetNStep();
125 if (nstep==0) return;
127 fCfContainer=new AliCFContainer(GetName(), GetTitle(), nstep, 1, nbins);
129 //delete unneeded steps
130 // for (Int_t istep=0; istep<nstep; ++istep) delete fCfContainer->GetGrid(istep);
132 //add step to the new container
134 for (Int_t icf=0; icf<arr->GetEntries(); ++icf){
135 AliCFContainer *cf=dynamic_cast<AliCFContainer*>(arr->At(icf));
137 for (Int_t istepCurr=0; istepCurr<cf->GetNStep(); ++istepCurr){
138 fCfContainer->SetGrid(istep, cf->GetGrid(istepCurr));
139 fCfContainer->SetStepTitle(istep,Form("%s, Pair: %s",cf->GetTitle(),cf->GetStepTitle(istepCurr)));
143 if (fEffGrid) delete fEffGrid;
144 fEffGrid=new AliCFEffGrid("eff","eff",*fCfContainer);
147 //________________________________________________________________
148 void AliDielectronCFdraw::SetCFContainers(const char* filename)
151 // get CF containers from file
155 TList *l=f.GetListOfKeys();
158 while ( (k=static_cast<TKey*>(nextKey())) ){
159 TObject *o=k->ReadObj();
160 if (o->IsA()->InheritsFrom(TSeqCollection::Class())){
161 TSeqCollection *arr=static_cast<TSeqCollection*>(o);
162 SetCFContainers(arr);
163 } else if (o->IsA()==AliCFContainer::Class()){
164 fCfContainer=static_cast<AliCFContainer*>(o);
165 if (fEffGrid) delete fEffGrid;
166 fEffGrid=new AliCFEffGrid("eff","eff",*fCfContainer);
171 //________________________________________________________________
172 void AliDielectronCFdraw::SetRangeUser(Int_t ivar, Double_t min, Double_t max, const char* slices)
175 // Set range of cut steps defined in slices
176 // Steps may be separated by one the the characteres ,;:
178 TObjArray *arr=TString(slices).Tokenize(",:;");
180 if (arr->GetEntriesFast()==0){
181 // all slices in case of 0 entries
182 for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
183 fCfContainer->SetRangeUser(ivar,min,max,istep);
187 TObjString *ostr=0x0;
188 while ( (ostr=static_cast<TObjString*>(next())) ) {
189 Int_t istep=ostr->GetString().Atoi();
190 fCfContainer->SetRangeUser(ivar,min,max,istep);
196 //________________________________________________________________
197 void AliDielectronCFdraw::UnsetRangeUser(Int_t ivar, const char* slices)
200 // Unset range of cut steps defined in slices
201 // Steps may be separated by one the the characteres ,;:
203 TObjArray *arr=TString(slices).Tokenize(",:;");
205 if (arr->GetEntriesFast()==0){
206 // all slices in case of 0 entries
207 for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
208 fCfContainer->GetAxis(ivar,istep)->SetRange(0,0);
212 TObjString *ostr=0x0;
213 while ( (ostr=static_cast<TObjString*>(next())) ) {
214 Int_t istep=ostr->GetString().Atoi();
215 fCfContainer->GetAxis(ivar,istep)->SetRange(0,0);
221 //________________________________________________________________
222 void AliDielectronCFdraw::Draw(const Option_t* varnames, const char* opt, const char* slices)
225 // Draw 'variables' of 'slices'
226 // for multidimensional draw variables may be separated by a ':'
227 // slice numbers may be separated by any of ,:;
229 // variables may be called by either their name or number
232 TObjArray *arrVars=TString(varnames).Tokenize(":");
233 Int_t entries=arrVars->GetEntriesFast();
234 if (entries<1||entries>3){
235 AliError("Wrong number of variables, supported are 1 - 3 dimensions");
241 TObjString *ostr=0x0;
242 Int_t ivar[3]={-1,-1,-1};
243 for (Int_t i=0; i<entries; ++i){
244 ostr=static_cast<TObjString*>(next());
245 if (ostr->GetString().IsDigit()){
246 ivar[i]=ostr->GetString().Atoi();
248 ivar[i]=fCfContainer->GetVar(ostr->GetName());
254 Draw(ivar[0],opt,slices);
257 Draw(ivar[1],ivar[0],opt,slices);
260 Draw(ivar[2],ivar[1],ivar[0],opt,slices);
266 //________________________________________________________________
267 void AliDielectronCFdraw::Draw(Int_t var, const char* opt, const char* slices)
270 // Draw variable var for all slices
271 // slices may be divided by and of ,;:
273 // if opt contains 'same' all histograms are drawn in the same pad
274 // otherwise the pad will be divided in sub pads and the histograms
275 // are drawn in each sub pad
279 Int_t vars[ndim]={var};
280 TObjArray *arr=CollectHistosProj(ndim,vars,slices);
285 //________________________________________________________________
286 void AliDielectronCFdraw::Draw(Int_t var0, Int_t var1, const char* opt, const char* slices)
292 Int_t vars[ndim]={var0,var1};
293 TObjArray *arr=CollectHistosProj(ndim,vars,slices);
298 //________________________________________________________________
299 void AliDielectronCFdraw::Draw(Int_t var0, Int_t var1, Int_t var2, const char* opt, const char* slices)
305 Int_t vars[ndim]={var0,var1,var2};
306 TObjArray *arr=CollectHistosProj(ndim,vars,slices);
311 //________________________________________________________________
312 TObjArray* AliDielectronCFdraw::CollectHistosProj(Int_t dim, Int_t *vars, const char* slices)
315 // Collect histos with 'dim'ension of the 'slices' separated by one of "':;'"
316 // in a TObjArray and return it
318 TObjArray *arr=TString(slices).Tokenize(",:;");
319 TObjArray *arrHists=0x0;
320 if (arr->GetEntriesFast()==0){
321 // all slices in case of 0 entries
322 arrHists=new TObjArray(fCfContainer->GetNStep());
323 for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
324 TH1 *hproj=Project(dim,vars,istep);
325 if (!hproj) continue;
326 hproj->SetName(Form("proj_%02d",istep));
327 hproj->SetTitle(fCfContainer->GetStepTitle(istep));
328 arrHists->Add(hproj);
331 arrHists=new TObjArray(arr->GetEntriesFast());
333 TObjString *ostr=0x0;
334 while ( (ostr=static_cast<TObjString*>(next())) ) {
335 Int_t istep=ostr->GetString().Atoi();
336 TH1 *hproj=Project(dim,vars,istep);
337 if (!hproj) continue;
338 hproj->SetName(Form("proj_%02d",istep));
339 hproj->SetTitle(fCfContainer->GetStepTitle(istep));
340 arrHists->Add(hproj);
348 //________________________________________________________________
349 TH1* AliDielectronCFdraw::Project(Int_t ndim, Int_t *vars, Int_t slice)
352 // Do an ndim projection
356 return fCfContainer->Project(vars[0],slice);
359 return fCfContainer->Project(vars[0],vars[1],slice);
362 return fCfContainer->Project(vars[0],vars[1],vars[2],slice);
368 //________________________________________________________________
369 TH1* AliDielectronCFdraw::Project(const Option_t* var, Int_t slice)
372 // translate variable names and do projection
374 TObjArray *arrVars=TString(var).Tokenize(":");
375 Int_t entries=arrVars->GetEntriesFast();
376 if (entries<1||entries>3){
377 AliError("Wrong number of variables, supported are 1 - 3 dimensions");
383 TObjString *ostr=0x0;
384 Int_t ivar[3]={-1,-1,-1};
385 for (Int_t i=0; i<entries; ++i){
386 ostr=static_cast<TObjString*>(next());
387 if (ostr->GetString().IsDigit()){
388 ivar[i]=ostr->GetString().Atoi();
390 ivar[i]=fCfContainer->GetVar(ostr->GetName());
394 return Project(entries,ivar,slice);
397 //________________________________________________________________
398 void AliDielectronCFdraw::DrawEfficiency(const char* varnames, const char* nominators, Int_t denominator, const char* opt)
401 // plot efficiencies for variables. Variable may be up to 3 dim, separated by a ':'
402 // you may have several nominators, sparated by one of ',:;'
405 TObjArray *arrVars=TString(varnames).Tokenize(":");
406 Int_t entries=arrVars->GetEntriesFast();
407 if (entries<1||entries>3){
408 AliError("Wrong number of variables, supported are 1 - 3 dimensions");
414 TObjString *ostr=0x0;
415 Int_t ivar[3]={-1,-1,-1};
416 for (Int_t i=0; i<entries; ++i){
417 ostr=static_cast<TObjString*>(next());
418 if (ostr->GetString().IsDigit()){
419 ivar[i]=ostr->GetString().Atoi();
421 ivar[i]=fCfContainer->GetVar(ostr->GetName());
427 if (optStr.Contains("2")) type=1;
431 DrawEfficiency(ivar[0],nominators, denominator,opt,type);
434 DrawEfficiency(ivar[1],ivar[0], nominators, denominator,opt,type);
437 DrawEfficiency(ivar[2],ivar[1],ivar[0],nominators, denominator,opt,type);
443 //________________________________________________________________
444 void AliDielectronCFdraw::DrawEfficiency(Int_t var, const char* nominators, Int_t denominator, const char* opt, Int_t type)
447 // Draw Efficiencies for all nominators
448 // nominators may be divided by and of ,;:
450 // if opt contains 'same' all histograms are drawn in the same pad
451 // otherwise the pad will be divided in sub pads and the histograms
452 // are drawn in each sub pad
456 Int_t vars[ndim]={var};
457 TObjArray *arr=CollectHistosEff(ndim,vars,nominators,denominator,type);
464 //________________________________________________________________
465 void AliDielectronCFdraw::DrawEfficiency(Int_t var0, Int_t var1, const char* nominators, Int_t denominator, const char* opt, Int_t type)
471 Int_t vars[ndim]={var0,var1};
472 TObjArray *arr=CollectHistosEff(ndim,vars,nominators,denominator,type);
479 //________________________________________________________________
480 void AliDielectronCFdraw::DrawEfficiency(Int_t var0, Int_t var1, Int_t var2, const char* nominators, Int_t denominator, const char* opt, Int_t type)
486 Int_t vars[ndim]={var0,var1,var2};
487 TObjArray *arr=CollectHistosEff(ndim,vars,nominators,denominator,type);
494 //________________________________________________________________
495 TObjArray* AliDielectronCFdraw::CollectHistosEff(Int_t dim, Int_t *vars, const char* nominators, Int_t denominator, Int_t type)
498 // Collect histos with 'dim'ension of the 'slices' separated by one of "':;'"
499 // in a TObjArray and return it
501 TObjArray *arr=TString(nominators).Tokenize(",:;");
502 TObjArray *arrHists=0x0;
505 if (arr->GetEntriesFast()==0){
506 // all slices in case of 0 entries
507 arrHists=new TObjArray(fCfContainer->GetNStep());
508 fVdata.ResizeTo(arrHists->GetSize());
509 for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
510 fEffGrid->CalculateEfficiency(istep,denominator);
511 TH1 *hproj=ProjectEff(dim,vars);
512 if (!hproj) continue;
513 Float_t eff=fEffGrid->GetAverage();
515 hproj->SetName(Form("eff_%02d/%02d",istep,denominator));
516 hproj->SetTitle(Form("%s (%.3f)",fCfContainer->GetStepTitle(istep),eff));
517 arrHists->Add(hproj);
520 arrHists=new TObjArray(arr->GetEntriesFast());
522 TObjString *ostr=0x0;
523 fVdata.ResizeTo(arrHists->GetSize());
525 while ( (ostr=static_cast<TObjString*>(next())) ) {
526 Int_t istep=ostr->GetString().Atoi();
527 fEffGrid->CalculateEfficiency(istep,denominator);
528 TH1 *hproj=ProjectEff(dim,vars);
529 if (!hproj) continue;
530 Float_t eff=fEffGrid->GetAverage();
532 hproj->SetName(Form("eff_%02d/%02d",istep,denominator));
533 hproj->SetTitle(Form("%s (%.3f)",fCfContainer->GetStepTitle(istep),eff));
534 arrHists->Add(hproj);
541 TH1 *hDen=Project(dim,vars,denominator);
542 Double_t entriesDen=hDen->GetEffectiveEntries();
543 if (arr->GetEntriesFast()==0){
544 // all slices in case of 0 entries
545 arrHists=new TObjArray(fCfContainer->GetNStep());
546 fVdata.ResizeTo(arrHists->GetSize());
547 for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
548 TH1 *hproj=Project(dim,vars,istep);
549 if (!hproj) continue;
551 if (entriesDen>0) eff=hproj->GetEffectiveEntries()/entriesDen;
553 hproj->Divide(hproj,hDen,1,1,"B");
554 hproj->SetName(Form("eff_%02d/%02d",istep,denominator));
555 hproj->SetTitle(Form("%s (%.3f)",fCfContainer->GetStepTitle(istep),eff));
556 arrHists->Add(hproj);
559 arrHists=new TObjArray(arr->GetEntriesFast());
560 fVdata.ResizeTo(arrHists->GetSize());
562 TObjString *ostr=0x0;
564 while ( (ostr=static_cast<TObjString*>(next())) ) {
565 Int_t istep=ostr->GetString().Atoi();
566 TH1 *hproj=Project(dim,vars,istep);
567 if (!hproj) continue;
569 if (entriesDen>0) eff=hproj->GetEffectiveEntries()/entriesDen;
571 hproj->Divide(hproj,hDen,1,1,"B");
572 hproj->SetName(Form("eff_%02d/%02d",istep,denominator));
573 hproj->SetTitle(Form("%s (%.3f)",fCfContainer->GetStepTitle(istep),eff));
574 arrHists->Add(hproj);
585 //________________________________________________________________
586 TH1* AliDielectronCFdraw::ProjectEff(Int_t ndim, Int_t *vars)
589 // Do an nim projection
593 return fEffGrid->Project(vars[0]);
596 return fEffGrid->Project(vars[0],vars[1]);
599 return fEffGrid->Project(vars[0],vars[1],vars[2]);
605 //________________________________________________________________
606 void AliDielectronCFdraw::Draw(const TObjArray *arr, const char* opt)
609 // draw all objects in arr
613 Bool_t drawSame = optStr.Contains("same");
614 Bool_t drawSamePlus = optStr.Contains("same+");
615 Bool_t drawEff = optStr.Contains("eff");
616 Bool_t optLeg = optStr.Contains("leg");
617 Bool_t optScaleMax = optStr.Contains("max");
619 if (!drawSamePlus) optStr.ReplaceAll("same","");
621 optStr.ReplaceAll("+","");
622 optStr.ReplaceAll("eff","");
623 optStr.ReplaceAll("leg","");
624 optStr.ReplaceAll("max","");
626 if (!gPad) new TCanvas;
628 Int_t nPads = arr->GetEntriesFast();
629 if (nPads==0) return;
632 // arr->UncheckedAt(0)->Draw(optStr.Data());
636 TCanvas *c=gPad->GetCanvas();
637 if (!gVirtualPS&&!drawSamePlus&&!drawSame&&nPads>1) c->Clear();
639 if (!drawSame&&nPads>1){
641 Int_t nCols = (Int_t)TMath::Ceil( TMath::Sqrt(nPads) );
642 Int_t nRows = (Int_t)TMath::Ceil( (Double_t)nPads/(Double_t)nCols );
643 c->Divide(nCols,nRows);
644 for (Int_t i=0; i<nPads; ++i){
646 arr->UncheckedAt(i)->Draw(optStr.Data());
651 //find already existing legend to attach entries to it
652 TIter nextPrimitive(gPad->GetListOfPrimitives());
654 while ((o=nextPrimitive())) if (o->IsA()==TLegend::Class()) leg=(TLegend*)o;
657 if (optLeg&&!leg) leg=new TLegend(.2,.3,.99,.9);
659 if (leg) addColor=leg->GetNRows();
661 if (nPads<7) offset=24;
662 for (Int_t i=0; i<nPads; ++i){
663 if (i==1&&!drawSamePlus) optStr+="same";
664 TH1 *hist=static_cast<TH1*>(arr->UncheckedAt(i));
665 hist->SetLineColor(i+1+addColor);
666 hist->SetLineWidth(2);
667 hist->SetMarkerColor(i+1+addColor);
668 hist->SetMarkerStyle(offset+i+addColor);
669 hist->Draw(optStr.Data());
671 if (drawEff&&i==0&&!drawSamePlus) {
672 hist->GetYaxis()->SetRangeUser(0,2);
673 hist->SetYTitle("Rec. Signal / Gen. Signal");
676 if (leg) leg->AddEntry(hist,hist->GetTitle(),"lp");
679 leg->SetFillColor(10);
680 leg->SetY1(.9-leg->GetNRows()*.05);
681 leg->SetY1NDC(.9-leg->GetNRows()*.05);
683 if (!drawSamePlus) leg->Draw();
686 TIter nextPrimitive(gPad->GetListOfPrimitives());
690 while ((o=nextPrimitive())) if (o->InheritsFrom(TH1::Class())){
692 if (!hfirst) hfirst=h;
693 if (h->GetMaximum()>max) max=h->GetMaximum();
696 hfirst->SetMaximum(max);