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