Logo ROOT  
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
13A 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];
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;
71 fTreeElist = 0;
72 fAction = 0;
73 fNfill = 0;
74 fDimension = 0;
75 fOldEstimate = 0;
76 fForceRead = 0;
77 fWeight = 1;
80}
81
82////////////////////////////////////////////////////////////////////////////////
83/// Selector destructor.
84
86{
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 }
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 }
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 }
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());
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());
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;
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());
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);
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
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{
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
975Bool_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;
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
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];
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
1124UInt_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);
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();
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?
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();
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);
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) {
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}
void Class()
Definition: Class.C:29
int Int_t
Definition: RtypesCore.h:43
unsigned int UInt_t
Definition: RtypesCore.h:44
const Bool_t kFALSE
Definition: RtypesCore.h:90
unsigned long ULong_t
Definition: RtypesCore.h:53
bool Bool_t
Definition: RtypesCore.h:61
double Double_t
Definition: RtypesCore.h:57
R__EXTERN Int_t gDebug
Definition: RtypesCore.h:117
long long Long64_t
Definition: RtypesCore.h:71
const Bool_t kTRUE
Definition: RtypesCore.h:89
#define BIT(n)
Definition: Rtypes.h:83
#define ClassImp(name)
Definition: Rtypes.h:361
#define gDirectory
Definition: TDirectory.h:229
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
float xmin
Definition: THbookFile.cxx:93
float ymin
Definition: THbookFile.cxx:93
float xmax
Definition: THbookFile.cxx:93
float ymax
Definition: THbookFile.cxx:93
#define gROOT
Definition: TROOT.h:406
const Int_t kCustomHistogram
R__EXTERN TStyle * gStyle
Definition: TStyle.h:410
#define gPad
Definition: TVirtualPad.h:287
virtual Int_t GetNdim() const
Definition: TFormula.h:237
virtual void SetTitleOffset(Float_t offset=1)
Set distance between the axis and the axis title.
Definition: TAttAxis.cxx:294
virtual Float_t GetTitleOffset() const
Definition: TAttAxis.h:43
virtual Color_t GetFillColor() const
Return the fill area color.
Definition: TAttFill.h:30
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition: TAttFill.h:31
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:37
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
Definition: TAttFill.h:39
virtual Color_t GetLineColor() const
Return the line color.
Definition: TAttLine.h:33
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition: TAttLine.h:42
virtual Width_t GetLineWidth() const
Return the line width.
Definition: TAttLine.h:35
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition: TAttLine.h:43
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition: TAttLine.h:40
virtual Style_t GetLineStyle() const
Return the line style.
Definition: TAttLine.h:34
virtual Style_t GetMarkerStyle() const
Return the marker style.
Definition: TAttMarker.h:32
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Definition: TAttMarker.h:38
virtual Color_t GetMarkerColor() const
Return the marker color.
Definition: TAttMarker.h:31
virtual Size_t GetMarkerSize() const
Return the marker size.
Definition: TAttMarker.h:33
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition: TAttMarker.h:40
virtual void SetMarkerSize(Size_t msize=1)
Set the marker size.
Definition: TAttMarker.h:41
Class to manage histogram axis.
Definition: TAxis.h:30
Double_t GetXmax() const
Definition: TAxis.h:134
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:416
Double_t GetXmin() const
Definition: TAxis.h:133
Int_t GetNbins() const
Definition: TAxis.h:121
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition: TAxis.cxx:537
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition: TAxis.cxx:525
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition: TAxis.cxx:455
Container of bits.
Definition: TBits.h:27
UInt_t GetNbits() const
Definition: TBits.h:134
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
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:80
void SetName(const char *name)
Definition: TCollection.h:204
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
static void InitializeColors()
Initialize colors used by the TCanvas based graphics (via TColor objects).
Definition: TColor.cxx:1086
A specialized string object used for TTree selections.
Definition: TCut.h:25
A list of entries and subentries in a TTree or TChain.
virtual Bool_t Enter(Long64_t entry, TTree *tree, Long64_t subentry)
Add entry #entry (, #subentry) to the list.
virtual TEntryListArray * GetSubListForEntry(Long64_t entry, TTree *tree=0)
Return the list holding the subentries for the given entry or 0.
A List of entry numbers in a TTree or TChain.
Definition: TEntryList.h:26
virtual Int_t Contains(Long64_t entry, TTree *tree=0)
Definition: TEntryList.cxx:519
virtual Bool_t GetReapplyCut() const
Definition: TEntryList.h:79
virtual void Reset()
Reset this list.
virtual Bool_t Enter(Long64_t entry, TTree *tree=0)
Add entry #entry to the list.
Definition: TEntryList.cxx:560
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
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
A TEventList object is a list of selected events (entries) in a TTree.
Definition: TEventList.h:31
virtual void Reset(Option_t *option="")
Reset number of entries in event list.
Definition: TEventList.cxx:329
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:236
virtual void Enter(Long64_t entry)
Enter element entry into the list.
Definition: TEventList.cxx:192
A TGraph is an object made of two arrays X and Y with npoints each.
Definition: TGraph.h:41
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
Set x and y values for point number i.
Definition: TGraph.cxx:2269
Int_t GetN() const
Definition: TGraph.h:123
virtual void Draw(Option_t *chopt="")
Draw this graph with its current attributes.
Definition: TGraph.cxx:760
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:2228
1-D histogram with a double per channel (see TH1 documentation)}
Definition: TH1.h:614
1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:571
The TH1 histogram class.
Definition: TH1.h:56
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:8393
TAxis * GetZaxis()
Definition: TH1.h:318
virtual Int_t GetDimension() const
Definition: TH1.h:278
@ kNoStats
don't draw stats box
Definition: TH1.h:160
virtual Bool_t CanExtendAllAxes() const
Returns true if all axes are extendable.
Definition: TH1.cxx:6278
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
Definition: TH1.cxx:6736
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
Definition: TH1.h:316
@ kAllAxes
Definition: TH1.h:73
virtual void SetMaximum(Double_t maximum=-1111)
Definition: TH1.h:394
TAxis * GetYaxis()
Definition: TH1.h:317
virtual void SetMinimum(Double_t minimum=-1111)
Definition: TH1.h:395
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:6291
TList * GetListOfFunctions() const
Definition: TH1.h:239
virtual TH1 * DrawCopy(Option_t *option="", const char *name_postfix="_copy") const
Copy this histogram and Draw in the current pad.
Definition: TH1.cxx:3045
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition: TH1.cxx:2998
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:3378
virtual void SetBins(Int_t nx, Double_t xmin, Double_t xmax)
Redefine x axis parameters.
Definition: TH1.cxx:8223
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition: TH1.cxx:8476
virtual void SetEntries(Double_t n)
Definition: TH1.h:381
virtual void SetStats(Bool_t stats=kTRUE)
Set statistics option on/off.
Definition: TH1.cxx:8446
2-D histogram with a double per channel (see TH1 documentation)}
Definition: TH2.h:292
2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:251
Service class for 2-Dim histogram classes.
Definition: TH2.h:30
Int_t Fill(Double_t)
Invalid Fill method.
Definition: TH2.cxx:294
3-D histogram with a double per channel (see TH1 documentation)}
Definition: TH3.h:304
3-D histogram with a float per channel (see TH1 documentation)}
Definition: TH3.h:267
The 3-D histogram classes derived from the 1-D histogram classes.
Definition: TH3.h:31
Int_t Fill(Double_t)
Invalid Fill method.
Definition: TH3.cxx:287
static THLimitsFinder * GetLimitsFinder()
Return pointer to the current finder.
virtual Int_t FindGoodLimits(TH1 *h, Double_t xmin, Double_t xmax)
Compute the best axis limits for the X axis.
Iterator of linked list.
Definition: TList.h:200
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:577
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
An array of TObjects.
Definition: TObjArray.h:37
TObject * UncheckedAt(Int_t i) const
Definition: TObjArray.h:90
virtual TObject * Remove(TObject *obj)
Remove object from array.
Definition: TObjArray.cxx:719
virtual void AddAt(TObject *obj, Int_t idx)
Add object at position ids.
Definition: TObjArray.cxx:254
TObject * At(Int_t idx) const
Definition: TObjArray.h:166
Mother of all ROOT objects.
Definition: TObject.h:37
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:357
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:187
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:877
virtual void Delete(Option_t *option="")
Delete this object.
Definition: TObject.cxx:169
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:443
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:891
virtual const char * GetTitle() const
Returns title of object.
Definition: TObject.cxx:401
virtual void Draw(Option_t *option="")
Default Draw method for all objects.
Definition: TObject.cxx:195
void ResetBit(UInt_t f)
Definition: TObject.h:186
@ kCanDelete
if object in a list can be deleted
Definition: TObject.h:58
A 3D polymarker.
Definition: TPolyMarker3D.h:33
void SetPoint(Int_t n, Double_t x, Double_t y, Double_t z)
Set point n to x, y, z.
virtual Int_t GetLastPoint() const
Definition: TPolyMarker3D.h:56
virtual void Draw(Option_t *option="")
Draws 3-D polymarker with its current attributes.
Profile2D histograms are used to display the mean value of Z and its RMS for each cell in X,...
Definition: TProfile2D.h:27
Int_t Fill(const Double_t *v)
Definition: TProfile2D.h:50
Profile Histogram.
Definition: TProfile.h:32
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
A specialized TSelector for TTree::Draw.
Definition: TSelectorDraw.h:31
TEntryListArray * fTreeElistArray
Definition: TSelectorDraw.h:41
virtual void SetEstimate(Long64_t n)
Set number of entries to estimate variable limits.
virtual void InitArrays(Int_t newsize)
Initialization of the primitive type arrays if the new size is bigger than the available space.
Int_t fAction
Pointer to previously used histogram.
Definition: TSelectorDraw.h:43
Int_t GetMultiplicity() const
Definition: TSelectorDraw.h:83
TTreeFormulaManager * fManager
Definition: TSelectorDraw.h:39
TTreeFormula * GetVar(Int_t i) const
Return the TTreeFormula corresponding to the i-th component of the request formula (where the compone...
Bool_t * fVarMultiple
[fSelectedRows]Local buffer for weights
Definition: TSelectorDraw.h:58
virtual Bool_t CompileVariables(const char *varexp="", const char *selection="")
Compile input variables and selection expression.
TSelectorDraw()
Default selector constructor.
Double_t * fW
Definition: TSelectorDraw.h:57
virtual void Terminate()
Called at the end of a loop on a TTree.
virtual UInt_t SplitNames(const TString &varexp, std::vector< TString > &names)
Build Index array for names in varexp.
Long64_t fCurrentSubEntry
Definition: TSelectorDraw.h:62
TTreeFormula * fSelect
[fDimension] Array of pointers to variables formula
Definition: TSelectorDraw.h:38
Long64_t fSelectedRows
Definition: TSelectorDraw.h:48
virtual void ClearFormula()
Delete internal buffers.
virtual ~TSelectorDraw()
Selector destructor.
virtual void TakeAction()
Execute action for object obj fNfill times.
Long64_t fOldEstimate
Definition: TSelectorDraw.h:49
Double_t fWeight
[fDimension] Maxima of varexp columns
Definition: TSelectorDraw.h:54
Int_t fNfill
Last entry loop number when object was drawn.
Definition: TSelectorDraw.h:45
virtual void ProcessFill(Long64_t entry)
Called in the entry loop for all entries accepted by Select.
TH1 * fOldHistogram
pointer to Tree Event list array
Definition: TSelectorDraw.h:42
Double_t * fVmax
[fDimension] Minima of varexp columns
Definition: TSelectorDraw.h:53
Int_t fMultiplicity
Total number of histogram fills.
Definition: TSelectorDraw.h:46
TTreeFormula ** fVar
Definition: TSelectorDraw.h:37
virtual void ProcessFillMultiple(Long64_t entry)
Called in the entry loop for all entries accepted by Select.
TObject * fTreeElist
Definition: TSelectorDraw.h:40
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 ...
Int_t * fNbins
Definition: TSelectorDraw.h:51
Double_t ** fVal
Definition: TSelectorDraw.h:55
Long64_t fDraw
Action type.
Definition: TSelectorDraw.h:44
Bool_t fSelectMultiple
[fDimension] true if fVar[i] has a variable index
Definition: TSelectorDraw.h:59
Int_t fValSize
[fSelectedRows][fDimension] Local buffer for the variables
Definition: TSelectorDraw.h:56
virtual void TakeEstimate()
Estimate limits for 1-D, 2-D or 3-D objects.
Bool_t fCleanElist
Definition: TSelectorDraw.h:60
virtual void ProcessFillObject(Long64_t entry)
Called in the entry loop for all entries accepted by Select.
Double_t * fVmin
[fDimension] Number of bins per dimension
Definition: TSelectorDraw.h:52
virtual void Begin(TTree *tree)
Called every time a loop on the tree(s) starts.
virtual Bool_t Notify()
This function is called at the first entry of a new tree in a chain.
virtual void SetStatus(Long64_t status)
Definition: TSelector.h:69
TList * fInput
List of objects available during processing.
Definition: TSelector.h:43
TString fOption
Option given to TTree::Process.
Definition: TSelector.h:41
virtual const char * GetOption() const
Definition: TSelector.h:59
virtual void Abort(const char *why, EAbort what=kAbortProcess)
Abort processing.
Definition: TSelector.cxx:116
TObject * fObject
! Current object if processing object (vs. TTree)
Definition: TSelector.h:42
virtual void ResetAbort()
Definition: TSelector.h:76
Basic string class.
Definition: TString.h:131
Ssiz_t Length() const
Definition: TString.h:405
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1125
const char * Data() const
Definition: TString.h:364
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:687
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 Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2289
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
Int_t GetColorPalette(Int_t i) const
Return color number i in current palette.
Definition: TStyle.cxx:1056
Int_t GetNumberOfColors() const
Return number of colors in the color palette.
Definition: TStyle.cxx:1122
Used to coordinate one or more TTreeFormula objects.
virtual Int_t GetNdata(Bool_t forceLoadDim=kFALSE)
Return number of available instances in the formulas.
virtual Bool_t Sync()
Synchronize all the formulae.
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 Int_t GetMultiplicity() const
Used to pass a selection expression to the Tree drawing routine.
Definition: TTreeFormula.h:58
virtual void ResetLoading()
Tell the formula that we are going to request a new entry.
TTreeFormulaManager * GetManager() const
Definition: TTreeFormula.h:189
T EvalInstance(Int_t i=0, const char *stringStack[]=0)
Evaluate this treeformula.
virtual Int_t GetMultiplicity() const
Definition: TTreeFormula.h:191
virtual void SetAxis(TAxis *axis=0)
Set the axis (in particular get the type).
virtual void UpdateFormulaLeaves()
This function is called TTreePlayer::UpdateFormulaLeaves, itself called by TChain::LoadTree when a ne...
virtual void * EvalObject(Int_t i=0)
Evaluate this treeformula.
virtual TClass * EvalClass(Int_t oper) const
Evaluate the class of the operation oper.
void SetQuickLoad(Bool_t quick)
Definition: TTreeFormula.h:207
A TTree represents a columnar dataset.
Definition: TTree.h:78
virtual Long64_t GetEstimate() const
Definition: TTree.h:461
virtual Double_t GetWeight() const
Definition: TTree.h:538
virtual TEntryList * GetEntryList()
Returns the entry list assigned to this tree.
Definition: TTree.cxx:5759
virtual void SetEstimate(Long64_t nentries=1000000)
Set number of entries to estimate variable limits.
Definition: TTree.cxx:8957
virtual Long64_t GetReadEntry() const
Definition: TTree.h:503
virtual TTree * GetTree() const
Definition: TTree.h:511
virtual void SetEntryList(TEntryList *list, Option_t *opt="")
Set an EntryList.
Definition: TTree.cxx:8893
TEventList * GetEventList() const
Definition: TTree.h:467
@ kForceRead
Definition: TTree.h:246
virtual Int_t GetUpdate() const
Definition: TTree.h:515
virtual Long64_t GetChainOffset() const
Definition: TTree.h:450
See TView3D.
Definition: TView.h:25
virtual Double_t * GetRmax()=0
virtual Double_t * GetRmin()=0
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
TGraphErrors * gr
Definition: legend1.C:25
TH1F * h1
Definition: legend1.C:5
Definition: graph.py:1
Definition: tree.py:1
auto * l
Definition: textangle.C:4