Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TParallelCoord.cxx
Go to the documentation of this file.
1// @(#)root/treeviewer:$Id$
2// Author: Bastien Dalla Piazza 02/08/2007
3
4/*************************************************************************
5 * Copyright (C) 1995-2007, 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#include "TParallelCoord.h"
13#include "TParallelCoordVar.h"
14#include "TParallelCoordRange.h"
15
16#include <cfloat>
17#include <iostream>
18
19#include "TROOT.h"
20#include "TVirtualPad.h"
21#include "TPolyLine.h"
22#include "TGraph.h"
23#include "TPaveText.h"
24#include "TStyle.h"
25#include "TEntryList.h"
26#include "TFrame.h"
27#include "TTree.h"
28#include "TTreePlayer.h"
29#include "TSelectorDraw.h"
30#include "TTreeFormula.h"
31#include "TView.h"
32#include "TRandom.h"
33#include "TCanvas.h"
34#include "TGaxis.h"
35#include "TFile.h"
36
37
38/** \class TParallelCoord
39Parallel Coordinates class.
40
41The multidimensional system of Parallel coordinates is a common way of studying
42high-dimensional geometry and visualizing multivariate problems. It has first
43been proposed by A. Inselberg in 1981.
44
45To show a set of points in an n-dimensional space, a backdrop is drawn
46consisting of n parallel lines. A point in n-dimensional space is represented as
47a polyline with vertices on the parallel axes; the position of the vertex on the
48i-th axis corresponds to the i-th coordinate of the point.
49
50This tool comes with a rather large gui in the editor. It is necessary to use
51this editor in order to explore a data set, as explained below.
52
53### Reduce cluttering:
54
55The main issue for parallel coordinates is the very high cluttering of the
56output when dealing with large data set. Two techniques have been implemented to
57bypass that so far:
58
59 - Draw doted lines instead of plain lines with an adjustable dots spacing. A
60 slider to adjust the dots spacing is available in the editor.
61 - Sort the entries to display with a "weight cut". On each axis is drawn a
62 histogram describing the distribution of the data on the corresponding
63 variable. The "weight" of an entry is the sum of the bin content of each bin
64 the entry is going through. An entry going through the histograms peaks will
65 have a big weight wether an entry going randomly through the histograms will
66 have a rather small weight. Setting a cut on this weight allows to draw only
67 the most representative entries. A slider set the cut is also available in
68 the gui.
69
70## Selections:
71
72Selections of specific entries can be defined over the data se using parallel
73coordinates. With that representation, a selection is an ensemble of ranges
74defined on the axes. Ranges defined on the same axis are conjugated with OR
75(an entry must be in one or the other ranges to be selected). Ranges on
76different axes are are conjugated with AND (an entry must be in all the ranges
77to be selected). Several selections can be defined with different colors. It is
78possible to generate an entry list from a given selection and apply it to the
79tree using the editor ("Apply to tree" button).
80
81## Axes:
82
83Options can be defined each axis separately using the right mouse click. These
84options can be applied to every axes using the editor.
85
86 - Axis width: If set to 0, the axis is simply a line. If higher, a color
87 histogram is drawn on the axis.
88 - Axis histogram height: If not 0, a usual bar histogram is drawn on the plot.
89
90The order in which the variables are drawn is essential to see the clusters. The
91axes can be dragged to change their position. A zoom is also available. The
92logarithm scale is also available by right clicking on the axis.
93
94## Candle chart:
95
96TParallelCoord can also be used to display a candle chart. In that mode, every
97variable is drawn in the same scale. The candle chart can be combined with the
98parallel coordinates mode, drawing the candle sticks over the axes.
99
100~~~ {.cpp}
101{
102 TCanvas *c1 = new TCanvas("c1");
103 TFile *f = TFile::Open("cernstaff.root");
104 TTree *T = (TTree*)f->Get("T");
105 T->Draw("Age:Grade:Step:Cost:Division:Nation","","para");
106 TParallelCoord* para = (TParallelCoord*)gPad->GetListOfPrimitives()->FindObject("ParaCoord");
107 TParallelCoordVar* grade = (TParallelCoordVar*)para->GetVarList()->FindObject("Grade");
108 grade->AddRange(new TParallelCoordRange(grade,11.5,14));
109 para->AddSelection("less30");
110 para->GetCurrentSelection()->SetLineColor(kViolet);
111 TParallelCoordVar* age = (TParallelCoordVar*)para->GetVarList()->FindObject("Age");
112 age->AddRange(new TParallelCoordRange(age,21,30));
113}
114~~~
115
116### Some references:
117
118 - Alfred Inselberg's Homepage <http://www.math.tau.ac.il/~aiisreal>, with
119 Visual Tutorial, History, Selected Publications and Applications.
120 - Almir Olivette Artero, Maria Cristina Ferreira de Oliveira, Haim Levkowitz,
121 "Uncovering Clusters in Crowded Parallel Coordinates Visualizations,"
122 infovis, pp. 81-88, IEEE Symposium on Information Visualization
123 (INFOVIS'04), 2004.
124*/
125
126////////////////////////////////////////////////////////////////////////////////
127/// Default constructor.
128
134
135////////////////////////////////////////////////////////////////////////////////
136/// Constructor without a reference to a tree,
137/// the datas must be added afterwards with
138/// TParallelCoord::AddVariable(Double_t*,const char*).
139
150
151////////////////////////////////////////////////////////////////////////////////
152/// Normal constructor, the datas must be added afterwards
153/// with TParallelCoord::AddVariable(Double_t*,const char*).
154
156 :TNamed("ParaCoord","ParaCoord")
157{
158 Init();
159 Int_t estimate = tree->GetEstimate();
160 if (nentries>estimate) {
161 Warning("TParallelCoord","Call tree->SetEstimate(tree->GetEntries()) to display all the tree variables");
163 } else {
165 }
167 fTree = tree;
170 else fTreeFileName = "";
171 fVarList = new TList();
172 fSelectList = new TList();
175}
176
177////////////////////////////////////////////////////////////////////////////////
178/// Destructor.
179
181{
182 if (fInitEntries != fCurrentEntries && fCurrentEntries != nullptr) delete fCurrentEntries;
183 if (fVarList) {
184 fVarList->Delete();
185 delete fVarList;
186 }
187 if (fSelectList) {
189 delete fSelectList;
190 }
191 if (fCandleAxis) delete fCandleAxis;
193}
194
195////////////////////////////////////////////////////////////////////////////////
196/// Add a variable.
197
198void TParallelCoord::AddVariable(Double_t* val, const char* title)
199{
200 ++fNvar;
201 fVarList->Add(new TParallelCoordVar(val,title,fVarList->GetSize(),this));
203}
204
205////////////////////////////////////////////////////////////////////////////////
206/// Add a variable from an expression.
207
209{
210 if(!fTree) return; // The tree from which one will get the data must be defined.
211
212 // Select in the only the entries of this TParallelCoord.
213 TEntryList *list = GetEntryList(false);
214 fTree->SetEntryList(list);
215
216 // ensure that there is only one variable given:
217
218 TString exp = varexp;
219
220 if (exp.Contains(':') || exp.Contains(">>") || exp.Contains("<<")) {
221 Warning("AddVariable","Only a single variable can be added at a time.");
222 return;
223 }
224 if (exp == ""){
225 Warning("AddVariable","Nothing to add");
226 return;
227 }
228
229 Long64_t en = fTree->Draw(varexp,"","goff");
230 if (en<0) {
231 Warning("AddVariable","%s could not be evaluated",varexp);
232 return;
233 }
234
236}
237
238////////////////////////////////////////////////////////////////////////////////
239/// Add a selection.
240
241void TParallelCoord::AddSelection(const char* title)
242{
246}
247
248////////////////////////////////////////////////////////////////////////////////
249/// Apply the current selection to the tree.
250
252{
253 if(!fTree) return;
254 if(fSelectList) {
255 if(fSelectList->GetSize() == 0) return;
257 }
260 fCurrentFirst = 0;
264 TIter next(fVarList);
265 while (auto var = (TParallelCoordVar*)next())
266 varexp.Append(TString::Format(":%s",var->GetTitle()));
267 varexp.Remove(TString::kLeading,':');
268 TSelectorDraw* selector = (TSelectorDraw*)((TTreePlayer*)fTree->GetPlayer())->GetSelector();
269 fTree->Draw(varexp.Data(),"","goff");
270 next.Reset();
271 Int_t i = 0;
272 while (auto var = (TParallelCoordVar*)next())
273 var->SetValues(fNentries, selector->GetVal(i++));
274 if (fSelectList) { // FIXME It would be better to update the selections by deleting
275 fSelectList->Delete(); // the meaningless ranges (selecting everything or nothing for example)
276 fCurrentSelection = nullptr; // after applying a new entrylist to the tree.
277 }
278 gPad->Modified();
279 gPad->Update();
280}
281
282////////////////////////////////////////////////////////////////////////////////
283/// Call constructor and add the variables.
284
286{
287 TParallelCoord* pc = new TParallelCoord(selector->GetTree(),selector->GetNfill());
288 pc->SetBit(kCanDelete);
289 selector->SetObject(pc);
291 for(Int_t i=0;i<selector->GetDimension();++i) {
292 if (selector->GetVal(i)) {
293 if (selector->GetVar(i)) {
294 pc->AddVariable(selector->GetVal(i),selector->GetVar(i)->GetTitle());
295 varexp.Append(TString::Format(":%s",selector->GetVar(i)->GetTitle()));
296 }
297 }
298 }
299 varexp.Remove(TString::kLeading,':');
300 if (selector->GetSelect())
301 varexp.Append(TString::Format("{%s}",selector->GetSelect()->GetTitle()));
302 pc->SetTitle(varexp.Data());
303 if (!candle) pc->Draw();
304 else pc->Draw("candle");
305}
306
307////////////////////////////////////////////////////////////////////////////////
308/// Clean up the selections from the ranges which could have been deleted
309/// when a variable has been deleted.
310
312{
313 TIter next(fSelectList);
314 TParallelCoordSelect* select;
315 while ((select = (TParallelCoordSelect*)next())){
316 if(select->Contains(range)) select->Remove(range);
317 }
318}
319
320////////////////////////////////////////////////////////////////////////////////
321/// Delete a selection.
322
330
331////////////////////////////////////////////////////////////////////////////////
332/// Compute the distance from the TParallelCoord.
333
335{
336 if(!gPad) return 9999;
337
338 TFrame *frame = gPad->GetFrame();
339
341
342 x1 = frame->GetX1()+0.01;
343 x2 = frame->GetX2()-0.01;
344 y2 = frame->GetY2()-0.01;
345 y1 = frame->GetY1()+0.01;
346
347 xx = gPad->AbsPixeltoX(px);
348 yy = gPad->AbsPixeltoY(py);
349
350 if(xx>x1 && xx<x2 && yy>y1 && yy<y2) return 0;
351 else return 9999;
352}
353
354////////////////////////////////////////////////////////////////////////////////
355/// Draw the parallel coordinates graph.
356
358{
359 if (!GetTree()) return;
361 bool optcandle = false;
362 TString opt = option;
363 opt.ToLower();
364 if(opt.Contains("candle")) {
365 optcandle = true;
366 opt.ReplaceAll("candle","");
367 }
368 if(optcandle) {
369 SetBit(kPaintEntries,false);
370 SetBit(kCandleChart,true);
371 SetGlobalScale(true);
372 }
373
374 if (gPad) {
375 if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
376 } else gROOT->MakeDefCanvas();
377 TView *view = gPad->GetView();
378 if(view){
379 delete view;
380 gPad->SetView(nullptr);
381 }
382 gPad->Clear();
383 if (!optcandle) {
384 if (gPad && gPad->IsA() == TCanvas::Class()
385 && !((TCanvas*)gPad)->GetShowEditor()) {
386 ((TCanvas*)gPad)->ToggleEditor();
387 ((TCanvas*)gPad)->ToggleEventStatus();
388 }
389 }
390
391 gPad->SetBit(TGraph::kClipFrame,true);
392
393 TFrame *frame = new TFrame(0.1,0.1,0.9,0.9);
394 frame->SetBorderSize(0);
395 frame->SetBorderMode(0);
396 frame->SetFillStyle(0);
397 frame->SetLineColor(gPad->GetFillColor());
398 frame->Draw();
400 TPaveText *title = new TPaveText(0.05,0.95,0.35,1);
401 title->AddText(GetTitle());
402 title->Draw();
404 TIter next(fVarList);
406 while ((var = (TParallelCoordVar*)next())) {
407 if(optcandle) {
408 var->SetBoxPlot(true);
409 var->SetHistogramHeight(0.5);
410 var->SetHistogramLineWidth(0);
411 }
412 }
413
414 if (optcandle) {
415 if (TestBit(kVertDisplay)) fCandleAxis = new TGaxis(0.05,0.1,0.05,0.9,GetGlobalMin(),GetGlobalMax());
416 else fCandleAxis = new TGaxis(0.1,0.05,0.9,0.05,GetGlobalMin(),GetGlobalMax());
417 fCandleAxis->Draw();
418 }
419
420 if (gPad && gPad->IsA() == TCanvas::Class())
421 ((TCanvas*)gPad)->Selected(gPad,this,1);
422}
423
424////////////////////////////////////////////////////////////////////////////////
425/// Execute the corresponding entry.
426
427void TParallelCoord::ExecuteEvent(Int_t /*entry*/, Int_t /*px*/, Int_t /*py*/)
428{
429 if (!gPad) return;
430 gPad->SetCursor(kHand);
431}
432
433////////////////////////////////////////////////////////////////////////////////
434/// Return the selection currently being edited.
435
444
445////////////////////////////////////////////////////////////////////////////////
446/// Get the whole entry list or one for a selection.
447
449{
450 if(!sel || fCurrentSelection->GetSize() == 0){ // If no selection is specified, return the entry list of all the entries.
451 return fInitEntries;
452 } else { // return the entry list corresponding to the current selection.
454 TIter next(fVarList);
455 for (Long64_t li=0;li<fNentries;++li) {
456 next.Reset();
457 bool inrange=true;
459 while((var = (TParallelCoordVar*)next())){
460 if(!var->Eval(li,fCurrentSelection)) inrange = false;
461 }
462 if(!inrange) continue;
464 }
465 return enlist;
466 }
467}
468
469////////////////////////////////////////////////////////////////////////////////
470/// return the global maximum.
471
473{
475 TIter next(fVarList);
477 while ((var = (TParallelCoordVar*)next())) {
478 if (gmax < var->GetCurrentMax()) gmax = var->GetCurrentMax();
479 }
480 return gmax;
481}
482
483////////////////////////////////////////////////////////////////////////////////
484/// return the global minimum.
485
487{
489 TIter next(fVarList);
491 while ((var = (TParallelCoordVar*)next())) {
492 if (gmin > var->GetCurrentMin()) gmin = var->GetCurrentMin();
493 }
494 return gmin;
495}
496
497////////////////////////////////////////////////////////////////////////////////
498/// get the binning of the histograms.
499
501{
502 return ((TParallelCoordVar*)fVarList->First())->GetNbins();
503}
504
505////////////////////////////////////////////////////////////////////////////////
506/// Get a selection from its title.
507
509{
510 TIter next(fSelectList);
512 while ((sel = (TParallelCoordSelect*)next()) && strcmp(title,sel->GetTitle())) { }
513 return sel;
514}
515
516////////////////////////////////////////////////////////////////////////////////
517/// return the tree if fTree is defined. If not, the method try to load the tree
518/// from fTreeFileName.
519
521{
522 if (fTree) return fTree;
523 if (fTreeFileName=="" || fTreeName=="") {
524 Error("GetTree","Cannot load the tree: no tree defined!");
525 return nullptr;
526 }
528 if (!f) {
529 Error("GetTree","Tree file name : \"%s\" does not exist (Are you in the correct directory?).",fTreeFileName.Data());
530 return nullptr;
531 } else if (f->IsZombie()) {
532 Error("GetTree","while opening \"%s\".",fTreeFileName.Data());
533 return nullptr;
534 } else {
535 fTree = (TTree*)f->Get(fTreeName.Data());
536 if (!fTree) {
537 Error("GetTree","\"%s\" not found in \"%s\".", fTreeName.Data(), fTreeFileName.Data());
538 return nullptr;
539 } else {
542 TIter next(fVarList);
543 while (auto var = (TParallelCoordVar*)next())
544 varexp.Append(TString::Format(":%s",var->GetTitle()));
545 varexp.Remove(TString::kLeading,':');
546 fTree->Draw(varexp.Data(),"","goff");
547 TSelectorDraw* selector = (TSelectorDraw*)((TTreePlayer*)fTree->GetPlayer())->GetSelector();
548 next.Reset();
549 Int_t i = 0;
550 while (auto var = (TParallelCoordVar*)next())
551 var->SetValues(fNentries, selector->GetVal(i++));
552 return fTree;
553 }
554 }
555}
556
557////////////////////////////////////////////////////////////////////////////////
558/// Get the variables values from its title.
559
561{
562 TIter next(fVarList);
563 TParallelCoordVar* var = nullptr;
564 while(((var = (TParallelCoordVar*)next()) != nullptr) && (var->GetTitle() != vartitle)) { }
565 if(!var) return nullptr;
566 else return var->GetValues();
567}
568
569////////////////////////////////////////////////////////////////////////////////
570/// Get the variables values from its index.
571
573{
574 if(i<0 || (UInt_t)i>fNvar) return nullptr;
575 else return ((TParallelCoordVar*)fVarList->At(i))->GetValues();
576}
577
578////////////////////////////////////////////////////////////////////////////////
579/// Initialise the data members of TParallelCoord.
580
582{
583 fNentries = 0;
584 fVarList = nullptr;
585 fSelectList = nullptr;
586 SetBit(kVertDisplay,true);
587 SetBit(kCurveDisplay,false);
588 SetBit(kPaintEntries,true);
589 SetBit(kLiveUpdate,false);
590 SetBit(kGlobalScale,false);
591 SetBit(kCandleChart,false);
592 SetBit(kGlobalLogScale,false);
593 fTree = nullptr;
594 fCurrentEntries = nullptr;
595 fInitEntries = nullptr;
596 fCurrentSelection = nullptr;
597 fNvar = 0;
598 fDotsSpacing = 0;
599 fCurrentFirst = 0;
600 fCurrentN = 0;
601 fCandleAxis = nullptr;
602 fWeightCut = 0;
603 fLineWidth = 1;
604 fLineColor = kGreen-8;
605 fTreeName = "";
606 fTreeFileName = "";
607}
608
609////////////////////////////////////////////////////////////////////////////////
610/// Paint the parallel coordinates graph.
611
613{
614 if (!GetTree()) return;
615 gPad->Range(0,0,1,1);
616 TFrame *frame = gPad->GetFrame();
617 frame->SetLineColor(gPad->GetFillColor());
620 PaintEntries(nullptr);
621 TIter next(fSelectList);
623 while((sel = (TParallelCoordSelect*)next())) {
624 if(sel->GetSize()>0 && sel->TestBit(TParallelCoordSelect::kActivated)) {
626 }
627 }
628 }
629 gPad->RangeAxis(0,0,1,1);
630
632 TParallelCoordVar* var=nullptr;
633 while((var = (TParallelCoordVar*)nextVar())) {
634 var->Paint();
635 }
636}
637
638////////////////////////////////////////////////////////////////////////////////
639/// Loop over the entries and paint them.
640
642{
643 if (fVarList->GetSize() < 2) return;
644 Int_t i=0;
645 Long64_t n=0;
646
647 Double_t *x = new Double_t[fNvar];
648 Double_t *y = new Double_t[fNvar];
649
650 TGraph *gr = nullptr;
651 TPolyLine *pl = nullptr;
652 TAttLine *evline = nullptr;
653
654 if (TestBit (kCurveDisplay)) {gr = new TGraph(fNvar); evline = (TAttLine*)gr;}
655 else {pl = new TPolyLine(fNvar); evline = (TAttLine*)pl;}
656
657 if (fDotsSpacing == 0) evline->SetLineStyle(1);
658 else evline->SetLineStyle(11);
659 if (!sel){
660 evline->SetLineWidth(GetLineWidth());
661 evline->SetLineColor(GetLineColor());
662 } else {
663 evline->SetLineWidth(sel->GetLineWidth());
664 evline->SetLineColor(sel->GetLineColor());
665 }
667
668 TFrame *frame = gPad->GetFrame();
669 Double_t lx = ((frame->GetX2() - frame->GetX1())/(fNvar-1));
670 Double_t ly = ((frame->GetY2() - frame->GetY1())/(fNvar-1));
671 Double_t a,b;
672 TRandom r;
673
675 TListIter next(fVarList);
676 bool inrange = true;
677 // Loop to check whenever the entry must be painted.
678 if (sel) {
679 while ((var = (TParallelCoordVar*)next())){
680 if (!var->Eval(n,sel)) inrange = false;
681 }
682 }
683 if (fWeightCut > 0) {
684 next.Reset();
685 Int_t entryweight = 0;
686 while ((var = (TParallelCoordVar*)next())) entryweight+=var->GetEntryWeight(n);
687 if (entryweight/(Int_t)fNvar < fWeightCut) inrange = false;
688 }
689 if(!inrange) continue;
690 i = 0;
691 next.Reset();
692 // Loop to set the polyline points.
693 while ((var = (TParallelCoordVar*)next())) {
694 var->GetEntryXY(n,x[i],y[i]);
695 ++i;
696 }
697 // beginning to paint the first point at a random distance
698 // to avoid artefacts when increasing the dots spacing.
699 if (fDotsSpacing != 0) {
700 if (TestBit(kVertDisplay)) {
701 a = (y[1]-y[0])/(x[1]-x[0]);
702 b = y[0]-a*x[0];
703 x[0] = x[0]+lx*r.Rndm();
704 y[0] = a*x[0]+b;
705 } else {
706 a = (x[1]-x[0])/(y[1]-y[0]);
707 b = x[0]-a*y[0];
708 y[0] = y[0]+ly*r.Rndm();
709 x[0] = a*y[0]+b;
710 }
711 }
712 if (pl) pl->PaintPolyLine(fNvar,x,y);
713 else gr->PaintGraph(fNvar,x,y,"C");
714 }
715
716 if (pl) delete pl;
717 if (gr) delete gr;
718 delete [] x;
719 delete [] y;
720}
721
722////////////////////////////////////////////////////////////////////////////////
723/// Delete a variable from the graph.
724
731
732////////////////////////////////////////////////////////////////////////////////
733/// Delete the variable "vartitle" from the graph.
734
736{
737 TIter next(fVarList);
738 TParallelCoordVar* var=nullptr;
739 while((var = (TParallelCoordVar*)next())) {
740 if (!strcmp(var->GetTitle(),vartitle)) break;
741 }
742 if(!var) {
743 Error("RemoveVariable","\"%s\" not a variable",vartitle);
744 return false;
745 } else {
746 RemoveVariable(var);
747 delete var;
748 return true;
749 }
750}
751
752////////////////////////////////////////////////////////////////////////////////
753/// Reset the tree entry list to the initial one..
754
756{
757 if(!fTree) return;
761 fCurrentFirst = 0;
763 TString varexp = "";
764 TIter next(fVarList);
765 while (auto var = (TParallelCoordVar*)next())
766 varexp.Append(TString::Format(":%s",var->GetTitle()));
767 varexp.Remove(TString::kLeading,':');
768 fTree->Draw(varexp.Data(),"","goff");
769 next.Reset();
770 TSelectorDraw* selector = (TSelectorDraw*)((TTreePlayer*)fTree->GetPlayer())->GetSelector();
771 Int_t i = 0;
772 while (auto var = (TParallelCoordVar*)next()) {
773 var->SetValues(fNentries, selector->GetVal(i++));
774 }
775 if (fSelectList) { // FIXME It would be better to update the selections by deleting
776 fSelectList->Delete(); // the meaningless ranges (selecting everything or nothing for example)
777 fCurrentSelection = nullptr; // after applying a new entrylist to the tree.
778 }
779 gPad->Modified();
780 gPad->Update();
781}
782
783////////////////////////////////////////////////////////////////////////////////
784/// Save the entry lists in a root file "filename.root".
785
787{
789 if (sfile.IsNull())
790 sfile.Form("%s_parallelcoord_entries.root", fTree->GetName());
791
793 TFile *f = TFile::Open(sfile.Data());
794 if (f) {
795 Warning("SaveEntryLists", "%s already exists.", sfile.Data());
796 if (!overwrite)
797 return;
798 Warning("SaveEntryLists", "Overwriting.");
799 f = new TFile(sfile.Data(), "RECREATE");
800 } else {
801 f = new TFile(sfile.Data(), "CREATE");
802 }
803 gDirectory = f;
804 fInitEntries->Write("initentries");
805 fCurrentEntries->Write("currententries");
806 f->Close();
807 delete f;
809 Info("SaveEntryLists", "File \"%s\" written.", sfile.Data());
810}
811
812////////////////////////////////////////////////////////////////////////////////
813/// Save the TParallelCoord in a macro.
814
816{
817 // Save the entrylists.
818 TString filename = TString::Format("%s_parallelcoord_entries.root", fTree->GetName());
819 SaveEntryLists(filename, true); // FIXME overwriting by default.
820 SaveTree(fTreeFileName, true); // FIXME overwriting by default.
821
822 if (!gROOT->ClassSaved(Class())) {
823 out << " TFile *para_f = nullptr, *para_entries = nullptr;\n";
824 out << " TTree* para_tree = nullptr;\n";
825 out << " TEntryList *para_currententries = nullptr;\n";
826 out << " TParallelCoordSelect *para_sel = nullptr;\n";
827 out << " TParallelCoordVar* para_var = nullptr;\n";
828 out << " TSelectorDraw *para_selector = nullptr;\n";
829 out << " TParallelCoord *para = nullptr;\n";
830 }
831 out << " // Create a TParallelCoord.\n";
832 out << " para_f = TFile::Open(\"" << TString(fTreeFileName).ReplaceSpecialCppChars() << "\");\n";
833 out << " para_tree = (TTree *)para_f->Get(\"" << fTreeName << "\");\n";
834 out << " para = new TParallelCoord(para_tree, " << fNentries << ");\n";
835 out << " // Load the entrylists.\n";
836 out << " para_entries = TFile::Open(\"" << TString(filename).ReplaceSpecialCppChars() << "\");\n";
837 out << " para_currententries = (TEntryList *)para_entries->Get(\"currententries\");\n";
838 out << " para_tree->SetEntryList(para_currententries);\n";
839 out << " para->SetInitEntries((TEntryList*)para_entries->Get(\"initentries\"));\n";
840 out << " para->SetCurrentEntries(para_currententries);\n";
841 TIter next(fSelectList);
842 out << " para->GetSelectList()->Delete();\n";
843 while (auto sel = (TParallelCoordSelect *)next()) {
844 out << " para->AddSelection(\"" << TString(sel->GetTitle()).ReplaceSpecialCppChars() << "\");\n";
845 out << " para_sel = (TParallelCoordSelect*)para->GetSelectList()->Last();\n";
846 sel->SaveLineAttributes(out, "para_sel", -1, -1, 1);
847 }
850 while (auto var = (TParallelCoordVar *)nextbis()) {
851 if (!varexp.IsNull())
852 varexp.Append(":");
853 varexp.Append(var->GetTitle());
854 }
855 out << " para_tree->Draw(\"" << varexp.ReplaceSpecialCppChars() << "\", \"\", \"goff\");\n";
856 out << " para_selector = (TSelectorDraw *)((TTreePlayer *)para_tree->GetPlayer())->GetSelector();\n";
857 nextbis.Reset();
858 Int_t i = 0;
859 while (auto var = (TParallelCoordVar *)nextbis()) {
860 out << " //***************************************\n";
861 out << " // Create the axis \"" << var->GetTitle() << "\".\n";
862 out << " para->AddVariable(para_selector->GetVal(" << i++ << "), \"" << TString(var->GetTitle()).ReplaceSpecialCppChars() << "\");\n";
863 out << " para_var = (TParallelCoordVar *)para->GetVarList()->Last();\n";
864 var->SavePrimitive(out, "pcalled");
865 }
866 out << " //***************************************\n";
867 out << " // Set the TParallelCoord parameters.\n";
868 out << " para->SetCurrentFirst(" << fCurrentFirst << ");\n";
869 out << " para->SetCurrentN(" << fCurrentN << ");\n";
870 out << " para->SetWeightCut(" << fWeightCut << ");\n";
871 out << " para->SetDotsSpacing(" << fDotsSpacing << ");\n";
872 out << " para->SetLineColor(" << TColor::SavePrimitiveColor(GetLineColor()) << ");\n";
873 out << " para->SetLineWidth(" << GetLineWidth() << ");\n";
874 out << " para->SetBit(TParallelCoord::kVertDisplay, " << TestBit(kVertDisplay) << ");\n";
875 out << " para->SetBit(TParallelCoord::kCurveDisplay, " << TestBit(kCurveDisplay) << ");\n";
876 out << " para->SetBit(TParallelCoord::kPaintEntries, " << TestBit(kPaintEntries) << ");\n";
877 out << " para->SetBit(TParallelCoord::kLiveUpdate, " << TestBit(kLiveUpdate) << ");\n";
878 out << " para->SetBit(TParallelCoord::kGlobalLogScale, " << TestBit(kGlobalLogScale) << ");\n";
880 out << " para->SetGlobalScale(true);\n";
882 out << " para->SetCandleChart(true);\n";
884 out << " para->SetGlobalLogScale(true);\n";
885 out << " \n";
886 SavePrimitiveDraw(out, "para", option);
887}
888
889////////////////////////////////////////////////////////////////////////////////
890/// Save the tree in a file if fTreeFileName == "".
891
893{
894 if (!fTreeFileName.IsNull())
895 return;
897 if (sfile.IsNull())
898 sfile.Form("%s.root",fTree->GetName());
899
900 TFile* f = TFile::Open(sfile.Data());
901 if (f) {
902 Warning("SaveTree","%s already exists.", sfile.Data());
903 if (!overwrite) return;
904 else Warning("SaveTree","Overwriting.");
905 f = new TFile(sfile.Data(),"RECREATE");
906 } else {
907 f = new TFile(sfile.Data(),"CREATE");
908 }
909 gDirectory = f;
912 Info("SaveTree", "File \"%s\" written.",sfile.Data());
913}
914
915////////////////////////////////////////////////////////////////////////////////
916/// Update the position of the axes.
917
919{
920 if(!gPad) return;
921 bool vert = TestBit (kVertDisplay);
922 TFrame *frame = gPad->GetFrame();
923 if (fVarList->GetSize() > 1) {
924 if (vert) {
925 frame->SetX1(1.0/((Double_t)fVarList->GetSize()+1));
926 frame->SetX2(1-frame->GetX1());
927 frame->SetY1(0.1);
928 frame->SetY2(0.9);
929 gPad->RangeAxis(1.0/((Double_t)fVarList->GetSize()+1),0.1,1-frame->GetX1(),0.9);
930 } else {
931 frame->SetX1(0.1);
932 frame->SetX2(0.9);
933 frame->SetY1(1.0/((Double_t)fVarList->GetSize()+1));
934 frame->SetY2(1-frame->GetY1());
935 gPad->RangeAxis(0.1,1.0/((Double_t)fVarList->GetSize()+1),0.9,1-frame->GetY1());
936 }
937
938 Double_t horSpace = (frame->GetX2() - frame->GetX1())/(fNvar-1);
939 Double_t verSpace = (frame->GetY2() - frame->GetY1())/(fNvar-1);
940 Int_t i=0;
941 TIter next(fVarList);
942
944 while((var = (TParallelCoordVar*)next())){
945 if (vert) var->SetX(gPad->GetFrame()->GetX1() + i*horSpace,TestBit(kGlobalScale));
946 else var->SetY(gPad->GetFrame()->GetY1() + i*verSpace,TestBit(kGlobalScale));
947 ++i;
948 }
949 } else if (fVarList->GetSize()==1) {
950 frame->SetX1(0.1);
951 frame->SetX2(0.9);
952 frame->SetY1(0.1);
953 frame->SetY2(0.9);
955 else ((TParallelCoordVar*)fVarList->First())->SetY(0.5,TestBit(kGlobalScale));
956 }
957}
958
959////////////////////////////////////////////////////////////////////////////////
960/// Set the same histogram axis binning for all axis.
961
963{
964 TIter next(fVarList);
966 while((var = (TParallelCoordVar*)next())) var->SetHistogramBinning(n);
967}
968
969////////////////////////////////////////////////////////////////////////////////
970/// Set the same histogram axis height for all axis.
971
973{
974 TIter next(fVarList);
976 while((var = (TParallelCoordVar*)next())) var->SetHistogramHeight(h);
977}
978
979////////////////////////////////////////////////////////////////////////////////
980/// All axes in log scale.
981
983{
984 if (lt == TestBit(kGlobalLogScale)) return;
986 TIter next(fVarList);
988 while ((var = (TParallelCoordVar*)next())) var->SetLogScale(lt);
990}
991
992////////////////////////////////////////////////////////////////////////////////
993/// Constraint all axes to the same scale.
994
996{
998 if (fCandleAxis) {
999 delete fCandleAxis;
1000 fCandleAxis = nullptr;
1001 }
1002 if (gl) {
1003 Double_t min,max;
1004 min = GetGlobalMin();
1005 max = GetGlobalMax();
1006 if (TestBit(kGlobalLogScale) && min<=0) min = 0.00001*max;
1007 if (TestBit(kVertDisplay)) {
1008 if (!TestBit(kGlobalLogScale)) fCandleAxis = new TGaxis(0.05,0.1,0.05,0.9,min,max);
1009 else fCandleAxis = new TGaxis(0.05,0.1,0.05,0.9,min,max,510,"G");
1010 } else {
1011 if (!TestBit(kGlobalLogScale)) fCandleAxis = new TGaxis(0.1,0.05,0.9,0.05,min,max);
1012 else fCandleAxis = new TGaxis(0.1,0.05,0.9,0.05,min,max,510,"G");
1013 }
1014 fCandleAxis->Draw();
1015 SetGlobalMin(min);
1016 SetGlobalMax(max);
1017 TIter next(fVarList);
1018 TParallelCoordVar* var;
1019 while ((var = (TParallelCoordVar*)next())) var->GetHistogram();
1020 }
1021 gPad->Modified();
1022 gPad->Update();
1023}
1024
1025////////////////////////////////////////////////////////////////////////////////
1026/// Set the same histogram axis line width for all axis.
1027
1029{
1030 TIter next(fVarList);
1031 TParallelCoordVar *var;
1032 while((var = (TParallelCoordVar*)next())) var->SetHistogramLineWidth(lw);
1033}
1034
1035////////////////////////////////////////////////////////////////////////////////
1036/// Set a candle chart display.
1037
1039{
1042 TIter next(fVarList);
1043 TParallelCoordVar* var;
1044 while ((var = (TParallelCoordVar*)next())) {
1045 var->SetBoxPlot(can);
1046 var->SetHistogramLineWidth(0);
1047 }
1048 if (fCandleAxis) delete fCandleAxis;
1049 fCandleAxis = nullptr;
1051 if (can) {
1052 if (TestBit(kVertDisplay)) fCandleAxis = new TGaxis(0.05,0.1,0.05,0.9,GetGlobalMin(),GetGlobalMax());
1053 else fCandleAxis = new TGaxis(0.1,0.05,0.9,0.05,GetGlobalMin(),GetGlobalMax());
1054 fCandleAxis->Draw();
1055 } else {
1056 if (fCandleAxis) {
1057 delete fCandleAxis;
1058 fCandleAxis = nullptr;
1059 }
1060 }
1061 gPad->Modified();
1062 gPad->Update();
1063}
1064
1065////////////////////////////////////////////////////////////////////////////////
1066/// Set the first entry to be displayed.
1067
1069{
1070 if(f<0 || f>fNentries) return;
1071 fCurrentFirst = f;
1073 TIter next(fVarList);
1074 TParallelCoordVar* var;
1075 while ((var = (TParallelCoordVar*)next())) {
1076 var->GetMinMaxMean();
1077 var->GetHistogram();
1079 }
1080}
1081
1082////////////////////////////////////////////////////////////////////////////////
1083/// Set the number of entry to be displayed.
1084
1086{
1087 if(n<=0) return;
1089 else fCurrentN = n;
1090 TIter next(fVarList);
1091 TParallelCoordVar* var;
1092 while ((var = (TParallelCoordVar*)next())) {
1093 var->GetMinMaxMean();
1094 var->GetHistogram();
1096 }
1097}
1098
1099////////////////////////////////////////////////////////////////////////////////
1100/// Set the selection being edited.
1101
1103{
1105 TIter next(fSelectList);
1107 while((sel = (TParallelCoordSelect*)next()) && strcmp(sel->GetTitle(),title))
1108 if (sel) fCurrentSelection = sel;
1109 return sel;
1110}
1111
1112////////////////////////////////////////////////////////////////////////////////
1113/// Set the selection being edited.
1114
1120
1121////////////////////////////////////////////////////////////////////////////////
1122/// Set dots spacing. Modify the line style 11.
1123/// If the canvas support transparency dot spacing is ignored.
1124
1126{
1127 if (gPad->GetCanvas()->SupportAlpha()) return;
1128 if (s == fDotsSpacing) return;
1129 fDotsSpacing = s;
1130 gStyle->SetLineStyleString(11, TString::Format("%d %d",4,s*8));
1131}
1132
1133////////////////////////////////////////////////////////////////////////////////
1134/// Set the entry lists of "para".
1135
1137{
1138 para->SetCurrentEntries(enlist);
1139 para->SetInitEntries(enlist);
1140}
1141
1142////////////////////////////////////////////////////////////////////////////////
1143/// Force all variables to adopt the same max.
1144
1146{
1147 TIter next(fVarList);
1148 TParallelCoordVar* var;
1149 while ((var = (TParallelCoordVar*)next())) {
1150 var->SetCurrentMax(max);
1151 }
1152}
1153
1154////////////////////////////////////////////////////////////////////////////////
1155/// Force all variables to adopt the same min.
1156
1158{
1159 TIter next(fVarList);
1160 TParallelCoordVar* var;
1161 while ((var = (TParallelCoordVar*)next())) {
1162 var->SetCurrentMin(min);
1163 }
1164}
1165
1166////////////////////////////////////////////////////////////////////////////////
1167/// If true, the pad is updated while the motion of a dragged range.
1168
1170{
1172 TIter next(fVarList);
1173 TParallelCoordVar* var;
1174 while((var = (TParallelCoordVar*)next())) var->SetLiveRangesUpdate(on);
1175}
1176
1177////////////////////////////////////////////////////////////////////////////////
1178/// Set the vertical or horizontal display.
1179
1181{
1182 if (vert == TestBit (kVertDisplay)) return;
1184 if (!gPad) return;
1185 TFrame* frame = gPad->GetFrame();
1186 if (!frame) return;
1187 UInt_t ui = 0;
1188 Double_t horaxisspace = (frame->GetX2() - frame->GetX1())/(fNvar-1);
1189 Double_t veraxisspace = (frame->GetY2() - frame->GetY1())/(fNvar-1);
1190 TIter next(fVarList);
1191 TParallelCoordVar* var;
1192 while ((var = (TParallelCoordVar*)next())) {
1193 if (vert) var->SetX(frame->GetX1() + ui*horaxisspace,TestBit(kGlobalScale));
1194 else var->SetY(frame->GetY1() + ui*veraxisspace,TestBit(kGlobalScale));
1195 ++ui;
1196 }
1197 if (TestBit(kCandleChart)) {
1198 if (fCandleAxis) delete fCandleAxis;
1199 if (TestBit(kVertDisplay)) fCandleAxis = new TGaxis(0.05,0.1,0.05,0.9,GetGlobalMin(),GetGlobalMax());
1200 else fCandleAxis = new TGaxis(0.1,0.05,0.9,0.05,GetGlobalMin(),GetGlobalMax());
1201 fCandleAxis->Draw();
1202 }
1203 gPad->Modified();
1204 gPad->Update();
1205}
1206
1207////////////////////////////////////////////////////////////////////////////////
1208/// Unzoom all variables.
1209
1211{
1212 TIter next(fVarList);
1213 TParallelCoordVar* var;
1214 while((var = (TParallelCoordVar*)next())) var->Unzoom();
1215}
@ kHand
Definition GuiTypes.h:374
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define a(i)
Definition RSha256.hxx:99
#define h(i)
Definition RSha256.hxx:106
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:83
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
@ kGreen
Definition Rtypes.h:67
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define gDirectory
Definition TDirectory.h:385
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t sel
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void on
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t TPoint TPoint const char y1
int nentries
#define gROOT
Definition TROOT.h:411
R__EXTERN TStyle * gStyle
Definition TStyle.h:442
#define gPad
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
Definition TAttFill.h:40
Line Attributes class.
Definition TAttLine.h:20
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition TAttLine.h:42
Double_t GetX1() const
Definition TBox.h:51
virtual void SetY2(Double_t y2)
Definition TBox.h:65
Double_t GetX2() const
Definition TBox.h:52
Double_t GetY1() const
Definition TBox.h:53
virtual void SetX1(Double_t x1)
Definition TBox.h:62
Double_t GetY2() const
Definition TBox.h:54
virtual void SetX2(Double_t x2)
Definition TBox.h:63
virtual void SetY1(Double_t y1)
Definition TBox.h:64
The Canvas class.
Definition TCanvas.h:23
static TClass * Class()
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
static TString SavePrimitiveColor(Int_t ci)
Convert color in C++ statement which can be used in SetColor directives Produced statement either inc...
Definition TColor.cxx:2556
Describe directory structure in memory.
Definition TDirectory.h:45
A List of entry numbers in a TTree or TChain.
Definition TEntryList.h:26
virtual Long64_t GetEntry(Long64_t index)
Return the number of the entry #index of this TEntryList in the TTree or TChain See also Next().
virtual Long64_t GetN() const
Definition TEntryList.h:78
A ROOT file is an on-disk file, usually with extension .root, that stores objects in a file-system-li...
Definition TFile.h:131
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
Definition TFile.cxx:3764
Define a Frame.
Definition TFrame.h:19
void Draw(Option_t *option="") override
Draw this frame with its current attributes.
Definition TFrame.cxx:66
The axis painter class.
Definition TGaxis.h:26
A TGraph is an object made of two arrays X and Y with npoints each.
Definition TGraph.h:41
@ kClipFrame
Clip to the frame boundary.
Definition TGraph.h:75
void PaintGraph(Int_t npoints, const Double_t *x, const Double_t *y, Option_t *chopt)
Draw the (x,y) as a graph.
Definition TGraph.cxx:1986
void Reset()
Iterator of linked list.
Definition TList.h:191
void Reset() override
Reset list iterator.
Definition TList.cxx:1158
A doubly linked list.
Definition TList.h:38
void Add(TObject *obj) override
Definition TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:819
TObject * First() const override
Return the first object in the list. Returns 0 when list is empty.
Definition TList.cxx:656
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:467
TObject * At(Int_t idx) const override
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx:354
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:173
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:202
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1057
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:203
virtual Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Definition TObject.cxx:964
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:864
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1071
static void SavePrimitiveDraw(std::ostream &out, const char *variable_name, Option_t *option=nullptr)
Save invocation of primitive Draw() method Skipped if option contains "nodraw" string.
Definition TObject.cxx:822
virtual void Draw(Option_t *option="")
Default Draw method for all objects.
Definition TObject.cxx:293
@ kCanDelete
if object in a list can be deleted
Definition TObject.h:68
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:1045
A TParallelCoordRange is a range used for parallel coordinates plots.
A TParallelCoordSelect is a specialised TList to hold TParallelCoordRanges used by TParallelCoord.
const char * GetTitle() const override
Returns title of object.
TParallelCoord axes.
void Paint(Option_t *option="") override
Paint the axis.
TH1F * GetHistogram()
Create or recreate the histogram.
void GetEntryXY(Long64_t n, Double_t &x, Double_t &y)
Get the position of the variable on the graph for the n'th entry.
void SetBoxPlot(bool box)
Set the axis to display a candle.
Double_t GetCurrentMax() const
void SetCurrentMin(Double_t min)
Set the current minimum of the axis.
void SetY(Double_t y, bool gl)
Set the Y position of the axis in the case of a horizontal axis.
void SetLiveRangesUpdate(bool on)
If true, the pad is updated while the motion of a dragged range.
void SetX(Double_t x, bool gl)
Set the X position of the axis in the case of a vertical axis.
Double_t GetCurrentMin() const
void SetCurrentMax(Double_t max)
Set the current maximum of the axis.
void SetLogScale(bool log)
Set the axis in log scale.
void GetQuantiles()
Get the box plot values (quantiles).
void SetHistogramHeight(Double_t h=0)
Set the height of the bar histogram.
Int_t GetEntryWeight(Long64_t evtidx)
Get the entry weight: The weight of an entry for a given variable is the bin content of the histogram...
void SetHistogramLineWidth(Int_t lw=2)
void GetMinMaxMean()
Get mean, min and max of those variable.
bool Eval(Long64_t evtidx, TParallelCoordSelect *select)
Check if the entry is within the range(s) of "select".
void SetHistogramBinning(Int_t n=100)
Set the histogram binning.
Parallel Coordinates class.
void AddSelection(const char *title)
Add a selection.
void ExecuteEvent(Int_t entry, Int_t px, Int_t py) override
Execute the corresponding entry.
void SetGlobalScale(bool gl)
Constraint all axes to the same scale.
void UnzoomAll()
Unzoom all variables.
TEntryList * fInitEntries
-> Selected entries when TParallelCoord first initialized.
void SetAxisHistogramLineWidth(Int_t lw=2)
Set the same histogram axis line width for all axis.
TTree * GetTree()
return the tree if fTree is defined.
TEntryList * fCurrentEntries
-> Current selected entries in the tree.
~TParallelCoord() override
Destructor.
TParallelCoordSelect * fCurrentSelection
! Current Selection being edited.
TParallelCoordSelect * GetCurrentSelection()
Return the selection currently being edited.
static void BuildParallelCoord(TSelectorDraw *selector, bool candle)
Call constructor and add the variables.
Double_t GetGlobalMin()
return the global minimum.
void Init()
Initialise the data members of TParallelCoord.
void SetLiveRangesUpdate(bool)
If true, the pad is updated while the motion of a dragged range.
void PaintEntries(TParallelCoordSelect *sel=nullptr)
Loop over the entries and paint them.
Int_t fDotsSpacing
Spacing between dots to draw the entries.
Int_t fWeightCut
Specify a cut on the entries from their weight (see TParallelCoordVar::GetEvtWeight(Long64_t))
void SetAxisHistogramHeight(Double_t h=0.5)
Set the same histogram axis height for all axis.
TParallelCoordSelect * GetSelection(const char *title)
Get a selection from its title.
TList * fSelectList
List of selections over the variables.
void DeleteSelection(TParallelCoordSelect *sel)
Delete a selection.
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Compute the distance from the TParallelCoord.
void SaveEntryLists(const char *filename="", bool overwrite=false)
Save the entry lists in a root file "filename.root".
Int_t GetNbins()
get the binning of the histograms.
TString fTreeName
Name of the tree.
void SaveTree(const char *filename="", bool overwrite=false)
Save the tree in a file if fTreeFileName == "".
void ResetTree()
Reset the tree entry list to the initial one..
void SetCandleChart(bool can)
Set a candle chart display.
void Paint(Option_t *options="") override
Paint the parallel coordinates graph.
void SetVertDisplay(bool vert=true)
Set the vertical or horizontal display.
TParallelCoord()
Default constructor.
TTree * fTree
! Pointer to the TTree.
Width_t fLineWidth
entries line width.
TString fTreeFileName
Name of the file containing the tree.
static TClass * Class()
void AddVariable(Double_t *val, const char *title="")
Add a variable.
Long64_t fCurrentFirst
First entry to display.
Color_t GetLineColor()
void SetCurrentN(Long64_t)
Set the number of entry to be displayed.
Double_t GetGlobalMax()
return the global maximum.
TParallelCoordSelect * SetCurrentSelection(const char *title)
Set the selection being edited.
void SetGlobalMax(Double_t max)
Force all variables to adopt the same max.
void SetGlobalMin(Double_t min)
Force all variables to adopt the same min.
Long64_t fCurrentN
Number of entries to display.
Long64_t fNentries
Number of entries;.
void RemoveVariable(TParallelCoordVar *var)
Delete a variable from the graph.
void ApplySelectionToTree()
Apply the current selection to the tree.
void SetAxesPosition()
Update the position of the axes.
UInt_t fNvar
Number of variables.
Color_t fLineColor
entries line color.
void SetAxisHistogramBinning(Int_t n=100)
Set the same histogram axis binning for all axis.
void SavePrimitive(std::ostream &out, Option_t *options) override
Save the TParallelCoord in a macro.
void CleanUpSelections(TParallelCoordRange *range)
Clean up the selections from the ranges which could have been deleted when a variable has been delete...
void Draw(Option_t *options="") override
Draw the parallel coordinates graph.
void SetDotsSpacing(Int_t s=0)
Set dots spacing.
static void SetEntryList(TParallelCoord *para, TEntryList *enlist)
Set the entry lists of "para".
@ kCurveDisplay
If the polylines are replaced by interpolated curves.
@ kGlobalScale
Every variable is on the same scale.
@ kVertDisplay
If the axes are drawn vertically, false if horizontally.
@ kGlobalLogScale
Every variable in log scale.
@ kPaintEntries
To paint all TParallelCoord entries.
@ kLiveUpdate
To paint the entries when being modified.
@ kCandleChart
To produce a candle chart.
void SetGlobalLogScale(bool)
All axes in log scale.
TEntryList * GetEntryList(bool sel=true)
Get the whole entry list or one for a selection.
Double_t * GetVariable(const char *var)
Get the variables values from its title.
void SetCurrentFirst(Long64_t)
Set the first entry to be displayed.
TGaxis * fCandleAxis
! An axis used when displaying a candle chart.
TList * fVarList
List of the variables.
Width_t GetLineWidth()
A Pave (see TPave) with text, lines or/and boxes inside.
Definition TPaveText.h:21
virtual TText * AddText(Double_t x1, Double_t y1, const char *label)
Add a new Text line to this pavetext at given coordinates.
void Draw(Option_t *option="") override
Draw this pavetext with its current attributes.
Defined by an array on N points in a 2-D space.
Definition TPolyLine.h:23
This is the base class for the ROOT Random number generators.
Definition TRandom.h:27
A specialized TSelector for TTree::Draw.
TTreeFormula * GetSelect() const
TTreeFormula * GetVar(Int_t i) const
Return the TTreeFormula corresponding to the i-th component of the request formula (where the compone...
virtual Int_t GetDimension() const
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 ...
TTree * GetTree() const
virtual Int_t GetNfill() const
virtual void SetObject(TObject *obj)
Definition TSelector.h:65
Basic string class.
Definition TString.h:138
void ToLower()
Change string to lower-case.
Definition TString.cxx:1189
TString & ReplaceSpecialCppChars()
Find special characters which are typically used in printf() calls and replace them by appropriate es...
Definition TString.cxx:1121
const char * Data() const
Definition TString.h:384
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:712
@ kLeading
Definition TString.h:284
Bool_t IsNull() const
Definition TString.h:422
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:2384
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:640
void SetLineStyleString(Int_t i, const char *text)
Set line style string using the PostScript convention.
Definition TStyle.cxx:1484
Implement some of the functionality of the class TTree requiring access to extra libraries (Histogram...
Definition TTreePlayer.h:37
A TTree represents a columnar dataset.
Definition TTree.h:89
TFile * GetCurrentFile() const
Return pointer to the current file.
Definition TTree.cxx:5555
TVirtualTreePlayer * GetPlayer()
Load the TTreePlayer (if not already done).
Definition TTree.cxx:6386
void Draw(Option_t *opt) override
Default Draw method for all objects.
Definition TTree.h:470
virtual void SetEntryList(TEntryList *list, Option_t *opt="")
Set an EntryList.
Definition TTree.cxx:9253
virtual Double_t * GetV1()
Definition TTree.h:615
Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0) override
Write this object to the current directory.
Definition TTree.cxx:9973
See TView3D.
Definition TView.h:25
virtual void SetView(Double_t longitude, Double_t latitude, Double_t psi, Int_t &irep)=0
virtual void SetBorderMode(Short_t bordermode)
Definition TWbox.h:51
virtual void SetBorderSize(Short_t bordersize)
Definition TWbox.h:52
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
TGraphErrors * gr
Definition legend1.C:25