]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGDQ/dielectron/AliDielectronHFhelper.cxx
198c02622e058f61558c8d9f3fa14284c94b3f27
[u/mrichter/AliRoot.git] / PWGDQ / dielectron / AliDielectronHFhelper.cxx
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 Histogram framework helper                           //
18 //                                                                       //
19 /*
20
21 A helper class to extract objects(histograms and/or profiles) from
22 a AliDielctronHF array of objects.
23
24
25 How to use it:
26
27   AliDielectronHFhelper *hf = new AliDielectronHFhelper("path/to/the/output/file.root", "ConfigName");
28   // print the structure
29   hf->Print();
30
31   //apply some cuts and print them
32   hf->SetRangeUser("cut1name",cutmin1,cutmax1);
33   hf->SetRangeUser(AliDielectronVarManager::kPt,ptmin,ptmax);
34   hf->PrintCuts();
35
36   // collect 1-,2- or 3-dim histograms or profiles with error option (default:"")
37   TObjArray *arrHists = hf->CollectHistos(AliDielectronVarManager::kM);
38   TObjArray *arrProfs = hf->CollectProfiles("",AliDielectronVarManager::kM,AliDielectronVarManager::kPt);
39
40   // then you are left with an array of histograms for all pair types or MC signals
41
42 */
43 //                                                                       //
44 ///////////////////////////////////////////////////////////////////////////
45
46 #include <TObjArray.h>
47 #include <TKey.h>
48 #include <TList.h>
49 #include <TClass.h>
50 #include <TObject.h>
51 #include <TFile.h>
52 #include <TString.h>
53 #include <TObjString.h>
54 #include <TVectorD.h>
55 #include <TMath.h>
56 #include <TH1.h>
57
58 #include <AliLog.h>
59
60 #include "AliDielectron.h"
61 #include "AliDielectronHFhelper.h"
62 #include "AliDielectronHF.h"
63
64 ClassImp(AliDielectronHFhelper)
65
66 //const char* AliDielectronHFhelper::fCutVars[AliDielectronHFhelper::kMaxCuts] = {"","","","","","","","","",""};
67
68 //________________________________________________________________
69 AliDielectronHFhelper::AliDielectronHFhelper(const char* filename, const char* container) :
70   TNamed(),
71   fMainArr(0x0),
72   fCutVars(0x0),
73   fCutLowLimits(0),
74   fCutUpLimits(0)
75 {
76   //
77   // get HF container(s) from file 'filename'
78   //
79   SetHFArray(filename, container);
80
81 }
82
83 //________________________________________________________________
84 AliDielectronHFhelper::~AliDielectronHFhelper()
85 {
86   //
87   // dtor
88   //
89   if(fMainArr) delete fMainArr;
90   if(fCutVars)     delete fCutVars;
91
92 }
93
94 //________________________________________________________________
95 void AliDielectronHFhelper::SetHFArray(const char* filename, const char* container)
96 {
97   //
98   // get HF container from file
99   //
100
101   TFile *f = TFile::Open(filename);
102
103   TList *l=f->GetListOfKeys();
104   TIter nextKey(l);
105   TKey *k=0x0;
106   while ( (k=static_cast<TKey*>(nextKey())) ){
107
108     TObject *o=k->ReadObj();
109     if (o->IsA()==TList::Class()){
110
111       TList *tlist=(TList*)o;
112
113       TIter next(tlist);
114       TObject *obj=0x0;
115       while ((obj = next())) {
116         TString objname(obj->GetName());
117
118         if( objname.Contains(Form("%s_HF",container)) && obj->IsA()==TObjArray::Class()) {
119           fMainArr = new TObjArray( *(dynamic_cast<TObjArray*>(obj)) );
120           fMainArr->SetOwner();
121           //fMainArr->Print();
122           return;
123         }
124       }
125     }
126   }
127
128 }
129 //________________________________________________________________
130 void AliDielectronHFhelper::SetRangeUser(const char *varname, Double_t min, Double_t max, Bool_t leg)
131 {
132   //
133   // Set range from variable name
134   //
135
136   Int_t size=fCutLowLimits.GetNrows();
137
138   // check if cut is already set
139   for(Int_t icut=0; icut<size; icut++) {
140     TString cutName = fCutVars->At(icut)->GetName();
141     if(!cutName.CompareTo(Form("%s%s",(leg?"Leg":""),varname))) {
142       UnsetRangeUser(varname,leg);
143       SetRangeUser(varname, min, max, leg);
144       return;
145     }
146   }
147
148   if(size>=kMaxCuts) return;
149
150   // arrays
151   if(!fCutVars) {
152     fCutVars = new TObjArray();
153     fCutVars->SetOwner();
154   }
155   fCutLowLimits.ResizeTo(size+1);
156   fCutUpLimits.ResizeTo(size+1);
157
158   // fill
159   TObjString *str = new TObjString(Form("%s%s",(leg?"Leg":""),varname));
160   fCutVars->Add(str);
161   fCutLowLimits(size) = min;
162   fCutUpLimits(size)  = max;
163   AliWarning(Form(" %s [%.2f,%.2f]",fCutVars->At(size)->GetName(),fCutLowLimits(size),fCutUpLimits(size)));
164 }
165
166 //________________________________________________________________
167 void AliDielectronHFhelper::SetRangeUser(AliDielectronVarManager::ValueTypes type, Double_t min, Double_t max, Bool_t leg)
168 {
169   //
170   // Set range from AliDielectronVarManager
171   //
172   SetRangeUser(AliDielectronVarManager::GetValueName(type), min, max, leg);
173 }
174
175 //________________________________________________________________
176 void AliDielectronHFhelper::UnsetRangeUser(const char *varname, Bool_t leg)
177 {
178   //
179   // unset range from variable name
180   //
181
182   Int_t size=fCutLowLimits.GetNrows();
183   TVectorD newlow;
184   TVectorD newup;
185
186   // find cut and build new vectors w/o it
187   Int_t ientries = 0;
188   for(Int_t icut=0; icut<size; icut++) {
189
190     TString cutName = fCutVars->At(icut)->GetName();
191     if(!cutName.CompareTo(Form("%s%s",(leg?"Leg":""),varname))) {
192       fCutVars->AddAt(0x0,icut);
193       continue;
194     }
195
196     // fill new vectors
197     newlow.ResizeTo(ientries+1);
198     newup.ResizeTo(ientries+1);
199     newlow(ientries) = fCutLowLimits(icut);
200     newup(ientries)  = fCutUpLimits(icut);
201
202     ientries++;
203   }
204
205   // adapt new arrays/vectors
206   fCutVars->Compress();
207
208   fCutLowLimits.ResizeTo(ientries);
209   fCutUpLimits.ResizeTo(ientries);
210   for(Int_t icut=0; icut<ientries; icut++) {
211     fCutLowLimits(icut) = newlow(icut);
212     fCutUpLimits(icut)  = newup(icut);
213   }
214   // PrintCuts();
215
216 }
217
218 //________________________________________________________________
219 void AliDielectronHFhelper::UnsetRangeUser(AliDielectronVarManager::ValueTypes type, Bool_t leg)
220 {
221   //
222   // Unset range from AliDielectronVarManager
223   //
224   UnsetRangeUser(AliDielectronVarManager::GetValueName(type), leg);
225 }
226
227 //________________________________________________________________
228 TObjArray* AliDielectronHFhelper::CollectProfiles(TString option,
229                                                   AliDielectronVarManager::ValueTypes varx,
230                                                   AliDielectronVarManager::ValueTypes vary,
231                                                   AliDielectronVarManager::ValueTypes varz,
232                                                   AliDielectronVarManager::ValueTypes vart)
233 {
234   //
235   // collect 1-3 dimensional TProfiles for all kind of pair types or sources
236   //
237
238   // reconstruct the histogram/profile name resp. key
239   Int_t dim    = 0;
240   if(varx < AliDielectronVarManager::kNMaxValues) dim++;
241   if(vary < AliDielectronVarManager::kNMaxValues) dim++;
242   if(varz < AliDielectronVarManager::kNMaxValues) dim++;
243   Bool_t bPairClass=0;
244   if( varx < AliDielectronVarManager::kPairMax ||
245       vary < AliDielectronVarManager::kPairMax ||
246       varz < AliDielectronVarManager::kPairMax ||
247       vart < AliDielectronVarManager::kPairMax  ) bPairClass=kTRUE;
248   Bool_t bwght= (option.Contains("weight",TString::kIgnoreCase));   // weighted histogram
249   Bool_t bprf = !(option.Contains("hist",TString::kIgnoreCase));     // tprofile
250   Bool_t bStdOpt=kTRUE;
251   if(option.Contains("S",TString::kIgnoreCase) || option.Contains("rms",TString::kIgnoreCase)) bStdOpt=kFALSE;
252
253   TString key = "";
254   if(bwght) dim--;
255   if(bprf)  dim--;
256   switch(dim) {
257   case 3:
258     key+=Form("%s_",AliDielectronVarManager::GetValueName(varx));
259     key+=Form("%s_",AliDielectronVarManager::GetValueName(vary));
260     key+=Form("%s",AliDielectronVarManager::GetValueName(varz));
261     if(bprf) key+=Form("-%s%s",AliDielectronVarManager::GetValueName(vart),(bStdOpt ? "avg" : "rms"));
262     break;
263   case 2:
264     key+=Form("%s_",AliDielectronVarManager::GetValueName(varx));
265     key+=Form("%s",AliDielectronVarManager::GetValueName(vary));
266     if(bprf) key+=Form("-%s%s",AliDielectronVarManager::GetValueName(varz),(bStdOpt ? "avg" : "rms"));
267     break;
268   case 1:
269     key+=Form("%s",AliDielectronVarManager::GetValueName(varx));
270     if(bprf) key+=Form("-%s%s",AliDielectronVarManager::GetValueName(vary),(bStdOpt ? "avg" : "rms"));
271     break;
272   }
273   // to differentiate btw. leg and pair histos
274   if(bPairClass) key.Prepend("p");
275   // prepend HF
276   key.Prepend("HF_");
277
278   // add the weighted part to the key
279   if(bwght) {
280     if(bprf) dim++;
281     switch(dim) {
282     case 3:   key+=Form("-wght%s",AliDielectronVarManager::GetValueName(vart)); break;
283     case 2:   key+=Form("-wght%s",AliDielectronVarManager::GetValueName(varz)); break;
284     case 1:   key+=Form("-wght%s",AliDielectronVarManager::GetValueName(vary)); break;
285     case 4:   AliError(Form(" NO weighted 3D profiles supported by the framework"));
286     }
287   }
288
289   //printf("--------> KEY: %s \n",key.Data());
290   // init array of histograms of interest
291   TObjArray *collection = new TObjArray(fMainArr->GetEntriesFast());
292   collection->SetOwner(kTRUE);
293
294   TObjArray *cloneArr = (TObjArray*) fMainArr->Clone("tmpArr");
295   if(!cloneArr) return 0x0;
296   cloneArr->SetOwner(kTRUE);
297
298   // loop over all pair types or sources
299   for(Int_t i=0; i<cloneArr->GetEntriesFast(); i++) {
300     if(!cloneArr->At(i))                             continue;
301     if(!((TObjArray*)cloneArr->At(i))->GetEntries()) continue;
302
303     // Get signal/source array with its histograms of interest
304     TObjArray *arr = (TObjArray*) GetObject(cloneArr->At(i)->GetName(),cloneArr);
305     if(arr) {
306
307       // find requested histogram
308       collection->AddAt(arr->FindObject(key.Data()), i);
309       if(!collection->At(i)) { AliError(Form("Object %s does not exist",key.Data())); return 0x0; }
310
311       // modify the signal/source name if needed (MConly)
312       TString stepName = cloneArr->At(i)->GetName();
313       stepName.ReplaceAll("(","");
314       stepName.ReplaceAll(")","");
315       stepName.ReplaceAll(": ","");
316       stepName.ReplaceAll(" ","_");
317       stepName.ReplaceAll("Signal","");
318       ((TH1*)collection->At(i))->SetName(Form("%s_%s",key.Data(),stepName.Data()));
319     }
320
321   }
322
323   // clean up the clone
324     delete cloneArr;
325     cloneArr=0;
326
327   return collection;
328 }
329
330 //________________________________________________________________
331 TObject* AliDielectronHFhelper::GetObject(const char *step, TObjArray *histArr)
332 {
333   // rename into GetSignalArray, return value is a tobjarray
334   //
335   // main function to receive a pair type or MC signal array
336   // with all its merged histograms valid for the cuts
337   //
338
339   AliDebug(1,Form(" Step %s selected",step));
340   // TODO: check memory
341
342   TObjArray *stepArr = 0x0; // this is the requested step
343   TObject *hist      = 0x0; // this is the returned object
344   if(!histArr) {
345     stepArr = (TObjArray*) fMainArr->FindObject(step)->Clone("tmpArr");
346   }
347   else {
348     stepArr = (TObjArray*) histArr->FindObject(step);
349   }
350
351   // apply cuts and get merged objects
352   if(stepArr) hist   = FindObjects(stepArr);
353   return hist;
354
355 }
356
357 //________________________________________________________________
358 TObject* AliDielectronHFhelper::FindObjects(TObjArray *stepArr)
359 {
360   // rename DoCuts, return values is a tobjarray
361   // apply cuts and exclude objects from the array for merging (CUT selection)
362   //
363
364   // debug
365   // TString title    = stepArr->At(0)->GetTitle();
366   // TObjArray* vars  = title.Tokenize(":");
367   // AliDebug(1,Form(" number of cuts/vars: %d/%d",fCutLowLimits.GetNrows(),vars->GetEntriesFast()));
368
369   // check for missing cuts
370   CheckCuts(stepArr);
371
372   // loop over all cuts
373   for(Int_t icut=0; icut<fCutLowLimits.GetNrows(); icut++) {
374
375     Bool_t bFndBin      = kFALSE; // bin with exact limits found
376     const char *cutvar  = fCutVars->At(icut)->GetName(); // cut variable
377     Double_t min        = fCutLowLimits(icut);           // lower limit
378     Double_t max        = fCutUpLimits(icut);            // upper limit
379     AliDebug(5,Form(" Cut %d: %s [%.2f,%.2f]",icut,cutvar,min,max));
380
381     // loop over the full grid of the signalArray (pair,source)
382     for(Int_t i=0; i<stepArr->GetEntriesFast(); i++) {
383
384       // continue if already empty
385       if(!stepArr->At(i)) continue;
386
387       // collect bins from the name
388       TString title    = stepArr->At(i)->GetName();
389       if(title.IsNull()) continue;
390       AliDebug(5,Form(" %03d object name: %s",i,title.Data()));
391
392       // loop over all variables
393       TObjArray *vars  = title.Tokenize(":");
394       for(Int_t ivar=0; ivar<vars->GetEntriesFast(); ivar++) {
395         TString binvar = vars->At(ivar)->GetName();
396         AliDebug(10,Form(" --> %d check bin var %s",ivar,binvar.Data()));
397
398         // check cuts set by the user, and compare to the bin limits
399         if(binvar.Contains(cutvar)) {
400           // bin limits
401           TObjArray *limits = binvar.Tokenize("#");
402           Double_t binmin = atof(limits->At(1)->GetName()); // lower bin limit
403           Double_t binmax = atof(limits->At(2)->GetName()); // upper bin limit
404           AliDebug(10,Form(" bin %s var %s [%.2f,%.2f]",binvar.Data(),limits->At(0)->GetName(),binmin,binmax));
405           if(limits) delete limits;
406
407           // cut and remove objects from the array
408           if(binmin < min || binmax < min || binmin > max || binmax > max ) {
409             AliDebug(10,Form(" removed, out of range! lower bin,cut: %.2f,%.2f or upper bin,cut: %.2f>%.2f",binmin,min,binmax,max));
410             stepArr->AddAt(0x0,i);
411           }
412           if(bFndBin && !(binmin == min && binmax == max)) {
413             stepArr->AddAt(0x0,i);
414             AliDebug(10,Form(" removed, within range! lower bin,cut: %.2f,%.2f or upper bin,cut: %.2f,%.2f",binmin,min,binmax,max));
415           }
416
417           // did we found a bin with exact the cut ranges
418           // this can happen only once per variable
419           if(binmin==min && binmax==max) bFndBin=kTRUE;
420
421         }
422
423       }
424       // clean up
425       if(vars)   delete vars;
426
427     } //end loop: pair step
428
429   } //end: loop cuts
430
431   // compress the array by removing all empty entries
432   stepArr->Compress();
433   AliDebug(1,Form(" Compression: %d objects left",stepArr->GetEntriesFast()));
434
435   // merge left objects
436   TObject* hist = Merge(stepArr);
437   //  if(hist) AliDebug(1,Form(" Merging: %e  entries",hist->GetEntries()));
438   return hist;
439 }
440
441 //________________________________________________________________
442 TObject* AliDielectronHFhelper::Merge(TObjArray *arr)
443 {
444   // returned object is tobjarray
445   // merge left objects into a single one (LAST step)
446   //
447
448   if(arr->GetEntriesFast()<1) { AliError(" No more objects left!"); return 0x0; }
449
450   TObjArray *final=(TObjArray*) arr->At(0)->Clone();
451   if(!final) return 0x0;
452   final->SetOwner();
453
454   TList listH;
455   TString listHargs;
456   listHargs.Form("((TCollection*)0x%lx)", (ULong_t)&listH);
457   Int_t error = 0;
458
459   //  final->Reset("CE");
460   //  final->SetTitle(""); //TODO: change in future
461   for(Int_t i=1; i<arr->GetEntriesFast(); i++) {
462     listH.Add(arr->At(i));
463     //   printf("%d: ent %.0f \n",i,((TH1*)((TObjArray*)arr->At(i))->At(0))->GetEntries());
464     //    final->Add((TH1*)arr->At(i));
465   }
466   //  arr->Clear();
467
468   final->Execute("Merge", listHargs.Data(), &error);
469   // returns a tobjarray of histograms/profiles
470   return final;
471 }
472
473 //________________________________________________________________
474 void AliDielectronHFhelper::CheckCuts(TObjArray *arr)
475 {
476   //
477   // Compare binning and cut variables. Add necessary cuts (full range, no exclusion)
478   //
479
480   // build array with bin variable, minimum and maximum bin values
481   TString titleFIRST       = arr->First()->GetName();
482   TString titleLAST        = arr->Last()->GetName();
483   TObjArray* binvarsF  = titleFIRST.Tokenize(":#");
484   TObjArray* binvarsL  = titleLAST.Tokenize(":#");
485   Double_t binmin[kMaxCuts]= {0.0};
486   Double_t binmax[kMaxCuts]= {0.0};
487   for(Int_t ivar=0; ivar<binvarsF->GetEntriesFast(); ivar++) {
488
489     TString elementF=binvarsF->At(ivar)->GetName();
490     TString elementL=binvarsL->At(ivar)->GetName();
491     AliDebug(1,Form(" binvar %d: %s,%s",ivar,elementF.Data(),elementL.Data()));
492
493     switch(ivar%3) {
494     case 0: continue; break;
495     case 1: binmin[(int)ivar/3]=atof(elementF.Data()); break;
496     case 2: binmax[(int)ivar/3]=atof(elementL.Data()); break;
497     }
498
499     binvarsF->AddAt(0x0,ivar);
500   }
501   binvarsF->Compress();
502
503   // loop over all vars and cuts, check for missing stuff
504   for(Int_t ivar=0; ivar<binvarsF->GetEntriesFast(); ivar++) {
505
506     TString binvar=binvarsF->At(ivar)->GetName();
507     Bool_t selected=kFALSE;
508
509     AliDebug(1,Form(" check cuts %d %s [%.2f,%.2f]",ivar,binvar.Data(),binmin[ivar],binmax[ivar]));
510     // loop over all cuts and check for missing stuff
511     for(Int_t icut=0; icut<fCutLowLimits.GetNrows(); icut++) {
512       if(binvar.Contains(fCutVars->At(icut)->GetName())) { selected=kTRUE; break; }
513       //      else break;
514     }
515
516     // add missing cut with max limits
517     if(!selected) {
518       AliWarning(Form(" Bin variable %s not covered. Add cut!",binvar.Data()));
519       Bool_t leg = binvar.BeginsWith("Leg");
520       if(leg) binvar.Remove(0,3);
521       SetRangeUser(binvar.Data(),binmin[ivar],binmax[ivar], leg);
522     }
523
524   }
525
526   // clean up
527   if(binvarsF) delete binvarsF;
528   if(binvarsL) delete binvarsL;
529 }
530
531 //________________________________________________________________
532 void AliDielectronHFhelper::Print(const Option_t* /*option*/) const
533 {
534
535   //
536   // Print out object contents
537   //
538   AliInfo(Form(" Container:               %s",fMainArr->GetName()));
539
540   // pairtypes, steps and sources
541   Int_t stepLast=0;
542   AliInfo(Form(" Number of filled steps:  %d",fMainArr->GetEntries()));
543   for(Int_t istep=0; istep<fMainArr->GetEntriesFast(); istep++) {
544     if(!fMainArr->At(istep))                             continue;
545     if(!((TObjArray*)fMainArr->At(istep))->GetEntries()) continue;
546     AliInfo(Form(" step %d: %s",istep,fMainArr->At(istep)->GetName()));
547     stepLast=istep;
548   }
549
550   AliInfo(Form(" Number of objects:    %d",
551                ((TObjArray*) ((TObjArray*)fMainArr->At(stepLast)) ->First())->GetEntriesFast()));
552
553   TString title       = ((TObjArray*)fMainArr->At(stepLast))->First()->GetName();
554   TObjArray* binvars  = title.Tokenize(":");
555   AliInfo(Form(" Number of variables:     %d",binvars->GetEntriesFast()));
556   delete binvars;
557
558   /* REACTIVATE
559   // check for missing cuts
560   CheckCuts(((TObjArray*)fMainArr->At(stepLast)));
561   // loop over all cuts
562   for(Int_t icut=0; icut<fCutLowLimits.GetNrows(); icut++) {
563     const char *cutvar  = fCutVars->At(icut)->GetName(); // cut variable
564     Double_t min        = fCutLowLimits(icut);           // lower limit
565     Double_t max        = fCutUpLimits(icut);            // upper limit
566     AliInfo(Form(" variable %d: %s [%.2f,%.2f]",icut,cutvar,min,max));
567   }
568   */
569   TObjArray* binvars2  = title.Tokenize(":#");
570   for(Int_t ivar=0; ivar<binvars2->GetEntriesFast(); ivar++) {
571     if(ivar%3) continue;
572     AliInfo(Form(" variable %.0f: %s",((Double_t)ivar)/3+1,binvars2->At(ivar)->GetName()));
573   }
574   delete binvars2;
575
576 }
577
578 //________________________________________________________________
579 void AliDielectronHFhelper::PrintCuts()
580 {
581
582   //
583   // Print cuts
584   //
585
586   // loop over all cuts
587   AliInfo(" Selected cuts:");
588   for(Int_t icut=0; icut<fCutLowLimits.GetNrows(); icut++)
589     AliInfo(Form(" %d: %s [%.2f,%.2f]",icut,fCutVars->At(icut)->GetName(),fCutLowLimits(icut),fCutUpLimits(icut)));
590
591 }
592