]>
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" |
7c2efce2 | 57 | #include "AliDielectronVarManager.h" |
6551594b | 58 | |
59 | ClassImp(AliDielectronCFdraw) | |
60 | ||
61 | AliDielectronCFdraw::AliDielectronCFdraw() : | |
62 | TNamed(), | |
a655b716 | 63 | fCfContainer(0x0), |
572b0139 | 64 | fEffGrid(0x0), |
65 | fVdata(0) | |
6551594b | 66 | { |
67 | // | |
68 | // Ctor | |
69 | // | |
70 | } | |
71 | ||
72 | //________________________________________________________________ | |
73 | AliDielectronCFdraw::AliDielectronCFdraw(const char*name, const char* title) : | |
74 | TNamed(name,title), | |
a655b716 | 75 | fCfContainer(0x0), |
572b0139 | 76 | fEffGrid(0x0), |
77 | fVdata(0) | |
6551594b | 78 | { |
79 | // | |
80 | // Named Ctor | |
81 | // | |
82 | ||
83 | } | |
84 | ||
a655b716 | 85 | //________________________________________________________________ |
86 | AliDielectronCFdraw::AliDielectronCFdraw(AliCFContainer *cont) : | |
87 | TNamed(cont->GetName(), cont->GetTitle()), | |
88 | fCfContainer(cont), | |
572b0139 | 89 | fEffGrid(new AliCFEffGrid("eff","eff",*cont)), |
90 | fVdata(0) | |
a655b716 | 91 | { |
92 | // | |
93 | // directly set the CF container | |
94 | // | |
95 | ||
96 | } | |
97 | ||
98 | //________________________________________________________________ | |
99 | AliDielectronCFdraw::AliDielectronCFdraw(const char* filename) : | |
100 | TNamed(), | |
101 | fCfContainer(0x0), | |
572b0139 | 102 | fEffGrid(0x0), |
103 | fVdata(0) | |
a655b716 | 104 | { |
105 | // | |
106 | // get CF container(s) from file 'filename' | |
107 | // | |
108 | SetCFContainers(filename); | |
109 | } | |
110 | ||
d327d9cd | 111 | //________________________________________________________________ |
112 | AliDielectronCFdraw::~AliDielectronCFdraw() | |
113 | { | |
114 | // | |
115 | // dtor | |
116 | // | |
117 | delete fCfContainer; | |
118 | delete fEffGrid; | |
119 | } | |
120 | ||
6551594b | 121 | //________________________________________________________________ |
122 | void AliDielectronCFdraw::SetCFContainers(const TSeqCollection *arr) | |
123 | { | |
124 | // | |
125 | // Merge CF Container out of several containers | |
126 | // | |
127 | ||
d327d9cd | 128 | delete fCfContainer; fCfContainer=0x0; |
129 | delete fEffGrid; fEffGrid=0x0; | |
6551594b | 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); | |
61d106d3 | 136 | if (!cf) continue; |
6551594b | 137 | nstep+=cf->GetNStep(); |
138 | } | |
61d106d3 | 139 | if (nstep==0) return; |
6551594b | 140 | Int_t nbins[1]={1}; |
141 | fCfContainer=new AliCFContainer(GetName(), GetTitle(), nstep, 1, nbins); | |
142 | ||
143 | //delete unneeded steps | |
572b0139 | 144 | // for (Int_t istep=0; istep<nstep; ++istep) delete fCfContainer->GetGrid(istep); |
6551594b | 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)); | |
66b2c564 | 153 | fCfContainer->SetStepTitle(istep,Form("%s, Pair: %s",cf->GetTitle(),cf->GetStepTitle(istepCurr))); |
6551594b | 154 | ++istep; |
155 | } | |
156 | } | |
a655b716 | 157 | if (fEffGrid) delete fEffGrid; |
158 | fEffGrid=new AliCFEffGrid("eff","eff",*fCfContainer); | |
6551594b | 159 | } |
160 | ||
161 | //________________________________________________________________ | |
162 | void AliDielectronCFdraw::SetCFContainers(const char* filename) | |
163 | { | |
164 | // | |
165 | // get CF containers from file | |
166 | // | |
167 | ||
168 | TFile f(filename); | |
169 | TList *l=f.GetListOfKeys(); | |
61d106d3 | 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 | } | |
a655b716 | 182 | } |
6551594b | 183 | } |
184 | ||
185 | //________________________________________________________________ | |
186 | void 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 | // | |
ba15fdfb | 192 | if (ivar==-1) return; |
6551594b | 193 | TObjArray *arr=TString(slices).Tokenize(",:;"); |
194 | ||
01e4cb7f | 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 | ||
6551594b | 208 | if (arr->GetEntriesFast()==0){ |
209 | // all slices in case of 0 entries | |
210 | for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){ | |
ffbede40 | 211 | fCfContainer->GetGrid(istep)->SetRangeUser(ivar,min,max); |
ba15fdfb | 212 | fCfContainer->GetAxis(ivar,istep)->SetBit(TAxis::kAxisRange,1); |
6551594b | 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(); | |
ffbede40 | 219 | fCfContainer->GetGrid(istep)->SetRangeUser(ivar,min,max); |
ba15fdfb | 220 | fCfContainer->GetAxis(ivar,istep)->SetBit(TAxis::kAxisRange,1); |
6551594b | 221 | } |
222 | } | |
223 | delete arr; | |
224 | } | |
225 | ||
7c2efce2 | 226 | //________________________________________________________________ |
227 | void 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); | |
d4619886 | 234 | if(leg) SetRangeUser(Form("%s%s","Leg2_",AliDielectronVarManager::GetValueName(type)), min, max, slices); |
7c2efce2 | 235 | |
236 | } | |
237 | ||
d327d9cd | 238 | //________________________________________________________________ |
239 | void 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 | //________________________________________________________________ | |
253 | void 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 | ||
7c2efce2 | 266 | //________________________________________________________________ |
267 | void 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 | ||
6551594b | 277 | //________________________________________________________________ |
278 | void 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 | // | |
ba15fdfb | 284 | if (ivar==-1) return; |
6551594b | 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){ | |
572b0139 | 290 | fCfContainer->GetAxis(ivar,istep)->SetRange(0,0); |
5cc8c825 | 291 | fCfContainer->GetAxis(ivar,istep)->SetBit(TAxis::kAxisRange,0); |
6551594b | 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(); | |
572b0139 | 298 | fCfContainer->GetAxis(ivar,istep)->SetRange(0,0); |
5cc8c825 | 299 | fCfContainer->GetAxis(ivar,istep)->SetBit(TAxis::kAxisRange,0); |
6551594b | 300 | } |
301 | } | |
302 | delete arr; | |
303 | } | |
304 | ||
305 | //________________________________________________________________ | |
572b0139 | 306 | void AliDielectronCFdraw::Draw(const Option_t* varnames, const char* opt, const char* slices) |
6551594b | 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}; | |
ffbede40 | 327 | for (Int_t i=entries-1; i>=0; --i){ |
6551594b | 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 | ||
ffbede40 | 336 | Draw(ivar[0],ivar[1],ivar[2],opt,slices); |
6551594b | 337 | delete arrVars; |
338 | } | |
339 | ||
7c2efce2 | 340 | //________________________________________________________________ |
341 | TString 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 | } | |
ba15fdfb | 380 | //________________________________________________________________ |
01e4cb7f | 381 | Int_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 | //________________________________________________________________ | |
ba15fdfb | 417 | TObjArray* 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 | ||
6551594b | 451 | //________________________________________________________________ |
452 | void 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 | ||
ffbede40 | 463 | Int_t vars[3]={var,-1,-1}; |
464 | TObjArray *arr=CollectHistosProj(vars,slices); | |
6551594b | 465 | Draw(arr,opt); |
466 | delete arr; | |
467 | } | |
468 | ||
469 | //________________________________________________________________ | |
470 | void AliDielectronCFdraw::Draw(Int_t var0, Int_t var1, const char* opt, const char* slices) | |
471 | { | |
472 | // | |
473 | // Draw 2D case | |
474 | // | |
ffbede40 | 475 | Int_t vars[3]={var0,var1,-1}; |
476 | TObjArray *arr=CollectHistosProj(vars,slices); | |
6551594b | 477 | Draw(arr,opt); |
478 | delete arr; | |
479 | } | |
480 | ||
481 | //________________________________________________________________ | |
482 | void AliDielectronCFdraw::Draw(Int_t var0, Int_t var1, Int_t var2, const char* opt, const char* slices) | |
483 | { | |
484 | // | |
485 | // Draw 3D case | |
486 | // | |
ffbede40 | 487 | Int_t vars[3]={var0,var1,var2}; |
488 | TObjArray *arr=CollectHistosProj(vars,slices); | |
6551594b | 489 | Draw(arr,opt); |
490 | delete arr; | |
491 | } | |
492 | ||
493 | //________________________________________________________________ | |
ffbede40 | 494 | TObjArray* AliDielectronCFdraw::CollectHistosProj(const Int_t vars[3], const char* slices) |
6551594b | 495 | { |
496 | // | |
ffbede40 | 497 | // Collect histos with up to 3 dimension of the 'slices' separated by one of "':;'" |
a655b716 | 498 | // in a TObjArray and return it |
ffbede40 | 499 | // if a dimension is not used it must be set to -1 |
6551594b | 500 | // |
a655b716 | 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){ | |
ffbede40 | 507 | TH1 *hproj=Project(vars,istep); |
572b0139 | 508 | if (!hproj) continue; |
66b2c564 | 509 | hproj->SetName(Form("proj_%02d",istep)); |
510 | hproj->SetTitle(fCfContainer->GetStepTitle(istep)); | |
a655b716 | 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(); | |
ffbede40 | 519 | TH1 *hproj=Project(vars,istep); |
572b0139 | 520 | if (!hproj) continue; |
66b2c564 | 521 | hproj->SetName(Form("proj_%02d",istep)); |
522 | hproj->SetTitle(fCfContainer->GetStepTitle(istep)); | |
a655b716 | 523 | arrHists->Add(hproj); |
524 | } | |
525 | } | |
526 | delete arr; | |
527 | ||
528 | return arrHists; | |
529 | } | |
530 | ||
ac390e40 | 531 | //________________________________________________________________ |
a823f01b | 532 | TObjArray* AliDielectronCFdraw::CollectMinvProj(Int_t slice, ECollectType collect, TString var) |
ac390e40 | 533 | { |
534 | // | |
a823f01b | 535 | // Collect invariant mass spectra of step 'slice' for pair types |
ac390e40 | 536 | // |
01e4cb7f | 537 | |
ac390e40 | 538 | TObjArray *arr = new TObjArray(); |
539 | arr->SetOwner(); | |
540 | for (Int_t iType = 0; iType <= AliDielectron::kEv1PMRot; iType++) { | |
a823f01b | 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); | |
ac390e40 | 568 | } |
a823f01b | 569 | UnsetRangeUser("PairType",Form("%d",slice)); |
ac390e40 | 570 | return arr; |
571 | } | |
572 | ||
a655b716 | 573 | //________________________________________________________________ |
ffbede40 | 574 | TH1* AliDielectronCFdraw::Project(const Int_t *vars, Int_t slice) |
a655b716 | 575 | { |
576 | // | |
2a14a7b1 | 577 | // Do an ndim projection |
a655b716 | 578 | // |
ffbede40 | 579 | return fCfContainer->Project(slice,vars[0],vars[1],vars[2]); |
a655b716 | 580 | } |
581 | ||
2a14a7b1 | 582 | //________________________________________________________________ |
583 | TH1* 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 | } | |
5720c765 | 595 | |
596 | TIter next(arrVars); | |
2a14a7b1 | 597 | TObjString *ostr=0x0; |
598 | Int_t ivar[3]={-1,-1,-1}; | |
ffbede40 | 599 | for (Int_t i=entries-1; i>=0; --i){ |
5720c765 | 600 | ostr=static_cast<TObjString*>(next()); |
2a14a7b1 | 601 | if (ostr->GetString().IsDigit()){ |
602 | ivar[i]=ostr->GetString().Atoi(); | |
603 | } else { | |
604 | ivar[i]=fCfContainer->GetVar(ostr->GetName()); | |
605 | } | |
606 | } | |
ffbede40 | 607 | if (ivar[0]==-1) return 0x0; |
2a14a7b1 | 608 | delete arrVars; |
ffbede40 | 609 | return fCfContainer->Project(slice,ivar[0],ivar[1],ivar[2]); |
2a14a7b1 | 610 | } |
611 | ||
a655b716 | 612 | //________________________________________________________________ |
554e40f8 | 613 | void AliDielectronCFdraw::DrawEfficiency(const char* varnames, const char* numerators, Int_t denominator, const char* opt) |
a655b716 | 614 | { |
615 | // | |
616 | // plot efficiencies for variables. Variable may be up to 3 dim, separated by a ':' | |
554e40f8 | 617 | // you may have several numerators, sparated by one of ',:;' |
a655b716 | 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}; | |
5720c765 | 631 | for (Int_t i=entries-1; i>=0; --i){ |
a655b716 | 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()); | |
6551594b | 637 | } |
638 | } | |
66b2c564 | 639 | |
640 | Int_t type=0; | |
641 | TString optStr(opt); | |
642 | if (optStr.Contains("2")) type=1; | |
a655b716 | 643 | |
5720c765 | 644 | DrawEfficiency(ivar[0],ivar[1],ivar[2],numerators, denominator,opt,type); |
a655b716 | 645 | delete arrVars; |
646 | } | |
647 | ||
648 | //________________________________________________________________ | |
554e40f8 | 649 | void AliDielectronCFdraw::DrawEfficiency(Int_t var, const char* numerators, Int_t denominator, const char* opt, Int_t type) |
a655b716 | 650 | { |
651 | // | |
554e40f8 | 652 | // Draw Efficiencies for all numerators |
653 | // numerators may be divided by and of ,;: | |
a655b716 | 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 | ||
ffbede40 | 660 | Int_t vars[3]={var,-1,-1}; |
661 | TObjArray *arr=CollectHistosEff(vars,numerators,denominator,type); | |
572b0139 | 662 | TString drawOpt=opt; |
663 | drawOpt+="eff"; | |
664 | Draw(arr,drawOpt); | |
a655b716 | 665 | delete arr; |
666 | } | |
667 | ||
668 | //________________________________________________________________ | |
554e40f8 | 669 | void AliDielectronCFdraw::DrawEfficiency(Int_t var0, Int_t var1, const char* numerators, Int_t denominator, const char* opt, Int_t type) |
a655b716 | 670 | { |
671 | // | |
672 | // Draw 2D case | |
673 | // | |
ffbede40 | 674 | Int_t vars[3]={var0,var1,-1}; |
675 | TObjArray *arr=CollectHistosEff(vars,numerators,denominator,type); | |
572b0139 | 676 | TString drawOpt=opt; |
677 | drawOpt+="eff"; | |
678 | Draw(arr,drawOpt); | |
a655b716 | 679 | delete arr; |
680 | } | |
681 | ||
682 | //________________________________________________________________ | |
554e40f8 | 683 | 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 | 684 | { |
685 | // | |
686 | // Draw 3D case | |
687 | // | |
ffbede40 | 688 | Int_t vars[3]={var0,var1,var2}; |
689 | TObjArray *arr=CollectHistosEff(vars,numerators,denominator,type); | |
572b0139 | 690 | TString drawOpt=opt; |
691 | drawOpt+="eff"; | |
692 | Draw(arr,drawOpt); | |
a655b716 | 693 | delete arr; |
6551594b | 694 | } |
695 | ||
696 | //________________________________________________________________ | |
ffbede40 | 697 | TObjArray* AliDielectronCFdraw::CollectHistosEff(const Int_t vars[3], const char* numerators, Int_t denominator, Int_t type) |
6551594b | 698 | { |
699 | // | |
700 | // Collect histos with 'dim'ension of the 'slices' separated by one of "':;'" | |
701 | // in a TObjArray and return it | |
702 | // | |
554e40f8 | 703 | TObjArray *arr=TString(numerators).Tokenize(",:;"); |
6551594b | 704 | TObjArray *arrHists=0x0; |
66b2c564 | 705 | |
706 | if (type==0){ | |
707 | if (arr->GetEntriesFast()==0){ | |
6551594b | 708 | // all slices in case of 0 entries |
66b2c564 | 709 | arrHists=new TObjArray(fCfContainer->GetNStep()); |
572b0139 | 710 | fVdata.ResizeTo(arrHists->GetSize()); |
66b2c564 | 711 | for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){ |
712 | fEffGrid->CalculateEfficiency(istep,denominator); | |
ffbede40 | 713 | TH1 *hproj=ProjectEff(vars); |
572b0139 | 714 | if (!hproj) continue; |
66b2c564 | 715 | Float_t eff=fEffGrid->GetAverage(); |
572b0139 | 716 | fVdata(istep)=eff; |
66b2c564 | 717 | hproj->SetName(Form("eff_%02d/%02d",istep,denominator)); |
572b0139 | 718 | hproj->SetTitle(Form("%s (%.3f)",fCfContainer->GetStepTitle(istep),eff)); |
66b2c564 | 719 | arrHists->Add(hproj); |
720 | } | |
721 | } else { | |
722 | arrHists=new TObjArray(arr->GetEntriesFast()); | |
723 | TIter next(arr); | |
724 | TObjString *ostr=0x0; | |
572b0139 | 725 | fVdata.ResizeTo(arrHists->GetSize()); |
726 | Int_t count=0; | |
66b2c564 | 727 | while ( (ostr=static_cast<TObjString*>(next())) ) { |
728 | Int_t istep=ostr->GetString().Atoi(); | |
729 | fEffGrid->CalculateEfficiency(istep,denominator); | |
ffbede40 | 730 | TH1 *hproj=ProjectEff(vars); |
572b0139 | 731 | if (!hproj) continue; |
66b2c564 | 732 | Float_t eff=fEffGrid->GetAverage(); |
572b0139 | 733 | fVdata(count++)=eff; |
66b2c564 | 734 | hproj->SetName(Form("eff_%02d/%02d",istep,denominator)); |
572b0139 | 735 | hproj->SetTitle(Form("%s (%.3f)",fCfContainer->GetStepTitle(istep),eff)); |
66b2c564 | 736 | arrHists->Add(hproj); |
737 | } | |
6551594b | 738 | } |
66b2c564 | 739 | } |
740 | ||
741 | //second approach | |
742 | if (type==1){ | |
ffbede40 | 743 | TH1 *hDen=Project(vars,denominator); |
66b2c564 | 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()); | |
572b0139 | 748 | fVdata.ResizeTo(arrHists->GetSize()); |
66b2c564 | 749 | for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){ |
ffbede40 | 750 | TH1 *hproj=Project(vars,istep); |
572b0139 | 751 | if (!hproj) continue; |
66b2c564 | 752 | Float_t eff=0; |
753 | if (entriesDen>0) eff=hproj->GetEffectiveEntries()/entriesDen; | |
572b0139 | 754 | fVdata(istep)=eff; |
48609e3d | 755 | hproj->Divide(hproj,hDen,1,1,"B"); |
66b2c564 | 756 | hproj->SetName(Form("eff_%02d/%02d",istep,denominator)); |
572b0139 | 757 | hproj->SetTitle(Form("%s (%.3f)",fCfContainer->GetStepTitle(istep),eff)); |
66b2c564 | 758 | arrHists->Add(hproj); |
759 | } | |
760 | } else { | |
761 | arrHists=new TObjArray(arr->GetEntriesFast()); | |
572b0139 | 762 | fVdata.ResizeTo(arrHists->GetSize()); |
66b2c564 | 763 | TIter next(arr); |
764 | TObjString *ostr=0x0; | |
572b0139 | 765 | Int_t count=0; |
66b2c564 | 766 | while ( (ostr=static_cast<TObjString*>(next())) ) { |
767 | Int_t istep=ostr->GetString().Atoi(); | |
ffbede40 | 768 | TH1 *hproj=Project(vars,istep); |
572b0139 | 769 | if (!hproj) continue; |
66b2c564 | 770 | Float_t eff=0; |
771 | if (entriesDen>0) eff=hproj->GetEffectiveEntries()/entriesDen; | |
572b0139 | 772 | fVdata(count++)=eff; |
48609e3d | 773 | hproj->Divide(hproj,hDen,1,1,"B"); |
66b2c564 | 774 | hproj->SetName(Form("eff_%02d/%02d",istep,denominator)); |
572b0139 | 775 | hproj->SetTitle(Form("%s (%.3f)",fCfContainer->GetStepTitle(istep),eff)); |
66b2c564 | 776 | arrHists->Add(hproj); |
777 | } | |
6551594b | 778 | } |
66b2c564 | 779 | delete hDen; |
6551594b | 780 | } |
a655b716 | 781 | |
66b2c564 | 782 | |
783 | delete arr; | |
6551594b | 784 | return arrHists; |
785 | } | |
786 | ||
787 | //________________________________________________________________ | |
ffbede40 | 788 | TH1* AliDielectronCFdraw::ProjectEff(const Int_t vars[3]) |
6551594b | 789 | { |
790 | // | |
791 | // Do an nim projection | |
792 | // | |
ffbede40 | 793 | return fEffGrid->Project(vars[0],vars[1],vars[2]); |
6551594b | 794 | } |
795 | ||
a655b716 | 796 | //________________________________________________________________ |
797 | void AliDielectronCFdraw::Draw(const TObjArray *arr, const char* opt) | |
798 | { | |
799 | // | |
800 | // draw all objects in arr | |
801 | // | |
802 | TString optStr(opt); | |
803 | optStr.ToLower(); | |
572b0139 | 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",""); | |
a655b716 | 816 | |
817 | if (!gPad) new TCanvas; | |
818 | ||
819 | Int_t nPads = arr->GetEntriesFast(); | |
820 | if (nPads==0) return; | |
821 | ||
572b0139 | 822 | // if (nPads==1){ |
823 | // arr->UncheckedAt(0)->Draw(optStr.Data()); | |
824 | // return; | |
825 | // } | |
a655b716 | 826 | |
827 | TCanvas *c=gPad->GetCanvas(); | |
8df8e382 | 828 | if (!gVirtualPS&&!drawSamePlus&&!drawSame&&nPads>1) c->Clear(); |
a655b716 | 829 | |
8df8e382 | 830 | if (!drawSame&&nPads>1){ |
a655b716 | 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; | |
572b0139 | 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(); | |
66b2c564 | 851 | Int_t offset=20; |
852 | if (nPads<7) offset=24; | |
a655b716 | 853 | for (Int_t i=0; i<nPads; ++i){ |
572b0139 | 854 | if (i==1&&!drawSamePlus) optStr+="same"; |
a655b716 | 855 | TH1 *hist=static_cast<TH1*>(arr->UncheckedAt(i)); |
572b0139 | 856 | hist->SetLineColor(i+1+addColor); |
66b2c564 | 857 | hist->SetLineWidth(2); |
572b0139 | 858 | hist->SetMarkerColor(i+1+addColor); |
859 | hist->SetMarkerStyle(offset+i+addColor); | |
a655b716 | 860 | hist->Draw(optStr.Data()); |
572b0139 | 861 | |
862 | if (drawEff&&i==0&&!drawSamePlus) { | |
863 | hist->GetYaxis()->SetRangeUser(0,2); | |
864 | hist->SetYTitle("Rec. Signal / Gen. Signal"); | |
865 | } | |
866 | ||
66b2c564 | 867 | if (leg) leg->AddEntry(hist,hist->GetTitle(),"lp"); |
a655b716 | 868 | } |
869 | if (leg){ | |
870 | leg->SetFillColor(10); | |
572b0139 | 871 | leg->SetY1(.9-leg->GetNRows()*.05); |
872 | leg->SetY1NDC(.9-leg->GetNRows()*.05); | |
66b2c564 | 873 | leg->SetMargin(.1); |
572b0139 | 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); | |
a655b716 | 888 | } |
889 | } | |
890 | ||
891 | } | |
554e40f8 | 892 | |
893 | //________________________________________________________________ | |
894 | Double_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 | |
ffbede40 | 901 | TH1 *hDen=fCfContainer->Project(denominator,0); |
554e40f8 | 902 | Double_t entriesDen=hDen->GetEffectiveEntries(); |
ffbede40 | 903 | TH1 *hproj=fCfContainer->Project(numerator,0); |
554e40f8 | 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 | } |