]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - PWGDQ/dielectron/AliDielectronCFdraw.cxx
Fixing a memory leak
[u/mrichter/AliRoot.git] / PWGDQ / dielectron / AliDielectronCFdraw.cxx
... / ...
CommitLineData
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// Dielectron Correction framework draw helper //
18// //
19/*
20
21
22
23
24
25
26
27
28
29*/
30// //
31///////////////////////////////////////////////////////////////////////////
32
33#include <TSeqCollection.h>
34#include <TObjArray.h>
35#include <TKey.h>
36#include <TList.h>
37#include <TClass.h>
38#include <TObject.h>
39#include <TVirtualPS.h>
40#include <TFile.h>
41#include <TString.h>
42#include <TObjString.h>
43#include <TVectorD.h>
44#include <TMath.h>
45#include <TH1.h>
46#include <TH2.h>
47#include <TH3.h>
48#include <TPad.h>
49#include <TCanvas.h>
50#include <TLegend.h>
51#include <AliCFEffGrid.h>
52
53#include <AliLog.h>
54
55#include "AliDielectronCFdraw.h"
56#include "AliDielectron.h"
57#include "AliDielectronVarManager.h"
58
59ClassImp(AliDielectronCFdraw)
60
61AliDielectronCFdraw::AliDielectronCFdraw() :
62 TNamed(),
63 fCfContainer(0x0),
64 fEffGrid(0x0),
65 fVdata(0)
66{
67 //
68 // Ctor
69 //
70}
71
72//________________________________________________________________
73AliDielectronCFdraw::AliDielectronCFdraw(const char*name, const char* title) :
74 TNamed(name,title),
75 fCfContainer(0x0),
76 fEffGrid(0x0),
77 fVdata(0)
78{
79 //
80 // Named Ctor
81 //
82
83}
84
85//________________________________________________________________
86AliDielectronCFdraw::AliDielectronCFdraw(AliCFContainer *cont) :
87 TNamed(cont->GetName(), cont->GetTitle()),
88 fCfContainer(cont),
89 fEffGrid(new AliCFEffGrid("eff","eff",*cont)),
90 fVdata(0)
91{
92 //
93 // directly set the CF container
94 //
95
96}
97
98//________________________________________________________________
99AliDielectronCFdraw::AliDielectronCFdraw(const char* filename) :
100 TNamed(),
101 fCfContainer(0x0),
102 fEffGrid(0x0),
103 fVdata(0)
104{
105 //
106 // get CF container(s) from file 'filename'
107 //
108 SetCFContainers(filename);
109}
110
111//________________________________________________________________
112AliDielectronCFdraw::~AliDielectronCFdraw()
113{
114 //
115 // dtor
116 //
117 delete fCfContainer;
118 delete fEffGrid;
119}
120
121//________________________________________________________________
122void AliDielectronCFdraw::SetCFContainers(const TSeqCollection *arr)
123{
124 //
125 // Merge CF Container out of several containers
126 //
127
128 delete fCfContainer; fCfContainer=0x0;
129 delete fEffGrid; fEffGrid=0x0;
130 TIter next(arr);
131 TObject *o=0x0;
132
133 Int_t nstep=0;
134 while ( (o=next()) ){
135 AliCFContainer *cf=dynamic_cast<AliCFContainer*>(o);
136 if (!cf) continue;
137 nstep+=cf->GetNStep();
138 }
139 if (nstep==0) return;
140 Int_t nbins[1]={1};
141 fCfContainer=new AliCFContainer(GetName(), GetTitle(), nstep, 1, nbins);
142
143 //delete unneeded steps
144// for (Int_t istep=0; istep<nstep; ++istep) delete fCfContainer->GetGrid(istep);
145
146 //add step to the new container
147 Int_t istep=0;
148 for (Int_t icf=0; icf<arr->GetEntries(); ++icf){
149 AliCFContainer *cf=dynamic_cast<AliCFContainer*>(arr->At(icf));
150 if (!cf) continue;
151 for (Int_t istepCurr=0; istepCurr<cf->GetNStep(); ++istepCurr){
152 fCfContainer->SetGrid(istep, cf->GetGrid(istepCurr));
153 fCfContainer->SetStepTitle(istep,Form("%s, Pair: %s",cf->GetTitle(),cf->GetStepTitle(istepCurr)));
154 ++istep;
155 }
156 }
157 if (fEffGrid) delete fEffGrid;
158 fEffGrid=new AliCFEffGrid("eff","eff",*fCfContainer);
159}
160
161//________________________________________________________________
162void AliDielectronCFdraw::SetCFContainers(const char* filename)
163{
164 //
165 // get CF containers from file
166 //
167
168 TFile f(filename);
169 TList *l=f.GetListOfKeys();
170 TIter nextKey(l);
171 TKey *k=0x0;
172 while ( (k=static_cast<TKey*>(nextKey())) ){
173 TObject *o=k->ReadObj();
174 if (o->IsA()->InheritsFrom(TSeqCollection::Class())){
175 TSeqCollection *arr=static_cast<TSeqCollection*>(o);
176 SetCFContainers(arr);
177 } else if (o->IsA()==AliCFContainer::Class()){
178 fCfContainer=static_cast<AliCFContainer*>(o);
179 if (fEffGrid) delete fEffGrid;
180 fEffGrid=new AliCFEffGrid("eff","eff",*fCfContainer);
181 }
182 }
183}
184
185//________________________________________________________________
186void AliDielectronCFdraw::SetRangeUser(Int_t ivar, Double_t min, Double_t max, const char* slices)
187{
188 //
189 // Set range of cut steps defined in slices
190 // Steps may be separated by one the the characteres ,;:
191 //
192 if (ivar==-1) return;
193 TObjArray *arr=TString(slices).Tokenize(",:;");
194
195 //Changes in root TAxis r48279
196 //it doesn't work any longer to give the same min and max in SetRangeUser
197 //the lines below fix this
198
199 TAxis *a = fCfContainer->GetAxis(ivar,0);
200 if (a) {
201 const Int_t bin=a->FindBin(min);
202 const Double_t binw=a->GetBinWidth(bin);
203 if (TMath::Abs(max-min)<binw*0.001){
204 max+=binw*0.001;
205 }
206 }
207
208 if (arr->GetEntriesFast()==0){
209 // all slices in case of 0 entries
210 for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
211 fCfContainer->GetGrid(istep)->SetRangeUser(ivar,min,max);
212 fCfContainer->GetAxis(ivar,istep)->SetBit(TAxis::kAxisRange,1);
213 }
214 } else {
215 TIter next(arr);
216 TObjString *ostr=0x0;
217 while ( (ostr=static_cast<TObjString*>(next())) ) {
218 Int_t istep=ostr->GetString().Atoi();
219 fCfContainer->GetGrid(istep)->SetRangeUser(ivar,min,max);
220 fCfContainer->GetAxis(ivar,istep)->SetBit(TAxis::kAxisRange,1);
221 }
222 }
223 delete arr;
224}
225
226//________________________________________________________________
227void AliDielectronCFdraw::SetRangeUser(AliDielectronVarManager::ValueTypes type, Double_t min, Double_t max, const char* slices, Bool_t leg)
228{
229 //
230 // Set range of cut steps defined in slices
231 // Steps may be separated by one the the characteres ,;:
232 //
233 SetRangeUser(Form("%s%s",(leg?"Leg1_":""),AliDielectronVarManager::GetValueName(type)), min, max, slices);
234 if(leg) SetRangeUser(Form("%s%s","Leg2_",AliDielectronVarManager::GetValueName(type)), min, max, slices);
235
236}
237
238//________________________________________________________________
239void AliDielectronCFdraw::SetRangeUser(const char* varname, Double_t min, Double_t max, const char* slices)
240{
241 //
242 // Set range from variable name
243 //
244 Int_t ivar=fCfContainer->GetVar(varname);
245 if (ivar==-1){
246 AliFatal(Form("Variable '%s' not found",varname));
247 return;
248 }
249 SetRangeUser(ivar,min,max,slices);
250}
251
252//________________________________________________________________
253void AliDielectronCFdraw::UnsetRangeUser(const char* varname, const char* slices)
254{
255 //
256 // Unset range from variable name
257 //
258 Int_t ivar=fCfContainer->GetVar(varname);
259 if (ivar==-1){
260 AliFatal(Form("Variable '%s' not found",varname));
261 return;
262 }
263 UnsetRangeUser(ivar,slices);
264}
265
266//________________________________________________________________
267void AliDielectronCFdraw::UnsetRangeUser(AliDielectronVarManager::ValueTypes type, const char* slices, Bool_t leg)
268{
269 //
270 // Unset range of cut steps defined in slices
271 // Steps may be separated by one the the characteres ,;:
272 //
273 UnsetRangeUser(Form("%s%s",(leg?"Leg1_":""),AliDielectronVarManager::GetValueName(type)), slices);
274 UnsetRangeUser(Form("%s%s",(leg?"Leg2_":""),AliDielectronVarManager::GetValueName(type)), slices);
275}
276
277//________________________________________________________________
278void AliDielectronCFdraw::UnsetRangeUser(Int_t ivar, const char* slices)
279{
280 //
281 // Unset range of cut steps defined in slices
282 // Steps may be separated by one the the characteres ,;:
283 //
284 if (ivar==-1) return;
285 TObjArray *arr=TString(slices).Tokenize(",:;");
286
287 if (arr->GetEntriesFast()==0){
288 // all slices in case of 0 entries
289 for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
290 fCfContainer->GetAxis(ivar,istep)->SetRange(0,0);
291 fCfContainer->GetAxis(ivar,istep)->SetBit(TAxis::kAxisRange,0);
292 }
293 } else {
294 TIter next(arr);
295 TObjString *ostr=0x0;
296 while ( (ostr=static_cast<TObjString*>(next())) ) {
297 Int_t istep=ostr->GetString().Atoi();
298 fCfContainer->GetAxis(ivar,istep)->SetRange(0,0);
299 fCfContainer->GetAxis(ivar,istep)->SetBit(TAxis::kAxisRange,0);
300 }
301 }
302 delete arr;
303}
304
305//________________________________________________________________
306void AliDielectronCFdraw::Draw(const Option_t* varnames, const char* opt, const char* slices)
307{
308 //
309 // Draw 'variables' of 'slices'
310 // for multidimensional draw variables may be separated by a ':'
311 // slice numbers may be separated by any of ,:;
312 //
313 // variables may be called by either their name or number
314 //
315
316 TObjArray *arrVars=TString(varnames).Tokenize(":");
317 Int_t entries=arrVars->GetEntriesFast();
318 if (entries<1||entries>3){
319 AliError("Wrong number of variables, supported are 1 - 3 dimensions");
320 delete arrVars;
321 return;
322 }
323
324 TIter next(arrVars);
325 TObjString *ostr=0x0;
326 Int_t ivar[3]={-1,-1,-1};
327 for (Int_t i=entries-1; i>=0; --i){
328 ostr=static_cast<TObjString*>(next());
329 if (ostr->GetString().IsDigit()){
330 ivar[i]=ostr->GetString().Atoi();
331 } else {
332 ivar[i]=fCfContainer->GetVar(ostr->GetName());
333 }
334 }
335
336 Draw(ivar[0],ivar[1],ivar[2],opt,slices);
337 delete arrVars;
338}
339
340//________________________________________________________________
341TString AliDielectronCFdraw::FindSteps(const char* search)
342{
343 //
344 // find steps/slices containg search string
345 // search strings may be separated by any of ,:;
346 //
347 TObjArray *arr=TString(search).Tokenize(",:;");
348 TIter next(arr);
349 TObjString *ostr=0x0;
350
351 TString slices="";
352 Int_t nfnd=0;
353 // loop over all steps
354 for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
355 TString steptit = fCfContainer->GetStepTitle(istep);
356 Bool_t bfnd=kFALSE;
357 next.Reset();
358 // loop over all search strings
359 while ( (ostr=static_cast<TObjString*>(next())) ) {
360 if( steptit.Contains(ostr->GetName()) ) bfnd=kTRUE;
361 else {
362 bfnd=kFALSE;
363 break;
364 }
365 }
366 // append found slices string
367 if(bfnd) {
368 if(nfnd)
369 slices.Append(Form(":%d",istep));
370 else
371 slices.Append(Form("%d", istep));
372 nfnd++;
373 }
374 }
375 delete arr;
376
377 if(!nfnd) AliWarning(" No step searched for found. returning all steps!");
378 return slices;
379}
380//________________________________________________________________
381Int_t AliDielectronCFdraw::FindStep(const char* search)
382{
383 //
384 // find first step/slice containg search string
385 // search strings may be separated by any of ,:;
386 //
387 TObjArray *arr=TString(search).Tokenize(",:;");
388 TIter next(arr);
389 TObjString *ostr=0x0;
390
391 // loop over all steps
392 for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
393 TString steptit = fCfContainer->GetStepTitle(istep);
394 Bool_t bfnd=kFALSE;
395 next.Reset();
396 // loop over all search strings
397 while ( (ostr=static_cast<TObjString*>(next())) ) {
398 if( steptit.Contains(ostr->GetName()) ) bfnd=kTRUE;
399 else {
400 bfnd=kFALSE;
401 break;
402 }
403 }
404 // return found slice/step
405 if(bfnd) {
406 delete arr;
407 return istep;
408 }
409 }
410
411 AliError(" No step searched for found. returning -1!");
412 delete arr;
413 return -1;
414
415}
416//________________________________________________________________
417TObjArray* AliDielectronCFdraw::CollectHistosProj(const Option_t* varnames, const char* slices)
418{
419 //
420 // Collect histos with 'variables' of 'slices'
421 // for multidimensional histograms, variables may be separated by a ':'
422 // slice numbers may be separated by any of ,:;
423 //
424 // variables may be called by either their name or number
425 //
426
427 TObjArray *arrVars=TString(varnames).Tokenize(":");
428 Int_t entries=arrVars->GetEntriesFast();
429 if (entries<1||entries>3){
430 AliError("Wrong number of variables, supported are 1 - 3 dimensions");
431 delete arrVars;
432 return 0x0;
433 }
434
435 TIter next(arrVars);
436 TObjString *ostr=0x0;
437 Int_t ivar[3]={-1,-1,-1};
438 for (Int_t i=entries-1; i>=0; --i){
439 ostr=static_cast<TObjString*>(next());
440 if (ostr->GetString().IsDigit()){
441 ivar[i]=ostr->GetString().Atoi();
442 } else {
443 ivar[i]=fCfContainer->GetVar(ostr->GetName());
444 }
445 }
446 delete arrVars;
447
448 return CollectHistosProj(ivar,slices);
449}
450
451//________________________________________________________________
452void AliDielectronCFdraw::Draw(Int_t var, const char* opt, const char* slices)
453{
454 //
455 // Draw variable var for all slices
456 // slices may be divided by and of ,;:
457 //
458 // if opt contains 'same' all histograms are drawn in the same pad
459 // otherwise the pad will be divided in sub pads and the histograms
460 // are drawn in each sub pad
461 //
462
463 Int_t vars[3]={var,-1,-1};
464 TObjArray *arr=CollectHistosProj(vars,slices);
465 Draw(arr,opt);
466 delete arr;
467}
468
469//________________________________________________________________
470void AliDielectronCFdraw::Draw(Int_t var0, Int_t var1, const char* opt, const char* slices)
471{
472 //
473 // Draw 2D case
474 //
475 Int_t vars[3]={var0,var1,-1};
476 TObjArray *arr=CollectHistosProj(vars,slices);
477 Draw(arr,opt);
478 delete arr;
479}
480
481//________________________________________________________________
482void AliDielectronCFdraw::Draw(Int_t var0, Int_t var1, Int_t var2, const char* opt, const char* slices)
483{
484 //
485 // Draw 3D case
486 //
487 Int_t vars[3]={var0,var1,var2};
488 TObjArray *arr=CollectHistosProj(vars,slices);
489 Draw(arr,opt);
490 delete arr;
491}
492
493//________________________________________________________________
494TObjArray* AliDielectronCFdraw::CollectHistosProj(const Int_t vars[3], const char* slices)
495{
496 //
497 // Collect histos with up to 3 dimension of the 'slices' separated by one of "':;'"
498 // in a TObjArray and return it
499 // if a dimension is not used it must be set to -1
500 //
501 TObjArray *arr=TString(slices).Tokenize(",:;");
502 TObjArray *arrHists=0x0;
503 if (arr->GetEntriesFast()==0){
504 // all slices in case of 0 entries
505 arrHists=new TObjArray(fCfContainer->GetNStep());
506 for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
507 TH1 *hproj=Project(vars,istep);
508 if (!hproj) continue;
509 hproj->SetName(Form("proj_%02d",istep));
510 hproj->SetTitle(fCfContainer->GetStepTitle(istep));
511 arrHists->Add(hproj);
512 }
513 } else {
514 arrHists=new TObjArray(arr->GetEntriesFast());
515 TIter next(arr);
516 TObjString *ostr=0x0;
517 while ( (ostr=static_cast<TObjString*>(next())) ) {
518 Int_t istep=ostr->GetString().Atoi();
519 TH1 *hproj=Project(vars,istep);
520 if (!hproj) continue;
521 hproj->SetName(Form("proj_%02d",istep));
522 hproj->SetTitle(fCfContainer->GetStepTitle(istep));
523 arrHists->Add(hproj);
524 }
525 }
526 delete arr;
527
528 return arrHists;
529}
530
531//________________________________________________________________
532TObjArray* AliDielectronCFdraw::CollectMinvProj(Int_t slice, ECollectType collect, TString var)
533{
534 //
535 // Collect invariant mass spectra of step 'slice' for pair types
536 //
537
538 TObjArray *arr = new TObjArray();
539 arr->SetOwner();
540 for (Int_t iType = 0; iType <= AliDielectron::kEv1PMRot; iType++) {
541
542 switch (iType) {
543 // same events
544 case AliDielectron::kEv1PP:
545 case AliDielectron::kEv1MM:
546 if(collect==kROT || collect==kME || collect==kMEOS) continue; break;
547 // mixed events
548 case AliDielectron::kEv1PEv2P:
549 case AliDielectron::kEv1MEv2M:
550 if(collect==kROT || collect==kSE || collect==kMEOS) continue; break;
551 case AliDielectron::kEv1MEv2P:
552 case AliDielectron::kEv1PEv2M:
553 if(collect==kROT || collect==kSE) continue; break;
554 // rotations
555 case AliDielectron::kEv1PMRot:
556 if(collect==kSE || collect==kME || collect==kMEOS) continue; break;
557 // unused
558 case AliDielectron::kEv2PP:
559 case AliDielectron::kEv2PM:
560 case AliDielectron::kEv2MM:
561 continue; break;
562 }
563 SetRangeUser("PairType",iType,iType,Form("%d",slice));
564 TH1 *hM=Project(var.Data(),slice);
565 hM->SetDirectory(0x0);
566 hM->SetNameTitle(Form("Minv_%d",iType),Form("M for type %d;M (GeV/c^{2})", iType));
567 arr->AddAt(hM,iType);
568 }
569 UnsetRangeUser("PairType",Form("%d",slice));
570 return arr;
571}
572
573//________________________________________________________________
574TH1* AliDielectronCFdraw::Project(const Int_t *vars, Int_t slice)
575{
576 //
577 // Do an ndim projection
578 //
579 return fCfContainer->Project(slice,vars[0],vars[1],vars[2]);
580}
581
582//________________________________________________________________
583TH1* AliDielectronCFdraw::Project(const Option_t* var, Int_t slice)
584{
585 //
586 // translate variable names and do projection
587 //
588 TObjArray *arrVars=TString(var).Tokenize(":");
589 Int_t entries=arrVars->GetEntriesFast();
590 if (entries<1||entries>3){
591 AliError("Wrong number of variables, supported are 1 - 3 dimensions");
592 delete arrVars;
593 return 0x0;
594 }
595
596 TIter next(arrVars);
597 TObjString *ostr=0x0;
598 Int_t ivar[3]={-1,-1,-1};
599 for (Int_t i=entries-1; i>=0; --i){
600 ostr=static_cast<TObjString*>(next());
601 if (ostr->GetString().IsDigit()){
602 ivar[i]=ostr->GetString().Atoi();
603 } else {
604 ivar[i]=fCfContainer->GetVar(ostr->GetName());
605 }
606 }
607 if (ivar[0]==-1) return 0x0;
608 delete arrVars;
609 return fCfContainer->Project(slice,ivar[0],ivar[1],ivar[2]);
610}
611
612//________________________________________________________________
613void AliDielectronCFdraw::DrawEfficiency(const char* varnames, const char* numerators, Int_t denominator, const char* opt)
614{
615 //
616 // plot efficiencies for variables. Variable may be up to 3 dim, separated by a ':'
617 // you may have several numerators, sparated by one of ',:;'
618 //
619
620 TObjArray *arrVars=TString(varnames).Tokenize(":");
621 Int_t entries=arrVars->GetEntriesFast();
622 if (entries<1||entries>3){
623 AliError("Wrong number of variables, supported are 1 - 3 dimensions");
624 delete arrVars;
625 return;
626 }
627
628 TIter next(arrVars);
629 TObjString *ostr=0x0;
630 Int_t ivar[3]={-1,-1,-1};
631 for (Int_t i=entries-1; i>=0; --i){
632 ostr=static_cast<TObjString*>(next());
633 if (ostr->GetString().IsDigit()){
634 ivar[i]=ostr->GetString().Atoi();
635 } else {
636 ivar[i]=fCfContainer->GetVar(ostr->GetName());
637 }
638 }
639
640 Int_t type=0;
641 TString optStr(opt);
642 if (optStr.Contains("2")) type=1;
643
644 DrawEfficiency(ivar[0],ivar[1],ivar[2],numerators, denominator,opt,type);
645 delete arrVars;
646}
647
648//________________________________________________________________
649void AliDielectronCFdraw::DrawEfficiency(Int_t var, const char* numerators, Int_t denominator, const char* opt, Int_t type)
650{
651 //
652 // Draw Efficiencies for all numerators
653 // numerators may be divided by and of ,;:
654 //
655 // if opt contains 'same' all histograms are drawn in the same pad
656 // otherwise the pad will be divided in sub pads and the histograms
657 // are drawn in each sub pad
658 //
659
660 Int_t vars[3]={var,-1,-1};
661 TObjArray *arr=CollectHistosEff(vars,numerators,denominator,type);
662 TString drawOpt=opt;
663 drawOpt+="eff";
664 Draw(arr,drawOpt);
665 delete arr;
666}
667
668//________________________________________________________________
669void AliDielectronCFdraw::DrawEfficiency(Int_t var0, Int_t var1, const char* numerators, Int_t denominator, const char* opt, Int_t type)
670{
671 //
672 // Draw 2D case
673 //
674 Int_t vars[3]={var0,var1,-1};
675 TObjArray *arr=CollectHistosEff(vars,numerators,denominator,type);
676 TString drawOpt=opt;
677 drawOpt+="eff";
678 Draw(arr,drawOpt);
679 delete arr;
680}
681
682//________________________________________________________________
683void AliDielectronCFdraw::DrawEfficiency(Int_t var0, Int_t var1, Int_t var2, const char* numerators, Int_t denominator, const char* opt, Int_t type)
684{
685 //
686 // Draw 3D case
687 //
688 Int_t vars[3]={var0,var1,var2};
689 TObjArray *arr=CollectHistosEff(vars,numerators,denominator,type);
690 TString drawOpt=opt;
691 drawOpt+="eff";
692 Draw(arr,drawOpt);
693 delete arr;
694}
695
696//________________________________________________________________
697TObjArray* AliDielectronCFdraw::CollectHistosEff(const Int_t vars[3], const char* numerators, Int_t denominator, Int_t type)
698{
699 //
700 // Collect histos with 'dim'ension of the 'slices' separated by one of "':;'"
701 // in a TObjArray and return it
702 //
703 TObjArray *arr=TString(numerators).Tokenize(",:;");
704 TObjArray *arrHists=0x0;
705
706 if (type==0){
707 if (arr->GetEntriesFast()==0){
708 // all slices in case of 0 entries
709 arrHists=new TObjArray(fCfContainer->GetNStep());
710 fVdata.ResizeTo(arrHists->GetSize());
711 for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
712 fEffGrid->CalculateEfficiency(istep,denominator);
713 TH1 *hproj=ProjectEff(vars);
714 if (!hproj) continue;
715 Float_t eff=fEffGrid->GetAverage();
716 fVdata(istep)=eff;
717 hproj->SetName(Form("eff_%02d/%02d",istep,denominator));
718 hproj->SetTitle(Form("%s (%.3f)",fCfContainer->GetStepTitle(istep),eff));
719 arrHists->Add(hproj);
720 }
721 } else {
722 arrHists=new TObjArray(arr->GetEntriesFast());
723 TIter next(arr);
724 TObjString *ostr=0x0;
725 fVdata.ResizeTo(arrHists->GetSize());
726 Int_t count=0;
727 while ( (ostr=static_cast<TObjString*>(next())) ) {
728 Int_t istep=ostr->GetString().Atoi();
729 fEffGrid->CalculateEfficiency(istep,denominator);
730 TH1 *hproj=ProjectEff(vars);
731 if (!hproj) continue;
732 Float_t eff=fEffGrid->GetAverage();
733 fVdata(count++)=eff;
734 hproj->SetName(Form("eff_%02d/%02d",istep,denominator));
735 hproj->SetTitle(Form("%s (%.3f)",fCfContainer->GetStepTitle(istep),eff));
736 arrHists->Add(hproj);
737 }
738 }
739 }
740
741 //second approach
742 if (type==1){
743 TH1 *hDen=Project(vars,denominator);
744 Double_t entriesDen=hDen->GetEffectiveEntries();
745 if (arr->GetEntriesFast()==0){
746 // all slices in case of 0 entries
747 arrHists=new TObjArray(fCfContainer->GetNStep());
748 fVdata.ResizeTo(arrHists->GetSize());
749 for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
750 TH1 *hproj=Project(vars,istep);
751 if (!hproj) continue;
752 Float_t eff=0;
753 if (entriesDen>0) eff=hproj->GetEffectiveEntries()/entriesDen;
754 fVdata(istep)=eff;
755 hproj->Divide(hproj,hDen,1,1,"B");
756 hproj->SetName(Form("eff_%02d/%02d",istep,denominator));
757 hproj->SetTitle(Form("%s (%.3f)",fCfContainer->GetStepTitle(istep),eff));
758 arrHists->Add(hproj);
759 }
760 } else {
761 arrHists=new TObjArray(arr->GetEntriesFast());
762 fVdata.ResizeTo(arrHists->GetSize());
763 TIter next(arr);
764 TObjString *ostr=0x0;
765 Int_t count=0;
766 while ( (ostr=static_cast<TObjString*>(next())) ) {
767 Int_t istep=ostr->GetString().Atoi();
768 TH1 *hproj=Project(vars,istep);
769 if (!hproj) continue;
770 Float_t eff=0;
771 if (entriesDen>0) eff=hproj->GetEffectiveEntries()/entriesDen;
772 fVdata(count++)=eff;
773 hproj->Divide(hproj,hDen,1,1,"B");
774 hproj->SetName(Form("eff_%02d/%02d",istep,denominator));
775 hproj->SetTitle(Form("%s (%.3f)",fCfContainer->GetStepTitle(istep),eff));
776 arrHists->Add(hproj);
777 }
778 }
779 delete hDen;
780 }
781
782
783 delete arr;
784 return arrHists;
785}
786
787//________________________________________________________________
788TH1* AliDielectronCFdraw::ProjectEff(const Int_t vars[3])
789{
790 //
791 // Do an nim projection
792 //
793 return fEffGrid->Project(vars[0],vars[1],vars[2]);
794}
795
796//________________________________________________________________
797void AliDielectronCFdraw::Draw(const TObjArray *arr, const char* opt)
798{
799 //
800 // draw all objects in arr
801 //
802 TString optStr(opt);
803 optStr.ToLower();
804 Bool_t drawSame = optStr.Contains("same");
805 Bool_t drawSamePlus = optStr.Contains("same+");
806 Bool_t drawEff = optStr.Contains("eff");
807 Bool_t optLeg = optStr.Contains("leg");
808 Bool_t optScaleMax = optStr.Contains("max");
809
810 if (!drawSamePlus) optStr.ReplaceAll("same","");
811
812 optStr.ReplaceAll("+","");
813 optStr.ReplaceAll("eff","");
814 optStr.ReplaceAll("leg","");
815 optStr.ReplaceAll("max","");
816
817 if (!gPad) new TCanvas;
818
819 Int_t nPads = arr->GetEntriesFast();
820 if (nPads==0) return;
821
822// if (nPads==1){
823// arr->UncheckedAt(0)->Draw(optStr.Data());
824// return;
825// }
826
827 TCanvas *c=gPad->GetCanvas();
828 if (!gVirtualPS&&!drawSamePlus&&!drawSame&&nPads>1) c->Clear();
829
830 if (!drawSame&&nPads>1){
831 //optimised division
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 );
834 c->Divide(nCols,nRows);
835 for (Int_t i=0; i<nPads; ++i){
836 c->cd(i+1);
837 arr->UncheckedAt(i)->Draw(optStr.Data());
838 }
839 } else {
840 TLegend *leg=0;
841 if (drawSamePlus){
842 //find already existing legend to attach entries to it
843 TIter nextPrimitive(gPad->GetListOfPrimitives());
844 TObject *o=0x0;
845 while ((o=nextPrimitive())) if (o->IsA()==TLegend::Class()) leg=(TLegend*)o;
846 }
847
848 if (optLeg&&!leg) leg=new TLegend(.2,.3,.99,.9);
849 Int_t addColor=0;
850 if (leg) addColor=leg->GetNRows();
851 Int_t offset=20;
852 if (nPads<7) offset=24;
853 for (Int_t i=0; i<nPads; ++i){
854 if (i==1&&!drawSamePlus) optStr+="same";
855 TH1 *hist=static_cast<TH1*>(arr->UncheckedAt(i));
856 hist->SetLineColor(i+1+addColor);
857 hist->SetLineWidth(2);
858 hist->SetMarkerColor(i+1+addColor);
859 hist->SetMarkerStyle(offset+i+addColor);
860 hist->Draw(optStr.Data());
861
862 if (drawEff&&i==0&&!drawSamePlus) {
863 hist->GetYaxis()->SetRangeUser(0,2);
864 hist->SetYTitle("Rec. Signal / Gen. Signal");
865 }
866
867 if (leg) leg->AddEntry(hist,hist->GetTitle(),"lp");
868 }
869 if (leg){
870 leg->SetFillColor(10);
871 leg->SetY1(.9-leg->GetNRows()*.05);
872 leg->SetY1NDC(.9-leg->GetNRows()*.05);
873 leg->SetMargin(.1);
874 if (!drawSamePlus) leg->Draw();
875 }
876 if (optScaleMax){
877 TIter nextPrimitive(gPad->GetListOfPrimitives());
878 TObject *o=0x0;
879 TH1 *hfirst=0x0;
880 Float_t max=0;
881 while ((o=nextPrimitive())) if (o->InheritsFrom(TH1::Class())){
882 TH1 *h=(TH1*)o;
883 if (!hfirst) hfirst=h;
884 if (h->GetMaximum()>max) max=h->GetMaximum();
885 }
886 max*=1.1;
887 hfirst->SetMaximum(max);
888 }
889 }
890
891}
892
893//________________________________________________________________
894Double_t AliDielectronCFdraw::GetAverageEfficiency(Int_t numerator, Int_t denominator, Double_t &effErr)
895{
896 //
897 // Extract the mean efficiency of the numerator and denominator
898 //
899
900 //use variable 0 as default, since for the average it doesn't matter
901 TH1 *hDen=fCfContainer->Project(denominator,0);
902 Double_t entriesDen=hDen->GetEffectiveEntries();
903 TH1 *hproj=fCfContainer->Project(numerator,0);
904 if (!hproj) return -1.;
905 Double_t entriesNum=hproj->GetEffectiveEntries();
906 if (entriesDen<1||entriesNum<1) return -1;
907
908 Double_t eff=-1.;
909 if (entriesDen>0) eff=entriesNum/entriesDen;
910 effErr=TMath::Sqrt(1./entriesNum+1./entriesDen)*eff;
911 delete hDen;
912 delete hproj;
913 return eff;
914}