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