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