Logo ROOT   master
Reference Guide
TSelectorDraw.cxx
Go to the documentation of this file.
1 // @(#)root/treeplayer:$Id$
2 // Author: Rene Brun 08/01/2003
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TSelectorDraw
13 A specialized TSelector for TTree::Draw.
14 */
15 
16 #include "TSelectorDraw.h"
17 #include "TROOT.h"
18 #include "TH2.h"
19 #include "TH3.h"
20 #include "TView.h"
21 #include "TGraph.h"
22 #include "TPolyMarker3D.h"
23 #include "TDirectory.h"
24 #include "TVirtualPad.h"
25 #include "TProfile.h"
26 #include "TProfile2D.h"
27 #include "TTreeFormulaManager.h"
28 #include "TEnv.h"
29 #include "TTree.h"
30 #include "TCut.h"
31 #include "TEntryList.h"
32 #include "TEventList.h"
33 #include "TEntryListArray.h"
34 #include "THLimitsFinder.h"
35 #include "TStyle.h"
36 #include "TClass.h"
37 #include "TColor.h"
38 
40 
42 
43 ////////////////////////////////////////////////////////////////////////////////
44 /// Default selector constructor.
45 
47 {
48  fTree = 0;
49  fW = 0;
50  fValSize = 4;
51  fVal = new Double_t*[fValSize];
52  fVmin = new Double_t[fValSize];
53  fVmax = new Double_t[fValSize];
54  fNbins = new Int_t[fValSize];
56  fVar = new TTreeFormula*[fValSize];
57  for (Int_t i = 0; i < fValSize; ++i) {
58  fVal[i] = 0;
59  fVar[i] = 0;
60  }
61  fManager = 0;
62  fMultiplicity = 0;
63  fSelect = 0;
64  fSelectedRows = 0;
65  fDraw = 0;
66  fObject = 0;
67  fOldHistogram = 0;
68  fObjEval = kFALSE;
71  fTreeElist = 0;
72  fAction = 0;
73  fNfill = 0;
74  fDimension = 0;
75  fOldEstimate = 0;
76  fForceRead = 0;
77  fWeight = 1;
78  fCurrentSubEntry = -1;
79  fTreeElistArray = 0;
80 }
81 
82 ////////////////////////////////////////////////////////////////////////////////
83 /// Selector destructor.
84 
86 {
87  ClearFormula();
88  delete [] fVar;
89  if (fVal) {
90  for (Int_t i = 0; i < fValSize; ++i)
91  delete [] fVal[i];
92  delete [] fVal;
93  }
94  if (fVmin) delete [] fVmin;
95  if (fVmax) delete [] fVmax;
96  if (fNbins) delete [] fNbins;
97  if (fVarMultiple) delete [] fVarMultiple;
98  if (fW) delete [] fW;
99 }
100 
101 ////////////////////////////////////////////////////////////////////////////////
102 /// Called every time a loop on the tree(s) starts.
103 
105 {
106  SetStatus(0);
107  ResetAbort();
109  fSelectedRows = 0;
110  fTree = tree;
111  fDimension = 0;
112  fAction = 0;
113 
114  TObject *obj = fInput->FindObject("varexp");
115  const char *varexp0 = obj ? obj->GetTitle() : "";
116  obj = fInput->FindObject("selection");
117  const char *selection = obj ? obj->GetTitle() : "";
118  const char *option = GetOption();
119 
120  TString opt, abrt;
121  char *hdefault = (char *)"htemp";
122  char *varexp = nullptr;
123  Int_t i, j, hkeep;
124  opt = option;
125  opt.ToLower();
126  fOldHistogram = 0;
127  TEntryList *enlist = 0;
128  TEventList *evlist = 0;
129  TString htitle;
130  Bool_t profile = kFALSE;
131  Bool_t optSame = kFALSE;
132  Bool_t optEnlist = kFALSE;
133  Bool_t optEnlistArray = kFALSE;
134  Bool_t optpara = kFALSE;
135  Bool_t optcandle = kFALSE;
136  Bool_t opt5d = kFALSE;
137  if (opt.Contains("same")) {
138  optSame = kTRUE;
139  opt.ReplaceAll("same", "");
140  }
141  if (opt.Contains("entrylist")) {
142  optEnlist = kTRUE;
143  if (opt.Contains("entrylistarray")) {
144  optEnlistArray = kTRUE;
145  opt.ReplaceAll("entrylistarray", "");
146  } else {
147  opt.ReplaceAll("entrylist", "");
148  }
149  }
150  if (opt.Contains("para")) {
151  optpara = kTRUE;
152  opt.ReplaceAll("para", "");
153  }
154  if (opt.Contains("candle")) {
155  optcandle = kTRUE;
156  opt.ReplaceAll("candle", "");
157  }
158  if (opt.Contains("gl5d")) {
159  opt5d = kTRUE;
160  opt.ReplaceAll("gl5d", "");
161  }
162  TCut realSelection(selection);
163  //input list - only TEntryList
164  TEntryList *inElist = fTree->GetEntryList();
165  evlist = fTree->GetEventList();
166  if (evlist && inElist) {
167  //this is needed because the input entry list was created
168  //by the fTree from the input TEventList and is owned by the fTree.
169  //Calling GetEntryList function changes ownership and here
170  //we want fTree to still delete this entry list
171 
172  inElist->SetBit(kCanDelete, kTRUE);
173  }
175  fTreeElist = inElist;
176 
177  fTreeElistArray = inElist ? dynamic_cast<TEntryListArray*>(fTreeElist) : 0;
178 
179 
180  if (inElist && inElist->GetReapplyCut()) {
181  realSelection *= inElist->GetTitle();
182  }
183 
184  // what each variable should contain:
185  // varexp0 - original expression eg "a:b>>htest"
186  // hname - name of new or old histogram
187  // hkeep - flag if to keep new histogram
188  // hnameplus - flag if to add to current histo
189  // i - length of variable expression stipped of everything after ">>"
190  // varexp - variable expression stipped of everything after ">>"
191  // fOldHistogram - pointer to hist hname
192  // elist - pointer to selection list of hname
193 
194  Bool_t canExtend = kTRUE;
195  if (optSame) canExtend = kFALSE;
196 
197  Int_t nbinsx = 0, nbinsy = 0, nbinsz = 0;
198  Double_t xmin = 0, xmax = 0, ymin = 0, ymax = 0, zmin = 0, zmax = 0;
199 
200  fObject = 0;
201  char *hname = nullptr;
202  TString hnamealloc;
203  i = 0;
204  if (varexp0 && strlen(varexp0)) {
205  for (UInt_t k = strlen(varexp0) - 1; k > 0; k--) {
206  if (varexp0[k] == '>' && varexp0[k-1] == '>') {
207  i = (int)(&(varexp0[k-1]) - varexp0); // length of varexp0 before ">>"
208  hnamealloc = &(varexp0[k+1]); // use TString to copy value of the
209  hname = (char *) hnamealloc.Data();
210  break;
211  }
212  }
213  }
214  // char *hname = (char*)strstr(varexp0,">>");
215  if (hname) {
216  hkeep = 1;
217  varexp = new char[i+1];
218  varexp[0] = 0; //necessary if i=0
219  Bool_t hnameplus = kFALSE;
220  while (*hname == ' ') hname++;
221  if (*hname == '+') {
222  hnameplus = kTRUE;
223  hname++;
224  while (*hname == ' ') hname++; //skip ' '
225  }
226  j = strlen(hname) - 1; // skip ' ' at the end
227  while (j) {
228  if (hname[j] != ' ') break;
229  hname[j] = 0;
230  j--;
231  }
232 
233  if (i) {
234  strlcpy(varexp,varexp0,i+1);
235 
236  Int_t mustdelete = 0;
238 
239  // parse things that follow the name of the histo between '(' and ')'.
240  // At this point hname contains the name of the specified histogram.
241  // Now the syntax is extended to handle an hname of the following format
242  // hname(nBIN [[,[xlow]][,xhigh]],...)
243  // so enclosed in brackets is the binning information, xlow, xhigh, and
244  // the same for the other dimensions
245 
246  char *pstart; // pointer to '('
247  char *pend; // pointer to ')'
248  char *cdummy; // dummy pointer
249  int ncomma; // number of commas between '(' and ')', later number of arguments
250  int ncols; // number of columns in varexpr
251  Double_t value; // parsed value (by sscanf)
252 
253  const Int_t maxvalues = 9;
254 
255  pstart = strchr(hname, '(');
256  pend = strchr(hname, ')');
257  if (pstart != 0) { // found the bracket
258 
259  mustdelete = 1;
260 
261  // check that there is only one open and close bracket
262  if (pstart == strrchr(hname, '(') && pend == strrchr(hname, ')')) {
263 
264  // count number of ',' between '(' and ')'
265  ncomma = 0;
266  cdummy = pstart;
267  cdummy = strchr(&cdummy[1], ',');
268  while (cdummy != 0) {
269  cdummy = strchr(&cdummy[1], ',');
270  ncomma++;
271  }
272 
273  if (ncomma + 1 > maxvalues) {
274  Error("DrawSelect", "ncomma+1>maxvalues, ncomma=%d, maxvalues=%d", ncomma, maxvalues);
275  ncomma = maxvalues - 1;
276  }
277 
278  ncomma++; // number of arguments
279  cdummy = pstart;
280 
281  // number of columns
282  ncols = 1;
283  for (j = 0; j < i; j++) {
284  if (varexp[j] == ':'
285  && !((j > 0 && varexp[j-1] == ':') || varexp[j+1] == ':')
286  ) {
287  ncols++;
288  }
289  }
290  if (ncols > 3) { // max 3 columns
291  Error("DrawSelect", "ncols > 3, ncols=%d", ncols);
292  ncols = 0;
293  }
294 
295  // check dimensions before and after ">>"
296  if (ncols * 3 < ncomma) {
297  Error("DrawSelect", "ncols*3 < ncomma ncols=%d, ncomma=%d", ncols, ncomma);
298  ncomma = ncols * 3;
299  }
300 
301  // scan the values one after the other
302  for (j = 0; j < ncomma; j++) {
303  cdummy++; // skip '(' or ','
304  if (sscanf(cdummy, " %lf ", &value) == 1) {
305  cdummy = strchr(&cdummy[1], ',');
306 
307  switch (j) { // do certain settings depending on position of argument
308  case 0: // binning x-axis
309  nbinsx = (Int_t)value;
310  if (ncols < 2) {
311  gEnv->SetValue("Hist.Binning.1D.x", nbinsx);
312  } else if (ncols < 3) {
313  gEnv->SetValue("Hist.Binning.2D.x", nbinsx);
314  gEnv->SetValue("Hist.Binning.2D.Prof", nbinsx);
315  } else {
316  gEnv->SetValue("Hist.Binning.3D.x", nbinsx);
317  gEnv->SetValue("Hist.Binning.3D.Profx", nbinsx);
318  }
319 
320  break;
321  case 1: // lower limit x-axis
322  xmin = value;
323  break;
324  case 2: // upper limit x-axis
325  xmax = value;
326  break;
327  case 3: // binning y-axis
328  nbinsy = (Int_t)value;
329  if (ncols < 3) gEnv->SetValue("Hist.Binning.2D.y", nbinsy);
330  else {
331  gEnv->SetValue("Hist.Binning.3D.y", nbinsy);
332  gEnv->SetValue("Hist.Binning.3D.Profy", nbinsy);
333  }
334  break;
335  case 4: // lower limit y-axis
336  ymin = value;
337  break;
338  case 5: // upper limit y-axis
339  ymax = value;
340  break;
341  case 6: // binning z-axis
342  nbinsz = (Int_t)value;
343  gEnv->SetValue("Hist.Binning.3D.z", nbinsz);
344  break;
345  case 7: // lower limit z-axis
346  zmin = value;
347  break;
348  case 8: // upper limit z-axis
349  zmax = value;
350  break;
351  default:
352  Error("DrawSelect", "j>8");
353  break;
354  }
355  } // if sscanf == 1
356  } // for j=0;j<ncomma;j++
357  } else {
358  Error("Begin", "Two open or close brackets found, hname=%s", hname);
359  }
360 
361  // fix up hname
362  pstart[0] = '\0'; // removes things after (and including) '('
363  } // if '(' is found
364 
365  j = strlen(hname) - 1; // skip ' ' at the end
366  while (j > 0) {
367  if (hname[j] != ' ') break; // skip ' ' at the end
368  hname[j] = 0;
369  j--;
370  }
371 
372  TObject *oldObject = gDirectory->Get(hname); // if hname contains '(...)' the return values is NULL, which is what we want
373  fOldHistogram = oldObject ? dynamic_cast<TH1*>(oldObject) : 0;
374 
375  if (!fOldHistogram && oldObject && !oldObject->InheritsFrom(TH1::Class())) {
376  abrt.Form("An object of type '%s' has the same name as the requested histo (%s)", oldObject->IsA()->GetName(), hname);
377  Abort(abrt);
378  delete[] varexp;
379  return;
380  }
381  if (fOldHistogram && !hnameplus) fOldHistogram->Reset(); // reset unless adding is wanted
382 
383  if (mustdelete) {
384  if (gDebug) {
385  Warning("Begin", "Deleting old histogram, since (possibly new) limits and binnings have been given");
386  }
387  delete fOldHistogram; fOldHistogram=0;
388  }
389 
390  } else {
391  // make selection list (i.e. varexp0 starts with ">>")
392  TObject *oldObject = gDirectory->Get(hname);
393  if (optEnlist) {
394  //write into a TEntryList
395  enlist = oldObject ? dynamic_cast<TEntryList*>(oldObject) : 0;
396 
397  if (!enlist && oldObject) {
398  abrt.Form("An object of type '%s' has the same name as the requested event list (%s)",
399  oldObject->IsA()->GetName(), hname);
400  Abort(abrt);
401  delete[] varexp;
402  return;
403  }
404  if (!enlist) {
405  if (optEnlistArray) {
406  enlist = new TEntryListArray(hname, realSelection.GetTitle());
407  } else {
408  enlist = new TEntryList(hname, realSelection.GetTitle());
409  }
410  }
411  if (enlist) {
412  if (!hnameplus) {
413  if (enlist == inElist) {
414  // We have been asked to reset the input list!!
415  // Let's set it aside for now ...
416  if (optEnlistArray) {
417  inElist = new TEntryListArray(*enlist);
418  } else {
419  inElist = new TEntryList(*enlist);
420  }
421  fCleanElist = kTRUE;
422  fTree->SetEntryList(inElist);
423  }
424  enlist->Reset();
425  enlist->SetTitle(realSelection.GetTitle());
426  } else {
427  TCut old = enlist->GetTitle();
428  TCut upd = old || realSelection.GetTitle();
429  enlist->SetTitle(upd.GetTitle());
430  }
431  }
432  } else {
433  //write into a TEventList
434  evlist = oldObject ? dynamic_cast<TEventList*>(oldObject) : 0;
435 
436  if (!evlist && oldObject) {
437  abrt.Form("An object of type '%s' has the same name as the requested event list (%s)",
438  oldObject->IsA()->GetName(), hname);
439  Abort(abrt);
440  delete[] varexp;
441  return;
442  }
443  if (!evlist) {
444  evlist = new TEventList(hname, realSelection.GetTitle(), 1000, 0);
445  }
446  if (evlist) {
447  if (!hnameplus) {
448  if (evlist == fTree->GetEventList()) {
449  // We have been asked to reset the input list!!
450  // Let's set it aside for now ...
451  Abort("Input and output lists are the same!");
452  delete[] varexp;
453  return;
454  }
455  evlist->Reset();
456  evlist->SetTitle(realSelection.GetTitle());
457  } else {
458  TCut old = evlist->GetTitle();
459  TCut upd = old || realSelection.GetTitle();
460  evlist->SetTitle(upd.GetTitle());
461  }
462  }
463  }
464 
465  } // if (i)
466  } else { // if (hname)
467  hname = hdefault;
468  hkeep = 0;
469  const size_t varexpLen = strlen(varexp0) + 1;
470  varexp = new char[varexpLen];
471  strlcpy(varexp, varexp0, varexpLen);
472  if (gDirectory) {
473  fOldHistogram = (TH1*)gDirectory->Get(hname);
475  }
476  }
477 
478  // Decode varexp and selection
479  if (!CompileVariables(varexp, realSelection.GetTitle())) {
480  abrt.Form("Variable compilation failed: {%s,%s}", varexp, realSelection.GetTitle());
481  Abort(abrt);
482  delete[] varexp;
483  return;
484  }
485  if (fDimension > 4 && !(optpara || optcandle || opt5d || opt.Contains("goff"))) {
486  Abort("Too many variables. Use the option \"para\", \"gl5d\" or \"candle\" to display more than 4 variables.");
487  delete[] varexp;
488  return;
489  }
490  if (fDimension < 2 && (optpara || optcandle)) {
491  Abort("The options \"para\" and \"candle\" require at least 2 variables.");
492  delete[] varexp;
493  return;
494  }
495 
496  // In case fOldHistogram exists, check dimensionality
497  Int_t nsel = strlen(selection);
498  if (nsel > 1) {
499  htitle.Form("%s {%s}", varexp, selection);
500  } else {
501  htitle = varexp;
502  }
503  if (fOldHistogram) {
504  Int_t olddim = fOldHistogram->GetDimension();
505  Int_t mustdelete = 0;
507  profile = kTRUE;
508  olddim = 2;
509  }
511  profile = kTRUE;
512  olddim = 3;
513  }
514  if (opt.Contains("prof") && fDimension > 1) {
515  // ignore "prof" for 1D.
516  if (!profile || olddim != fDimension) mustdelete = 1;
517  } else if (opt.Contains("col") && fDimension>2) {
518  if (olddim+1 != fDimension) mustdelete = 1;
519  } else {
520  if (olddim != fDimension) mustdelete = 1;
521  }
522  if (mustdelete) {
523  Warning("Begin", "Deleting old histogram with different dimensions");
524  delete fOldHistogram;
525  fOldHistogram = 0;
526  }
527  }
528 
529  // Create a default canvas if none exists
530  fDraw = 0;
531  if (!gPad && !opt.Contains("goff") && fDimension > 0) {
532  gROOT->MakeDefCanvas();
533  if (!gPad) {
534  Abort("Creation of default canvas failed");
535  delete[] varexp;
536  return;
537  }
538  }
539 
540  // 1-D distribution
541  TH1 *hist;
542  if (fDimension == 1) {
543  fAction = 1;
544  if (!fOldHistogram) {
545  fNbins[0] = gEnv->GetValue("Hist.Binning.1D.x", 100);
546  if (gPad && optSame) {
547  TListIter np(gPad->GetListOfPrimitives());
548  TObject *op;
549  TH1 *oldhtemp = 0;
550  while ((op = np()) && !oldhtemp) {
551  if (op->InheritsFrom(TH1::Class())) oldhtemp = (TH1 *)op;
552  }
553  if (oldhtemp) {
554  fNbins[0] = oldhtemp->GetXaxis()->GetNbins();
555  fVmin[0] = oldhtemp->GetXaxis()->GetXmin();
556  fVmax[0] = oldhtemp->GetXaxis()->GetXmax();
557  } else {
558  fVmin[0] = gPad->GetUxmin();
559  fVmax[0] = gPad->GetUxmax();
560  }
561  } else {
562  fAction = -1;
563  fVmin[0] = xmin;
564  fVmax[0] = xmax;
565  if (xmin < xmax) canExtend = kFALSE;
566  }
567  }
568  if (fOldHistogram) {
569  hist = fOldHistogram;
570  fNbins[0] = hist->GetXaxis()->GetNbins();
571  } else {
572  TString precision = gEnv->GetValue("Hist.Precision.1D", "float");
573  if (precision.Contains("float")) {
574  hist = new TH1F(hname, htitle.Data(), fNbins[0], fVmin[0], fVmax[0]);
575  } else {
576  hist = new TH1D(hname, htitle.Data(), fNbins[0], fVmin[0], fVmax[0]);
577  }
578  hist->SetLineColor(fTree->GetLineColor());
579  hist->SetLineWidth(fTree->GetLineWidth());
580  hist->SetLineStyle(fTree->GetLineStyle());
581  hist->SetFillColor(fTree->GetFillColor());
582  hist->SetFillStyle(fTree->GetFillStyle());
586  if (canExtend) hist->SetCanExtend(TH1::kAllAxes);
587  if (!hkeep) {
588  hist->GetXaxis()->SetTitle(fVar[0]->GetTitle());
589  hist->SetBit(kCanDelete);
590  if (!opt.Contains("goff")) hist->SetDirectory(0);
591  }
592  if (opt.Length() && opt.Contains("e")) hist->Sumw2();
593  }
594  fVar[0]->SetAxis(hist->GetXaxis());
595  fObject = hist;
596 
597  // 2-D distribution
598  } else if (fDimension == 2 && !(optpara || optcandle)) {
599  fAction = 2;
600  if (!fOldHistogram || !optSame) {
601  fNbins[0] = gEnv->GetValue("Hist.Binning.2D.y", 40);
602  fNbins[1] = gEnv->GetValue("Hist.Binning.2D.x", 40);
603  if (opt.Contains("prof")) fNbins[1] = gEnv->GetValue("Hist.Binning.2D.Prof", 100);
604  if (optSame) {
605  TH1 *oldhtemp = (TH1*)gPad->FindObject(hdefault);
606  if (oldhtemp) {
607  fNbins[1] = oldhtemp->GetXaxis()->GetNbins();
608  fVmin[1] = oldhtemp->GetXaxis()->GetXmin();
609  fVmax[1] = oldhtemp->GetXaxis()->GetXmax();
610  fNbins[0] = oldhtemp->GetYaxis()->GetNbins();
611  fVmin[0] = oldhtemp->GetYaxis()->GetXmin();
612  fVmax[0] = oldhtemp->GetYaxis()->GetXmax();
613  } else {
614  fNbins[1] = gEnv->GetValue("Hist.Binning.2D.x", 40);
615  fVmin[1] = gPad->GetUxmin();
616  fVmax[1] = gPad->GetUxmax();
617  fNbins[0] = gEnv->GetValue("Hist.Binning.2D.y", 40);
618  fVmin[0] = gPad->GetUymin();
619  fVmax[0] = gPad->GetUymax();
620  }
621  } else {
622  if (!fOldHistogram) fAction = -2;
623  fVmin[1] = xmin;
624  fVmax[1] = xmax;
625  fVmin[0] = ymin;
626  fVmax[0] = ymax;
627  if (xmin < xmax && ymin < ymax) canExtend = kFALSE;
628  }
629  }
630  if (profile || opt.Contains("prof")) {
631  TProfile *hp;
632  if (fOldHistogram) {
633  fAction = 4;
634  hp = (TProfile*)fOldHistogram;
635  } else {
636  if (fAction < 0) {
637  fAction = -4;
638  fVmin[1] = xmin;
639  fVmax[1] = xmax;
640  if (xmin < xmax) canExtend = kFALSE;
641  }
642  if (fAction == 2) {
643  //we come here when option = "same prof"
644  fAction = -4;
645  TH1 *oldhtemp = (TH1*)gPad->FindObject(hdefault);
646  if (oldhtemp) {
647  fNbins[1] = oldhtemp->GetXaxis()->GetNbins();
648  fVmin[1] = oldhtemp->GetXaxis()->GetXmin();
649  fVmax[1] = oldhtemp->GetXaxis()->GetXmax();
650  }
651  }
652  if (opt.Contains("profs")) {
653  hp = new TProfile(hname, htitle.Data(), fNbins[1], fVmin[1], fVmax[1], "s");
654  } else if (opt.Contains("profi")) {
655  hp = new TProfile(hname, htitle.Data(), fNbins[1], fVmin[1], fVmax[1], "i");
656  } else if (opt.Contains("profg")) {
657  hp = new TProfile(hname, htitle.Data(), fNbins[1], fVmin[1], fVmax[1], "g");
658  } else {
659  hp = new TProfile(hname, htitle.Data(), fNbins[1], fVmin[1], fVmax[1], "");
660  }
661  if (!hkeep) {
662  hp->SetBit(kCanDelete);
663  if (!opt.Contains("goff")) hp->SetDirectory(0);
664  }
673  if (canExtend) hp->SetCanExtend(TH1::kAllAxes);
674  }
675  fVar[1]->SetAxis(hp->GetXaxis());
676  fObject = hp;
677 
678  } else {
679  TH2 *h2;
680  if (fOldHistogram) {
681  h2 = (TH2F*)fOldHistogram;
682  } else {
683  TString precision = gEnv->GetValue("Hist.Precision.2D", "float");
684  if (precision.Contains("float")) {
685  h2 = new TH2F(hname, htitle.Data(), fNbins[1], fVmin[1], fVmax[1], fNbins[0], fVmin[0], fVmax[0]);
686  } else {
687  h2 = new TH2D(hname, htitle.Data(), fNbins[1], fVmin[1], fVmax[1], fNbins[0], fVmin[0], fVmax[0]);
688  }
697  if (canExtend) h2->SetCanExtend(TH1::kAllAxes);
698  if (!hkeep) {
699  h2->GetXaxis()->SetTitle(fVar[1]->GetTitle());
700  h2->GetYaxis()->SetTitle(fVar[0]->GetTitle());
701  h2->SetBit(TH1::kNoStats);
702  h2->SetBit(kCanDelete);
703  if (!opt.Contains("goff")) h2->SetDirectory(0);
704  }
705  }
706  fVar[0]->SetAxis(h2->GetYaxis());
707  fVar[1]->SetAxis(h2->GetXaxis());
708  Bool_t graph = kFALSE;
709  Int_t l = opt.Length();
710  if (l == 0 || optSame) graph = kTRUE;
711  if (opt.Contains("p") || opt.Contains("*") || opt.Contains("l")) graph = kTRUE;
712  if (opt.Contains("surf") || opt.Contains("lego") || opt.Contains("cont")) graph = kFALSE;
713  if (opt.Contains("col") || opt.Contains("hist") || opt.Contains("scat")) graph = kFALSE;
714  if (opt.Contains("box")) graph = kFALSE;
715  fObject = h2;
716  if (graph) {
717  fAction = 12;
718  if (!fOldHistogram && !optSame) fAction = -12;
719  }
720  }
721 
722  // 3-D distribution
723  } else if ((fDimension == 3 || fDimension == 4) && !(optpara || optcandle)) {
724  fAction = 3;
725  if (fDimension == 4) fAction = 40;
726  if (!fOldHistogram || !optSame) {
727  fNbins[0] = gEnv->GetValue("Hist.Binning.3D.z", 20);
728  fNbins[1] = gEnv->GetValue("Hist.Binning.3D.y", 20);
729  fNbins[2] = gEnv->GetValue("Hist.Binning.3D.x", 20);
730  if (fDimension == 3 && opt.Contains("prof")) {
731  fNbins[1] = gEnv->GetValue("Hist.Binning.3D.Profy", 20);
732  fNbins[2] = gEnv->GetValue("Hist.Binning.3D.Profx", 20);
733  } else if (fDimension == 3 && opt.Contains("col")) {
734  fNbins[0] = gEnv->GetValue("Hist.Binning.2D.y", 40);
735  fNbins[1] = gEnv->GetValue("Hist.Binning.2D.x", 40);
736  }
737  if (optSame) {
738  TH1 *oldhtemp = (TH1*)gPad->FindObject(hdefault);
739  if (oldhtemp) {
740  fNbins[2] = oldhtemp->GetXaxis()->GetNbins();
741  fVmin[2] = oldhtemp->GetXaxis()->GetXmin();
742  fVmax[2] = oldhtemp->GetXaxis()->GetXmax();
743  fNbins[1] = oldhtemp->GetYaxis()->GetNbins();
744  fVmin[1] = oldhtemp->GetYaxis()->GetXmin();
745  fVmax[1] = oldhtemp->GetYaxis()->GetXmax();
746  fNbins[0] = oldhtemp->GetZaxis()->GetNbins();
747  fVmin[0] = oldhtemp->GetZaxis()->GetXmin();
748  fVmax[0] = oldhtemp->GetZaxis()->GetXmax();
749  } else {
750  TView *view = gPad->GetView();
751  if (!view) {
752  Error("Begin", "You cannot use option same when no 3D view exists");
753  fVmin[0] = fVmin[1] = fVmin[2] = -1;
754  fVmax[0] = fVmax[1] = fVmax[2] = 1;
755  view = TView::CreateView(1, fVmin, fVmax);
756  }
757  Double_t *rmin = view->GetRmin();
758  Double_t *rmax = view->GetRmax();
759  fNbins[2] = gEnv->GetValue("Hist.Binning.3D.z", 20);
760  fVmin[2] = rmin[0];
761  fVmax[2] = rmax[0];
762  fNbins[1] = gEnv->GetValue("Hist.Binning.3D.y", 20);
763  fVmin[1] = rmin[1];
764  fVmax[1] = rmax[1];
765  fNbins[0] = gEnv->GetValue("Hist.Binning.3D.x", 20);
766  fVmin[0] = rmin[2];
767  fVmax[0] = rmax[2];
768  }
769  } else {
770  if (!fOldHistogram && fDimension == 3) fAction = -3;
771  fVmin[2] = xmin;
772  fVmax[2] = xmax;
773  fVmin[1] = ymin;
774  fVmax[1] = ymax;
775  fVmin[0] = zmin;
776  fVmax[0] = zmax;
777  if (xmin < xmax && ymin < ymax && zmin < zmax) canExtend = kFALSE;
778  }
779  }
780  if ((fDimension == 3) && (profile || opt.Contains("prof"))) {
781  TProfile2D *hp;
782  if (fOldHistogram) {
783  fAction = 23;
784  hp = (TProfile2D*)fOldHistogram;
785  } else {
786  if (fAction < 0) {
787  fAction = -23;
788  fVmin[2] = xmin;
789  fVmax[2] = xmax;
790  fVmin[1] = ymin;
791  fVmax[1] = ymax;
792  if (xmin < xmax && ymin < ymax) canExtend = kFALSE;
793  }
794  if (opt.Contains("profs")) {
795  hp = new TProfile2D(hname, htitle.Data(), fNbins[2], fVmin[2], fVmax[2], fNbins[1], fVmin[1], fVmax[1], "s");
796  } else if (opt.Contains("profi")) {
797  hp = new TProfile2D(hname, htitle.Data(), fNbins[2], fVmin[2], fVmax[2], fNbins[1], fVmin[1], fVmax[1], "i");
798  } else if (opt.Contains("profg")) {
799  hp = new TProfile2D(hname, htitle.Data(), fNbins[2], fVmin[2], fVmax[2], fNbins[1], fVmin[1], fVmax[1], "g");
800  } else {
801  hp = new TProfile2D(hname, htitle.Data(), fNbins[2], fVmin[2], fVmax[2], fNbins[1], fVmin[1], fVmax[1], "");
802  }
803  if (!hkeep) {
804  hp->SetBit(kCanDelete);
805  if (!opt.Contains("goff")) hp->SetDirectory(0);
806  }
815  if (canExtend) hp->SetCanExtend(TH1::kAllAxes);
816  }
817  fVar[1]->SetAxis(hp->GetYaxis());
818  fVar[2]->SetAxis(hp->GetXaxis());
819  fObject = hp;
820  } else if (fDimension == 3 && opt.Contains("col")) {
821  TH2F *h2;
822  if (fOldHistogram) {
823  h2 = (TH2F*)fOldHistogram;
824  } else {
825  h2 = new TH2F(hname, htitle.Data(), fNbins[1], fVmin[1], fVmax[1], fNbins[0], fVmin[0], fVmax[0]);
834  if (canExtend) h2->SetCanExtend(TH1::kAllAxes);
835  if (!hkeep) {
836  h2->GetXaxis()->SetTitle(fVar[1]->GetTitle());
837  h2->GetYaxis()->SetTitle(fVar[0]->GetTitle());
838  h2->GetZaxis()->SetTitle(fVar[2]->GetTitle());
839  h2->SetBit(TH1::kNoStats);
840  h2->SetBit(kCanDelete);
841  if (!opt.Contains("goff")) h2->SetDirectory(0);
842  }
843  }
844  fVar[0]->SetAxis(h2->GetYaxis());
845  fVar[1]->SetAxis(h2->GetXaxis());
846  fObject = h2;
847  fAction = 33;
848  } else {
849  TH3 *h3;
850  if (fOldHistogram) {
851  h3 = (TH3F*)fOldHistogram;
852  } else {
853  TString precision = gEnv->GetValue("Hist.Precision.3D", "float");
854  if (precision.Contains("float")) {
855  h3 = new TH3F(hname, htitle.Data(), fNbins[2], fVmin[2], fVmax[2], fNbins[1], fVmin[1], fVmax[1], fNbins[0], fVmin[0], fVmax[0]);
856  } else {
857  h3 = new TH3D(hname, htitle.Data(), fNbins[2], fVmin[2], fVmax[2], fNbins[1], fVmin[1], fVmax[1], fNbins[0], fVmin[0], fVmax[0]);
858  }
867  if (canExtend) h3->SetCanExtend(TH1::kAllAxes);
868  if (!hkeep) {
869  //small correction for the title offsets in x,y to take into account the angles
870  Double_t xoffset = h3->GetXaxis()->GetTitleOffset();
871  Double_t yoffset = h3->GetYaxis()->GetTitleOffset();
872  h3->GetXaxis()->SetTitleOffset(1.2 * xoffset);
873  h3->GetYaxis()->SetTitleOffset(1.2 * yoffset);
874  h3->GetXaxis()->SetTitle(fVar[2]->GetTitle());
875  h3->GetYaxis()->SetTitle(fVar[1]->GetTitle());
876  h3->GetZaxis()->SetTitle(fVar[0]->GetTitle());
877  h3->SetBit(kCanDelete);
878  h3->SetBit(TH1::kNoStats);
879  if (!opt.Contains("goff")) h3->SetDirectory(0);
880  }
881  }
882  fVar[0]->SetAxis(h3->GetZaxis());
883  fVar[1]->SetAxis(h3->GetYaxis());
884  fVar[2]->SetAxis(h3->GetXaxis());
885  fObject = h3;
886  Int_t noscat = strlen(option);
887  if (optSame) noscat -= 4;
888  if (!noscat && fDimension == 3) {
889  fAction = 13;
890  if (!fOldHistogram && !optSame) fAction = -13;
891  }
892  }
893  // An Event List
894  } else if (enlist) {
895  fAction = 5;
897  fTree->SetEstimate(1);
898  fObject = enlist;
899  } else if (evlist) {
900  fAction = 5;
902  fTree->SetEstimate(1);
903  fObject = evlist;
904  } else if (optcandle || optpara || opt5d) {
905  if (optcandle) fAction = 7;
906  else if (opt5d) fAction = 8;
907  else fAction = 6;
908  }
909  if (varexp) delete[] varexp;
910  for (i = 0; i < fValSize; ++i)
911  fVarMultiple[i] = kFALSE;
913  for (i = 0; i < fDimension; ++i) {
914  if (fVar[i] && fVar[i]->GetMultiplicity()) fVarMultiple[i] = kTRUE;
915  }
916 
918 
920  fWeight = fTree->GetWeight();
921  fNfill = 0;
922 
923  for (i = 0; i < fDimension; ++i) {
924  if (!fVal[i] && fVar[i]) {
925  fVal[i] = new Double_t[(Int_t)fTree->GetEstimate()];
926  }
927  }
928 
929  if (!fW) fW = new Double_t[(Int_t)fTree->GetEstimate()];
930 
931  for (i = 0; i < fValSize; ++i) {
932  fVmin[i] = DBL_MAX;
933  fVmax[i] = -DBL_MAX;
934  }
935 }
936 
937 ////////////////////////////////////////////////////////////////////////////////
938 /// Delete internal buffers.
939 
941 {
942  ResetBit(kWarn);
943  for (Int_t i = 0; i < fValSize; ++i) {
944  delete fVar[i];
945  fVar[i] = 0;
946  }
947  delete fSelect; fSelect = 0;
948  fManager = 0;
949  fMultiplicity = 0;
950 }
951 
952 ////////////////////////////////////////////////////////////////////////////////
953 /// Compile input variables and selection expression.
954 ///
955 /// varexp is an expression of the general form e1:e2:e3
956 /// where e1,etc is a formula referencing a combination of the columns
957 ///
958 /// Example:
959 ///
960 /// varexp = x simplest case: draw a 1-Dim distribution of column named x
961 /// = sqrt(x) : draw distribution of sqrt(x)
962 /// = x*y/z
963 /// = y:sqrt(x) 2-Dim distribution of y versus sqrt(x)
964 ///
965 /// selection is an expression with a combination of the columns
966 ///
967 /// Example:
968 ///
969 /// selection = "x<y && sqrt(z)>3.2"
970 ///
971 /// in a selection all the C++ operators are authorized
972 ///
973 /// Return kFALSE if any of the variable is not compilable.
974 
975 Bool_t TSelectorDraw::CompileVariables(const char *varexp, const char *selection)
976 {
977  Int_t i, nch, ncols;
978 
979  // Compile selection expression if there is one
980  fDimension = 0;
981  ClearFormula();
982  fMultiplicity = 0;
983  fObjEval = kFALSE;
984 
985  if (strlen(selection)) {
986  fSelect = new TTreeFormula("Selection", selection, fTree);
988  if (!fSelect->GetNdim()) {
989  delete fSelect;
990  fSelect = 0;
991  return kFALSE;
992  }
993  }
994 
995  // if varexp is empty, take first column by default
996  nch = strlen(varexp);
997  if (nch == 0) {
998  fDimension = 0;
999  if (fSelect) {
1001  }
1003 
1004  if (fManager) {
1005  fManager->Sync();
1006 
1009  }
1010 
1011  return kTRUE;
1012  }
1013 
1014  // otherwise select only the specified columns
1015  std::vector<TString> varnames;
1016  ncols = SplitNames(varexp, varnames);
1017 
1018  InitArrays(ncols);
1019 
1020  fManager = new TTreeFormulaManager();
1021  if (fSelect) fManager->Add(fSelect);
1023  for (i = 0; i < ncols; ++i) {
1024  fVar[i] = new TTreeFormula(TString::Format("Var%i", i + 1), varnames[i].Data(), fTree);
1025  fVar[i]->SetQuickLoad(kTRUE);
1026  if(!fVar[i]->GetNdim()) { ClearFormula(); return kFALSE; }
1027  fManager->Add(fVar[i]);
1028  }
1029  fManager->Sync();
1030 
1033 
1034  fDimension = ncols;
1035 
1036  if (ncols == 1) {
1037  TClass *cl = fVar[0]->EvalClass();
1038  if (cl) {
1039  fObjEval = kTRUE;
1040  }
1041  }
1042  return kTRUE;
1043 }
1044 
1045 ////////////////////////////////////////////////////////////////////////////////
1046 /// Return the last values corresponding to the i-th component
1047 /// of the formula being processed (where the component are ':' separated).
1048 /// The actual number of entries is:
1049 ///
1050 /// GetSelectedRows() % tree->GetEstimate()
1051 ///
1052 /// Note GetSelectedRows currently returns the actual number of values plotted
1053 /// and thus if the formula contains arrays, this number might be greater than
1054 /// the number of entries in the trees.
1055 ///
1056 /// By default TTree::Draw creates the arrays obtained
1057 /// with all GetVal and GetW with a length corresponding to the
1058 /// parameter fEstimate. By default fEstimate=10000 and can be modified
1059 /// via TTree::SetEstimate. A possible recipe is to do
1060 ///
1061 /// tree->SetEstimate(tree->GetEntries());
1062 ///
1063 /// You must call SetEstimate if the expected number of selected rows
1064 /// is greater than 10000.
1065 ///
1066 /// See TTree::Draw for additional details.
1067 
1069 {
1070  if (i < 0 || i >= fDimension)
1071  return 0;
1072  else
1073  return fVal[i];
1074 }
1075 
1076 ////////////////////////////////////////////////////////////////////////////////
1077 /// Return the TTreeFormula corresponding to the i-th component
1078 /// of the request formula (where the component are ':' separated).
1079 
1081 {
1082  if (i < 0 || i >= fDimension)
1083  return 0;
1084  else
1085  return fVar[i];
1086 }
1087 
1088 ////////////////////////////////////////////////////////////////////////////////
1089 /// Initialization of the primitive type arrays if the new size is bigger than the available space.
1090 
1092 {
1093  if (newsize > fValSize) {
1094  Int_t oldsize = fValSize;
1095  while (fValSize < newsize)
1096  fValSize *= 2; // Double the available space until it matches the new size.
1097  if (fNbins) delete [] fNbins;
1098  if (fVmin) delete [] fVmin;
1099  if (fVmax) delete [] fVmax;
1100  if (fVarMultiple) delete [] fVarMultiple;
1101 
1102  fNbins = new Int_t[fValSize];
1103  fVmin = new Double_t[fValSize];
1104  fVmax = new Double_t[fValSize];
1105  fVarMultiple = new Bool_t[fValSize];
1106 
1107  for (Int_t i = 0; i < oldsize; ++i)
1108  delete [] fVal[i];
1109  delete [] fVal;
1110  delete [] fVar;
1111  fVal = new Double_t*[fValSize];
1112  fVar = new TTreeFormula*[fValSize];
1113  for (Int_t i = 0; i < fValSize; ++i) {
1114  fVal[i] = 0;
1115  fVar[i] = 0;
1116  }
1117  }
1118 }
1119 
1120 ////////////////////////////////////////////////////////////////////////////////
1121 /// Build Index array for names in varexp.
1122 /// This will allocated a C style array of TString and Ints
1123 
1124 UInt_t TSelectorDraw::SplitNames(const TString &varexp, std::vector<TString> &names)
1125 {
1126  names.clear();
1127 
1128  Bool_t ternary = kFALSE;
1129  Int_t prev = 0;
1130  for (Int_t i = 0; i < varexp.Length(); i++) {
1131  if (varexp[i] == ':'
1132  && !((i > 0 && varexp[i-1] == ':') || varexp[i+1] == ':')
1133  ) {
1134  if (ternary) {
1135  ternary = kFALSE;
1136  } else {
1137  names.push_back(varexp(prev, i - prev));
1138  prev = i + 1;
1139  }
1140  }
1141  if (varexp[i] == '?') {
1142  ternary = kTRUE;
1143  }
1144  }
1145  names.push_back(varexp(prev, varexp.Length() - prev));
1146  return names.size();
1147 }
1148 
1149 
1150 ////////////////////////////////////////////////////////////////////////////////
1151 /// This function is called at the first entry of a new tree in a chain.
1152 
1154 {
1155  if (fTree) fWeight = fTree->GetWeight();
1156  if (fVar) {
1157  for (Int_t i = 0; i < fDimension; ++i) {
1158  if (fVar[i]) fVar[i]->UpdateFormulaLeaves();
1159  }
1160  }
1162  return kTRUE;
1163 }
1164 
1165 ////////////////////////////////////////////////////////////////////////////////
1166 /// Called in the entry loop for all entries accepted by Select.
1167 
1169 {
1170  if (fObjEval) {
1171  ProcessFillObject(entry);
1172  return;
1173  }
1174 
1175  if (fMultiplicity) {
1176  ProcessFillMultiple(entry);
1177  return;
1178  }
1179 
1180  // simple case with no multiplicity
1181  if (fForceRead && fManager->GetNdata() <= 0) return;
1182 
1183  if (fSelect) {
1185  if (!fW[fNfill]) return;
1186  } else fW[fNfill] = fWeight;
1187  if (fVal) {
1188  for (Int_t i = 0; i < fDimension; ++i) {
1189  if (fVar[i]) fVal[i][fNfill] = fVar[i]->EvalInstance(0);
1190  }
1191  }
1192  fNfill++;
1193  if (fNfill >= fTree->GetEstimate()) {
1194  TakeAction();
1195  fNfill = 0;
1196  }
1197 }
1198 
1199 ////////////////////////////////////////////////////////////////////////////////
1200 /// Called in the entry loop for all entries accepted by Select.
1201 /// Complex case with multiplicity.
1202 
1204 {
1205  // Grab the array size of the formulas for this entry
1206  Int_t ndata = fManager->GetNdata();
1207 
1208  // No data at all, let's move on to the next entry.
1209  if (!ndata) return;
1210 
1211  // If the entry list is a TEntryListArray, get the selected subentries for this entry
1212  TEntryList *subList = 0;
1213  if (fTreeElistArray) {
1214  subList = fTreeElistArray->GetSubListForEntry(entry, fTree->GetTree());
1215  }
1216 
1217  Int_t nfill0 = fNfill;
1218 
1219  // Calculate the first values
1220  if (fSelect) {
1221  // coverity[var_deref_model] fSelectMultiple==kTRUE => fSelect != 0
1223  if (!fW[fNfill] && !fSelectMultiple) return;
1224  } else fW[fNfill] = fWeight;
1225 
1226  // Always call EvalInstance(0) to insure the loading
1227  // of the branches.
1228  if (fW[fNfill] && (!subList || subList->Contains(0))) {
1229  if (fDimension == 0 && fSelectMultiple) fCurrentSubEntry = (Long64_t) 0; // to fill TEntryListArray
1230  for (Int_t i = 0; i < fDimension; ++i) {
1231  if (fVar[i]) fVal[i][fNfill] = fVar[i]->EvalInstance(0);
1232  }
1233  fNfill++;
1234  if (fNfill >= fTree->GetEstimate()) {
1235  TakeAction();
1236  fNfill = 0;
1237  }
1238  } else {
1239  for (Int_t i = 0; i < fDimension; ++i) {
1240  if (fVar[i]) fVar[i]->ResetLoading();
1241  }
1242  }
1243  Double_t ww = fW[nfill0];
1244 
1245  for (Int_t i = 1; i < ndata; i++) {
1246  if (subList && !subList->Contains(i)) continue;
1247  if (fSelectMultiple) {
1248  // coverity[var_deref_model] fSelectMultiple==kTRUE => fSelect != 0
1249  ww = fWeight * fSelect->EvalInstance(i);
1250  if (ww == 0) continue;
1251  if (fNfill == nfill0) {
1252  for (Int_t k = 0; k < fDimension; ++k) {
1253  if (!fVarMultiple[k]) fVal[k][fNfill] = fVar[k]->EvalInstance(0);
1254  }
1255  }
1256  if (fDimension == 0) fCurrentSubEntry = (Long64_t) i; // to fill TEntryListArray
1257  }
1258  for (Int_t k = 0; k < fDimension; ++k) {
1259  if (fVarMultiple[k]) fVal[k][fNfill] = fVar[k]->EvalInstance(i);
1260  else fVal[k][fNfill] = fVal[k][nfill0];
1261  }
1262  fW[fNfill] = ww;
1263 
1264  fNfill++;
1265  if (fNfill >= fTree->GetEstimate()) {
1266  TakeAction();
1267  fNfill = 0;
1268  }
1269  }
1270 }
1271 
1272 ////////////////////////////////////////////////////////////////////////////////
1273 /// Called in the entry loop for all entries accepted by Select.
1274 /// Case where the only variable returns an object (or pointer to).
1275 
1277 {
1278  // Complex case with multiplicity.
1279 
1280  // Grab the array size of the formulas for this entry
1281  Int_t ndata = fManager->GetNdata();
1282 
1283  // No data at all, let's move on to the next entry.
1284  if (!ndata) return;
1285 
1286  Int_t nfill0 = fNfill;
1287  Double_t ww = 0;
1288 
1289  for (Int_t i = 0; i < ndata; i++) {
1290  if (i == 0) {
1291  if (fSelect) {
1293  if (!fW[fNfill] && !fSelectMultiple) return;
1294  } else fW[fNfill] = fWeight;
1295  ww = fW[nfill0];
1296  } else if (fSelectMultiple) {
1297  ww = fWeight * fSelect->EvalInstance(i);
1298  if (ww == 0) continue;
1299  }
1300  if (fDimension >= 1 && fVar[0]) {
1301  TClass *cl = fVar[0]->EvalClass();
1302  if (cl == TBits::Class()) {
1303 
1304  void *obj = fVar[0]->EvalObject(i);
1305 
1306  if (obj) {
1307  TBits *bits = (TBits*)obj;
1308  Int_t nbits = bits->GetNbits();
1309 
1310  Int_t nextbit = -1;
1311  while (1) {
1312  nextbit = bits->FirstSetBit(nextbit + 1);
1313  if (nextbit >= nbits) break;
1314  fVal[0][fNfill] = nextbit;
1315  fW[fNfill] = ww;
1316  fNfill++;
1317  }
1318  }
1319 
1320  } else {
1321 
1322  if (!TestBit(kWarn)) {
1323  Warning("ProcessFillObject",
1324  "Not implemented for %s",
1325  cl ? cl->GetName() : "unknown class");
1326  SetBit(kWarn);
1327  }
1328 
1329  }
1330  }
1331  if (fNfill >= fTree->GetEstimate()) {
1332  TakeAction();
1333  fNfill = 0;
1334  }
1335  }
1336 
1337 }
1338 
1339 ////////////////////////////////////////////////////////////////////////////////
1340 /// Set number of entries to estimate variable limits.
1341 
1343 {
1344  if (fVal) {
1345  for (Int_t i = 0; i < fValSize; ++i) {
1346  delete [] fVal[i];
1347  fVal[i] = 0;
1348  }
1349  }
1350  delete [] fW; fW = 0;
1351 }
1352 
1353 ////////////////////////////////////////////////////////////////////////////////
1354 /// Execute action for object obj fNfill times.
1355 
1357 {
1358  Int_t i;
1359  //__________________________1-D histogram_______________________
1360  if (fAction == 1)((TH1*)fObject)->FillN(fNfill, fVal[0], fW);
1361  //__________________________2-D histogram_______________________
1362  else if (fAction == 2) {
1363  TH2 *h2 = (TH2*)fObject;
1364  for (i = 0; i < fNfill; i++) h2->Fill(fVal[1][i], fVal[0][i], fW[i]);
1365  }
1366  //__________________________Profile histogram_______________________
1367  else if (fAction == 4)((TProfile*)fObject)->FillN(fNfill, fVal[1], fVal[0], fW);
1368  //__________________________Event List______________________________
1369  else if (fAction == 5) {
1371  TEntryListArray *enlistarray = (TEntryListArray*)fObject;
1372  Long64_t enumb = fTree->GetTree()->GetReadEntry();
1373  enlistarray->Enter(enumb, 0, fCurrentSubEntry);
1374  } else if (fObject->InheritsFrom(TEntryList::Class())) {
1375  TEntryList *enlist = (TEntryList*)fObject;
1376  Long64_t enumb = fTree->GetTree()->GetReadEntry();
1377  enlist->Enter(enumb);
1378  } else {
1379  TEventList *evlist = (TEventList*)fObject;
1381  if (evlist->GetIndex(enumb) < 0) evlist->Enter(enumb);
1382  }
1383  }
1384  //__________________________2D scatter plot_______________________
1385  else if (fAction == 12) {
1386  TH2 *h2 = (TH2*)fObject;
1387  if (h2->CanExtendAllAxes() && h2->TestBit(kCanDelete)) {
1388  for (i = 0; i < fNfill; i++) {
1389  if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
1390  if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
1391  if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
1392  if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
1393  }
1395  }
1396  TGraph *pm = new TGraph(fNfill, fVal[1], fVal[0]);
1397  pm->SetEditable(kFALSE);
1398  pm->SetBit(kCanDelete);
1407 
1408  if (!fDraw && !strstr(fOption.Data(), "goff")) {
1409  if (fOption.Length() == 0 || strcasecmp(fOption.Data(), "same") == 0) pm->Draw("p");
1410  else pm->Draw(fOption.Data());
1411  }
1412  if (!h2->TestBit(kCanDelete)) {
1413  for (i = 0; i < fNfill; i++) h2->Fill(fVal[1][i], fVal[0][i], fW[i]);
1414  }
1415  }
1416  //__________________________3D scatter plot_______________________
1417  else if (fAction == 3) {
1418  TH3 *h3 = (TH3*)fObject;
1419  if (!h3->TestBit(kCanDelete)) {
1420  for (i = 0; i < fNfill; i++) h3->Fill(fVal[2][i], fVal[1][i], fVal[0][i], fW[i]);
1421  }
1422  } else if (fAction == 13) {
1423  TPolyMarker3D *pm3d = new TPolyMarker3D(fNfill);
1426  pm3d->SetMarkerSize(fTree->GetMarkerSize());
1427  for (i = 0; i < fNfill; i++) {
1428  pm3d->SetPoint(i, fVal[2][i], fVal[1][i], fVal[0][i]);
1429  }
1430  pm3d->Draw();
1431  TH3 *h3 = (TH3*)fObject;
1432  if (!h3->TestBit(kCanDelete)) {
1433  for (i = 0; i < fNfill; i++) h3->Fill(fVal[2][i], fVal[1][i], fVal[0][i], fW[i]);
1434  }
1435  }
1436  //__________________________3D scatter plot (3rd variable = col)__
1437  else if (fAction == 33) {
1438  TH2 *h2 = (TH2*)fObject;
1439  TakeEstimate();
1440  Int_t ncolors = gStyle->GetNumberOfColors();
1441  TObjArray *grs = (TObjArray*)h2->GetListOfFunctions()->FindObject("graphs");
1442  Int_t col;
1443  TGraph *gr;
1444  if (!grs) {
1445  grs = new TObjArray(ncolors);
1446  grs->SetOwner();
1447  grs->SetName("graphs");
1448  h2->GetListOfFunctions()->Add(grs, "P");
1449  for (col = 0; col < ncolors; col++) {
1450  gr = new TGraph();
1454  grs->AddAt(gr, col);
1455  }
1456  }
1457  h2->SetEntries(fNfill);
1458  h2->SetMinimum(fVmin[2]);
1459  h2->SetMaximum(fVmax[2]);
1460  // Fill the graphs according to the color
1461  for (i = 0; i < fNfill; i++) {
1462  col = Int_t(ncolors * ((fVal[2][i] - fVmin[2]) / (fVmax[2] - fVmin[2])));
1463  if (col < 0) col = 0;
1464  if (col > ncolors - 1) col = ncolors - 1;
1465  gr = (TGraph*)grs->UncheckedAt(col);
1466  if (gr) gr->SetPoint(gr->GetN(), fVal[1][i], fVal[0][i]);
1467  }
1468  // Remove potential empty graphs
1469  for (col = 0; col < ncolors; col++) {
1470  gr = (TGraph*)grs->At(col);
1471  if (gr && gr->GetN() <= 0) grs->Remove(gr);
1472  }
1473  }
1474  //__________________________2D Profile Histogram__________________
1475  else if (fAction == 23) {
1476  TProfile2D *hp2 = (TProfile2D*)fObject;
1477  for (i = 0; i < fNfill; i++) hp2->Fill(fVal[2][i], fVal[1][i], fVal[0][i], fW[i]);
1478  }
1479  //__________________________4D scatter plot_______________________
1480  else if (fAction == 40) {
1481  TakeEstimate();
1482  TH3 *h3 = (TH3*)fObject;
1483  Int_t ncolors = gStyle->GetNumberOfColors();
1484  if (ncolors == 0) {
1486  ncolors = gStyle->GetNumberOfColors();
1487  }
1488  TObjArray *pms = (TObjArray*)h3->GetListOfFunctions()->FindObject("polymarkers");
1489  Int_t col;
1490  TPolyMarker3D *pm3d;
1491  if (!pms) {
1492  pms = new TObjArray(ncolors);
1493  pms->SetOwner();
1494  pms->SetName("polymarkers");
1495  h3->GetListOfFunctions()->Add(pms);
1496  for (col = 0; col < ncolors; col++) {
1497  pm3d = new TPolyMarker3D();
1498  pm3d->SetMarkerColor(gStyle->GetColorPalette(col));
1500  pm3d->SetMarkerSize(fTree->GetMarkerSize());
1501  pms->AddAt(pm3d, col);
1502  }
1503  }
1504  h3->SetEntries(fNfill);
1505  h3->SetMinimum(fVmin[3]);
1506  h3->SetMaximum(fVmax[3]);
1507  for (i = 0; i < fNfill; i++) {
1508  col = Int_t(ncolors * ((fVal[3][i] - fVmin[3]) / (fVmax[3] - fVmin[3])));
1509  if (col > ncolors-1) col = ncolors-1;
1510  if (col < 0) col = 0;
1511  pm3d = (TPolyMarker3D*)pms->UncheckedAt(col);
1512  pm3d->SetPoint(pm3d->GetLastPoint() + 1, fVal[2][i], fVal[1][i], fVal[0][i]);
1513  }
1514  }
1515  //__________________________Parallel coordinates / candle chart_______________________
1516  else if (fAction == 6 || fAction == 7) {
1517  TakeEstimate();
1518  Bool_t candle = (fAction == 7);
1519  // Using CINT to avoid a dependency in TParallelCoord
1520  if (!fOption.Contains("goff"))
1521  gROOT->ProcessLine(TString::Format("TParallelCoord::BuildParallelCoord((TSelectorDraw*)0x%lx,0x%lx)",
1522  (ULong_t)this, (ULong_t)candle));
1523  } else if (fAction == 8) {
1524  //gROOT->ProcessLineFast(TString::Format("(new TGL5DDataSet((TTree *)0x%1x))->Draw(\"%s\");", fTree, fOption.Data()));
1525  }
1526  //__________________________something else_______________________
1527  else if (fAction < 0) {
1528  fAction = -fAction;
1529  TakeEstimate();
1530  }
1531 
1532  // Do we need to update screen?
1533  fSelectedRows += fNfill;
1534  if (!fTree->GetUpdate()) return;
1535  if (fSelectedRows > fDraw + fTree->GetUpdate()) {
1536  if (fDraw) gPad->Modified();
1537  else fObject->Draw(fOption.Data());
1538  gPad->Update();
1539  fDraw = fSelectedRows;
1540  }
1541 }
1542 
1543 ////////////////////////////////////////////////////////////////////////////////
1544 /// Estimate limits for 1-D, 2-D or 3-D objects.
1545 
1547 {
1548  Int_t i;
1549  Double_t rmin[3], rmax[3];
1550  Double_t vminOld[4], vmaxOld[4];
1551  for (i = 0; i < fValSize && i < 4; i++) {
1552  vminOld[i] = fVmin[i];
1553  vmaxOld[i] = fVmax[i];
1554  }
1555  for (i = 0; i < fValSize; ++i) {
1556  fVmin[i] = DBL_MAX;
1557  fVmax[i] = - DBL_MAX;
1558  }
1559  //__________________________1-D histogram_______________________
1560  if (fAction == 1) {
1561  TH1 *h1 = (TH1*)fObject;
1562  if (h1->CanExtendAllAxes()) {
1563  for (i = 0; i < fNfill; i++) {
1564  if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
1565  if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
1566  }
1568  }
1569  h1->FillN(fNfill, fVal[0], fW);
1570  //__________________________2-D histogram_______________________
1571  } else if (fAction == 2) {
1572  TH2 *h2 = (TH2*)fObject;
1573  if (h2->CanExtendAllAxes()) {
1574  for (i = 0; i < fNfill; i++) {
1575  if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
1576  if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
1577  if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
1578  if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
1579  }
1581  }
1582  for (i = 0; i < fNfill; i++) h2->Fill(fVal[1][i], fVal[0][i], fW[i]);
1583  //__________________________Profile histogram_______________________
1584  } else if (fAction == 4) {
1585  TProfile *hp = (TProfile*)fObject;
1586  if (hp->CanExtendAllAxes()) {
1587  for (i = 0; i < fNfill; i++) {
1588  if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
1589  if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
1590  if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
1591  if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
1592  }
1594  }
1595  hp->FillN(fNfill, fVal[1], fVal[0], fW);
1596  //__________________________2D scatter plot_______________________
1597  } else if (fAction == 12) {
1598  TH2 *h2 = (TH2*)fObject;
1599  if (h2->CanExtendAllAxes()) {
1600  for (i = 0; i < fNfill; i++) {
1601  if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
1602  if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
1603  if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
1604  if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
1605  }
1607  // In case the new lower limits of h2 axis are 0, it is better to set them to the minimum of
1608  // the data set (which should be >0) to avoid data cut when plotting in log scale.
1609  TAxis *aX = h2->GetXaxis();
1610  TAxis *aY = h2->GetYaxis();
1611  Double_t xmin = aX->GetXmin();
1612  Double_t ymin = aY->GetXmin();
1613  if (xmin == 0 || ymin == 0) {
1614  if (aX->GetBinUpEdge(aX->FindFixBin(0.01*aX->GetBinWidth(aX->GetFirst()))) > fVmin[1]) xmin = fVmin[1];
1615  if (aY->GetBinUpEdge(aY->FindFixBin(0.01*aY->GetBinWidth(aY->GetFirst()))) > fVmin[0]) ymin = fVmin[0];
1616  h2->SetBins(aX->GetNbins(), xmin, aX->GetXmax(), aY->GetNbins(), ymin, aY->GetXmax());
1617  }
1618  }
1619 
1620  if (!strstr(fOption.Data(), "same") && !strstr(fOption.Data(), "goff")) {
1621  if (!h2->TestBit(kCanDelete)) {
1622  // case like: T.Draw("y:x>>myhist")
1623  // we must draw a copy before filling the histogram h2=myhist
1624  // because h2 will be filled below and we do not want to show
1625  // the binned scatter-plot, the TGraph being better.
1626  TH1 *h2c = h2->DrawCopy(fOption.Data(),"");
1627  if (h2c) h2c->SetStats(kFALSE);
1628  } else {
1629  // case like: T.Draw("y:x")
1630  // h2 is a temporary histogram (htemp). This histogram
1631  // will be automatically deleted by TPad::Clear
1632  h2->Draw();
1633  }
1634  gPad->Update();
1635  }
1636  TGraph *pm = new TGraph(fNfill, fVal[1], fVal[0]);
1637  pm->SetEditable(kFALSE);
1638  pm->SetBit(kCanDelete);
1647  if (!fDraw && !strstr(fOption.Data(),"goff")) {
1648  if (fOption.Length() == 0 || strcasecmp(fOption.Data(),"same")==0) {
1649  pm->Draw("p");
1650  }
1651  else {
1652  TString opt = fOption;
1653  opt.ToLower();
1654  if (opt.Contains("a")) {
1655  TString temp(opt);
1656  temp.ReplaceAll("same","");
1657  if (temp.Contains("a")) {
1658  if (h2->TestBit(kCanDelete)) {
1659  // h2 will be deleted, the axis setting is delegated to only
1660  // the TGraph.
1661  h2 = 0;
1662  }
1663  }
1664  }
1665  pm->Draw(fOption.Data());
1666  }
1667  }
1668  if (h2 && !h2->TestBit(kCanDelete)) {
1669  for (i = 0; i < fNfill; i++) h2->Fill(fVal[1][i], fVal[0][i], fW[i]);
1670  }
1671  //__________________________3D scatter plot with option col_______________________
1672  } else if (fAction == 33) {
1673  TH2 *h2 = (TH2*)fObject;
1674  Bool_t process2 = kFALSE;
1675  if (h2->CanExtendAllAxes()) {
1676  if (vminOld[2] == DBL_MAX)
1677  process2 = kTRUE;
1678  for (i = 0; i < fValSize && i < 4; i++) {
1679  fVmin[i] = vminOld[i];
1680  fVmax[i] = vmaxOld[i];
1681  }
1682  for (i = 0; i < fNfill; i++) {
1683  if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
1684  if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
1685  if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
1686  if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
1687  if (process2) {
1688  if (fVmin[2] > fVal[2][i]) fVmin[2] = fVal[2][i];
1689  if (fVmax[2] < fVal[2][i]) fVmax[2] = fVal[2][i];
1690  }
1691  }
1693  // In case the new lower limits of h2 axis are 0, it is better to set them to the minimum of
1694  // the data set (which should be >0) to avoid data cut when plotting in log scale.
1695  TAxis *aX = h2->GetXaxis();
1696  TAxis *aY = h2->GetYaxis();
1697  Double_t xmin = aX->GetXmin();
1698  Double_t ymin = aY->GetXmin();
1699  if (xmin == 0 || ymin == 0) {
1700  if (aX->GetBinUpEdge(aX->FindFixBin(0.01*aX->GetBinWidth(aX->GetFirst()))) > fVmin[1]) xmin = fVmin[1];
1701  if (aY->GetBinUpEdge(aY->FindFixBin(0.01*aY->GetBinWidth(aY->GetFirst()))) > fVmin[0]) ymin = fVmin[0];
1702  h2->SetBins(aX->GetNbins(), xmin, aX->GetXmax(), aY->GetNbins(), ymin, aY->GetXmax());
1703  }
1704  } else {
1705  for (i = 0; i < fNfill; i++) {
1706  if (fVmin[2] > fVal[2][i]) fVmin[2] = fVal[2][i];
1707  if (fVmax[2] < fVal[2][i]) fVmax[2] = fVal[2][i];
1708  }
1709  }
1710  //__________________________3D scatter plot_______________________
1711  } else if (fAction == 3 || fAction == 13) {
1712  TH3 *h3 = (TH3*)fObject;
1713  if (h3->CanExtendAllAxes()) {
1714  for (i = 0; i < fNfill; i++) {
1715  if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
1716  if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
1717  if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
1718  if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
1719  if (fVmin[2] > fVal[2][i]) fVmin[2] = fVal[2][i];
1720  if (fVmax[2] < fVal[2][i]) fVmax[2] = fVal[2][i];
1721  }
1723  }
1724  if (fAction == 3) {
1725  for (i = 0; i < fNfill; i++) h3->Fill(fVal[2][i], fVal[1][i], fVal[0][i], fW[i]);
1726  return;
1727  }
1728  if (!strstr(fOption.Data(), "same") && !strstr(fOption.Data(), "goff")) {
1729  if (!h3->TestBit(kCanDelete)) {
1730  // case like: T.Draw("y:x>>myhist")
1731  // we must draw a copy before filling the histogram h3=myhist
1732  // because h3 will be filled below and we do not want to show
1733  // the binned scatter-plot, the TGraph being better.
1734  TH1 *h3c = h3->DrawCopy(fOption.Data(),"");
1735  if (h3c) h3c->SetStats(kFALSE);
1736  } else {
1737  // case like: T.Draw("y:x")
1738  // h3 is a temporary histogram (htemp). This histogram
1739  // will be automatically deleted by TPad::Clear
1740  h3->Draw(fOption.Data());
1741  }
1742  gPad->Update();
1743  } else {
1744  rmin[0] = fVmin[2]; rmin[1] = fVmin[1]; rmin[2] = fVmin[0];
1745  rmax[0] = fVmax[2]; rmax[1] = fVmax[1]; rmax[2] = fVmax[0];
1746  gPad->Clear();
1747  gPad->Range(-1, -1, 1, 1);
1748  TView::CreateView(1, rmin, rmax);
1749  }
1750  TPolyMarker3D *pm3d = new TPolyMarker3D(fNfill);
1753  pm3d->SetMarkerSize(fTree->GetMarkerSize());
1754  for (i = 0; i < fNfill; i++) {
1755  pm3d->SetPoint(i, fVal[2][i], fVal[1][i], fVal[0][i]);
1756  }
1757  if (!fDraw && !strstr(fOption.Data(), "goff")) pm3d->Draw();
1758  if (!h3->TestBit(kCanDelete)) {
1759  for (i = 0; i < fNfill; i++) h3->Fill(fVal[2][i], fVal[1][i], fVal[0][i], fW[i]);
1760  }
1761 
1762  //__________________________2D Profile Histogram__________________
1763  } else if (fAction == 23) {
1764  TProfile2D *hp = (TProfile2D*)fObject;
1765  if (hp->CanExtendAllAxes()) {
1766  for (i = 0; i < fNfill; i++) {
1767  if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
1768  if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
1769  if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
1770  if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
1771  if (fVmin[2] > fVal[2][i]) fVmin[2] = fVal[2][i];
1772  if (fVmax[2] < fVal[2][i]) fVmax[2] = fVal[2][i];
1773  }
1775  }
1776  for (i = 0; i < fNfill; i++) hp->Fill(fVal[2][i], fVal[1][i], fVal[0][i], fW[i]);
1777  //__________________________4D scatter plot_______________________
1778  } else if (fAction == 40) {
1779  TH3 *h3 = (TH3*)fObject;
1780  if (h3->CanExtendAllAxes()) {
1781  for (i = 0; i < fValSize && i < 4; i++) {
1782  fVmin[i] = vminOld[i];
1783  fVmax[i] = vmaxOld[i];
1784  }
1785  for (i = 0; i < fNfill; i++) {
1786  if (fVmin[0] > fVal[0][i]) fVmin[0] = fVal[0][i];
1787  if (fVmax[0] < fVal[0][i]) fVmax[0] = fVal[0][i];
1788  if (fVmin[1] > fVal[1][i]) fVmin[1] = fVal[1][i];
1789  if (fVmax[1] < fVal[1][i]) fVmax[1] = fVal[1][i];
1790  if (fVmin[2] > fVal[2][i]) fVmin[2] = fVal[2][i];
1791  if (fVmax[2] < fVal[2][i]) fVmax[2] = fVal[2][i];
1792  if (fVmin[3] > fVal[3][i]) fVmin[3] = fVal[3][i];
1793  if (fVmax[3] < fVal[3][i]) fVmax[3] = fVal[3][i];
1794  }
1796  } else {
1797  for (i = 0; i < fNfill; i++) {
1798  if (fVmin[3] > fVal[3][i]) fVmin[3] = fVal[3][i];
1799  if (fVmax[3] < fVal[3][i]) fVmax[3] = fVal[3][i];
1800  }
1801  }
1802  }
1803  //__________________________Parallel coordinates plot / candle chart_______________________
1804  else if (fAction == 6 || fAction == 7) {
1805  for (i = 0; i < fDimension; ++i) {
1806  for (Long64_t entry = 0; entry < fNfill; entry++) {
1807  if (fVmin[i] > fVal[i][entry]) fVmin[i] = fVal[i][entry];
1808  if (fVmax[i] < fVal[i][entry]) fVmax[i] = fVal[i][entry];
1809  }
1810  }
1811  }
1812 }
1813 
1814 ////////////////////////////////////////////////////////////////////////////////
1815 /// Called at the end of a loop on a TTree.
1816 
1818 {
1819  if (fNfill) TakeAction();
1820 
1821  if ((fSelectedRows == 0) && (TestBit(kCustomHistogram) == 0)) fDraw = 1; // do not draw
1822 
1824 }
virtual void InitArrays(Int_t newsize)
Initialization of the primitive type arrays if the new size is bigger than the available space...
virtual void Enter(Long64_t entry)
Enter element entry into the list.
Definition: TEventList.cxx:191
virtual void SetTitleOffset(Float_t offset=1)
Set distance between the axis and the axis title.
Definition: TAttAxis.cxx:294
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition: TAttLine.h:43
UInt_t GetNbits() const
Definition: TBits.h:134
An array of TObjects.
Definition: TObjArray.h:37
virtual void Terminate()
Called at the end of a loop on a TTree.
float xmin
Definition: THbookFile.cxx:93
TTreeFormula * GetVar(Int_t i) const
Return the TTreeFormula corresponding to the i-th component of the request formula (where the compone...
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition: TAxis.cxx:455
long long Long64_t
Definition: RtypesCore.h:69
virtual void SetMaximum(Double_t maximum=-1111)
Definition: TH1.h:394
virtual Double_t * GetVal(Int_t i) const
Return the last values corresponding to the i-th component of the formula being processed (where the ...
A list of entries and subentries in a TTree or TChain.
virtual void SetDirectory(TDirectory *dir)
By default when an histogram is created, it is added to the list of histogram objects in the current ...
Definition: TH1.cxx:8371
3-D histogram with a float per channel (see TH1 documentation)}
Definition: TH3.h:267
virtual Double_t * GetRmax()=0
virtual Bool_t Sync()
Synchronize all the formulae.
virtual void SetEstimate(Long64_t n)
Set number of entries to estimate variable limits.
Double_t ** fVal
Definition: TSelectorDraw.h:55
float ymin
Definition: THbookFile.cxx:93
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:687
TTreeFormula ** fVar
Definition: TSelectorDraw.h:37
TEntryListArray * fTreeElistArray
Definition: TSelectorDraw.h:41
R__EXTERN TStyle * gStyle
Definition: TStyle.h:410
virtual void ProcessFill(Long64_t entry)
Called in the entry loop for all entries accepted by Select.
virtual void SetBins(Int_t nx, Double_t xmin, Double_t xmax)
Redefine x axis parameters.
Definition: TH1.cxx:8201
virtual TEntryList * GetEntryList()
Returns the entry list assigned to this tree.
Definition: TTree.cxx:5699
Int_t fAction
Pointer to previously used histogram.
Definition: TSelectorDraw.h:43
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
#define BIT(n)
Definition: Rtypes.h:83
virtual Bool_t Enter(Long64_t entry, TTree *tree, Long64_t subentry)
Add entry #entry (, #subentry) to the list.
virtual TClass * EvalClass(Int_t oper) const
Evaluate the class of the operation oper.
Bool_t * fVarMultiple
[fSelectedRows]Local buffer for weights
Definition: TSelectorDraw.h:58
See TView3D.
Definition: TView.h:25
virtual void SetMinimum(Double_t minimum=-1111)
Definition: TH1.h:395
TTreeFormulaManager * fManager
Definition: TSelectorDraw.h:39
static THLimitsFinder * GetLimitsFinder()
Return pointer to the current finder.
#define gROOT
Definition: TROOT.h:415
virtual TObject * Remove(TObject *obj)
Remove object from array.
Definition: TObjArray.cxx:718
virtual void TakeAction()
Execute action for object obj fNfill times.
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
Basic string class.
Definition: TString.h:131
1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:571
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1125
int Int_t
Definition: RtypesCore.h:41
virtual TH1 * DrawCopy(Option_t *option="", const char *name_postfix="_copy") const
Copy this histogram and Draw in the current pad.
Definition: TH1.cxx:3027
virtual void Draw(Option_t *option="")
Default Draw method for all objects.
Definition: TObject.cxx:194
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
Definition: TAttFill.h:39
Int_t * fNbins
Definition: TSelectorDraw.h:51
TObject * At(Int_t idx) const
Definition: TObjArray.h:166
virtual void * EvalObject(Int_t i=0)
Evaluate this treeformula.
Profile Histogram.
Definition: TProfile.h:32
Long64_t fCurrentSubEntry
Definition: TSelectorDraw.h:62
virtual Int_t FindGoodLimits(TH1 *h, Double_t xmin, Double_t xmax)
Compute the best axis limits for the X axis.
TH1 * fOldHistogram
pointer to Tree Event list array
Definition: TSelectorDraw.h:42
virtual void Add(TTreeFormula *)
Add a new formula to the list of formulas managed The manager of the formula will be changed and the ...
virtual void Draw(Option_t *chopt="")
Draw this graph with its current attributes.
Definition: TGraph.cxx:751
Int_t GetMultiplicity() const
Definition: TSelectorDraw.h:83
virtual Int_t GetNdim() const
Definition: TFormula.h:237
virtual Width_t GetLineWidth() const
Return the line width.
Definition: TAttLine.h:35
don&#39;t draw stats box
Definition: TH1.h:160
Iterator of linked list.
Definition: TList.h:197
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:693
virtual Bool_t CanExtendAllAxes() const
Returns true if all axes are extendable.
Definition: TH1.cxx:6256
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
Definition: TH1.cxx:6714
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:575
if object in a list can be deleted
Definition: TObject.h:58
Int_t fValSize
[fSelectedRows][fDimension] Local buffer for the variables
Definition: TSelectorDraw.h:56
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition: TAxis.cxx:525
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=0)
Set the value of a resource or create a new resource.
Definition: TEnv.cxx:736
virtual TEntryListArray * GetSubListForEntry(Long64_t entry, TTree *tree=0)
Return the list holding the subentries for the given entry or 0.
virtual Style_t GetMarkerStyle() const
Return the marker style.
Definition: TAttMarker.h:32
virtual Double_t GetWeight() const
Definition: TTree.h:529
virtual Style_t GetLineStyle() const
Return the line style.
Definition: TAttLine.h:34
virtual Int_t GetDimension() const
Definition: TH1.h:278
Int_t Fill(const Double_t *v)
Definition: TProfile2D.h:50
Double_t GetXmin() const
Definition: TAxis.h:133
Used to coordinate one or more TTreeFormula objects.
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Definition: TString.cxx:2311
void Class()
Definition: Class.C:29
TTreeFormulaManager * GetManager() const
Definition: TTreeFormula.h:189
virtual Long64_t GetReadEntry() const
Definition: TTree.h:494
virtual const char * GetOption() const
Definition: TSelector.h:59
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Definition: TAttMarker.h:38
virtual Size_t GetMarkerSize() const
Return the marker size.
Definition: TAttMarker.h:33
TString fOption
Option given to TTree::Process.
Definition: TSelector.h:41
Double_t fWeight
[fDimension] Maxima of varexp columns
Definition: TSelectorDraw.h:54
TH1F * h1
Definition: legend1.C:5
Int_t GetColorPalette(Int_t i) const
Return color number i in current palette.
Definition: TStyle.cxx:921
TTreeFormula * fSelect
[fDimension] Array of pointers to variables formula
Definition: TSelectorDraw.h:38
The 3-D histogram classes derived from the 1-D histogram classes.
Definition: TH3.h:31
Used to pass a selection expression to the Tree drawing routine.
Definition: TTreeFormula.h:58
virtual TTree * GetTree() const
Definition: TTree.h:502
virtual Int_t GetMultiplicity() const
Definition: TTreeFormula.h:191
A specialized string object used for TTree selections.
Definition: TCut.h:25
Int_t fMultiplicity
Total number of histogram fills.
Definition: TSelectorDraw.h:46
TObject * fObject
! Current object if processing object (vs. TTree)
Definition: TSelector.h:42
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition: TAttLine.h:40
virtual void Delete(Option_t *option="")
Delete this object.
Definition: TObject.cxx:168
virtual void Begin(TTree *tree)
Called every time a loop on the tree(s) starts.
float ymax
Definition: THbookFile.cxx:93
virtual Bool_t Notify()
This function is called at the first entry of a new tree in a chain.
virtual Long64_t GetChainOffset() const
Definition: TTree.h:441
TObject * fTreeElist
Definition: TSelectorDraw.h:40
virtual void SetEstimate(Long64_t nentries=1000000)
Set number of entries to estimate variable limits.
Definition: TTree.cxx:8857
Service class for 2-Dim histogram classes.
Definition: TH2.h:30
UInt_t FirstSetBit(UInt_t startBit=0) const
Return position of first non null bit (starting from position 0 and up)
Definition: TBits.cxx:359
Class to manage histogram axis.
Definition: TAxis.h:30
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition: TH1.cxx:2980
3-D histogram with a double per channel (see TH1 documentation)}
Definition: TH3.h:304
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:37
virtual void SetStatus(Long64_t status)
Definition: TSelector.h:69
virtual void Abort(const char *why, EAbort what=kAbortProcess)
Abort processing.
Definition: TSelector.cxx:116
virtual ~TSelectorDraw()
Selector destructor.
2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:251
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:442
virtual Bool_t CompileVariables(const char *varexp="", const char *selection="")
Compile input variables and selection expression.
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2289
unsigned int UInt_t
Definition: RtypesCore.h:42
virtual Float_t GetTitleOffset() const
Definition: TAttAxis.h:43
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:887
Ssiz_t Length() const
Definition: TString.h:405
Double_t * fVmin
[fDimension] Number of bins per dimension
Definition: TSelectorDraw.h:52
virtual void UpdateFormulaLeaves()
This function is called TTreePlayer::UpdateFormulaLeaves, itself called by TChain::LoadTree when a ne...
Int_t GetN() const
Definition: TGraph.h:123
A TEventList object is a list of selected events (entries) in a TTree.
Definition: TEventList.h:31
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:75
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition: TAttMarker.h:40
virtual Long64_t GetEstimate() const
Definition: TTree.h:452
TAxis * GetYaxis()
Definition: TH1.h:317
Int_t Fill(Double_t)
Invalid Fill method.
Definition: TH3.cxx:286
float xmax
Definition: THbookFile.cxx:93
void SetName(const char *name)
Definition: TCollection.h:204
1-D histogram with a double per channel (see TH1 documentation)}
Definition: TH1.h:614
Definition: graph.py:1
virtual Int_t Contains(Long64_t entry, TTree *tree=0)
Definition: TEntryList.cxx:517
Int_t GetNumberOfColors() const
Return number of colors in the color palette.
Definition: TStyle.cxx:987
virtual void Draw(Option_t *option="")
Draws 3-D polymarker with its current attributes.
virtual void AddAt(TObject *obj, Int_t idx)
Add object at position ids.
Definition: TObjArray.cxx:253
virtual void SetMarkerSize(Size_t msize=1)
Set the marker size.
Definition: TAttMarker.h:41
virtual Double_t * GetRmin()=0
TGraphErrors * gr
Definition: legend1.C:25
Long64_t fDraw
Action type.
Definition: TSelectorDraw.h:44
A specialized TSelector for TTree::Draw.
Definition: TSelectorDraw.h:31
const Int_t kCustomHistogram
const Bool_t kFALSE
Definition: RtypesCore.h:88
Long64_t fSelectedRows
Definition: TSelectorDraw.h:48
virtual Color_t GetLineColor() const
Return the line color.
Definition: TAttLine.h:33
void SetPoint(Int_t n, Double_t x, Double_t y, Double_t z)
Set point n to x, y, z.
TObject * UncheckedAt(Int_t i) const
Definition: TObjArray.h:90
virtual Int_t GetUpdate() const
Definition: TTree.h:506
Bool_t fCleanElist
Definition: TSelectorDraw.h:60
#define ClassImp(name)
Definition: Rtypes.h:365
virtual void ResetAbort()
Definition: TSelector.h:76
virtual void SetEntryList(TEntryList *list, Option_t *opt="")
Set an EntryList.
Definition: TTree.cxx:8793
Bool_t fSelectMultiple
[fDimension] true if fVar[i] has a variable index
Definition: TSelectorDraw.h:59
Double_t * fVmax
[fDimension] Minima of varexp columns
Definition: TSelectorDraw.h:53
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
virtual void ProcessFillMultiple(Long64_t entry)
Called in the entry loop for all entries accepted by Select.
unsigned long ULong_t
Definition: RtypesCore.h:51
virtual Bool_t GetReapplyCut() const
Definition: TEntryList.h:79
virtual void ProcessFillObject(Long64_t entry)
Called in the entry loop for all entries accepted by Select.
virtual Color_t GetFillColor() const
Return the fill area color.
Definition: TAttFill.h:30
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
The TH1 histogram class.
Definition: TH1.h:56
Double_t * fW
Definition: TSelectorDraw.h:57
T EvalInstance(Int_t i=0, const char *stringStack[]=0)
Evaluate this treeformula.
virtual Bool_t Enter(Long64_t entry, TTree *tree=0)
Add entry #entry to the list.
Definition: TEntryList.cxx:558
Profile2D histograms are used to display the mean value of Z and its RMS for each cell in X...
Definition: TProfile2D.h:27
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition: TAttLine.h:42
static TView * CreateView(Int_t system=1, const Double_t *rmin=0, const Double_t *rmax=0)
Create a concrete default 3-d view via the plug-in manager.
Definition: TView.cxx:27
TAxis * GetZaxis()
Definition: TH1.h:318
virtual UInt_t SetCanExtend(UInt_t extendBitMask)
Make the histogram axes extendable / not extendable according to the bit mask returns the previous bi...
Definition: TH1.cxx:6269
Mother of all ROOT objects.
Definition: TObject.h:37
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:416
Container of bits.
Definition: TBits.h:27
Long64_t fOldEstimate
Definition: TSelectorDraw.h:49
virtual const char * GetTitle() const
Returns title of object.
Definition: TObject.cxx:400
virtual void TakeEstimate()
Estimate limits for 1-D, 2-D or 3-D objects.
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition: TAxis.cxx:537
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
Set x and y values for point number i.
Definition: TGraph.cxx:2260
A 3D polymarker.
Definition: TPolyMarker3D.h:32
TList * fInput
List of objects available during processing.
Definition: TSelector.h:43
void FillN(Int_t, const Double_t *, const Double_t *, Int_t)
Fill this histogram with an array x and weights w.
Definition: TProfile.h:62
virtual void Add(TObject *obj)
Definition: TList.h:87
auto * l
Definition: textangle.C:4
virtual void Reset()
Reset this list.
virtual void FillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride=1)
Fill this histogram with an array x and weights w.
Definition: TH1.cxx:3360
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition: TH1.cxx:8454
A TGraph is an object made of two arrays X and Y with npoints each.
Definition: TGraph.h:41
Int_t fNfill
Last entry loop number when object was drawn.
Definition: TSelectorDraw.h:45
#define gPad
Definition: TVirtualPad.h:287
virtual void ClearFormula()
Delete internal buffers.
R__EXTERN Int_t gDebug
Definition: Rtypes.h:91
virtual UInt_t SplitNames(const TString &varexp, std::vector< TString > &names)
Build Index array for names in varexp.
Definition: tree.py:1
virtual void SetEntries(Double_t n)
Definition: TH1.h:381
A TTree represents a columnar dataset.
Definition: TTree.h:72
#define gDirectory
Definition: TDirectory.h:223
static void InitializeColors()
Initialize colors used by the TCanvas based graphics (via TColor objects).
Definition: TColor.cxx:1083
void SetQuickLoad(Bool_t quick)
Definition: TTreeFormula.h:207
void ResetBit(UInt_t f)
Definition: TObject.h:171
TEventList * GetEventList() const
Definition: TTree.h:458
virtual Int_t GetNdata(Bool_t forceLoadDim=kFALSE)
Return number of available instances in the formulas.
virtual Color_t GetMarkerColor() const
Return the marker color.
Definition: TAttMarker.h:31
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition: TAttFill.h:31
Int_t GetNbins() const
Definition: TAxis.h:121
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:356
Int_t Fill(Double_t)
Invalid Fill method.
Definition: TH2.cxx:292
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
TList * GetListOfFunctions() const
Definition: TH1.h:239
virtual void SetEditable(Bool_t editable=kTRUE)
if editable=kFALSE, the graph cannot be modified with the mouse by default a TGraph is editable ...
Definition: TGraph.cxx:2219
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
A List of entry numbers in a TTree or TChain.
Definition: TEntryList.h:25
virtual Int_t GetIndex(Long64_t entry) const
Return index in the list of element with value entry array is supposed to be sorted prior to this cal...
Definition: TEventList.cxx:235
const Bool_t kTRUE
Definition: RtypesCore.h:87
TSelectorDraw()
Default selector constructor.
Double_t GetXmax() const
Definition: TAxis.h:134
virtual Int_t GetLastPoint() const
Definition: TPolyMarker3D.h:56
virtual Int_t GetMultiplicity() const
virtual void SetStats(Bool_t stats=kTRUE)
Set statistics option on/off.
Definition: TH1.cxx:8424
virtual void ResetLoading()
Tell the formula that we are going to request a new entry.
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:873
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
Definition: TH1.h:316
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual void Reset(Option_t *option="")
Reset number of entries in event list.
Definition: TEventList.cxx:328
virtual void SetAxis(TAxis *axis=0)
Set the axis (in particular get the type).
2-D histogram with a double per channel (see TH1 documentation)}
Definition: TH2.h:292
const char * Data() const
Definition: TString.h:364