1 /*************************************************************************
2 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 ///////////////////////////////////////////////////////////////////////////
17 // Dielectron Histogram framework helper //
21 A helper class to extract objects(histograms and/or profiles) from
22 a AliDielctronHF array of objects.
27 AliDielectronHFhelper *hf = new AliDielectronHFhelper("path/to/the/output/file.root", "ConfigName");
28 // print the structure
31 //apply some cuts and print them
32 hf->SetRangeUser("cut1name",cutmin1,cutmax1);
33 hf->SetRangeUser(AliDielectronVarManager::kPt,ptmin,ptmax);
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);
40 // then you are left with an array of histograms for all pair types or MC signals
44 ///////////////////////////////////////////////////////////////////////////
46 #include <TObjArray.h>
53 #include <TObjString.h>
60 #include "AliDielectron.h"
61 #include "AliDielectronHFhelper.h"
62 #include "AliDielectronHF.h"
64 ClassImp(AliDielectronHFhelper)
66 //const char* AliDielectronHFhelper::fCutVars[AliDielectronHFhelper::kMaxCuts] = {"","","","","","","","","",""};
68 //________________________________________________________________
69 AliDielectronHFhelper::AliDielectronHFhelper(const char* filename, const char* container) :
77 // get HF container(s) from file 'filename'
79 SetHFArray(filename, container);
83 //________________________________________________________________
84 AliDielectronHFhelper::~AliDielectronHFhelper()
89 if(fMainArr) delete fMainArr;
90 if(fCutVars) delete fCutVars;
94 //________________________________________________________________
95 void AliDielectronHFhelper::SetHFArray(const char* filename, const char* container)
98 // get HF container from file
101 TFile *f = TFile::Open(filename);
103 TList *l=f->GetListOfKeys();
106 while ( (k=static_cast<TKey*>(nextKey())) ){
108 TObject *o=k->ReadObj();
109 if (o->IsA()==TList::Class()){
111 TList *tlist=(TList*)o;
115 while ((obj = next())) {
116 TString objname(obj->GetName());
118 if( objname.Contains(Form("%s_HF",container)) && obj->IsA()==TObjArray::Class()) {
119 fMainArr = new TObjArray( *(dynamic_cast<TObjArray*>(obj)) );
128 //________________________________________________________________
129 void AliDielectronHFhelper::SetRangeUser(const char *varname, Double_t min, Double_t max, Bool_t leg)
132 // Set range from variable name
135 Int_t size=fCutLowLimits.GetNrows();
137 // check if cut is already set
138 for(Int_t icut=0; icut<size; icut++) {
139 TString cutName = fCutVars->At(icut)->GetName();
140 if(!cutName.CompareTo(Form("%s%s",(leg?"Leg":""),varname))) {
141 UnsetRangeUser(varname,leg);
142 SetRangeUser(varname, min, max, leg);
147 if(size>=kMaxCuts) return;
151 fCutVars = new TObjArray();
152 fCutVars->SetOwner();
154 fCutLowLimits.ResizeTo(size+1);
155 fCutUpLimits.ResizeTo(size+1);
158 TObjString *str = new TObjString(Form("%s%s",(leg?"Leg":""),varname));
160 fCutLowLimits(size) = min;
161 fCutUpLimits(size) = max;
162 AliWarning(Form(" %s [%.2f,%.2f]",fCutVars->At(size)->GetName(),fCutLowLimits(size),fCutUpLimits(size)));
165 //________________________________________________________________
166 void AliDielectronHFhelper::SetRangeUser(AliDielectronVarManager::ValueTypes type, Double_t min, Double_t max, Bool_t leg)
169 // Set range from AliDielectronVarManager
171 SetRangeUser(AliDielectronVarManager::GetValueName(type), min, max, leg);
174 //________________________________________________________________
175 void AliDielectronHFhelper::UnsetRangeUser(const char *varname, Bool_t leg)
178 // unset range from variable name
181 Int_t size=fCutLowLimits.GetNrows();
185 // find cut and build new vectors w/o it
187 for(Int_t icut=0; icut<size; icut++) {
189 TString cutName = fCutVars->At(icut)->GetName();
190 if(!cutName.CompareTo(Form("%s%s",(leg?"Leg":""),varname))) {
191 fCutVars->AddAt(0x0,icut);
196 newlow.ResizeTo(ientries+1);
197 newup.ResizeTo(ientries+1);
198 newlow(ientries) = fCutLowLimits(icut);
199 newup(ientries) = fCutUpLimits(icut);
204 // adapt new arrays/vectors
205 fCutVars->Compress();
207 fCutLowLimits.ResizeTo(ientries);
208 fCutUpLimits.ResizeTo(ientries);
209 for(Int_t icut=0; icut<ientries; icut++) {
210 fCutLowLimits(icut) = newlow(icut);
211 fCutUpLimits(icut) = newup(icut);
217 //________________________________________________________________
218 void AliDielectronHFhelper::UnsetRangeUser(AliDielectronVarManager::ValueTypes type, Bool_t leg)
221 // Unset range from AliDielectronVarManager
223 UnsetRangeUser(AliDielectronVarManager::GetValueName(type), leg);
226 //________________________________________________________________
227 TObjArray* AliDielectronHFhelper::CollectProfiles(TString option,
228 AliDielectronVarManager::ValueTypes varx,
229 AliDielectronVarManager::ValueTypes vary,
230 AliDielectronVarManager::ValueTypes varz,
231 AliDielectronVarManager::ValueTypes vart)
234 // collect 1-3 dimensional TProfiles for all kind of pair types or sources
237 // reconstruct the histogram/profile name resp. key
239 if(varx < AliDielectronVarManager::kNMaxValues) dim++;
240 if(vary < AliDielectronVarManager::kNMaxValues) dim++;
241 if(varz < AliDielectronVarManager::kNMaxValues) dim++;
243 if( varx < AliDielectronVarManager::kPairMax ||
244 vary < AliDielectronVarManager::kPairMax ||
245 varz < AliDielectronVarManager::kPairMax ||
246 vart < AliDielectronVarManager::kPairMax ) bPairClass=kTRUE;
247 Bool_t bprf = !(option.Contains("hist",TString::kIgnoreCase));
248 Bool_t bStdOpt=kTRUE;
249 if(option.Contains("S",TString::kIgnoreCase) || option.Contains("rms",TString::kIgnoreCase)) bStdOpt=kFALSE;
255 key+=Form("%s_",AliDielectronVarManager::GetValueName(varx));
256 key+=Form("%s_",AliDielectronVarManager::GetValueName(vary));
257 key+=Form("%s",AliDielectronVarManager::GetValueName(varz));
258 if(bprf) key+=Form("-%s%s",AliDielectronVarManager::GetValueName(vart),(bStdOpt ? "avg" : "rms"));
261 key+=Form("%s_",AliDielectronVarManager::GetValueName(varx));
262 key+=Form("%s",AliDielectronVarManager::GetValueName(vary));
263 if(bprf) key+=Form("-%s%s",AliDielectronVarManager::GetValueName(varz),(bStdOpt ? "avg" : "rms"));
266 key+=Form("%s",AliDielectronVarManager::GetValueName(varx));
267 if(bprf) key+=Form("-%s%s",AliDielectronVarManager::GetValueName(vary),(bStdOpt ? "avg" : "rms"));
270 // to differentiate btw. leg and pair histos
271 if(bPairClass) key.Prepend("p");
275 //TODO: printf("--------> KEY: %s \n",key.Data());
276 // get the requested object from the arrays
277 TObjArray *collection = new TObjArray(fMainArr->GetEntriesFast());
279 TObjArray *cloneArr = (TObjArray*) fMainArr->Clone("tmpArr");
280 if(!cloneArr) return 0x0;
281 cloneArr->SetOwner(kTRUE);
283 // loop over all pair types or sources
284 for(Int_t i=0; i<cloneArr->GetEntriesFast(); i++) {
285 if(!cloneArr->At(i)) continue;
286 if(!((TObjArray*)cloneArr->At(i))->GetEntries()) continue;
287 TString stepName = cloneArr->At(i)->GetName();
289 // find histogram of interest from array of objects
290 TObjArray *arr = (TObjArray*) GetObject(cloneArr->At(i)->GetName(),cloneArr);
292 collection->AddAt(arr->FindObject(key.Data()), i);
293 if(!collection->At(i)) AliError(Form("Object %s does not exist",key.Data()));
294 // modify the key name
295 stepName.ReplaceAll("(","");
296 stepName.ReplaceAll(")","");
297 stepName.ReplaceAll(": ","");
298 stepName.ReplaceAll(" ","_");
299 stepName.ReplaceAll("Signal","");
300 ((TH1*)collection->At(i))->SetName(Form("%s_%s",key.Data(),stepName.Data()));
305 // clean up the clone
314 //________________________________________________________________
315 TObject* AliDielectronHFhelper::GetObject(const char *step, TObjArray *histArr)
318 // main function to recieve a pair type or MC signal array
321 AliDebug(1,Form(" Step %s selected",step));
322 // TODO: check memory
324 TObjArray *stepArr = 0x0; // this is the requested step
327 stepArr = (TObjArray*) fMainArr->FindObject(step)->Clone("tmpArr");
330 stepArr = (TObjArray*) histArr->FindObject(step);
333 if(stepArr) hist = FindObjects(stepArr);
338 //________________________________________________________________
339 TObject* AliDielectronHFhelper::FindObjects(TObjArray *stepArr)
342 // apply cuts and exclude objects from the array
346 // TString title = stepArr->At(0)->GetTitle();
347 // TObjArray* vars = title.Tokenize(":");
348 // AliDebug(1,Form(" number of cuts/vars: %d/%d",fCutLowLimits.GetNrows(),vars->GetEntriesFast()));
350 // check for missing cuts
353 // loop over all cuts
354 for(Int_t icut=0; icut<fCutLowLimits.GetNrows(); icut++) {
356 Bool_t bFndBin = kFALSE; // bin with exact limits found
357 const char *cutvar = fCutVars->At(icut)->GetName(); // cut variable
358 Double_t min = fCutLowLimits(icut); // lower limit
359 Double_t max = fCutUpLimits(icut); // upper limit
360 AliDebug(5,Form(" Cut %d: %s [%.2f,%.2f]",icut,cutvar,min,max));
362 // loop over the full grid of given step
363 for(Int_t i=0; i<stepArr->GetEntriesFast(); i++) {
365 // continue if already empty
366 if(!stepArr->At(i)) continue;
368 // collect bins from the name
369 TString title = stepArr->At(i)->GetName();
370 if(title.IsNull()) continue;
371 AliDebug(5,Form(" %03d object name: %s",i,title.Data()));
373 // loop over all variables
374 TObjArray *vars = title.Tokenize(":");
375 for(Int_t ivar=0; ivar<vars->GetEntriesFast(); ivar++) {
376 TString binvar = vars->At(ivar)->GetName();
377 AliDebug(10,Form(" --> %d check bin var %s",ivar,binvar.Data()));
379 // check cuts set by the user, and compare to the bin limits
380 if(binvar.Contains(cutvar)) {
382 TObjArray *limits = binvar.Tokenize("#");
383 Double_t binmin = atof(limits->At(1)->GetName()); // lower bin limit
384 Double_t binmax = atof(limits->At(2)->GetName()); // upper bin limit
385 AliDebug(10,Form(" bin %s var %s [%.2f,%.2f]",binvar.Data(),limits->At(0)->GetName(),binmin,binmax));
386 if(limits) delete limits;
388 // cut and remove objects from the array
389 if(binmin < min || binmax < min || binmin > max || binmax > max ) {
390 AliDebug(10,Form(" removed, out of range! lower bin,cut: %.2f,%.2f or upper bin,cut: %.2f>%.2f",binmin,min,binmax,max));
391 stepArr->AddAt(0x0,i);
393 if(bFndBin && !(binmin == min && binmax == max)) {
394 stepArr->AddAt(0x0,i);
395 AliDebug(10,Form(" removed, within range! lower bin,cut: %.2f,%.2f or upper bin,cut: %.2f,%.2f",binmin,min,binmax,max));
398 // did we found a bin with exact the cut ranges
399 // this can happen only once per variable
400 if(binmin==min && binmax==max) bFndBin=kTRUE;
406 if(vars) delete vars;
412 // compress the array by removing all empty entries
414 AliDebug(1,Form(" Compression: %d objects left",stepArr->GetEntriesFast()));
416 // merge left objects
417 TObject* hist = Merge(stepArr);
418 // if(hist) AliDebug(1,Form(" Merging: %e entries",hist->GetEntries()));
422 //________________________________________________________________
423 TObject* AliDielectronHFhelper::Merge(TObjArray *arr)
426 // merge left objects to a single one
429 if(arr->GetEntriesFast()<1) { AliError(" No more objects left!"); return 0x0; }
431 TObject *final=arr->At(0)->Clone();
432 if(!final) return 0x0;
436 listHargs.Form("((TCollection*)0x%lx)", (ULong_t)&listH);
439 // final->Reset("CE");
440 // final->SetTitle(""); //TODO: change in future
441 for(Int_t i=1; i<arr->GetEntriesFast(); i++) {
442 listH.Add(arr->At(i));
443 // printf("%d: ent %.0f \n",i,((TH1*)((TObjArray*)arr->At(i))->At(0))->GetEntries());
444 // final->Add((TH1*)arr->At(i));
448 final->Execute("Merge", listHargs.Data(), &error);
452 //________________________________________________________________
453 void AliDielectronHFhelper::CheckCuts(TObjArray *arr)
456 // Compare binning and cut variables. Add necessary cuts (full range, no exclusion)
459 // build array with bin variable, minimum and maximum bin values
460 TString titleFIRST = arr->First()->GetName();
461 TString titleLAST = arr->Last()->GetName();
462 TObjArray* binvarsF = titleFIRST.Tokenize(":#");
463 TObjArray* binvarsL = titleLAST.Tokenize(":#");
464 Double_t binmin[kMaxCuts]= {0.0};
465 Double_t binmax[kMaxCuts]= {0.0};
466 for(Int_t ivar=0; ivar<binvarsF->GetEntriesFast(); ivar++) {
468 TString elementF=binvarsF->At(ivar)->GetName();
469 TString elementL=binvarsL->At(ivar)->GetName();
470 AliDebug(1,Form(" binvar %d: %s,%s",ivar,elementF.Data(),elementL.Data()));
473 case 0: continue; break;
474 case 1: binmin[(int)ivar/3]=atof(elementF.Data()); break;
475 case 2: binmax[(int)ivar/3]=atof(elementL.Data()); break;
478 binvarsF->AddAt(0x0,ivar);
480 binvarsF->Compress();
482 // loop over all vars and cuts, check for missing stuff
483 for(Int_t ivar=0; ivar<binvarsF->GetEntriesFast(); ivar++) {
485 TString binvar=binvarsF->At(ivar)->GetName();
486 Bool_t selected=kFALSE;
488 AliDebug(1,Form(" check cuts %d %s [%.2f,%.2f]",ivar,binvar.Data(),binmin[ivar],binmax[ivar]));
489 // loop over all cuts and check for missing stuff
490 for(Int_t icut=0; icut<fCutLowLimits.GetNrows(); icut++) {
491 if(binvar.Contains(fCutVars->At(icut)->GetName())) { selected=kTRUE; break; }
495 // add missing cut with max limits
497 AliWarning(Form(" Bin variable %s not covered. Add cut!",binvar.Data()));
498 Bool_t leg = binvar.BeginsWith("Leg");
499 if(leg) binvar.Remove(0,3);
500 SetRangeUser(binvar.Data(),binmin[ivar],binmax[ivar], leg);
506 if(binvarsF) delete binvarsF;
507 if(binvarsL) delete binvarsL;
510 //________________________________________________________________
511 void AliDielectronHFhelper::Print(const Option_t* /*option*/) const
515 // Print out object contents
517 AliInfo(Form(" Container: %s",fMainArr->GetName()));
519 // pairtypes, steps and sources
521 AliInfo(Form(" Number of filled steps: %d",fMainArr->GetEntries()));
522 for(Int_t istep=0; istep<fMainArr->GetEntriesFast(); istep++) {
523 if(!fMainArr->At(istep)) continue;
524 if(!((TObjArray*)fMainArr->At(istep))->GetEntries()) continue;
525 AliInfo(Form(" step %d: %s",istep,fMainArr->At(istep)->GetName()));
529 AliInfo(Form(" Number of objects: %d",
530 ((TObjArray*) ((TObjArray*)fMainArr->At(stepLast)) ->First())->GetEntriesFast()));
532 TString title = ((TObjArray*)fMainArr->At(stepLast))->First()->GetName();
533 TObjArray* binvars = title.Tokenize(":");
534 AliInfo(Form(" Number of variables: %d",binvars->GetEntriesFast()));
537 TObjArray* binvars2 = title.Tokenize(":#");
538 for(Int_t ivar=0; ivar<binvars2->GetEntriesFast(); ivar++) {
540 AliInfo(Form(" variable %.0f: %s",((Double_t)ivar)/3+1,binvars2->At(ivar)->GetName()));
546 //________________________________________________________________
547 void AliDielectronHFhelper::PrintCuts()
554 // loop over all cuts
555 AliInfo(" Selected cuts:");
556 for(Int_t icut=0; icut<fCutLowLimits.GetNrows(); icut++)
557 AliInfo(Form(" %d: %s [%.2f,%.2f]",icut,fCutVars->At(icut)->GetName(),fCutLowLimits(icut),fCutUpLimits(icut)));