]>
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 | //________________________________________________________________ |
a823f01b | 419 | TObjArray* AliDielectronCFdraw::CollectMinvProj(Int_t slice, ECollectType collect, TString var) |
ac390e40 | 420 | { |
421 | // | |
a823f01b | 422 | // Collect invariant mass spectra of step 'slice' for pair types |
ac390e40 | 423 | // |
424 | ||
425 | TObjArray *arr = new TObjArray(); | |
426 | arr->SetOwner(); | |
427 | for (Int_t iType = 0; iType <= AliDielectron::kEv1PMRot; iType++) { | |
a823f01b | 428 | |
429 | switch (iType) { | |
430 | // same events | |
431 | case AliDielectron::kEv1PP: | |
432 | case AliDielectron::kEv1MM: | |
433 | if(collect==kROT || collect==kME || collect==kMEOS) continue; break; | |
434 | // mixed events | |
435 | case AliDielectron::kEv1PEv2P: | |
436 | case AliDielectron::kEv1MEv2M: | |
437 | if(collect==kROT || collect==kSE || collect==kMEOS) continue; break; | |
438 | case AliDielectron::kEv1MEv2P: | |
439 | case AliDielectron::kEv1PEv2M: | |
440 | if(collect==kROT || collect==kSE) continue; break; | |
441 | // rotations | |
442 | case AliDielectron::kEv1PMRot: | |
443 | if(collect==kSE || collect==kME || collect==kMEOS) continue; break; | |
444 | // unused | |
445 | case AliDielectron::kEv2PP: | |
446 | case AliDielectron::kEv2PM: | |
447 | case AliDielectron::kEv2MM: | |
448 | continue; break; | |
449 | } | |
450 | SetRangeUser("PairType",iType,iType,Form("%d",slice)); | |
451 | TH1 *hM=Project(var.Data(),slice); | |
452 | hM->SetDirectory(0x0); | |
453 | hM->SetNameTitle(Form("Minv_%d",iType),Form("M for type %d;M (GeV/c^{2})", iType)); | |
454 | arr->AddAt(hM,iType); | |
ac390e40 | 455 | } |
a823f01b | 456 | UnsetRangeUser("PairType",Form("%d",slice)); |
ac390e40 | 457 | return arr; |
458 | } | |
459 | ||
a655b716 | 460 | //________________________________________________________________ |
ffbede40 | 461 | TH1* AliDielectronCFdraw::Project(const Int_t *vars, Int_t slice) |
a655b716 | 462 | { |
463 | // | |
2a14a7b1 | 464 | // Do an ndim projection |
a655b716 | 465 | // |
ffbede40 | 466 | return fCfContainer->Project(slice,vars[0],vars[1],vars[2]); |
a655b716 | 467 | } |
468 | ||
2a14a7b1 | 469 | //________________________________________________________________ |
470 | TH1* AliDielectronCFdraw::Project(const Option_t* var, Int_t slice) | |
471 | { | |
472 | // | |
473 | // translate variable names and do projection | |
474 | // | |
475 | TObjArray *arrVars=TString(var).Tokenize(":"); | |
476 | Int_t entries=arrVars->GetEntriesFast(); | |
477 | if (entries<1||entries>3){ | |
478 | AliError("Wrong number of variables, supported are 1 - 3 dimensions"); | |
479 | delete arrVars; | |
480 | return 0x0; | |
481 | } | |
5720c765 | 482 | |
483 | TIter next(arrVars); | |
2a14a7b1 | 484 | TObjString *ostr=0x0; |
485 | Int_t ivar[3]={-1,-1,-1}; | |
ffbede40 | 486 | for (Int_t i=entries-1; i>=0; --i){ |
5720c765 | 487 | ostr=static_cast<TObjString*>(next()); |
2a14a7b1 | 488 | if (ostr->GetString().IsDigit()){ |
489 | ivar[i]=ostr->GetString().Atoi(); | |
490 | } else { | |
491 | ivar[i]=fCfContainer->GetVar(ostr->GetName()); | |
492 | } | |
493 | } | |
ffbede40 | 494 | if (ivar[0]==-1) return 0x0; |
2a14a7b1 | 495 | delete arrVars; |
ffbede40 | 496 | return fCfContainer->Project(slice,ivar[0],ivar[1],ivar[2]); |
2a14a7b1 | 497 | } |
498 | ||
a655b716 | 499 | //________________________________________________________________ |
554e40f8 | 500 | void AliDielectronCFdraw::DrawEfficiency(const char* varnames, const char* numerators, Int_t denominator, const char* opt) |
a655b716 | 501 | { |
502 | // | |
503 | // plot efficiencies for variables. Variable may be up to 3 dim, separated by a ':' | |
554e40f8 | 504 | // you may have several numerators, sparated by one of ',:;' |
a655b716 | 505 | // |
506 | ||
507 | TObjArray *arrVars=TString(varnames).Tokenize(":"); | |
508 | Int_t entries=arrVars->GetEntriesFast(); | |
509 | if (entries<1||entries>3){ | |
510 | AliError("Wrong number of variables, supported are 1 - 3 dimensions"); | |
511 | delete arrVars; | |
512 | return; | |
513 | } | |
514 | ||
515 | TIter next(arrVars); | |
516 | TObjString *ostr=0x0; | |
517 | Int_t ivar[3]={-1,-1,-1}; | |
5720c765 | 518 | for (Int_t i=entries-1; i>=0; --i){ |
a655b716 | 519 | ostr=static_cast<TObjString*>(next()); |
520 | if (ostr->GetString().IsDigit()){ | |
521 | ivar[i]=ostr->GetString().Atoi(); | |
522 | } else { | |
523 | ivar[i]=fCfContainer->GetVar(ostr->GetName()); | |
6551594b | 524 | } |
525 | } | |
66b2c564 | 526 | |
527 | Int_t type=0; | |
528 | TString optStr(opt); | |
529 | if (optStr.Contains("2")) type=1; | |
a655b716 | 530 | |
5720c765 | 531 | DrawEfficiency(ivar[0],ivar[1],ivar[2],numerators, denominator,opt,type); |
a655b716 | 532 | delete arrVars; |
533 | } | |
534 | ||
535 | //________________________________________________________________ | |
554e40f8 | 536 | void AliDielectronCFdraw::DrawEfficiency(Int_t var, const char* numerators, Int_t denominator, const char* opt, Int_t type) |
a655b716 | 537 | { |
538 | // | |
554e40f8 | 539 | // Draw Efficiencies for all numerators |
540 | // numerators may be divided by and of ,;: | |
a655b716 | 541 | // |
542 | // if opt contains 'same' all histograms are drawn in the same pad | |
543 | // otherwise the pad will be divided in sub pads and the histograms | |
544 | // are drawn in each sub pad | |
545 | // | |
546 | ||
ffbede40 | 547 | Int_t vars[3]={var,-1,-1}; |
548 | TObjArray *arr=CollectHistosEff(vars,numerators,denominator,type); | |
572b0139 | 549 | TString drawOpt=opt; |
550 | drawOpt+="eff"; | |
551 | Draw(arr,drawOpt); | |
a655b716 | 552 | delete arr; |
553 | } | |
554 | ||
555 | //________________________________________________________________ | |
554e40f8 | 556 | void AliDielectronCFdraw::DrawEfficiency(Int_t var0, Int_t var1, const char* numerators, Int_t denominator, const char* opt, Int_t type) |
a655b716 | 557 | { |
558 | // | |
559 | // Draw 2D case | |
560 | // | |
ffbede40 | 561 | Int_t vars[3]={var0,var1,-1}; |
562 | TObjArray *arr=CollectHistosEff(vars,numerators,denominator,type); | |
572b0139 | 563 | TString drawOpt=opt; |
564 | drawOpt+="eff"; | |
565 | Draw(arr,drawOpt); | |
a655b716 | 566 | delete arr; |
567 | } | |
568 | ||
569 | //________________________________________________________________ | |
554e40f8 | 570 | 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 | 571 | { |
572 | // | |
573 | // Draw 3D case | |
574 | // | |
ffbede40 | 575 | Int_t vars[3]={var0,var1,var2}; |
576 | TObjArray *arr=CollectHistosEff(vars,numerators,denominator,type); | |
572b0139 | 577 | TString drawOpt=opt; |
578 | drawOpt+="eff"; | |
579 | Draw(arr,drawOpt); | |
a655b716 | 580 | delete arr; |
6551594b | 581 | } |
582 | ||
583 | //________________________________________________________________ | |
ffbede40 | 584 | TObjArray* AliDielectronCFdraw::CollectHistosEff(const Int_t vars[3], const char* numerators, Int_t denominator, Int_t type) |
6551594b | 585 | { |
586 | // | |
587 | // Collect histos with 'dim'ension of the 'slices' separated by one of "':;'" | |
588 | // in a TObjArray and return it | |
589 | // | |
554e40f8 | 590 | TObjArray *arr=TString(numerators).Tokenize(",:;"); |
6551594b | 591 | TObjArray *arrHists=0x0; |
66b2c564 | 592 | |
593 | if (type==0){ | |
594 | if (arr->GetEntriesFast()==0){ | |
6551594b | 595 | // all slices in case of 0 entries |
66b2c564 | 596 | arrHists=new TObjArray(fCfContainer->GetNStep()); |
572b0139 | 597 | fVdata.ResizeTo(arrHists->GetSize()); |
66b2c564 | 598 | for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){ |
599 | fEffGrid->CalculateEfficiency(istep,denominator); | |
ffbede40 | 600 | TH1 *hproj=ProjectEff(vars); |
572b0139 | 601 | if (!hproj) continue; |
66b2c564 | 602 | Float_t eff=fEffGrid->GetAverage(); |
572b0139 | 603 | fVdata(istep)=eff; |
66b2c564 | 604 | hproj->SetName(Form("eff_%02d/%02d",istep,denominator)); |
572b0139 | 605 | hproj->SetTitle(Form("%s (%.3f)",fCfContainer->GetStepTitle(istep),eff)); |
66b2c564 | 606 | arrHists->Add(hproj); |
607 | } | |
608 | } else { | |
609 | arrHists=new TObjArray(arr->GetEntriesFast()); | |
610 | TIter next(arr); | |
611 | TObjString *ostr=0x0; | |
572b0139 | 612 | fVdata.ResizeTo(arrHists->GetSize()); |
613 | Int_t count=0; | |
66b2c564 | 614 | while ( (ostr=static_cast<TObjString*>(next())) ) { |
615 | Int_t istep=ostr->GetString().Atoi(); | |
616 | fEffGrid->CalculateEfficiency(istep,denominator); | |
ffbede40 | 617 | TH1 *hproj=ProjectEff(vars); |
572b0139 | 618 | if (!hproj) continue; |
66b2c564 | 619 | Float_t eff=fEffGrid->GetAverage(); |
572b0139 | 620 | fVdata(count++)=eff; |
66b2c564 | 621 | hproj->SetName(Form("eff_%02d/%02d",istep,denominator)); |
572b0139 | 622 | hproj->SetTitle(Form("%s (%.3f)",fCfContainer->GetStepTitle(istep),eff)); |
66b2c564 | 623 | arrHists->Add(hproj); |
624 | } | |
6551594b | 625 | } |
66b2c564 | 626 | } |
627 | ||
628 | //second approach | |
629 | if (type==1){ | |
ffbede40 | 630 | TH1 *hDen=Project(vars,denominator); |
66b2c564 | 631 | Double_t entriesDen=hDen->GetEffectiveEntries(); |
632 | if (arr->GetEntriesFast()==0){ | |
633 | // all slices in case of 0 entries | |
634 | arrHists=new TObjArray(fCfContainer->GetNStep()); | |
572b0139 | 635 | fVdata.ResizeTo(arrHists->GetSize()); |
66b2c564 | 636 | for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){ |
ffbede40 | 637 | TH1 *hproj=Project(vars,istep); |
572b0139 | 638 | if (!hproj) continue; |
66b2c564 | 639 | Float_t eff=0; |
640 | if (entriesDen>0) eff=hproj->GetEffectiveEntries()/entriesDen; | |
572b0139 | 641 | fVdata(istep)=eff; |
48609e3d | 642 | hproj->Divide(hproj,hDen,1,1,"B"); |
66b2c564 | 643 | hproj->SetName(Form("eff_%02d/%02d",istep,denominator)); |
572b0139 | 644 | hproj->SetTitle(Form("%s (%.3f)",fCfContainer->GetStepTitle(istep),eff)); |
66b2c564 | 645 | arrHists->Add(hproj); |
646 | } | |
647 | } else { | |
648 | arrHists=new TObjArray(arr->GetEntriesFast()); | |
572b0139 | 649 | fVdata.ResizeTo(arrHists->GetSize()); |
66b2c564 | 650 | TIter next(arr); |
651 | TObjString *ostr=0x0; | |
572b0139 | 652 | Int_t count=0; |
66b2c564 | 653 | while ( (ostr=static_cast<TObjString*>(next())) ) { |
654 | Int_t istep=ostr->GetString().Atoi(); | |
ffbede40 | 655 | TH1 *hproj=Project(vars,istep); |
572b0139 | 656 | if (!hproj) continue; |
66b2c564 | 657 | Float_t eff=0; |
658 | if (entriesDen>0) eff=hproj->GetEffectiveEntries()/entriesDen; | |
572b0139 | 659 | fVdata(count++)=eff; |
48609e3d | 660 | hproj->Divide(hproj,hDen,1,1,"B"); |
66b2c564 | 661 | hproj->SetName(Form("eff_%02d/%02d",istep,denominator)); |
572b0139 | 662 | hproj->SetTitle(Form("%s (%.3f)",fCfContainer->GetStepTitle(istep),eff)); |
66b2c564 | 663 | arrHists->Add(hproj); |
664 | } | |
6551594b | 665 | } |
66b2c564 | 666 | delete hDen; |
6551594b | 667 | } |
a655b716 | 668 | |
66b2c564 | 669 | |
670 | delete arr; | |
6551594b | 671 | return arrHists; |
672 | } | |
673 | ||
674 | //________________________________________________________________ | |
ffbede40 | 675 | TH1* AliDielectronCFdraw::ProjectEff(const Int_t vars[3]) |
6551594b | 676 | { |
677 | // | |
678 | // Do an nim projection | |
679 | // | |
ffbede40 | 680 | return fEffGrid->Project(vars[0],vars[1],vars[2]); |
6551594b | 681 | } |
682 | ||
a655b716 | 683 | //________________________________________________________________ |
684 | void AliDielectronCFdraw::Draw(const TObjArray *arr, const char* opt) | |
685 | { | |
686 | // | |
687 | // draw all objects in arr | |
688 | // | |
689 | TString optStr(opt); | |
690 | optStr.ToLower(); | |
572b0139 | 691 | Bool_t drawSame = optStr.Contains("same"); |
692 | Bool_t drawSamePlus = optStr.Contains("same+"); | |
693 | Bool_t drawEff = optStr.Contains("eff"); | |
694 | Bool_t optLeg = optStr.Contains("leg"); | |
695 | Bool_t optScaleMax = optStr.Contains("max"); | |
696 | ||
697 | if (!drawSamePlus) optStr.ReplaceAll("same",""); | |
698 | ||
699 | optStr.ReplaceAll("+",""); | |
700 | optStr.ReplaceAll("eff",""); | |
701 | optStr.ReplaceAll("leg",""); | |
702 | optStr.ReplaceAll("max",""); | |
a655b716 | 703 | |
704 | if (!gPad) new TCanvas; | |
705 | ||
706 | Int_t nPads = arr->GetEntriesFast(); | |
707 | if (nPads==0) return; | |
708 | ||
572b0139 | 709 | // if (nPads==1){ |
710 | // arr->UncheckedAt(0)->Draw(optStr.Data()); | |
711 | // return; | |
712 | // } | |
a655b716 | 713 | |
714 | TCanvas *c=gPad->GetCanvas(); | |
8df8e382 | 715 | if (!gVirtualPS&&!drawSamePlus&&!drawSame&&nPads>1) c->Clear(); |
a655b716 | 716 | |
8df8e382 | 717 | if (!drawSame&&nPads>1){ |
a655b716 | 718 | //optimised division |
719 | Int_t nCols = (Int_t)TMath::Ceil( TMath::Sqrt(nPads) ); | |
720 | Int_t nRows = (Int_t)TMath::Ceil( (Double_t)nPads/(Double_t)nCols ); | |
721 | c->Divide(nCols,nRows); | |
722 | for (Int_t i=0; i<nPads; ++i){ | |
723 | c->cd(i+1); | |
724 | arr->UncheckedAt(i)->Draw(optStr.Data()); | |
725 | } | |
726 | } else { | |
727 | TLegend *leg=0; | |
572b0139 | 728 | if (drawSamePlus){ |
729 | //find already existing legend to attach entries to it | |
730 | TIter nextPrimitive(gPad->GetListOfPrimitives()); | |
731 | TObject *o=0x0; | |
732 | while ((o=nextPrimitive())) if (o->IsA()==TLegend::Class()) leg=(TLegend*)o; | |
733 | } | |
734 | ||
735 | if (optLeg&&!leg) leg=new TLegend(.2,.3,.99,.9); | |
736 | Int_t addColor=0; | |
737 | if (leg) addColor=leg->GetNRows(); | |
66b2c564 | 738 | Int_t offset=20; |
739 | if (nPads<7) offset=24; | |
a655b716 | 740 | for (Int_t i=0; i<nPads; ++i){ |
572b0139 | 741 | if (i==1&&!drawSamePlus) optStr+="same"; |
a655b716 | 742 | TH1 *hist=static_cast<TH1*>(arr->UncheckedAt(i)); |
572b0139 | 743 | hist->SetLineColor(i+1+addColor); |
66b2c564 | 744 | hist->SetLineWidth(2); |
572b0139 | 745 | hist->SetMarkerColor(i+1+addColor); |
746 | hist->SetMarkerStyle(offset+i+addColor); | |
a655b716 | 747 | hist->Draw(optStr.Data()); |
572b0139 | 748 | |
749 | if (drawEff&&i==0&&!drawSamePlus) { | |
750 | hist->GetYaxis()->SetRangeUser(0,2); | |
751 | hist->SetYTitle("Rec. Signal / Gen. Signal"); | |
752 | } | |
753 | ||
66b2c564 | 754 | if (leg) leg->AddEntry(hist,hist->GetTitle(),"lp"); |
a655b716 | 755 | } |
756 | if (leg){ | |
757 | leg->SetFillColor(10); | |
572b0139 | 758 | leg->SetY1(.9-leg->GetNRows()*.05); |
759 | leg->SetY1NDC(.9-leg->GetNRows()*.05); | |
66b2c564 | 760 | leg->SetMargin(.1); |
572b0139 | 761 | if (!drawSamePlus) leg->Draw(); |
762 | } | |
763 | if (optScaleMax){ | |
764 | TIter nextPrimitive(gPad->GetListOfPrimitives()); | |
765 | TObject *o=0x0; | |
766 | TH1 *hfirst=0x0; | |
767 | Float_t max=0; | |
768 | while ((o=nextPrimitive())) if (o->InheritsFrom(TH1::Class())){ | |
769 | TH1 *h=(TH1*)o; | |
770 | if (!hfirst) hfirst=h; | |
771 | if (h->GetMaximum()>max) max=h->GetMaximum(); | |
772 | } | |
773 | max*=1.1; | |
774 | hfirst->SetMaximum(max); | |
a655b716 | 775 | } |
776 | } | |
777 | ||
778 | } | |
554e40f8 | 779 | |
780 | //________________________________________________________________ | |
781 | Double_t AliDielectronCFdraw::GetAverageEfficiency(Int_t numerator, Int_t denominator, Double_t &effErr) | |
782 | { | |
783 | // | |
784 | // Extract the mean efficiency of the numerator and denominator | |
785 | // | |
786 | ||
787 | //use variable 0 as default, since for the average it doesn't matter | |
ffbede40 | 788 | TH1 *hDen=fCfContainer->Project(denominator,0); |
554e40f8 | 789 | Double_t entriesDen=hDen->GetEffectiveEntries(); |
ffbede40 | 790 | TH1 *hproj=fCfContainer->Project(numerator,0); |
554e40f8 | 791 | if (!hproj) return -1.; |
792 | Double_t entriesNum=hproj->GetEffectiveEntries(); | |
793 | if (entriesDen<1||entriesNum<1) return -1; | |
794 | ||
795 | Double_t eff=-1.; | |
796 | if (entriesDen>0) eff=entriesNum/entriesDen; | |
797 | effErr=TMath::Sqrt(1./entriesNum+1./entriesDen)*eff; | |
798 | delete hDen; | |
799 | delete hproj; | |
800 | return eff; | |
801 | } |