CbmRoot
Loading...
Searching...
No Matches
PairAnalysisHistos.cxx
Go to the documentation of this file.
1/* Copyright (C) 2015-2020 Justus-Liebig-Universitaet Giessen, Giessen
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Julian Book [committer] */
4/*
5 TOADD: reserved words, MC signals, hist classes, MC weighting, plotting!
6
7 Histograms such as THxF,D, TProfile,2D,3D and n-dimensonal objects such as
8 (THn, THnSparse) can be added via the various template functions:
9 - AddHistogram
10 - AddProfile + different error option (Mean,Rms,.. see: TProfile::BuildOptions(..))
11 - AddSparse
12 In addition histograms can be filled with weights.
13
14 Different kind of binnings can be passed (linear, arbitrary, logarithmic)
15 either via the PairAnalysisHelper functionalities:
16 - PairAnalysisHelper::MakeLinBinning(nbins,low,high)
17 - PairAnalysisHelper::MakeLogBinning(nbins,low,high)
18 - PairAnalysisHelper::MakeArbitraryBinning("1.,4.,10.,..")
19
20 The 'name' and 'title;titleX;titleY;...' of the objects and all axis labels,
21 units and names and object names are set in a consistent way and
22 it is ensured that they are unique.
23
24 Variables are added via the enumerator of PairAnalysisVarManager. Any
25 computation of variables (max=10) are implemented according to TFormula
26 using the TMath functions.
27
28 The arguments and options in the function DrawSame and DrawTaskSame provide various and
29 powerful possibilities to plot and post-process histograms.
30
31 Examples:
32
33 // 1 dimensional
34 AddHistogram("Event", PairAnalysisHelper::MakeLinBinning(200,-1.,1.), PairAnalysisVarManager::kXvPrim);
35
36 AddHistogram("Event", PairAnalysisHelper::MakeLinBinning(200,0.0,10.0), "VtxChi/VtxNDF"); // using formulas
37
38 AddHistogram("Track", PairAnalysisHelper::MakeLogBinning(400,0,4.), PairAnalysisVarManager::kPt); // logarithmic
39
40 AddHistogram("Hit.TRD",PairAnalysisHelper::MakeLinBinning(105,-1.e+2,5.), "ElossdEdx-ElossMC"); // use MC truth
41
42 // 2 dimensional
43 AddHistogram("Track", PairAnalysisHelper::MakeLinBinning(100,-0.5,3.), PairAnalysisVarManager::kY,
44 PairAnalysisHelper::MakeLinBinning(125,0,5.), PairAnalysisVarManager::kPt);
45
46 AddProfile( "Track", PairAnalysisHelper::MakeLogBinning(50,0.05,10.), PairAnalysisVarManager::kP,
47 PairAnalysisVarManager::kTRDHits, "I"); // Y-average
48
49 ...
50
51*/
52
53#include "PairAnalysisHistos.h"
54
55#include <TAxis.h>
56#include <TCanvas.h>
57#include <TCollection.h>
58#include <TError.h>
59#include <TFile.h>
60#include <TFormula.h>
61#include <TGaxis.h>
62#include <TH1.h>
63#include <TH1D.h>
64#include <TH1F.h>
65#include <TH2.h>
66#include <TH3.h>
67#include <THStack.h>
68#include <THashList.h>
69#include <THn.h>
70#include <THnBase.h>
71#include <THnSparse.h>
72#include <TKey.h>
73#include <TLatex.h>
74#include <TLegend.h>
75#include <TLegendEntry.h>
76#include <TMath.h>
77#include <TObjArray.h>
78#include <TObjString.h>
79#include <TProfile.h>
80#include <TProfile2D.h>
81#include <TProfile3D.h>
82#include <TROOT.h>
83#include <TString.h>
84#include <TVectorD.h>
85#include <TVirtualPS.h>
86#include <typeinfo>
87
88#include "PairAnalysis.h"
89#include "PairAnalysisHelper.h"
92#include "PairAnalysisStyler.h"
94
95ClassImp(PairAnalysisHistos)
96
97
98 PairAnalysisHistos::PairAnalysisHistos()
99 : // TCollection(),
100 TNamed("PairAnalysisHistos", "PairAnalysis Histogram Container")
101 , fHistoList()
102 , fMetaData(0x0)
103 , fList(0x0)
104 , fUsedVars(new TBits(PairAnalysisVarManager::kNMaxValues))
105 , fReservedWords(new TString("Hit;Track;Pair"))
106 , fPrecision(Eprecision::kFloat)
107{
108 //
109 // Default constructor
110 //
111 fHistoList.SetOwner(kTRUE);
112 fHistoList.SetName("PairAnalysis_Histos");
115}
116
117//_____________________________________________________________________________
118PairAnalysisHistos::PairAnalysisHistos(const char* name, const char* title)
119 : // TCollection(),
120 TNamed(name, title)
121 , fHistoList()
122 , fMetaData(0x0)
123 , fList(0x0)
124 , fUsedVars(new TBits(PairAnalysisVarManager::kNMaxValues))
125 , fReservedWords(new TString("Hit;Track;Pair"))
126 , fPrecision(Eprecision::kFloat)
127{
128 //
129 // TNamed constructor
130 //
131 fHistoList.SetOwner(kTRUE);
132 fHistoList.SetName(name);
135}
136
137//_____________________________________________________________________________
138PairAnalysisHistos::~PairAnalysisHistos()
139{
140 //
141 // Destructor
142 //
143 fHistoList.Clear();
144 if (fUsedVars) delete fUsedVars;
145 if (fList) fList->Clear();
146 if (fMetaData) delete fMetaData;
147 delete fReservedWords;
148}
149
150//_____________________________________________________________________________
151void PairAnalysisHistos::UserHistogram(const char* histClass, Int_t ndim, TObjArray* limits, UInt_t* vars,
152 UInt_t valTypeW)
153{
154 //
155 // Histogram creation n>3 dimension only with non-linear binning
156 //
157
158 Bool_t isOk = kTRUE;
159 isOk &= (ndim < 21 && ndim > 3);
160 if (!isOk) {
161 Warning("UserHistogram", "Array sizes should be between 3 and 20. Not adding Histogram to '%s'.", histClass);
162 return;
163 }
164 isOk &= (ndim == limits->GetEntriesFast());
165 if (!isOk) return;
166
167 // set automatic histo name
168 TString name;
169 for (Int_t iv = 0; iv < ndim; iv++)
170 name += Form("%s_", PairAnalysisVarManager::GetValueName(vars[iv]));
171 name.Resize(name.Length() - 1);
172
173 isOk &= IsHistogramOk(histClass, name);
174
175 THnD* hist;
176 Int_t bins[ndim];
177 if (isOk) {
178 // get number of bins
179 for (Int_t idim = 0; idim < ndim; idim++) {
180 TVectorD* vec = (TVectorD*) limits->At(idim);
181 bins[idim] = vec->GetNrows() - 1;
182 }
183
184 hist = new THnD(name.Data(), "", ndim, bins, 0x0, 0x0);
185
186 // set binning
187 for (Int_t idim = 0; idim < ndim; idim++) {
188 TVectorD* vec = (TVectorD*) limits->At(idim);
189 hist->SetBinEdges(idim, vec->GetMatrixArray());
190 }
191
192 // store variales in axes
193 StoreVariables(hist, vars);
194 hist->SetUniqueID(valTypeW); // store weighting variable
195
196 // store which variables are used
197 for (Int_t i = 0; i < ndim; i++)
198 fUsedVars->SetBitNumber(vars[i], kTRUE);
199 fUsedVars->SetBitNumber(valTypeW, kTRUE);
200
201 Bool_t isReserved = fReservedWords->Contains(histClass);
202 if (isReserved) UserHistogramReservedWords(histClass, hist);
203 else
204 UserHistogram(histClass, hist);
205 }
206}
207
208//_____________________________________________________________________________
209void PairAnalysisHistos::AddSparse(const char* histClass, Int_t ndim, TObjArray* limits, UInt_t* vars, UInt_t valTypeW)
210{
211 //
212 // THnSparse creation with non-linear binning
213 //
214
215 Bool_t isOk = kTRUE;
216 isOk &= (ndim == limits->GetEntriesFast());
217 if (!isOk) return;
218
219 // set automatic histo name
220 TString name;
221 for (Int_t iv = 0; iv < ndim; iv++)
222 name += Form("%s_", PairAnalysisVarManager::GetValueName(vars[iv]));
223 name.Resize(name.Length() - 1);
224
225 isOk &= IsHistogramOk(histClass, name);
226
227 // THnSparseD *hist;
228 PairAnalysisHn* hist;
229 Int_t bins[ndim];
230 if (isOk) {
231 // get number of bins
232 for (Int_t idim = 0; idim < ndim; idim++) {
233 TVectorD* vec = (TVectorD*) limits->At(idim);
234 bins[idim] = vec->GetNrows() - 1;
235 }
236
237 // hist=new THnSparseD(name.Data(),"", ndim, bins, 0x0, 0x0);
238 hist = new PairAnalysisHn(name.Data(), "", ndim, bins, 0x0, 0x0);
239
240 // set binning
241 for (Int_t idim = 0; idim < ndim; idim++) {
242 TVectorD* vec = (TVectorD*) limits->At(idim);
243 hist->SetBinEdges(idim, vec->GetMatrixArray());
244 }
245
246 // store variales in axes
247 StoreVariables(hist, vars);
248 hist->SetUniqueID(valTypeW); // store weighting variable
249
250 // store which variables are used
251 for (Int_t i = 0; i < ndim; i++)
252 fUsedVars->SetBitNumber(vars[i], kTRUE);
253 fUsedVars->SetBitNumber(valTypeW, kTRUE);
254
255 Bool_t isReserved = fReservedWords->Contains(histClass);
256 if (isReserved) UserHistogramReservedWords(histClass, hist);
257 else
258 UserHistogram(histClass, hist);
259 }
260}
261
262//_____________________________________________________________________________
263void PairAnalysisHistos::AddSparse(const char* histClass, Int_t ndim, TObjArray* limits, TFormula** vars,
264 UInt_t valTypeW)
265{
266 //
267 // THnSparse creation with non-linear binning
268 //
269
270 Bool_t isOk = kTRUE;
271 isOk &= (ndim == limits->GetEntriesFast());
272 if (!isOk) return;
273
274 // set automatic histo name
275 TString name;
276 for (Int_t iv = 0; iv < ndim; iv++)
277 name += Form("%s_", (PairAnalysisHelper::GetFormulaName(vars[iv])).Data());
278 name.Resize(name.Length() - 1);
279 name.ReplaceAll("f(", "");
280 name.ReplaceAll(")", "");
281 name.Prepend("f(");
282 name.Append(")");
283
284 isOk &= IsHistogramOk(histClass, name);
285
286 // THnSparseD *hist;
287 PairAnalysisHn* hist;
288 Int_t bins[ndim];
289 if (isOk) {
290 // get number of bins
291 for (Int_t idim = 0; idim < ndim; idim++) {
292 TVectorD* vec = (TVectorD*) limits->At(idim);
293 bins[idim] = vec->GetNrows() - 1;
294 }
295
296 // hist=new THnSparseD(name.Data(),"", ndim, bins, 0x0, 0x0);
297 hist = new PairAnalysisHn(name.Data(), "", ndim, bins, 0x0, 0x0);
298
299 // set binning
300 for (Int_t idim = 0; idim < ndim; idim++) {
301 TVectorD* vec = (TVectorD*) limits->At(idim);
302 hist->SetBinEdges(idim, vec->GetMatrixArray());
303 }
304
305 // add formulas to list of functions
306 for (Int_t idim = 0; idim < ndim; idim++) {
307 vars[idim]->SetName(Form("axis%dFormula", idim));
308 hist->GetListOfFunctions()->Add(vars[idim]);
309 }
310
311 // store variales in axes
312 // StoreVariables(hist, vars);
313 hist->SetUniqueID(valTypeW); // store weighting variable
314
315 // adapt the name and title of the histogram in case they are empty
316 AdaptNameTitle(hist, histClass);
317
318 // store which variables are used
319 //for(Int_t i=0; i<ndim; i++) fUsedVars->SetBitNumber(vars[i],kTRUE);
320 fUsedVars->SetBitNumber(valTypeW, kTRUE);
321
322 Bool_t isReserved = fReservedWords->Contains(histClass);
323 if (isReserved) UserHistogramReservedWords(histClass, hist);
324 else
325 UserHistogram(histClass, hist);
326 }
327}
328
329//_____________________________________________________________________________
330TString PairAnalysisHistos::UserHistogram(const char* histClass, TObject* hist)
331{
332 //
333 // Add any type of user histogram
334 //
335
336 //special case for the calss Pair. where histograms will be created for all pair classes
337 Bool_t isReserved = fReservedWords->Contains(histClass);
338 if (isReserved) {
339 UserHistogramReservedWords(histClass, hist);
340 return hist->GetName();
341 }
342
343 // if (!IsHistogramOk(histClass,hist->GetName())) return hist->GetName();
344 // THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
345 // // hist->SetDirectory(0);
346
347 // store variables axis
348 UInt_t valType[20] = {0};
349 // extract variables from axis
350 FillVarArray(hist, valType);
351 // TODO: implement THn/PairAnalysisHn
352 // change to mc truth variables if available
353 TString hclass = histClass;
354 if (hclass.Contains("MCtruth") && !(hist->IsA() == PairAnalysisHn::Class())) {
355 for (Int_t i = 0; i < 2; i++) {
357 // UInt_t valTypeFromTitle = 0;
358 if (!i) valType[i] = PairAnalysisVarManager::GetValueType(((TH1*) hist)->GetXaxis()->GetName());
359 else
360 valType[i] = PairAnalysisVarManager::GetValueType(((TH1*) hist)->GetYaxis()->GetName());
361 //Printf("SWITCH TO MC: before: %d %s, (via axis name %d) ---->",valType[i],PairAnalysisVarManager::GetValueName(valType[i]),valTypeFromTitle);
362 valType[i] = PairAnalysisVarManager::GetValueTypeMC(valType[i]);
363 // if theres no corresponding MCtruth variable, skip adding this histogram
364 // if(valType[i] < PairAnalysisVarManager::kNMaxValues && valType[i]>0) return hist->GetName();
365 if (valType[i] < PairAnalysisVarManager::kPairMax && valType[i] > 0) return hist->GetName();
366 // request filling of mc variable
367 fUsedVars->SetBitNumber(valType[i], kTRUE);
368 // Printf("after: %d %s",valType[i],PairAnalysisVarManager::GetValueName(valType[i]));
369 }
370 StoreVariables(hist, valType);
371 hist->SetUniqueID(valType[19]); // store weighting variable
372 // check for formulas
373 if (hist->InheritsFrom(TH1::Class())) {
374 TIter next(((TH1*) hist)->GetListOfFunctions());
375 TFormula* f = 0;
376 while ((f = dynamic_cast<TFormula*>(next()))) {
377 for (Int_t i = 0; i < f->GetNpar(); i++) {
378 Int_t parMC = PairAnalysisVarManager::GetValueTypeMC(f->GetParameter(i));
379 // if theres none corresponding MCtruth variable, skip adding this histogram
380 if (parMC < PairAnalysisVarManager::kNMaxValues) return hist->GetName();
381 f->SetParameter(i, parMC);
382 f->SetParName(i, PairAnalysisVarManager::GetValueName(parMC));
383 fUsedVars->SetBitNumber(parMC, kTRUE);
384 }
385 }
386 // change histogram key according to mctruth information
387 AdaptNameTitle((TH1*) hist, histClass);
388 }
389 }
390 else {
391 StoreVariables(hist, valType);
392 hist->SetUniqueID(valType[19]); // store weighting variable
393 }
394
395 // add histogram to class
396 if (!IsHistogramOk(histClass, hist->GetName())) return hist->GetName();
397 THashList* classTable = (THashList*) fHistoList.FindObject(histClass);
398 // hist->SetDirectory(0);
399 if (classTable) classTable->Add(hist);
400 return hist->GetName();
401}
402
403//_____________________________________________________________________________
404TH1* PairAnalysisHistos::GetTHist(const char* histClass, const char* name, const char* title,
405 const TVectorD* const binsX, const TVectorD* const binsY, const TVectorD* const binsZ)
406{
407 //
408 // retrieve n-dimensional Hist depending on arguments
409 //
410 Bool_t isOk = kTRUE;
411 isOk &= IsHistogramOk(histClass, name);
412 isOk &= (binsX != 0x0);
413 if (!isOk) return 0x0;
414 switch (fPrecision) {
415 case Eprecision::kFloat:
416 if (!binsY) return (new TH1F(name, title, binsX->GetNrows() - 1, binsX->GetMatrixArray()));
417 else if (!binsZ)
418 return (new TH2F(name, title, binsX->GetNrows() - 1, binsX->GetMatrixArray(), binsY->GetNrows() - 1,
419 binsY->GetMatrixArray()));
420 else
421 return (new TH3F(name, title, binsX->GetNrows() - 1, binsX->GetMatrixArray(), binsY->GetNrows() - 1,
422 binsY->GetMatrixArray(), binsZ->GetNrows() - 1, binsZ->GetMatrixArray()));
423 break;
424 case Eprecision::kDouble:
425 if (!binsY) return (new TH1D(name, title, binsX->GetNrows() - 1, binsX->GetMatrixArray()));
426 else if (!binsZ)
427 return (new TH2D(name, title, binsX->GetNrows() - 1, binsX->GetMatrixArray(), binsY->GetNrows() - 1,
428 binsY->GetMatrixArray()));
429 else
430 return (new TH3D(name, title, binsX->GetNrows() - 1, binsX->GetMatrixArray(), binsY->GetNrows() - 1,
431 binsY->GetMatrixArray(), binsZ->GetNrows() - 1, binsZ->GetMatrixArray()));
432 break;
433 default: return 0x0; break;
434 }
435}
436
437//_____________________________________________________________________________
438TH1* PairAnalysisHistos::GetTProf(const char* histClass, const char* name, const char* title,
439 const TVectorD* const binsX, const TVectorD* const binsY, const TVectorD* const binsZ,
440 TString option)
441{
442 //
443 // retrieve n-dimensional profile histogram with error options depending on arguments
444 //
445 Bool_t isOk = kTRUE;
446 isOk &= IsHistogramOk(histClass, name);
447 isOk &= (binsX != 0x0);
448 if (!isOk) return 0x0;
449 // parse error option
450 TString opt = "";
451 Double_t pmin = 0., pmax = 0.;
452 if (!option.IsNull()) {
453 TObjArray* arr = option.Tokenize(";");
454 arr->SetOwner();
455 opt = ((TObjString*) arr->At(0))->GetString();
456 if (arr->GetEntriesFast() > 1) pmin = (((TObjString*) arr->At(1))->GetString()).Atof();
457 if (arr->GetEntriesFast() > 2) pmax = (((TObjString*) arr->At(2))->GetString()).Atof();
458 delete arr;
459 }
460 // build profile with error options and return it
461 TH1* prof = 0x0;
462 if (!binsY)
463 return (new TProfile(name, title, binsX->GetNrows() - 1, binsX->GetMatrixArray(), pmin, pmax, opt.Data()));
464 else if (!binsZ) {
465 prof = new TProfile2D(name, title, binsX->GetNrows() - 1, binsX->GetMatrixArray(), binsY->GetNrows() - 1,
466 binsY->GetMatrixArray());
467 ((TProfile2D*) prof)->BuildOptions(pmin, pmax, opt.Data());
468 return prof;
469 }
470 else {
471 prof = new TProfile3D(name, title, binsX->GetNrows() - 1, binsX->GetMatrixArray(), binsY->GetNrows() - 1,
472 binsY->GetMatrixArray(), binsZ->GetNrows() - 1, binsZ->GetMatrixArray());
473 ((TProfile3D*) prof)->BuildOptions(pmin, pmax, opt.Data());
474 return prof;
475 }
476}
477
478//_____________________________________________________________________________
479TFormula* PairAnalysisHistos::GetFormula(const char* name, const char* formula)
480{
481 //
482 // build a TFormula object
483 //
484 TFormula* form = new TFormula(name, formula);
485 // compile function
486 if (form->Compile()) return 0x0;
487 //set parameter/variable identifier
488 for (Int_t i = 0; i < form->GetNpar(); i++) {
489 form->SetParName(i, PairAnalysisVarManager::GetValueName(form->GetParameter(i)));
490 fUsedVars->SetBitNumber((Int_t) form->GetParameter(i), kTRUE);
491 }
492 return form;
493}
494
495//_____________________________________________________________________________
496void PairAnalysisHistos::AddClass(const char* histClass)
497{
498 //
499 // Add a class of histograms
500 // Several classes can be added by separating them by a ';' e.g. 'class1;class2;class3'
501 //
502 TString hists(histClass);
503 TObjArray* arr = hists.Tokenize(";");
504 TIter next(arr);
505 TObject* o = 0;
506 while ((o = next())) {
507 if (fHistoList.FindObject(o->GetName())) {
508 Warning("AddClass", "Cannot create class '%s' it already exists.", histClass);
509 continue;
510 }
511 if (fReservedWords->Contains(o->GetName())) {
512 Error("AddClass", "Pair is a reserved word, please use another name");
513 continue;
514 }
515 THashList* table = new THashList;
516 table->SetOwner(kTRUE);
517 table->SetName(o->GetName());
518 fHistoList.Add(table);
519 }
520 delete arr;
521}
522
523//_____________________________________________________________________________
524void PairAnalysisHistos::FillClass(TString histClass, const Double_t* values)
525{
526 //
527 // Fill class 'histClass' (by name)
528 //
529 THashList* classTable = (THashList*) fHistoList.FindObject(histClass.Data());
530 if (!classTable) {
531 // Warning("FillClass","Cannot fill class '%s' its not defined.",histClass.Data());
532 return;
533 }
534
535 TIter nextHist(classTable);
536 TObject* obj = 0;
537 while ((obj = (TObject*) nextHist()))
538 FillValues(obj, values);
539
540 return;
541}
542
543//_____________________________________________________________________________
544void PairAnalysisHistos::UserHistogramReservedWords(const char* histClass, const TObject* hist)
545{
546 //
547 // Creation of histogram for all pair or track types
548 //
549 TString title(hist->GetTitle());
550
551 TIter nextClass(&fHistoList);
552 THashList* l = 0;
553 while ((l = static_cast<THashList*>(nextClass()))) {
554 TString name(l->GetName());
555 if (name.Contains(histClass)) {
556 TObject* h = hist->Clone();
557 // Tobject has no function SetDirectory, didn't we need this???
558 // h->SetDirectory(0);
559 if (h->InheritsFrom(TH1::Class())) ((TH1*) h)->SetTitle(Form("%s %s", title.Data(), l->GetName()));
560 else
561 ((THnBase*) h)->SetTitle(Form("%s %s", title.Data(), l->GetName()));
562
563 UserHistogram(l->GetName(), h);
564 }
565 }
566 delete hist;
567
568 return;
569}
570
571//_____________________________________________________________________________
572void PairAnalysisHistos::DumpToFile(const char* file)
573{
574 //
575 // Dump the histogram list to a newly created root file
576 //
577 TFile f(file, "recreate");
578 fHistoList.Write(fHistoList.GetName(), TObject::kSingleKey);
579 f.Close();
580}
581
582//_____________________________________________________________________________
583TObject* PairAnalysisHistos::GetHist(const char* histClass, const char* name) const
584{
585 //
586 // return object 'name' in 'histClass'
587 //
588 THashList* classTable = (THashList*) fHistoList.FindObject(histClass);
589 if (!classTable) return 0x0;
590 return classTable->FindObject(name);
591}
592
593//_____________________________________________________________________________
594TH1* PairAnalysisHistos::GetHistogram(const char* histClass, const char* name) const
595{
596 //
597 // return histogram 'name' in 'histClass'
598 //
599 return ((TH1*) GetHist(histClass, name));
600}
601
602//_____________________________________________________________________________
603TObject* PairAnalysisHistos::GetHist(const char* cutClass, const char* histClass, const char* name) const
604{
605 //
606 // return object from list of list of histograms
607 // this function is thought for retrieving histograms if a list of PairAnalysisHistos is set
608 //
609
610 if (!fList) return 0x0;
611 THashList* h = dynamic_cast<THashList*>(fList->FindObject(cutClass));
612 if (!h) return 0x0;
613 THashList* classTable = dynamic_cast<THashList*>(h->FindObject(histClass));
614 if (!classTable) return 0x0;
615 return classTable->FindObject(name);
616}
617
618//_____________________________________________________________________________
619TH1* PairAnalysisHistos::GetHistogram(const char* cutClass, const char* histClass, const char* name) const
620{
621 //
622 // return histogram from list of list of histograms
623 // this function is thought for retrieving histograms if a list of PairAnalysisHistos is set
624 //
625 return ((TH1*) GetHist(cutClass, histClass, name));
626}
627
628//_____________________________________________________________________________
629void PairAnalysisHistos::Draw(const Option_t* option)
630{
631 //
632 // Draw histograms
633 //
634
635 TString drawStr(option);
636 TObjArray* arr = drawStr.Tokenize(";");
637 arr->SetOwner();
638 TIter nextOpt(arr);
639
640 TString drawClasses;
641 TObjString* ostr = 0x0;
642
643 TString currentOpt;
644 TString testOpt;
645 while ((ostr = (TObjString*) nextOpt())) {
646 currentOpt = ostr->GetString();
647 currentOpt.Remove(TString::kBoth, '\t');
648 currentOpt.Remove(TString::kBoth, ' ');
649
650 testOpt = "classes=";
651 if (currentOpt.Contains(testOpt.Data())) { drawClasses = currentOpt(testOpt.Length(), currentOpt.Length()); }
652 }
653
654 delete arr;
655 drawStr.ToLower();
656 //optionsfList
657 // Bool_t same=drawOpt.Contains("same"); //FIXME not yet implemented
658
659 TCanvas* c = 0x0;
660 if (gVirtualPS) {
661 if (!gPad) {
662 Error("Draw", "When writing to a file you have to create a canvas before opening "
663 "the file!!!");
664 return;
665 }
666 c = gPad->GetCanvas();
667 c->cd();
668 // c=new TCanvas;
669 }
670
671 TIter nextClass(&fHistoList);
672 THashList* classTable = 0;
673 // Bool_t first=kTRUE;
674 while ((classTable = (THashList*) nextClass())) {
675 //test classes option
676 if (!drawClasses.IsNull() && !drawClasses.Contains(classTable->GetName())) continue;
677 //optimised division
678 Int_t nPads = classTable->GetEntries();
679 Int_t nCols = (Int_t) TMath::Ceil(TMath::Sqrt(nPads));
680 Int_t nRows = (Int_t) TMath::Ceil((Double_t) nPads / (Double_t) nCols);
681
682 //create canvas
683 if (!gVirtualPS) {
684 TString canvasName;
685 canvasName.Form("c%s_%s", GetName(), classTable->GetName());
686 c = (TCanvas*) gROOT->FindObject(canvasName.Data());
687 if (!c) c = new TCanvas(canvasName.Data(), Form("%s: %s", GetName(), classTable->GetName()));
688 c->Clear();
689 }
690 else {
691 // if (first){
692 // first=kFALSE;
693 // if (nPads>1) gVirtualPS->NewPage();
694 // } else {
695 if (nPads > 1) c->Clear();
696 // }
697 }
698 if (nCols > 1 || nRows > 1) c->Divide(nCols, nRows);
699
700 //loop over histograms and draw them
701 TIter nextHist(classTable);
702 Int_t iPad = 0;
703 TH1* h = 0;
704 while ((h = (TH1*) nextHist())) {
705 TString drawOpt;
706 if ((h->InheritsFrom(TH2::Class()))) drawOpt = "colz";
707 if (nCols > 1 || nRows > 1) c->cd(++iPad);
708 if (TMath::Abs(h->GetXaxis()->GetBinWidth(1) - h->GetXaxis()->GetBinWidth(2)) > 1e-10) gPad->SetLogx();
709 if (TMath::Abs(h->GetYaxis()->GetBinWidth(1) - h->GetYaxis()->GetBinWidth(2)) > 1e-10) gPad->SetLogy();
710 if (TMath::Abs(h->GetZaxis()->GetBinWidth(1) - h->GetZaxis()->GetBinWidth(2)) > 1e-10) gPad->SetLogz();
711 TString histOpt = h->GetOption();
712 histOpt.ToLower();
713 if (histOpt.Contains("logx")) gPad->SetLogx();
714 if (histOpt.Contains("logy")) gPad->SetLogy();
715 if (histOpt.Contains("logz")) gPad->SetLogz();
716 histOpt.ReplaceAll("logx", "");
717 histOpt.ReplaceAll("logy", "");
718 histOpt.ReplaceAll("logz", "");
719 h->Draw(drawOpt.Data());
720 }
721 if (gVirtualPS) { c->Update(); }
722 }
723 // if (gVirtualPS) delete c;
724}
725
726//_____________________________________________________________________________
727void PairAnalysisHistos::Print(const Option_t* option) const
728{
729 //
730 // Print classes and histograms
731 //
732 TString optString(option);
733
734 if (optString.IsNull()) PrintStructure();
735}
736
737//_____________________________________________________________________________
738void PairAnalysisHistos::PrintStructure() const
739{
740 //
741 // Print classes and histograms in the class to stdout
742 //
743 if (!fList) {
744 TIter nextClass(&fHistoList);
745 THashList* classTable = 0;
746 while ((classTable = (THashList*) nextClass())) {
747 TIter nextHist(classTable);
748 TObject* o = 0;
749 Printf("+ %s\n", classTable->GetName());
750 while ((o = nextHist()))
751 Printf("| ->%s\n", o->GetName());
752 }
753 }
754 else {
755 TIter nextCutClass(fList);
756 THashList* cutClass = 0x0;
757 while ((cutClass = (THashList*) nextCutClass())) {
758 TString cla = cutClass->GetName();
759 if (cla.Contains("QAcuts")) continue;
760 Printf("+ %s\n", cutClass->GetName());
761 TIter nextClass(cutClass);
762 THashList* classTable = 0;
763 while ((classTable = (THashList*) nextClass())) {
764 TIter nextHist(classTable);
765 TObject* o = 0;
766 Printf("| + %s\n", classTable->GetName());
767 while ((o = nextHist()))
768 Printf("| | ->%s\n", o->GetName());
769 }
770 }
771 }
772}
773
774//_____________________________________________________________________________
775void PairAnalysisHistos::SetHistogramList(THashList& list, Bool_t setOwner /*=kTRUE*/)
776{
777 //
778 // set histogram classes and histograms to this instance. It will take onwnership!
779 //
780 ResetHistogramList();
781 TString name(GetName());
782 // if (name == "PairAnalysisHistos")
783 SetName(list.GetName());
784 TIter next(&list);
785 TObject* o;
786 while ((o = next())) {
787 fHistoList.Add(o);
788 }
789 if (setOwner) {
790 list.SetOwner(kFALSE);
791 fHistoList.SetOwner(kTRUE);
792 fHistoList.SetName(list.GetName());
793 }
794 else {
795 fHistoList.SetOwner(kFALSE);
796 fHistoList.SetName(list.GetName());
797 }
798}
799
800//_____________________________________________________________________________
801Bool_t PairAnalysisHistos::SetCutClass(const char* cutClass)
802{
803 //
804 // Assign histogram list according to cutClass
805 //
806
807 if (!fList) return kFALSE;
808 ResetHistogramList();
809 THashList* h = dynamic_cast<THashList*>(fList->FindObject(cutClass));
810 if (!h) {
811 Warning("SetCutClass", "cutClass '%s' not found", cutClass);
812 return kFALSE;
813 }
814 SetHistogramList(*h, kFALSE);
815 return kTRUE;
816}
817//_____________________________________________________________________________
818Bool_t PairAnalysisHistos::IsHistogramOk(const char* histClass, const char* name)
819{
820 //
821 // check whether the histogram class exists and the histogram itself does not exist yet
822 //
823 Bool_t isReserved = fReservedWords->Contains(histClass);
824 if (!fHistoList.FindObject(histClass) && !isReserved) {
825 Warning("IsHistogramOk",
826 "Cannot create histogram. Class '%s' not defined. Please create it "
827 "using AddClass before.",
828 histClass);
829 return kFALSE;
830 }
831 if (GetHist(histClass, name)) {
832 Warning("IsHistogramOk", "Cannot create histogram '%s' in class '%s': It already exists!", name, histClass);
833 return kFALSE;
834 }
835 return kTRUE;
836}
837
838// //_____________________________________________________________________________
839// TIterator* PairAnalysisHistos::MakeIterator(Bool_t dir) const
840// {
841// //
842// //
843// //
844// return new TListIter(&fHistoList, dir);
845// }
846
847//_____________________________________________________________________________
848void PairAnalysisHistos::ReadFromFile(const char* file, const char* task, const char* config)
849{
850 //
851 // Read histos from file
852 //
853 TFile f(file);
854 TIter nextKey(f.GetListOfKeys());
855 TKey* key = 0;
856 while ((key = (TKey*) nextKey())) {
857 TString name = key->GetName();
858 // check for meta data
859 if (name.Contains(Form("PairAnalysisMetaData_%s", task))) {
860 fMetaData = new PairAnalysisMetaData();
861 fMetaData->SetMetaData(*dynamic_cast<TList*>(f.Get(key->GetName())), kFALSE);
862 }
863 // check for histos
864 if (!name.Contains(Form("PairAnalysisHistos_%s", task))) continue;
865 if (!strlen(task) && !name.Contains(task)) continue;
866 TObject* o = f.Get(key->GetName());
867 TList* list = dynamic_cast<TList*>(o);
868 if (!list) continue;
869 else
870 fList = list;
871 THashList* listCfg = dynamic_cast<THashList*>(list->FindObject(config));
872 if (!listCfg) continue;
873 SetHistogramList(*listCfg);
874 break;
875 }
876 f.Close();
877 // load style
879}
880
881//_____________________________________________________________________________
882TObjArray* PairAnalysisHistos::DrawTaskSame(TString histName, TString opt, TString histClassDenom, TString taskDenom)
883{
893
894
895 TObjArray* selections = histClassDenom.Tokenize(":;,");
896
897 opt.ToLower();
898 TString optString(opt);
899 Bool_t optGoff = optString.Contains("goff");
900 Bool_t optEff = optString.Contains("eff");
901 Bool_t optCutStep = optString.Contains("cutstep");
902 Bool_t optSelCfg = optString.Contains("selcfg");
903 opt.ReplaceAll("selcfg", "");
904 fHistoList.SetOwner(kFALSE);
905
907 TObjArray* arr = NULL;
908 if (optGoff) Info("DrawTaskSame", "graphics option off, collect an array");
909 {
910 // arr=(TObjArray*)gROOT->FindObject(Form("%s",histName.Data()));
911 //arr=(TObjArray*)gROOT->FindObject(GetName());
912 // if(arr) { Warning("DrawTaskSame","Clear existing array %s",GetName()); arr->ls(); arr->Clear(); }
913 // else
914 arr = new TObjArray();
915 // arr->SetName(Form("%s",histName.Data()));
916 arr->SetName(GetName());
917 arr->SetOwner(kFALSE);
918 }
919
921 TString legendname = GetName();
922 // printf("DrawTaskSame: legendname %s\n",legendname.Data());
923
925 TObjArray* reservedWords = fReservedWords->Tokenize(":;");
926
928 if (optCutStep) {
929 TString cutstepTask = fHistoList.GetName();
930 THashList* listCutStep = dynamic_cast<THashList*>(fList->FindObject(cutstepTask));
931 if (listCutStep) fList = listCutStep;
932 }
933
935 THashList* listDenom = dynamic_cast<THashList*>(fList->FindObject(taskDenom.Data()));
936 if (listDenom) opt += "div";
937
939 TIter nextCfg(fList);
940 THashList* listCfg = 0;
941 while ((listCfg = static_cast<THashList*>(nextCfg()))) {
942
943 TString lname = listCfg->GetName();
944
946 if (lname.Contains("QAcuts_")) continue;
947 Info("DrawTaskSame", " Task name %s ", lname.Data());
948
950 if (!optEff && listDenom && lname.EqualTo(taskDenom)) continue;
951
953 if (optSelCfg && selections->GetEntriesFast()) {
954 Bool_t pass = kFALSE;
955 for (Int_t is = 0; is < selections->GetEntriesFast(); is++) {
956 Bool_t testIgnore = kFALSE;
957 TString raw = ((TObjString*) selections->At(is))->GetString();
958
959 // printf("sel: '%s' \n", histClassDenom.Data());
960
963 for (Int_t ir = 0; ir < reservedWords->GetEntriesFast(); ir++) {
964 testIgnore = raw.Contains(((TObjString*) reservedWords->At(ir))->GetString());
965 if (testIgnore) break;
966 }
967 if (testIgnore) continue;
968
969 TString srch = raw;
970 srch.ReplaceAll("!", "");
971 Bool_t optExclSel = !(srch.EqualTo(raw)); // exclude or not
972 // printf("selection %d/%d: raw '%s' \t search: '%s' exclude: %d compare to: '%s' \t pass %d \n",
973 // is,selections->GetEntriesFast()-1,raw.Data(),srch.Data(),optExclSel,lname.Data(),pass);
974 // printf("\t decision !(%d^%d)=%d \n",(!lname.EqualTo(srch)),(optExclSel),!(!lname.EqualTo(srch))^(optExclSel));
976 if (!(!lname.EqualTo(srch)) ^ (optExclSel)) pass = kTRUE;
978 if (lname.EqualTo(srch)) {
979 pass = !(!lname.EqualTo(srch)) ^ (optExclSel);
980 // printf("\t same config found -> stop with pass: %d \n",pass);
981 break;
982 }
983 // remove config selection string abgearbeitet
984 // histClassDenom.ReplaceAll(raw.Data(),"");
985 }
986 if (!pass) continue;
987 }
988
990 if (lname.EqualTo(legendname)) legendname = "";
991
993 ResetHistogramList();
994 TIter next(listCfg);
995 Int_t idx = 0;
996 TObject* o;
997 while ((o = next())) {
998 fHistoList.AddAt(o, idx++);
999 }
1000 //fHistoList.Print();
1001
1003 SetName(listCfg->GetName());
1004 arr->AddAll(DrawSame(histName, (opt + "task").Data(), histClassDenom, listDenom));
1005 }
1006
1008 if (optString.Contains("leg")) {
1009 // printf("DrawTaskSame: SET legendname %s\n",legendname.Data());
1010 legendname.ReplaceAll(".", "");
1011 TList* prim = gPad->GetListOfPrimitives();
1012 TLegend* leg = (TLegend*) prim->FindObject("TPave");
1013 // remove legend header from legend entry
1014 TList* llist = leg->GetListOfPrimitives();
1015 Int_t nent = llist->GetEntries();
1016 for (Int_t il = 0; il < nent; il++) {
1017 TLegendEntry* lent = static_cast<TLegendEntry*>(llist->At(il));
1018 TString lst(lent->GetLabel());
1019 lst.ReplaceAll(legendname.Data(), "");
1020 lent->SetLabel(lst.Data());
1021 }
1022
1023 if (!legendname.EqualTo("none")) leg->SetHeader("");
1024 else
1025 leg->SetHeader(legendname.Data());
1026 PairAnalysisStyler::SetLegendAttributes(leg); // coordinates, margins, fillstyle, fontsize
1027 leg->Draw();
1028 }
1029
1031 if (selections) delete selections;
1032 if (reservedWords) delete reservedWords;
1033 if (!optGoff) delete arr;
1034
1035 return arr;
1036}
1037
1038//_____________________________________________________________________________
1039TObjArray* PairAnalysisHistos::DrawSame(TString histName, TString option, TString histClassDenom, THashList* listDenom)
1040{
1087
1088 TString optString(option);
1089 optString.ToLower();
1090 printf("Plot hist: '%s' class-denom/sel: '%s' \t listDenom: '%s' \t options: "
1091 "'%s' \n",
1092 histName.Data(), histClassDenom.Data(), (listDenom ? listDenom->GetName() : ""), optString.Data());
1093 Bool_t optBack = optString.Contains("back");
1094 optString.ReplaceAll("back", "");
1095 Bool_t optGoff = optString.Contains("goff");
1096 optString.ReplaceAll("goff", "");
1097 Bool_t optTask = optString.Contains("task");
1098 optString.ReplaceAll("task", "");
1099 Bool_t optCutStep = optString.Contains("cutstep");
1100 optString.ReplaceAll("cutstep", "");
1102 Bool_t optDiv = optString.Contains("div");
1103 optString.ReplaceAll("div", "");
1104 Bool_t optEff = optString.Contains("eff");
1105 optString.ReplaceAll("eff", "");
1106 Bool_t optRatio = optString.Contains("ratio");
1107 optString.ReplaceAll("ratio", "");
1108 Bool_t optOneOver = optString.Contains("oneover");
1109 optString.ReplaceAll("oneover", "");
1111 Bool_t optNoMCtrue = optString.Contains("nomctrue");
1112 optString.ReplaceAll("nomctrue", "");
1113 Bool_t optNoMC = optString.Contains("nomc");
1114 optString.ReplaceAll("nomc", "");
1115 Bool_t optOnlyMCtrue = optString.Contains("onlymctrue");
1116 optString.ReplaceAll("onlymctrue", "");
1117 Bool_t optOnlyMC = optString.Contains("onlymc");
1118 optString.ReplaceAll("onlymc", "");
1119 Bool_t optSel = optString.Contains("sel");
1120 optString.ReplaceAll("sel", "");
1122 Bool_t optCan = optString.Contains("can");
1123 optString.ReplaceAll("can", "");
1124 Bool_t optLegFull = optString.Contains("legf");
1125 optString.ReplaceAll("legf", "");
1126 Bool_t optLeg = optString.Contains("leg");
1127 optString.ReplaceAll("leg", "");
1128 Bool_t optDet = optString.Contains("det");
1129 optString.ReplaceAll("det", "");
1130 Bool_t optMeta = optString.Contains("meta");
1131 optString.ReplaceAll("meta", "");
1132 Bool_t optWdth = optString.Contains("width");
1133 optString.ReplaceAll("width", "");
1134 Bool_t optRbnStat = optString.Contains("rebinstat");
1135 optString.ReplaceAll("rebinstat", "stat");
1136 Bool_t optRbn = optString.Contains("rebin");
1137 Bool_t optSmooth = optString.Contains("smooth");
1138 Bool_t optSclMax = optString.Contains("sclmax");
1139 optString.ReplaceAll("sclmax", "");
1140 Bool_t optNormY = optString.Contains("normy");
1141 optString.ReplaceAll("normy", "");
1142 Bool_t optNorm = optString.Contains("norm");
1143 optString.ReplaceAll("norm", "");
1144 Bool_t optCumR = optString.Contains("cumr");
1145 optString.ReplaceAll("cumr", "");
1146 Bool_t optCum = optString.Contains("cum");
1147 optString.ReplaceAll("cum", "");
1148 Bool_t optEvt = optString.Contains("events");
1149 optString.ReplaceAll("events", "");
1150 Bool_t optStack = optString.Contains("stack");
1151 optString.ReplaceAll("stack", "");
1152 Bool_t optRstSty = optString.Contains("rststy");
1153 optString.ReplaceAll("rststy", "");
1154 Bool_t optSlicesY = optString.Contains("slicesy");
1155 optString.ReplaceAll("slicesy", "");
1157 Bool_t optMeanX = optString.Contains("meanx");
1158 optString.ReplaceAll("meanx", "");
1159 Bool_t optRmsX = optString.Contains("rmsx");
1160 optString.ReplaceAll("rmsx", "");
1161 Bool_t optMeanY = optString.Contains("meany");
1162 optString.ReplaceAll("meany", "");
1163 Bool_t optRmsY = optString.Contains("rmsy");
1164 optString.ReplaceAll("rmsy", "");
1165 Bool_t optGeant = optString.Contains("geant");
1166 optString.ReplaceAll("geant", "");
1167 Bool_t optPdgClean = optString.Contains("pdgc");
1168 optString.ReplaceAll("pdgc", "");
1169 Bool_t optPdg = optString.Contains("pdg");
1170 optString.ReplaceAll("pdg", "");
1171
1173 Int_t rbn = 2;
1174 if (optRbn) {
1175 TString rebin(optString(optString.Index("rebin", 5, 0, TString::kExact) + 5));
1176 if (rebin.IsDigit()) {
1177 rbn = rebin.Atoi();
1178 optString.ReplaceAll(rebin, "");
1179 }
1180 optString.ReplaceAll("rebin", "");
1181 }
1184 TArrayD* limits = NULL;
1185 Double_t stat = 0.8;
1186 if (optRbnStat) {
1187 TString rebin(optString(optString.Index("stat", 4, 0, TString::kExact) + 4, 4));
1188 if (!rebin.IsFloat()) rebin = optString(optString.Index("stat", 4, 0, TString::kExact) + 4, 3);
1189 if (rebin.IsFloat()) {
1190 stat = rebin.Atof();
1191 // printf("rebinstat string: '%s' -> %f\n",rebin.Data(),stat);
1192 optString.ReplaceAll(rebin, "");
1193 }
1194 optString.ReplaceAll("stat", "");
1195 }
1196
1198 Int_t smth = 1;
1199 if (optSmooth) {
1200 TString smooth(optString(optString.Index("smooth", 6, 0, TString::kExact) + 6));
1201 if (smooth.IsDigit()) {
1202 smth = smooth.Atoi();
1203 optString.ReplaceAll(smooth, "");
1204 }
1205 optString.ReplaceAll("smooth", "");
1206 }
1207
1209 if (optLegFull) optLeg = kTRUE;
1210 if (optCumR) optCum = kTRUE;
1211
1213 TString select("");
1214 TObjArray* selections = (optSel ? histClassDenom.Tokenize(":;,") : NULL);
1215 if (optSel) histClassDenom = "";
1216
1218 TObjArray* arr = 0x0;
1219 if (optGoff) {
1220 Info("DrawSame", "graphics option off, collect an array");
1221 // arr=(TObjArray*)gROOT->FindObject(Form("%s",histName.Data()));
1222 arr = (TObjArray*) gROOT->FindObject(GetName());
1223 if (arr) {
1224 Warning("DrawSame", "Clear existing array %s", GetName());
1225 arr->ls();
1226 arr->Clear();
1227 }
1228 else
1229 arr = new TObjArray();
1230 // arr->SetName(Form("%s",histName.Data()));
1231 arr->SetName(GetName());
1232 arr->SetOwner(kFALSE);
1233 }
1234
1236 THStack* hs = NULL;
1237 // if(optStack) {
1238 // hs = new THStack("hs","stacked histograms");
1239 // }
1240
1242 TCanvas* c = 0;
1243 if (optCan) {
1244 c = (TCanvas*) gROOT->FindObject(Form("c%s", histName.Data()));
1245 if (!c) { c = new TCanvas(Form("c%s", histName.Data()), Form("All '%s' histograms", histName.Data())); }
1246 // c->Clear();
1247 c->cd();
1248 }
1249
1251 TH1* hFirst = 0x0;
1252 TObject* obj;
1253 Int_t nobj = 0;
1254 TList* prim = (gPad ? gPad->GetListOfPrimitives() : 0x0);
1255 // if(prim) prim->ls();
1256 // if(prim && prim->GetSize()>1 && !optGoff) prim->RemoveLast(); // remove redraw axis histogram
1257 for (Int_t io = 0; io < (prim ? prim->GetSize() : 0); io++) {
1258 obj = prim->At(io);
1259 if (obj->InheritsFrom(TH1::Class()) && obj != prim->At(io + 1)) nobj++;
1260 if (obj->InheritsFrom(THStack::Class()) && obj != prim->At(io + 1)) nobj++;
1261 if (nobj == 1) hFirst = (TH1*) obj;
1262 }
1263
1265 TLegend* leg = 0;
1266 if ((optLeg && !nobj)) {
1267 leg = new TLegend(0. + gPad->GetLeftMargin() + gStyle->GetTickLength("Y"),
1268 0. + gPad->GetBottomMargin() + gStyle->GetTickLength("X"),
1269 1. - gPad->GetRightMargin() + gStyle->GetTickLength("Y"),
1270 1. - gPad->GetTopMargin() + gStyle->GetTickLength("X"), GetName(), "nbNDC");
1271 if (optTask && !optCutStep) leg->SetHeader("");
1272 }
1273 else if (nobj) {
1274 leg = (TLegend*) prim->FindObject("TPave");
1275 // leg->SetX1(0. + gPad->GetLeftMargin() + gStyle->GetTickLength("Y"));
1276 // leg->SetY1(0. + gPad->GetBottomMargin()+ gStyle->GetTickLength("X"));
1277 // leg->SetX2(1. - gPad->GetRightMargin() + gStyle->GetTickLength("Y"));
1278 // leg->SetY2(1. - gPad->GetTopMargin() + gStyle->GetTickLength("X"));
1279 // leg->SetOption("nbNDC");
1280 }
1281
1282 Info("DrawSame", "Basics: nobj: %d \t leg: %p", nobj, leg);
1283
1285 if (optString.Contains("logx")) gPad->SetLogx();
1286 if (optString.Contains("logy")) gPad->SetLogy();
1287 if (optString.Contains("logz")) gPad->SetLogz();
1288 optString.ReplaceAll("logx", "");
1289 optString.ReplaceAll("logy", "");
1290 optString.ReplaceAll("logz", "");
1291
1293 Int_t events = 1;
1294 if (fMetaData && optEvt) fMetaData->GetMeta("events", &events);
1295
1296 Int_t i = nobj;
1297 if (optTask && nobj) i = nobj;
1298 TListIter next(&fHistoList, (optBack ? kIterBackward : kIterForward));
1299 //TIter next(&fHistoList);
1300 THashList* classTable = 0;
1301 // TH1 *hFirst=0x0;
1303 while ((classTable = (THashList*) next())) {
1304 TString histClass = classTable->GetName();
1305
1306 Int_t ndel = histClass.CountChar('_');
1307 Info("DrawSame",
1308 "Search for hist: '%s' class-denom: '%s' select: '%s' \t ndel: %d \t "
1309 "for class: '%s'",
1310 histName.Data(), histClassDenom.Data(), select.Data(), ndel, histClass.Data());
1311
1313 if ((optNoMC && ndel > 0) || (optEff && ndel < 1) || (optNoMCtrue && histClass.Contains("_MCtruth"))
1314 || (optOnlyMC && ndel < 1) || (optOnlyMCtrue && ndel < 2))
1315 continue;
1316
1318 if (optSel && selections->GetEntriesFast()) {
1319 Bool_t pass = kFALSE;
1320 for (Int_t is = 0; is < selections->GetEntriesFast(); is++) {
1321 TString raw = ((TObjString*) selections->At(is))->GetString();
1322 TString srch = raw;
1323 srch.ReplaceAll("!", "");
1324 Bool_t optExclSel = !(srch.EqualTo(raw)); // exclude or not
1326 if (!(!histClass.Contains(srch, TString::kIgnoreCase)) ^ (optExclSel)) pass = kTRUE;
1328 if (histClass.EqualTo(srch, TString::kIgnoreCase)) {
1329 pass = !(!histClass.EqualTo(srch, TString::kIgnoreCase)) ^ (optExclSel);
1330 break;
1331 }
1332 }
1333 if (!pass) continue;
1334 }
1335
1336
1339 TH1* h = (TH1*) classTable->FindObject(histName.Data());
1340 if (!h && !optNoMC && !optNoMCtrue) {
1342 TString histdenomMC = histName + "MC";
1343 h = (TH1*) classTable->FindObject(histdenomMC.Data());
1344 }
1345 if (!h) continue;
1346 if (h->GetEntries() < 1.) continue;
1347
1349 if (optEff && !histClass.Contains("_MCtruth")) histClassDenom = histClass + "_MCtruth";
1350 Info("DrawSame", " Hist found in histClass '%s' (search for denom '%s') ", histClass.Data(), histClassDenom.Data());
1351
1353 if ((optEff || optRatio) /*&& !optTask*/
1354 && (histClass.EqualTo(histClassDenom) || !fHistoList.FindObject(histClassDenom.Data())))
1355 continue;
1356 else if (!histClassDenom.IsNull())
1357 Info("DrawSame", " Denom histClass '%s' found ", histClassDenom.Data());
1358
1360 if (i == 0 && !hFirst) hFirst = h;
1361
1363 if (optRbn || optRbnStat)
1364 Info("DrawSame", " Rebin by %d, to <%.1f%% stat. uncertainty per bin", (optRbn ? rbn : 0),
1365 (optRbnStat ? stat * 100 : 0));
1366 if (optNormY || optNorm || optEvt)
1367 Info("DrawSame", " Normalize in y-axis,2D's only(%d), by int.(%d), by #events(%d)", optNormY, optNorm, optEvt);
1368 if (optSclMax) Info("DrawSame", " Scale to maximum(%d)", optSclMax);
1369 if (optCum)
1370 Info("DrawSame",
1371 " Cumulate sum of bins along x-axis, 1D's left-to-right(%d), "
1372 "right-to-left(%d)",
1373 !optCumR, optCumR);
1374
1376 h->Sumw2();
1377 if (optRbn && h->InheritsFrom(TH2::Class())) h = ((TH2*) h)->RebinX(rbn, h->GetName());
1378 else if (optRbn)
1379 h->Rebin(rbn);
1380 if (optNormY && h->GetDimension() == 2 && !(h->GetSumOfWeights() == 0) && !optCum)
1382 if (optRbnStat && h->GetDimension() == 1) {
1385 h = h->Rebin(limits->GetSize() - 1, h->GetName(), limits->GetArray());
1386 h->Scale(1., "width");
1387 // delete limits;
1388 }
1389 if (optCum) PairAnalysisHelper::Cumulate(h, optCumR, optNorm);
1390 if (optSmooth) h->Smooth(smth);
1391
1393 TString ytitle = h->GetYaxis()->GetTitle();
1394 TString ztitle = h->GetZaxis()->GetTitle();
1395 if (ytitle.Contains("{evt}")) optEvt = kFALSE;
1396
1397 if (optNorm && !(h->GetSumOfWeights() == 0) && !optCum)
1398 h = h->DrawNormalized(i > 0 ? (optString + "same").Data() : optString.Data());
1399 if (optEvt) h->Scale(1. / events);
1400 if (optSclMax) h->Scale(1. / h->GetBinContent(h->GetMaximumBin()));
1401
1403 switch (h->GetDimension()) {
1404 case 1:
1405 if (optEvt) h->SetYTitle((ytitle + "/N_{evt}").Data());
1406 if (optNorm) h->SetYTitle((ytitle.Append(" (normalized)")).Data());
1407 if (optCum) h->SetYTitle((ytitle.Prepend("cumulated ")).Data());
1408 if (optRatio) h->SetYTitle("ratio");
1409 if (optDiv) h->SetYTitle("ratio");
1410 if (optEff) h->SetYTitle("acceptance #times efficiency");
1411 if (optSclMax) h->SetYTitle((ytitle + "/N_{max}").Data());
1412 break;
1413 case 2:
1414 if (optEvt) h->SetZTitle((ztitle + "/N_{evt}").Data());
1415 // if(optNormY) h->SetYTitle( (ytitle.Append(" (normalized)")).Data() );
1416 if (optNorm) h->SetZTitle((ztitle.Prepend("normalized ")).Data());
1417 if (optRatio) h->SetZTitle("ratio");
1418 if (optDiv) h->SetZTitle("ratio");
1419 if (optEff) h->SetZTitle("acceptance #times efficiency");
1420 if (optSclMax) h->SetZTitle((ztitle + "/N_{max}").Data());
1421 break;
1422 }
1423
1425 if ((optEff || optRatio) && !optNorm && !optEvt && !optTask) {
1426 Info("DrawSame", " Calculate '%s' w/o normalisation and within the same task", (optEff ? "efficiency" : "ratio"));
1427 // TString clMC = histClass+"_MCtruth";
1428 THashList* clDenom = (THashList*) fHistoList.FindObject(histClassDenom.Data());
1429 TH1* hMC = (TH1*) h->Clone(); // needed to preserve the labeling of non-mc histogram
1430 TString histdenomMC = UserHistogram(histClassDenom.Data(), hMC);
1431 TH1* hdenom = (TH1*) clDenom->FindObject(histdenomMC.Data());
1432 if (!hdenom) {
1433 Error("DrawSame", "Denominator object not found");
1434 continue;
1435 }
1436 Info("DrawSame", " Divide %s(#=%.3e) by %s(#=%.3e)", h->GetName(), h->GetEntries(), hdenom->GetName(),
1437 hdenom->GetEntries());
1438 delete hMC; //delete the surplus object
1439 // normalize and rebin only once
1440 hdenom->Sumw2(); //why is it crashing here
1441 if (optRbnStat && (optEff || !(i % 10))) {
1442 hdenom = hdenom->Rebin(limits->GetSize() - 1, hdenom->GetName(), limits->GetArray());
1443 hdenom->Scale(1., "width");
1444 }
1445 if (optRbn && (optEff || !(i % 10))) hdenom->RebinX(rbn);
1446 if (optEvt && (optEff || !(i % 10))) hdenom->Scale(1. / events);
1447 if (!hdenom || !h->Divide(hdenom)) {
1448 Warning("DrawSame(eff/ratio)", "Division failed!!!!");
1449 continue;
1450 }
1451 }
1452 else if (optTask && (optDiv || optEff || optRatio)) {
1453 Info("DrawSame", " Calculate '%s' using different tasks",
1454 (optEff ? "efficiency" : (optRatio ? "ratio" : "divison")));
1455 // denominators
1456 TH1* hdenom = 0x0;
1457 TH1* htden = 0x0;
1458 if (optEff || optRatio) {
1459 THashList* clDenom = (THashList*) fHistoList.FindObject(histClassDenom.Data());
1460 TH1* hMC = (TH1*) h->Clone(); // needed to preserve the labeling of non-mc histogram
1461 TString histdenomMC = UserHistogram(histClassDenom.Data(), hMC);
1462 //delete the surplus object
1463 delete hMC;
1464
1465 if (clDenom) { hdenom = (TH1*) clDenom->FindObject(histdenomMC.Data()); }
1466
1467 if (listDenom) {
1468 THashList* clTaskDen = (THashList*) listDenom->FindObject(histClassDenom.Data());
1469 if (clTaskDen) {
1470 // htden=(TH1*)clTaskDen->FindObject(hdenom->GetName());
1471 htden = (TH1*) clTaskDen->FindObject(histdenomMC.Data());
1472 Info("DrawSame",
1473 "calculate eff/ratio using task-denom: '%s' class-denom: '%s' "
1474 "hist-denom: '%s'",
1475 listDenom->GetName(), histClassDenom.Data(), histdenomMC.Data());
1476 // keep only one of them, otherwise you might divide the same objects twice
1477 if (htden) hdenom = 0x0;
1478 }
1479 }
1480
1481 } // optEff || optRatio
1482
1483
1484 // task ratio
1485 TH1* htnom = 0x0;
1486 if (optDiv && !optEff) {
1487 Info("DrawSame", " Search for '%s' in task '%s'", histClass.Data(), listDenom->GetName());
1488 THashList* clTaskNom = (THashList*) listDenom->FindObject(histClass.Data());
1489 if (!clTaskNom) continue;
1490 htnom = (TH1*) clTaskNom->FindObject(histName.Data());
1491 if (!htnom) continue;
1492 }
1493
1494 if (hdenom) hdenom->Sumw2();
1495 if (htden) htden->Sumw2();
1496 if (htnom) htnom->Sumw2();
1497
1499 Int_t nbinsh = (h ? h->GetNbinsX() : -1);
1500 Int_t nbinsd = (hdenom ? hdenom->GetNbinsX() : -2);
1501 Int_t nbinstd = (htden ? htden->GetNbinsX() : -3);
1502 Int_t nbinstn = (htnom ? htnom->GetNbinsX() : -4);
1503
1504 // normalize and rebin only once
1505 if (optRbn) {
1506 if (hdenom && nbinsd > nbinsh) hdenom->RebinX(rbn);
1507 if (htden && nbinstd > nbinsh) htden->RebinX(rbn);
1508 if (htnom && nbinstn > nbinsh) htnom->RebinX(rbn);
1509 }
1510 if (optRbnStat) {
1511 if (hdenom && nbinsd > nbinsh) {
1512 hdenom = hdenom->Rebin(limits->GetSize() - 1, hdenom->GetName(), limits->GetArray());
1513 hdenom->Scale(1., "width");
1514 }
1515 if (htden && nbinstd > nbinsh) {
1516 htden = htden->Rebin(limits->GetSize() - 1, htden->GetName(), limits->GetArray());
1517 htden->Scale(1., "width");
1518 }
1519 if (htnom && nbinstn > nbinsh) {
1520 htnom = htnom->Rebin(limits->GetSize() - 1, htnom->GetName(), limits->GetArray());
1521 htnom->Scale(1., "width");
1522 }
1523 }
1524
1525 if (optEvt && !i) {
1526 if (hdenom) hdenom->Scale(1. / events);
1527 if (htden) htden->Scale(1. / events);
1528 if (htnom) htnom->Scale(1. / events);
1529 }
1530
1531 Info("DrawSame",
1532 " Use nominator (%p,#=%.3e) and denominator 'same task & different "
1533 "class'(%p,#=%.3e), 'certain task & different class'(%p,#=%.3e), "
1534 "'certain task & same class'(%p,#=%.3e)",
1535 h, h->GetEntries(), hdenom, (hdenom ? hdenom->GetEntries() : 0), htden, (htden ? htden->GetEntries() : 0),
1536 htnom, (htnom ? htnom->GetEntries() : 0));
1537 // Printf("h %p (bins%d) \t hdenom %p (bins%d) \t htdenom %p (bins%d) \t htnom %p (bins%d)",
1538 // h,h->GetNbinsX(),hdenom,(hdenom?hdenom->GetNbinsX():0),
1539 // htden,(htden?htden->GetNbinsX():0),htnom,(htnom?htnom->GetNbinsX():0));
1540
1541 // standard ratio
1542 if (hdenom && !h->Divide(hdenom)) {
1543 Warning("DrawSame(eff/ratio)", "h & denom division failed!!!!");
1544 continue;
1545 }
1546 else if (htden && htnom && !i && !htnom->Divide(htden)) {
1547 Warning("DrawSame(eff/ratio)", "task-nom/task-denom division failed!!!!");
1548 continue;
1549 }
1550 else if (optDiv && htnom && !h->Divide(htnom)) {
1551 Warning("DrawSame(eff/ratio)", "h & task-nom division failed!!!!");
1552 continue;
1553 }
1554 else if (htden && !h->Divide(htden)) {
1555 Warning("DrawSame(eff/ratio)", "h & task-denom division failed!!!!");
1556 continue;
1557 }
1558 }
1559
1561 if (optWdth && !optRbnStat) h->Scale(1., "width");
1562
1563
1565 if (optOneOver) {
1566 Info("DrawSame", " Scale by 1/content");
1567 TH1* hOne = (TH1*) h->Clone("one");
1568 hOne->Reset("ICSE");
1569 for (Int_t ib = 0; ib < (h->GetNbinsX() + 2) * (h->GetNbinsY() + 2) * (h->GetNbinsZ() + 2); ib++)
1570 hOne->SetBinContent(ib, 1.);
1571 if (hOne->Divide(h)) h = hOne;
1572 }
1573
1575 if (optGeant) {
1576 Info("DrawSame", " Set GEANT bin labels");
1578 }
1579
1581 if (optPdg || optPdgClean) {
1582 Info("DrawSame", " Set PDG bin labels");
1584 }
1585
1588 if (h->GetLineColor() == kBlack && !optString.Contains("col")) { // avoid color updates
1589 h->UseCurrentStyle();
1590 PairAnalysisStyler::Style(h, i - (optRstSty ? nobj : 0));
1591 }
1593 if (optString.Contains("scat")) h->SetMarkerStyle(kDot);
1594 if (optString.Contains("e")) h->SetLineStyle(kSolid);
1595 // if(optString.Contains("text")) { h->SetLineColor(1); h->SetMarkerColor(1); }
1596
1598 // h->SetName(histClass.Data());
1599 h->SetTitle(histClass.Data());
1600
1603 if (optGoff) {
1604 if (optTask) h->SetTitle(Form("%s %s", GetName(), h->GetTitle()));
1605 arr->Add(h);
1606 }
1607 else if (optStack) {
1608 if (!hs) hs = new THStack("hs", Form(";%s;%s", h->GetXaxis()->GetTitle(), h->GetYaxis()->GetTitle()));
1609 hs->Add(h);
1610 }
1611 else {
1612 optString.ReplaceAll(" ", "");
1613 Info("DrawSame", " Draw object with options: '%s'", optString.Data());
1614 // h->Draw(i>0?(optString+"same").Data():optString.Data());
1615 if (!optSlicesY) { h->Draw(h != hFirst ? (optString + "same").Data() : optString.Data()); }
1616 else if (h->GetDimension() == 2) {
1617 // loop over all projections
1618 for (Int_t bin = 1; bin < h->GetNbinsX(); bin++) {
1619 TH1* hp = ((TH2*) h)->ProjectionY(Form("%s_%d", h->GetName(), bin), bin, bin, "e");
1620 if (!hp) continue;
1621 Long64_t nentries = Long64_t(hp->GetEntries());
1622 if (nentries == 0) {
1623 delete hp;
1624 continue;
1625 }
1626 PairAnalysisStyler::Style(hp, i + (bin - 1) - (optRstSty ? nobj : 0));
1627 if (optRbn) hp->Rebin(rbn);
1628 if (optRbnStat) {
1630 limits = PairAnalysisHelper::MakeStatBinLimits(hp, stat);
1631 hp = hp->Rebin(limits->GetSize() - 1, hp->GetName(), limits->GetArray());
1632 hp->Scale(1., "width");
1633 }
1634 if (optCum) PairAnalysisHelper::Cumulate(hp, optCumR, optNorm);
1635 if (optSmooth) hp->Smooth(smth);
1636 hp->Draw(hFirst ? (optString + "same").Data() : optString.Data());
1637 }
1638 }
1639 }
1640
1641
1643 if (h && h->GetEntries() > 0.) {
1644
1645 TString ratioName = histClassDenom;
1646 TString divName = (listDenom ? listDenom->GetName() : "");
1647 if (optEff) divName += (listDenom ? "(MC)" : "");
1648 // adapt legend name
1649 // remove reserved words
1650 TObjArray* reservedWords = fReservedWords->Tokenize(":;");
1651 for (Int_t ir = 0; ir < reservedWords->GetEntriesFast(); ir++) {
1652 // printf("histClass %s \t search for %s \n",histClass.Data(),((TObjString*)reservedWords->At(ir))->GetString().Data());
1653 histClass.ReplaceAll(((TObjString*) reservedWords->At(ir))->GetString(), "");
1654 ratioName.ReplaceAll(((TObjString*) reservedWords->At(ir))->GetString(), "");
1655 divName.ReplaceAll(((TObjString*) reservedWords->At(ir))->GetString(), "");
1656 }
1657 // change default signal names to titles
1658 for (Int_t isig = 0; isig < static_cast<Int_t>(PairAnalysisSignalMC::EDefinedSignal::kNSignals); isig++) {
1659 TString src = PairAnalysisSignalMC::fgkSignals[isig][0];
1660 TString rpl = PairAnalysisSignalMC::fgkSignals[isig][1];
1661 // avoid mc signal in header AND leg-entry
1662 if (leg && (rpl.EqualTo(leg->GetHeader()) || src.EqualTo(leg->GetHeader()))) rpl = "";
1663 histClass.ReplaceAll(src, rpl);
1664 ratioName.ReplaceAll(src, rpl);
1665 divName.ReplaceAll(src, rpl);
1666 }
1667 // printf("histClass %s \n",histClass.Data());
1668
1669 // change MCtruth to MC
1670 for (Int_t isig = 0; isig < static_cast<Int_t>(PairAnalysisSignalMC::EDefinedSignal::kNSignals); isig++) {
1671 histClass.ReplaceAll("MCtruth", "MC");
1672 ratioName.ReplaceAll("MCtruth", "MC");
1673 divName.ReplaceAll("MCtruth", "MC");
1674 }
1675 // remove pairing name if it is a MC
1676 for (Int_t iptype = 0; iptype < PairAnalysis::fNTypes; iptype++) {
1677 if (ndel > 0) histClass.ReplaceAll(PairAnalysis::PairClassName(iptype), "");
1678 if (ratioName.CountChar('_') > 0) ratioName.ReplaceAll(PairAnalysis::PairClassName(iptype), "");
1679 if (divName.CountChar('_') > 0) divName.ReplaceAll(PairAnalysis::PairClassName(iptype), "");
1680 }
1681 // save Dalitz and Short underscore
1682 histClass.ReplaceAll("_{Dalitz}", "#{Dalitz}");
1683 ratioName.ReplaceAll("_{Dalitz}", "#{Dalitz}");
1684 divName.ReplaceAll("_{Dalitz}", "#{Dalitz}");
1685 histClass.ReplaceAll("_{S}", "#{S}");
1686 ratioName.ReplaceAll("_{S}", "#{S}");
1687 divName.ReplaceAll("_{S}", "#{S}");
1688 // remove delimiters
1689 histClass.ReplaceAll("_", " ");
1690 ratioName.ReplaceAll("_", " ");
1691 divName.ReplaceAll("_", " ");
1692 histClass.ReplaceAll(".", "");
1693 ratioName.ReplaceAll(".", "");
1694 divName.ReplaceAll(".", "");
1695 // get Dalitz and Short back
1696 histClass.ReplaceAll("#{Dalitz}", "_{Dalitz}");
1697 ratioName.ReplaceAll("#{Dalitz}", "_{Dalitz}");
1698 divName.ReplaceAll("#{Dalitz}", "_{Dalitz}");
1699 histClass.ReplaceAll("#{S}", "_{S}");
1700 ratioName.ReplaceAll("#{S}", "_{S}");
1701 divName.ReplaceAll("#{S}", "_{S}");
1702 // remove trailing and leading spaces
1703 histClass.Remove(TString::kBoth, ' ');
1704 ratioName.Remove(TString::kBoth, ' ');
1705 divName.Remove(TString::kBoth, ' ');
1706
1707 //build final ratio name
1708 if (optRatio) histClass += "/" + ratioName;
1709
1710 // delete the surplus
1711 delete reservedWords;
1712
1713 // modify legend option
1714 TString legOpt = optString + "L";
1715 legOpt.ReplaceAll("hist", "");
1716 legOpt.ReplaceAll("scat", "");
1717 if (legOpt.Contains("col")) legOpt = "";
1718 legOpt.ReplaceAll("z", "");
1719 legOpt.ReplaceAll("e", "");
1720 if (optTask) histClass.Prepend(Form("%s ", GetName()));
1721 if ((optTask && optCutStep && i) || (optStack && (i - nobj))) histClass.Prepend("+");
1722 if (optDiv && !optOneOver) histClass.ReplaceAll(GetName(), Form("%s/%s", GetName(), divName.Data()));
1723 if (optDiv && optOneOver) histClass.Prepend(Form("%s/", divName.Data()));
1724 if (optDet) {
1725 for (ECbmModuleId idet = ECbmModuleId::kRef; idet < ECbmModuleId::kNofSystems; ++idet) {
1726 if (histName.Contains(PairAnalysisHelper::GetDetName(idet))) histClass = PairAnalysisHelper::GetDetName(idet);
1727 }
1728 }
1729 // else if(nobj) histClass="";
1730 if (optMeanX) histClass += Form(" #LTx#GT=%.1e", h->GetMean());
1731 if (optRmsX) histClass += Form(" RMS(x)=%.1e", h->GetRMS());
1732 if (optMeanY) histClass += Form(" #LTy#GT=%.2e", h->GetMean(2));
1733 if (optRmsY) histClass += Form(" RMS(y)=%.2e", h->GetRMS(2));
1734 histClass.ReplaceAll("e+00", "");
1735 // no entry for colored plots
1736 if (optLeg && leg /*&& !legOpt.Contains("col")*/) leg->AddEntry(h, histClass.Data(), legOpt.Data());
1737 // if (leg) leg->AddEntry(h,classTable->GetName(),(optString+"L").Data());
1738 ++i;
1739 }
1740 else if (nobj && leg)
1741 leg->AddEntry(hFirst, "", "");
1742
1743 //++i;
1744
1745
1746 // }
1747 // cleanup
1748 if (limits) delete limits;
1749 } //while loop histclass
1750
1752 if (optStack) {
1753 optString.ReplaceAll(" ", "");
1754 Info("DrawSame", " Draw stacked object with options: '%s'", optString.Data());
1755 hs->Draw(nobj > 0 ? (optString + "same").Data() : optString.Data());
1756 }
1757
1760 if (leg) {
1762 if (!nobj) leg->Draw();
1763 }
1764
1766 if (gPad) {
1767 Double_t max = -1e10;
1768 Double_t min = +1e10;
1769 TListIter nextObj(gPad->GetListOfPrimitives(), kIterBackward);
1770 // TObject *obj;
1771 while ((obj = nextObj())) {
1772 if (obj->InheritsFrom(TH1::Class())) {
1773 TH1* h1 = static_cast<TH1*>(obj);
1774
1775 max = TMath::Max(max, PairAnalysisHelper::GetContentMaximum(h1)); //h1->GetMaximum();
1776 Double_t tmpmax = max * (gPad->GetLogy() ? 5. : 1.1);
1777 if (optEff) tmpmax = 1.1;
1778 h1->SetMaximum(tmpmax);
1779
1780 Double_t objmin = PairAnalysisHelper::GetContentMinimum(h1);
1781 if (gPad->GetLogy() && objmin < 0.) objmin = 0.5;
1782 min = TMath::Min(min, objmin);
1783 Double_t tmpmin = min * (min < 0. ? 1.1 : 0.9);
1784 // if(optEff) tmpmin=0.;
1785 h1->SetMinimum(tmpmin);
1786
1787 // Printf("after %s max%f \t min%f \t for logy %.3e >? %.3e",
1788 // h1->GetTitle(),tmpmax,tmpmin, tmpmax/(tmpmin>0.?tmpmin:1.),TMath::Power(10.,TGaxis::GetMaxDigits()));
1789
1790 // Printf("max%f \t min%f",h1->GetMaximum(),PairAnalysisHelper::GetContentMinimum(h1));
1791 // max=TMath::Max(max,PairAnalysisHelper::GetContentMaximum(h1));
1792 // min=TMath::Min(min,PairAnalysisHelper::GetContentMinimum(h1));//hobj->GetBinContent(hobj->GetMinimumBin()));
1793 // Printf("max%f \t min%f",max,min);
1794 // if(!optEff) h1->SetMaximum(max*(gPad->GetLogy()?5.:1.1));
1795 // else h1->SetMaximum(1.1);
1796 // if(!optEff) h1->SetMinimum( min*(min<0.?1.1:0.9) ); //TODO: doesnt work, why?? Negative values?
1797
1799 if (gPad->GetLogy()
1800 && (tmpmax / (tmpmin > 0. ? tmpmin : 1.) > TMath::Power(10., TGaxis::GetMaxDigits())
1801 || tmpmin < TMath::Power(10., -TGaxis::GetMaxDigits())
1802 || tmpmin > TMath::Power(10., +TGaxis::GetMaxDigits()))) {
1803 // if(gPad->GetLogy() && tmpmax/(tmpmin>0.?tmpmin:1.) > TMath::Power(10.,TGaxis::GetMaxDigits())) {
1804 h1->GetYaxis()->SetMoreLogLabels(kFALSE);
1805 h1->GetYaxis()->SetNoExponent(kFALSE);
1806 }
1807 Double_t tmpXmin = h1->GetXaxis()->GetXmin();
1808 if (gPad->GetLogx()
1809 && h1->GetXaxis()->GetXmax() / (TMath::Abs(tmpXmin) < 1.e-10 ? 1. : tmpXmin)
1810 > TMath::Power(10., TGaxis::GetMaxDigits())) {
1811 // printf("Xaxis: max%f , min%f \t ratio %.3e >? %.3e \n",h1->GetXaxis()->GetXmax(),(TMath::Abs(tmpXmin)<1.e-10?1.:tmpXmin),
1812 // h1->GetXaxis()->GetXmax()/(TMath::Abs(tmpXmin)<1.e-10?1.:tmpXmin),TMath::Power(10.,TGaxis::GetMaxDigits()));
1813 h1->GetXaxis()->SetMoreLogLabels(kFALSE);
1814 h1->GetXaxis()->SetNoExponent(kFALSE);
1815 }
1816 }
1817 }
1819 if (!nobj && optMeta && fMetaData && !gPad->GetPrimitive("meta")) { fMetaData->DrawSame(""); }
1820
1823 if (!optTask && 0) {
1824 if (leg) leg->DrawClone();
1825 nextObj.Reset();
1826 Int_t ileg = 0;
1827 while ((obj = nextObj())) {
1828 if (obj->InheritsFrom(TLegend::Class())) {
1829 if (ileg > 0) delete obj;
1830 ileg++;
1831 }
1832 }
1833 }
1834 }
1835
1838 //if(gPad && !optGoff) gPad->RedrawAxis();
1839
1841 // if(optGoff) { c->Close(); delete c; }
1842
1844 if (selections) delete selections;
1845
1846 return arr;
1847}
1848
1849//_____________________________________________________________________________
1850void PairAnalysisHistos::SetReservedWords(const char* words)
1851{
1852 //
1853 // set reserved words
1854 //
1855
1856 (*fReservedWords) = words;
1857}
1858
1859//_____________________________________________________________________________
1860void PairAnalysisHistos::StoreVariables(TObject* obj, UInt_t valType[20])
1861{
1862 //
1863 //
1864 //
1865 if (!obj) return;
1866 if (obj->InheritsFrom(TH1::Class())) StoreVariables(static_cast<TH1*>(obj), valType);
1867 else if (obj->InheritsFrom(THnBase::Class()))
1868 StoreVariables(static_cast<THnBase*>(obj), valType);
1869
1870 return;
1871}
1872
1873
1874//_____________________________________________________________________________
1875void PairAnalysisHistos::StoreVariables(TH1* obj, UInt_t valType[20])
1876{
1877 //
1878 // store variables in the axis (special for TProfile3D)
1879 //
1880
1881 Int_t dim = obj->GetDimension();
1882
1883 // dimension correction for profiles
1884 if (obj->IsA() == TProfile::Class() || obj->IsA() == TProfile2D::Class() || obj->IsA() == TProfile3D::Class()) {
1885 dim++;
1886 }
1887
1888 if (dim >= 1) { obj->GetXaxis()->SetUniqueID(valType[0]); }
1889 if (dim >= 2) { obj->GetYaxis()->SetUniqueID(valType[1]); }
1890 if (dim >= 3) { obj->GetZaxis()->SetUniqueID(valType[2]); }
1891 // Tprofile3D variable
1892 if (dim >= 4) { obj->SetUniqueID(valType[3]); }
1893
1894 return;
1895}
1896
1897//_____________________________________________________________________________
1898void PairAnalysisHistos::StoreVariables(THnBase* obj, UInt_t valType[20])
1899{
1900 //
1901 // store variables in the axis
1902 //
1903
1904 obj->Sumw2();
1905
1906 // check for formulas and skip the rest if needed
1907 TList* list = obj->GetListOfFunctions();
1908 if (obj->IsA() == PairAnalysisHn::Class()) list = (static_cast<PairAnalysisHn*>(obj))->GetListOfFunctions();
1909 if (list && list->Last()) return;
1910
1911 Int_t dim = obj->GetNdimensions();
1912
1913 for (Int_t it = 0; it < dim; it++) {
1914 obj->GetAxis(it)->SetUniqueID(valType[it]);
1915 obj->GetAxis(it)->SetName(Form("%s", PairAnalysisVarManager::GetValueName(valType[it])));
1916 obj->GetAxis(it)->SetTitle(Form("%s %s", PairAnalysisVarManager::GetValueLabel(valType[it]),
1918 }
1919 return;
1920}
1921
1922//_____________________________________________________________________________
1923void PairAnalysisHistos::FillValues(TObject* obj, const Double_t* values)
1924{
1925 //
1926 //
1927 //
1928 if (!obj) return;
1929 if (obj->InheritsFrom(TH1::Class())) FillValues(static_cast<TH1*>(obj), values);
1930 else if (obj->InheritsFrom(THnBase::Class()))
1931 FillValues(static_cast<THnBase*>(obj), values);
1932
1933 return;
1934}
1935
1936//_____________________________________________________________________________
1937void PairAnalysisHistos::FillValues(TH1* obj, const Double_t* values)
1938{
1939 //
1940 // fill values for TH1 inherted classes
1941 //
1942
1943 Int_t dim = obj->GetDimension();
1944 Bool_t bprf = kFALSE;
1945 // UInt_t nValues = (UInt_t) PairAnalysisVarManager::kNMaxValues;
1946 UInt_t valueTypes = obj->GetUniqueID();
1947 if (valueTypes == static_cast<UInt_t>(PairAnalysisHistos::Eoption::kNoAutoFill)) return;
1948 Bool_t weight = (valueTypes != static_cast<UInt_t>(Eoption::kNoWeights));
1949
1950 // check if tprofile
1951 if (obj->IsA() == TProfile::Class() || obj->IsA() == TProfile2D::Class() || obj->IsA() == TProfile3D::Class())
1952 bprf = kTRUE;
1953
1954 // TO BEAUTIFY: switch off manually weighting of profile3Ds
1955 if (obj->IsA() == TProfile3D::Class()) weight = kFALSE;
1956
1957 // check for formulas
1958 TList* list = obj->GetListOfFunctions();
1959 TFormula* xform = dynamic_cast<TFormula*>(list->FindObject("xFormula"));
1960 TFormula* yform = dynamic_cast<TFormula*>(list->FindObject("yFormula"));
1961 TFormula* zform = dynamic_cast<TFormula*>(list->FindObject("zFormula"));
1962 TFormula* pform = dynamic_cast<TFormula*>(list->FindObject("pFormula"));
1963 TFormula* wform = dynamic_cast<TFormula*>(list->FindObject("wFormula"));
1964 // Bool_t bform = (xform || yform || zform /*|| wform*/);
1965
1966 // get variables from axis unique IDs
1967 UInt_t value1 = obj->GetXaxis()->GetUniqueID();
1968 UInt_t value2 = obj->GetYaxis()->GetUniqueID();
1969 UInt_t value3 = obj->GetZaxis()->GetUniqueID();
1970 UInt_t value4 = obj->GetUniqueID(); // get weighting/profile var stored in the unique ID
1971
1972 Double_t fvals[4] = {values[value1], values[value2], values[value3], values[value4]};
1973
1974 // use formulas to update fill values
1975 if (xform) fvals[0] = PairAnalysisHelper::EvalFormula(xform, values);
1976 if (yform) fvals[1] = PairAnalysisHelper::EvalFormula(yform, values);
1977 if (zform) fvals[2] = PairAnalysisHelper::EvalFormula(zform, values);
1978 if (wform) fvals[3] = PairAnalysisHelper::EvalFormula(wform, values);
1979 if (pform) fvals[3] = PairAnalysisHelper::EvalFormula(pform, values); // weighting overwriting for Profile3D
1980
1981 /*
1982 // ask for inclusive trigger map variables
1983 if(value1!=PairAnalysisVarManager::kTriggerInclONL && value1!=PairAnalysisVarManager::kTriggerInclOFF &&
1984 value2!=PairAnalysisVarManager::kTriggerInclONL && value2!=PairAnalysisVarManager::kTriggerInclOFF &&
1985 value3!=PairAnalysisVarManager::kTriggerInclONL && value3!=PairAnalysisVarManager::kTriggerInclOFF &&
1986 value4!=PairAnalysisVarManager::kTriggerInclONL && value4!=PairAnalysisVarManager::kTriggerInclOFF ) {
1987 // no trigger map variable selected
1988 */
1989 switch (dim) {
1990 case 1:
1991 if (!bprf && !weight) obj->Fill(fvals[0]); // histograms
1992 else if (!bprf && weight)
1993 obj->Fill(fvals[0], fvals[3]); // weighted histograms
1994 else if (bprf && !weight)
1995 ((TProfile*) obj)->Fill(fvals[0], fvals[1]); // profiles
1996 else
1997 ((TProfile*) obj)->Fill(fvals[0], fvals[1], fvals[3]); // weighted profiles
1998 break;
1999 case 2:
2000 if (!bprf && !weight) obj->Fill(fvals[0], fvals[1]); // histograms
2001 else if (!bprf && weight)
2002 ((TH2*) obj)->Fill(fvals[0], fvals[1], fvals[3]); // weighted histograms
2003 else if (bprf && !weight)
2004 ((TProfile2D*) obj)->Fill(fvals[0], fvals[1], fvals[2]); // profiles
2005 else
2006 ((TProfile2D*) obj)->Fill(fvals[0], fvals[1], fvals[2], fvals[3]); // weighted profiles
2007 break;
2008 case 3:
2009 if (!bprf && !weight) ((TH3*) obj)->Fill(fvals[0], fvals[1], fvals[2]); // histograms
2010 else if (!bprf && weight)
2011 ((TH3*) obj)->Fill(fvals[0], fvals[1], fvals[2], fvals[3]); // weighted histograms
2012 else if (bprf && !weight)
2013 ((TProfile3D*) obj)->Fill(fvals[0], fvals[1], fvals[2], fvals[3]); // profiles
2014 else
2015 Printf(" WARNING: weighting NOT yet possible for TProfile3Ds !");
2016 break;
2017 }
2018 /* }
2019 else {
2020 // fill inclusive trigger map variables
2021 if(weight) return;
2022 switch ( dim ) {
2023 case 1:
2024 for(Int_t i=0; i<30; i++) { if(TESTBIT((UInt_t)fvals[0],i)) obj->Fill(i); }
2025 break;
2026 case 2:
2027 if((value1==PairAnalysisVarManager::kTriggerInclOFF && value2==PairAnalysisVarManager::kTriggerInclONL) ||
2028 (value1==PairAnalysisVarManager::kTriggerInclONL && value2==PairAnalysisVarManager::kTriggerInclOFF) ) {
2029 for(Int_t i=0; i<30; i++) {
2030 if((UInt_t)fvals[0]==BIT(i)) {
2031 for(Int_t i2=0; i2<30; i2++) {
2032 if((UInt_t)fvals[1]==BIT(i2)) {
2033 obj->Fill(i, i2);
2034 } // bit fired
2035 } //loop 2
2036 }//bit fired
2037 } // loop 1
2038 }
2039 else if(value1==PairAnalysisVarManager::kTriggerInclONL || value1==PairAnalysisVarManager::kTriggerInclOFF) {
2040 for(Int_t i=0; i<30; i++) { if(TESTBIT((UInt_t)fvals[0],i)) obj->Fill(i, fvals[1]); }
2041 }
2042 else if(value2==PairAnalysisVarManager::kTriggerInclONL || value2==PairAnalysisVarManager::kTriggerInclOFF) {
2043 for(Int_t i=0; i<30; i++) { if(TESTBIT((UInt_t)fvals[1],i)) obj->Fill(fvals[0], i); }
2044 }
2045 else //makes no sense
2046 return;
2047 break;
2048 default: return;
2049 }
2050
2051 } //end: trigger filling
2052 */
2053
2054 return;
2055}
2056
2057//_____________________________________________________________________________
2058void PairAnalysisHistos::FillValues(THnBase* obj, const Double_t* values)
2059{
2060 //
2061 // fill values for THn inherted classes
2062 //
2063
2064 // skip if manual filling
2065 UInt_t value4 = obj->GetUniqueID(); // weighting variable if any
2066 if (value4 == static_cast<UInt_t>(PairAnalysisHistos::Eoption::kNoAutoFill)) return;
2067
2068 // check for formulas and skip the rest if needed
2069 TList* list = obj->GetListOfFunctions();
2070 if (obj->IsA() == PairAnalysisHn::Class()) list = (static_cast<PairAnalysisHn*>(obj))->GetListOfFunctions();
2071 Bool_t useFormulas = (list && list->Last());
2072
2073 // do weighting
2074 Bool_t weight = (value4 != static_cast<UInt_t>(Eoption::kNoWeights));
2075
2076 // fill array
2077 const Int_t dim = obj->GetNdimensions();
2078 Double_t fill[dim];
2079
2080 // loop over all axes
2081 for (Int_t it = 0; it < dim; it++) {
2082 if (useFormulas) {
2083 TString formName = Form("axis%dFormula", it);
2084 TFormula* form = dynamic_cast<TFormula*>(list->FindObject(formName));
2085 fill[it] = PairAnalysisHelper::EvalFormula(form, values);
2086 }
2087 else {
2088 fill[it] = values[obj->GetAxis(it)->GetUniqueID()];
2089 }
2090 }
2091
2092 // fill object
2093 if (!weight) obj->Fill(fill);
2094 else
2095 obj->Fill(fill, values[value4]);
2096
2097 return;
2098}
2099
2100//_____________________________________________________________________________
2101void PairAnalysisHistos::FillVarArray(TObject* obj, UInt_t* valType)
2102{
2103 //
2104 // extract variables stored in the axis (special for TProfile3D)
2105 //
2106
2107
2108 if (!obj) return;
2109
2110 if (obj->InheritsFrom(TH1::Class())) {
2111 valType[0] = ((TH1*) obj)->GetXaxis()->GetUniqueID();
2112 valType[1] = ((TH1*) obj)->GetYaxis()->GetUniqueID();
2113 valType[2] = ((TH1*) obj)->GetZaxis()->GetUniqueID();
2114 valType[3] = ((TH1*) obj)->GetUniqueID(); // weighting(profile) var stored in unique ID
2115 }
2116 else if (obj->InheritsFrom(THnBase::Class())) {
2117 for (Int_t it = 0; it < ((THn*) obj)->GetNdimensions(); it++)
2118 valType[it] = ((THn*) obj)->GetAxis(it)->GetUniqueID();
2119 }
2120 valType[19] = obj->GetUniqueID(); //weights
2121 return;
2122}
2123
2124//_____________________________________________________________________________
2125void PairAnalysisHistos::AdaptNameTitle(TH1* hist, const char* histClass)
2126{
2127
2128 //
2129 // adapt name and title of the histogram
2130 //
2131
2132 Int_t dim = hist->GetDimension();
2133 TString currentName = ""; //hist->GetName();
2134 TString currentTitle = ""; //hist->GetTitle();
2135 TString hclass = histClass;
2136 //get reserved class
2137 TObjArray* arr = hclass.Tokenize("_.");
2138 arr->SetOwner();
2139 hclass = ((TObjString*) arr->At(0))->GetString();
2140 delete arr;
2141 hclass.ToLower();
2142
2143 Bool_t bname = (currentName.IsNull());
2144 Bool_t btitle = (currentTitle.IsNull());
2145 Bool_t bprf = kFALSE;
2146 if (hist->IsA() == TProfile::Class() || hist->IsA() == TProfile2D::Class() || hist->IsA() == TProfile3D::Class())
2147 bprf = kTRUE;
2148
2149 // tprofile options
2150 Double_t pmin = 0., pmax = 0.;
2151 TString option = "", calcrange = "";
2152 Bool_t bStdOpt = kTRUE;
2153 if (bprf) {
2154 switch (dim) {
2155 case 3:
2156 option = ((TProfile3D*) hist)->GetErrorOption();
2157 pmin = ((TProfile3D*) hist)->GetTmin();
2158 pmax = ((TProfile3D*) hist)->GetTmax();
2159 break;
2160 case 2:
2161 option = ((TProfile2D*) hist)->GetErrorOption();
2162 pmin = ((TProfile2D*) hist)->GetZmin();
2163 pmax = ((TProfile2D*) hist)->GetZmax();
2164 break;
2165 case 1:
2166 option = ((TProfile*) hist)->GetErrorOption();
2167 pmin = ((TProfile*) hist)->GetYmin();
2168 pmax = ((TProfile*) hist)->GetYmax();
2169 break;
2170 }
2171 if (option.Contains("s", TString::kIgnoreCase)) bStdOpt = kFALSE;
2172 if (pmin != pmax)
2173 calcrange = Form("#cbar_{%+.*f}^{%+.*f}", PairAnalysisHelper::GetPrecision(pmin), pmin,
2175 }
2176
2177 UInt_t varx = hist->GetXaxis()->GetUniqueID();
2178 UInt_t vary = hist->GetYaxis()->GetUniqueID();
2179 UInt_t varz = hist->GetZaxis()->GetUniqueID();
2180 UInt_t varp = hist->GetUniqueID();
2181 Bool_t weight = (varp != static_cast<UInt_t>(Eoption::kNoWeights));
2182 if (bprf && dim == 3) weight = kFALSE; // no weighting for profile3D
2183
2184 // store titles in the axis
2185 if (btitle) {
2186 TString tit = "";
2188 hist->GetXaxis()->SetName(PairAnalysisVarManager::GetValueName(varx));
2189 hist->GetYaxis()->SetName(PairAnalysisVarManager::GetValueName(vary));
2190 hist->GetZaxis()->SetName(PairAnalysisVarManager::GetValueName(varz));
2191 // adapt according to formula
2192 TFormula* xform = dynamic_cast<TFormula*>(hist->GetListOfFunctions()->FindObject("xFormula"));
2193 TFormula* yform = dynamic_cast<TFormula*>(hist->GetListOfFunctions()->FindObject("yFormula"));
2194 TFormula* zform = dynamic_cast<TFormula*>(hist->GetListOfFunctions()->FindObject("zFormula"));
2195 TFormula* wform = dynamic_cast<TFormula*>(hist->GetListOfFunctions()->FindObject("wFormula"));
2196 if (xform) { hist->GetXaxis()->SetName(PairAnalysisHelper::GetFormulaName(xform).Data()); }
2197 if (yform) { hist->GetYaxis()->SetName(PairAnalysisHelper::GetFormulaName(yform).Data()); }
2198 if (zform) { hist->GetZaxis()->SetName(PairAnalysisHelper::GetFormulaName(zform).Data()); }
2200 hist->GetXaxis()->SetTitle(PairAnalysisVarManager::GetValueLabel(varx));
2201 hist->GetYaxis()->SetTitle(PairAnalysisVarManager::GetValueLabel(vary));
2202 hist->GetZaxis()->SetTitle(PairAnalysisVarManager::GetValueLabel(varz));
2203 // adapt according to formula
2204 if (xform) { hist->GetXaxis()->SetTitle(PairAnalysisHelper::GetFormulaTitle(xform).Data()); }
2205 if (yform) { hist->GetYaxis()->SetTitle(PairAnalysisHelper::GetFormulaTitle(yform).Data()); }
2206 if (zform) { hist->GetZaxis()->SetTitle(PairAnalysisHelper::GetFormulaTitle(zform).Data()); }
2207 // profile axis
2208 if (bprf && dim < 3) {
2209 TAxis* ax = 0x0;
2210 switch (dim) {
2211 case 2: ax = hist->GetZaxis(); break;
2212 case 1: ax = hist->GetYaxis(); break;
2213 }
2214 tit = ax->GetTitle();
2215 tit.Prepend((bStdOpt ? "#LT" : "RMS("));
2216 tit.Append((bStdOpt ? "#GT" : ")"));
2217 // TODO: activate --> tit.Append ( Form("_{%ss}",hclass.Data()));
2218 tit.Append(calcrange.Data());
2219 ax->SetTitle(tit.Data());
2220 }
2221 // append the units for all axes (except formula)
2222 tit = Form("%s %s", hist->GetXaxis()->GetTitle(), PairAnalysisVarManager::GetValueUnit(varx));
2223 if (!xform) hist->GetXaxis()->SetTitle(tit.Data());
2224 tit = Form("%s %s", hist->GetYaxis()->GetTitle(), PairAnalysisVarManager::GetValueUnit(vary));
2225 if (!yform) hist->GetYaxis()->SetTitle(tit.Data());
2226 tit = Form("%s %s", hist->GetZaxis()->GetTitle(), PairAnalysisVarManager::GetValueUnit(varz));
2227 if (!zform) hist->GetZaxis()->SetTitle(tit.Data());
2228 // overwrite titles with hist class if needed
2229 if (!bprf) {
2230 switch (dim) {
2231 case 1: hist->GetYaxis()->SetTitle(Form("%ss", hclass.Data())); break;
2232 case 2: hist->GetZaxis()->SetTitle(Form("%ss", hclass.Data())); break;
2233 }
2234 }
2235 // weighted axis (maximal 2 dimensional)
2236 if (weight) {
2237 TAxis* ax = hist->GetYaxis();
2238 if (dim == 2) ax = hist->GetZaxis();
2240 if (wform) { tit = PairAnalysisHelper::GetFormulaTitle(wform); }
2241 ax->SetTitle(Form("%s weighted %s", tit.Data(), ax->GetTitle()));
2242 }
2243
2244 // create an unique name
2245 TFormula* pform = dynamic_cast<TFormula*>(hist->GetListOfFunctions()->FindObject("pFormula"));
2246 if (bname) switch (dim) {
2247 case 3:
2248 currentName += Form("%s_", hist->GetXaxis()->GetName());
2249 currentName += Form("%s_", hist->GetYaxis()->GetName());
2250 currentName += Form("%s", hist->GetZaxis()->GetName());
2251 if (bprf && !pform)
2252 currentName += Form("-%s%s", PairAnalysisVarManager::GetValueName(varp), (bStdOpt ? "avg" : "rms"));
2253 else if (bprf)
2254 currentName += Form("-%s%s", PairAnalysisHelper::GetFormulaName(pform).Data(), (bStdOpt ? "avg" : "rms"));
2255 if (weight && !bprf) currentName += Form("-wght%s", PairAnalysisVarManager::GetValueName(varp));
2256 break;
2257 case 2:
2258 currentName += Form("%s_", hist->GetXaxis()->GetName());
2259 currentName += Form("%s", hist->GetYaxis()->GetName());
2260 if (bprf) currentName += Form("-%s%s", hist->GetZaxis()->GetName(), (bStdOpt ? "avg" : "rms"));
2261 if (weight && !wform) currentName += Form("-wght%s", PairAnalysisVarManager::GetValueName(varp));
2262 else if (weight && wform)
2263 currentName += Form("-wght%s", PairAnalysisHelper::GetFormulaName(wform).Data());
2264 break;
2265 case 1:
2266 currentName += Form("%s", hist->GetXaxis()->GetName());
2267 if (bprf) currentName += Form("-%s%s", hist->GetYaxis()->GetName(), (bStdOpt ? "avg" : "rms"));
2268 if (weight && !wform) currentName += Form("-wght%s", PairAnalysisVarManager::GetValueName(varp));
2269 else if (weight && wform)
2270 currentName += Form("-wght%s", PairAnalysisHelper::GetFormulaName(wform).Data());
2271 break;
2272 }
2273 // to differentiate btw. leg and pair histos
2274 // if(!strcmp(histClass,"Pair")) currentName.Prepend("p");
2275 if (hclass.Contains("pair")) currentName.Prepend("p");
2276 hist->SetName(currentName.Data());
2277 }
2278}
2279
2280
2281//_____________________________________________________________________________
2282void PairAnalysisHistos::AdaptNameTitle(THnBase* hist, const char* histClass)
2283{
2284
2285 //
2286 // adapt name and title of the histogram
2287 //
2288
2289 Int_t dim = hist->GetNdimensions();
2290 TString currentName = ""; //hist->GetName();
2291 TString currentTitle = ""; //hist->GetTitle();
2292 TString hclass = histClass;
2293 //get reserved class
2294 TObjArray* arr = hclass.Tokenize("_.");
2295 arr->SetOwner();
2296 hclass = ((TObjString*) arr->At(0))->GetString();
2297 delete arr;
2298 hclass.ToLower();
2299
2300 Bool_t bname = (currentName.IsNull());
2301 Bool_t btitle = (currentTitle.IsNull());
2302
2303 TList* list = (static_cast<PairAnalysisHn*>(hist))->GetListOfFunctions();
2304
2305 // store titles in the axis
2306 if (btitle) {
2307 TString tit = "";
2308 // adapt according to formula
2309 for (Int_t it = 0; it < dim; it++) {
2310 TString formName = Form("axis%dFormula", it);
2311 TFormula* form = dynamic_cast<TFormula*>(list->FindObject(formName));
2312 hist->GetAxis(it)->SetName(PairAnalysisHelper::GetFormulaName(form).Data());
2313 // adapt according to formula
2314 hist->GetAxis(it)->SetTitle(PairAnalysisHelper::GetFormulaTitle(form).Data());
2315 }
2316 }
2317
2318 // create an unique name
2319 if (bname) {
2320 currentName = hist->GetName();
2321 if (hclass.Contains("pair")) currentName.Prepend("p");
2322 hist->SetName(currentName.Data());
2323 }
2324}
ECbmModuleId
Definition CbmDefs.h:39
@ kRef
Reference plane.
@ kNofSystems
For loops over active systems.
ClassImp(PairAnalysisHistos) PairAnalysisHistos
Data class with information on a STS local track.
TList * GetListOfFunctions() const
static const char * fgkSignals[static_cast< int >(EDefinedSignal::kNSignals)][2]
static const char * GetValueName(Int_t i)
static const char * GetValueUnit(Int_t i)
static UInt_t GetValueTypeMC(UInt_t var)
static UInt_t GetValueType(const char *valname)
static const char * GetValueLabel(Int_t i)
static const char * PairClassName(Int_t i)
static constexpr Int_t fNTypes
Int_t GetPrecision(Double_t value)
TString GetFormulaName(TFormula *form)
void SetGEANTBinLabels(TH1 *hist)
TArrayD * MakeStatBinLimits(TH1 *h, Double_t stat)
TString GetFormulaTitle(TFormula *form)
Double_t GetContentMinimum(TH1 *h, Bool_t inclErr=kTRUE)
Double_t GetContentMaximum(TH1 *h, Bool_t inclErr=kTRUE)
Double_t EvalFormula(TFormula *form, const Double_t *values)
void SetPDGBinLabels(TH1 *hist, Bool_t clean)
TString GetDetName(ECbmModuleId det)
void Cumulate(TH1 *h, Bool_t reverse=kFALSE, Bool_t norm=kFALSE)
void Style(TObject *obj, Int_t idx=0)
void SetLegendAttributes(TLegend *leg, Bool_t fill=kFALSE)