Logo ROOT  
Reference Guide
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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
38
39/** \class TParallelCoord
40Parallel Coordinates class.
41
42The multidimensional system of Parallel coordinates is a common way of studying
43high-dimensional geometry and visualizing multivariate problems. It has first
44been proposed by A. Inselberg in 1981.
45
46To show a set of points in an n-dimensional space, a backdrop is drawn
47consisting of n parallel lines. A point in n-dimensional space is represented as
48a polyline with vertices on the parallel axes; the position of the vertex on the
49i-th axis corresponds to the i-th coordinate of the point.
50
51This tool comes with a rather large gui in the editor. It is necessary to use
52this editor in order to explore a data set, as explained below.
53
54### Reduce cluttering:
55
56The main issue for parallel coordinates is the very high cluttering of the
57output when dealing with large data set. Two techniques have been implemented to
58bypass that so far:
59
60 - Draw doted lines instead of plain lines with an adjustable dots spacing. A
61 slider to adjust the dots spacing is available in the editor.
62 - Sort the entries to display with a "weight cut". On each axis is drawn a
63 histogram describing the distribution of the data on the corresponding
64 variable. The "weight" of an entry is the sum of the bin content of each bin
65 the entry is going through. An entry going through the histograms peaks will
66 have a big weight wether an entry going randomly through the histograms will
67 have a rather small weight. Setting a cut on this weight allows to draw only
68 the most representative entries. A slider set the cut is also available in
69 the gui.
70
71## Selections:
72
73Selections of specific entries can be defined over the data se using parallel
74coordinates. With that representation, a selection is an ensemble of ranges
75defined on the axes. Ranges defined on the same axis are conjugated with OR
76(an entry must be in one or the other ranges to be selected). Ranges on
77different axes are are conjugated with AND (an entry must be in all the ranges
78to be selected). Several selections can be defined with different colors. It is
79possible to generate an entry list from a given selection and apply it to the
80tree using the editor ("Apply to tree" button).
81
82## Axes:
83
84Options can be defined each axis separately using the right mouse click. These
85options can be applied to every axes using the editor.
86
87 - Axis width: If set to 0, the axis is simply a line. If higher, a color
88 histogram is drawn on the axis.
89 - Axis histogram height: If not 0, a usual bar histogram is drawn on the plot.
90
91The order in which the variables are drawn is essential to see the clusters. The
92axes can be dragged to change their position. A zoom is also available. The
93logarithm scale is also available by right clicking on the axis.
94
95## Candle chart:
96
97TParallelCoord can also be used to display a candle chart. In that mode, every
98variable is drawn in the same scale. The candle chart can be combined with the
99parallel coordinates mode, drawing the candle sticks over the axes.
100
101~~~ {.cpp}
102{
103 TCanvas *c1 = new TCanvas("c1");
104 TFile *f = TFile::Open("cernstaff.root");
105 TTree *T = (TTree*)f->Get("T");
106 T->Draw("Age:Grade:Step:Cost:Division:Nation","","para");
107 TParallelCoord* para = (TParallelCoord*)gPad->GetListOfPrimitives()->FindObject("ParaCoord");
108 TParallelCoordVar* grade = (TParallelCoordVar*)para->GetVarList()->FindObject("Grade");
109 grade->AddRange(new TParallelCoordRange(grade,11.5,14));
110 para->AddSelection("less30");
111 para->GetCurrentSelection()->SetLineColor(kViolet);
112 TParallelCoordVar* age = (TParallelCoordVar*)para->GetVarList()->FindObject("Age");
113 age->AddRange(new TParallelCoordRange(age,21,30));
114}
115~~~
116
117### Some references:
118
119 - Alfred Inselberg's Homepage <http://www.math.tau.ac.il/~aiisreal>, with
120 Visual Tutorial, History, Selected Publications and Applications.
121 - Almir Olivette Artero, Maria Cristina Ferreira de Oliveira, Haim Levkowitz,
122 "Uncovering Clusters in Crowded Parallel Coordinates Visualizations,"
123 infovis, pp. 81-88, IEEE Symposium on Information Visualization
124 (INFOVIS'04), 2004.
125*/
126
127////////////////////////////////////////////////////////////////////////////////
128/// Default constructor.
129
135
136////////////////////////////////////////////////////////////////////////////////
137/// Constructor without a reference to a tree,
138/// the datas must be added afterwards with
139/// TParallelCoord::AddVariable(Double_t*,const char*).
140
151
152////////////////////////////////////////////////////////////////////////////////
153/// Normal constructor, the datas must be added afterwards
154/// with TParallelCoord::AddVariable(Double_t*,const char*).
155
157 :TNamed("ParaCoord","ParaCoord")
158{
159 Init();
160 Int_t estimate = tree->GetEstimate();
161 if (nentries>estimate) {
162 Warning("TParallelCoord","Call tree->SetEstimate(tree->GetEntries()) to display all the tree variables");
164 } else {
166 }
168 fTree = tree;
171 else fTreeFileName = "";
172 fVarList = new TList();
173 fSelectList = new TList();
176}
177
178////////////////////////////////////////////////////////////////////////////////
179/// Destructor.
180
182{
183 if (fInitEntries != fCurrentEntries && fCurrentEntries != nullptr) delete fCurrentEntries;
184 if (fVarList) {
185 fVarList->Delete();
186 delete fVarList;
187 }
188 if (fSelectList) {
190 delete fSelectList;
191 }
192 if (fCandleAxis) delete fCandleAxis;
194}
195
196////////////////////////////////////////////////////////////////////////////////
197/// Add a variable.
198
199void TParallelCoord::AddVariable(Double_t* val, const char* title)
200{
201 ++fNvar;
202 fVarList->Add(new TParallelCoordVar(val,title,fVarList->GetSize(),this));
204}
205
206////////////////////////////////////////////////////////////////////////////////
207/// Add a variable from an expression.
208
210{
211 if(!fTree) return; // The tree from which one will get the data must be defined.
212
213 // Select in the only the entries of this TParallelCoord.
214 TEntryList *list = GetEntryList(false);
215 fTree->SetEntryList(list);
216
217 // ensure that there is only one variable given:
218
219 TString exp = varexp;
220
221 if (exp.Contains(':') || exp.Contains(">>") || exp.Contains("<<")) {
222 Warning("AddVariable","Only a single variable can be added at a time.");
223 return;
224 }
225 if (exp == ""){
226 Warning("AddVariable","Nothing to add");
227 return;
228 }
229
230 Long64_t en = fTree->Draw(varexp,"","goff");
231 if (en<0) {
232 Warning("AddVariable","%s could not be evaluated",varexp);
233 return;
234 }
235
237}
238
239////////////////////////////////////////////////////////////////////////////////
240/// Add a selection.
241
242void TParallelCoord::AddSelection(const char* title)
243{
247}
248
249////////////////////////////////////////////////////////////////////////////////
250/// Apply the current selection to the tree.
251
253{
254 if(!fTree) return;
255 if(fSelectList) {
256 if(fSelectList->GetSize() == 0) return;
258 }
261 fCurrentFirst = 0;
265 TIter next(fVarList);
266 while (auto var = (TParallelCoordVar*)next())
267 varexp.Append(TString::Format(":%s",var->GetTitle()));
268 varexp.Remove(TString::kLeading,':');
269 TSelectorDraw* selector = (TSelectorDraw*)((TTreePlayer*)fTree->GetPlayer())->GetSelector();
270 fTree->Draw(varexp.Data(),"","goff");
271 next.Reset();
272 Int_t i = 0;
273 while (auto var = (TParallelCoordVar*)next())
274 var->SetValues(fNentries, selector->GetVal(i++));
275 if (fSelectList) { // FIXME It would be better to update the selections by deleting
276 fSelectList->Delete(); // the meaningless ranges (selecting everything or nothing for example)
277 fCurrentSelection = nullptr; // after applying a new entrylist to the tree.
278 }
279 gPad->Modified();
280 gPad->Update();
281}
282
283////////////////////////////////////////////////////////////////////////////////
284/// Call constructor and add the variables.
285
287{
288 TParallelCoord* pc = new TParallelCoord(selector->GetTree(),selector->GetNfill());
289 pc->SetBit(kCanDelete);
290 selector->SetObject(pc);
292 for(Int_t i=0;i<selector->GetDimension();++i) {
293 if (selector->GetVal(i)) {
294 if (selector->GetVar(i)) {
295 pc->AddVariable(selector->GetVal(i),selector->GetVar(i)->GetTitle());
296 varexp.Append(TString::Format(":%s",selector->GetVar(i)->GetTitle()));
297 }
298 }
299 }
300 varexp.Remove(TString::kLeading,':');
301 if (selector->GetSelect())
302 varexp.Append(TString::Format("{%s}",selector->GetSelect()->GetTitle()));
303 pc->SetTitle(varexp.Data());
304 if (!candle) pc->Draw();
305 else pc->Draw("candle");
306}
307
308////////////////////////////////////////////////////////////////////////////////
309/// Clean up the selections from the ranges which could have been deleted
310/// when a variable has been deleted.
311
313{
314 TIter next(fSelectList);
316 while ((select = (TParallelCoordSelect*)next())){
317 if(select->Contains(range)) select->Remove(range);
318 }
319}
320
321////////////////////////////////////////////////////////////////////////////////
322/// Delete a selection.
323
331
332////////////////////////////////////////////////////////////////////////////////
333/// Compute the distance from the TParallelCoord.
334
336{
337 if(!gPad) return 9999;
338
339 TFrame *frame = gPad->GetFrame();
340
342
343 x1 = frame->GetX1()+0.01;
344 x2 = frame->GetX2()-0.01;
345 y2 = frame->GetY2()-0.01;
346 y1 = frame->GetY1()+0.01;
347
348 xx = gPad->AbsPixeltoX(px);
349 yy = gPad->AbsPixeltoY(py);
350
351 if(xx>x1 && xx<x2 && yy>y1 && yy<y2) return 0;
352 else return 9999;
353}
354
355////////////////////////////////////////////////////////////////////////////////
356/// Draw the parallel coordinates graph.
357
359{
360 if (!GetTree()) return;
362 bool optcandle = false;
363 TString opt = option;
364 opt.ToLower();
365 if(opt.Contains("candle")) {
366 optcandle = true;
367 opt.ReplaceAll("candle","");
368 }
369 if(optcandle) {
370 SetBit(kPaintEntries,false);
371 SetBit(kCandleChart,true);
372 SetGlobalScale(true);
373 }
374
375 if (gPad) {
376 if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
377 } else gROOT->MakeDefCanvas();
378 TView *view = gPad->GetView();
379 if(view){
380 delete view;
381 gPad->SetView(nullptr);
382 }
383 gPad->Clear();
384 if (!optcandle) {
385 if (gPad && gPad->IsA() == TCanvas::Class()
386 && !((TCanvas*)gPad)->GetShowEditor()) {
387 ((TCanvas*)gPad)->ToggleEditor();
388 ((TCanvas*)gPad)->ToggleEventStatus();
389 }
390 }
391
392 gPad->SetBit(TGraph::kClipFrame,true);
393
394 TFrame *frame = new TFrame(0.1,0.1,0.9,0.9);
395 frame->SetBorderSize(0);
396 frame->SetBorderMode(0);
397 frame->SetFillStyle(0);
398 frame->SetLineColor(gPad->GetFillColor());
399 frame->Draw();
401 TPaveText *title = new TPaveText(0.05,0.95,0.35,1);
402 title->AddText(GetTitle());
403 title->Draw();
405 TIter next(fVarList);
407 while ((var = (TParallelCoordVar*)next())) {
408 if(optcandle) {
409 var->SetBoxPlot(true);
410 var->SetHistogramHeight(0.5);
411 var->SetHistogramLineWidth(0);
412 }
413 }
414
415 if (optcandle) {
416 if (TestBit(kVertDisplay)) fCandleAxis = new TGaxis(0.05,0.1,0.05,0.9,GetGlobalMin(),GetGlobalMax());
417 else fCandleAxis = new TGaxis(0.1,0.05,0.9,0.05,GetGlobalMin(),GetGlobalMax());
418 fCandleAxis->Draw();
419 }
420
421 if (gPad && gPad->IsA() == TCanvas::Class())
422 ((TCanvas*)gPad)->Selected(gPad,this,1);
423}
424
425////////////////////////////////////////////////////////////////////////////////
426/// Execute the corresponding entry.
427
428void TParallelCoord::ExecuteEvent(Int_t /*entry*/, Int_t /*px*/, Int_t /*py*/)
429{
430 if (!gPad) return;
431 gPad->SetCursor(kHand);
432}
433
434////////////////////////////////////////////////////////////////////////////////
435/// Return the selection currently being edited.
436
445
446////////////////////////////////////////////////////////////////////////////////
447/// Get the whole entry list or one for a selection.
448
450{
451 if(!sel || fCurrentSelection->GetSize() == 0){ // If no selection is specified, return the entry list of all the entries.
452 return fInitEntries;
453 } else { // return the entry list corresponding to the current selection.
455 TIter next(fVarList);
456 for (Long64_t li=0;li<fNentries;++li) {
457 next.Reset();
458 bool inrange=true;
460 while((var = (TParallelCoordVar*)next())){
461 if(!var->Eval(li,fCurrentSelection)) inrange = false;
462 }
463 if(!inrange) continue;
465 }
466 return enlist;
467 }
468}
469
470////////////////////////////////////////////////////////////////////////////////
471/// return the global maximum.
472
474{
476 TIter next(fVarList);
478 while ((var = (TParallelCoordVar*)next())) {
479 if (gmax < var->GetCurrentMax()) gmax = var->GetCurrentMax();
480 }
481 return gmax;
482}
483
484////////////////////////////////////////////////////////////////////////////////
485/// return the global minimum.
486
488{
490 TIter next(fVarList);
492 while ((var = (TParallelCoordVar*)next())) {
493 if (gmin > var->GetCurrentMin()) gmin = var->GetCurrentMin();
494 }
495 return gmin;
496}
497
498////////////////////////////////////////////////////////////////////////////////
499/// get the binning of the histograms.
500
502{
503 return ((TParallelCoordVar*)fVarList->First())->GetNbins();
504}
505
506////////////////////////////////////////////////////////////////////////////////
507/// Get a selection from its title.
508
510{
511 TIter next(fSelectList);
513 while ((sel = (TParallelCoordSelect*)next()) && strcmp(title,sel->GetTitle())) { }
514 return sel;
515}
516
517////////////////////////////////////////////////////////////////////////////////
518/// return the tree if fTree is defined. If not, the method try to load the tree
519/// from fTreeFileName.
520
522{
523 if (fTree) return fTree;
524 if (fTreeFileName=="" || fTreeName=="") {
525 Error("GetTree","Cannot load the tree: no tree defined!");
526 return nullptr;
527 }
529 if (!f) {
530 Error("GetTree","Tree file name : \"%s\" does not exist (Are you in the correct directory?).",fTreeFileName.Data());
531 return nullptr;
532 } else if (f->IsZombie()) {
533 Error("GetTree","while opening \"%s\".",fTreeFileName.Data());
534 return nullptr;
535 } else {
536 fTree = (TTree*)f->Get(fTreeName.Data());
537 if (!fTree) {
538 Error("GetTree","\"%s\" not found in \"%s\".", fTreeName.Data(), fTreeFileName.Data());
539 return nullptr;
540 } else {
543 TIter next(fVarList);
544 while (auto var = (TParallelCoordVar*)next())
545 varexp.Append(TString::Format(":%s",var->GetTitle()));
546 varexp.Remove(TString::kLeading,':');
547 fTree->Draw(varexp.Data(),"","goff");
548 TSelectorDraw* selector = (TSelectorDraw*)((TTreePlayer*)fTree->GetPlayer())->GetSelector();
549 next.Reset();
550 Int_t i = 0;
551 while (auto var = (TParallelCoordVar*)next())
552 var->SetValues(fNentries, selector->GetVal(i++));
553 return fTree;
554 }
555 }
556}
557
558////////////////////////////////////////////////////////////////////////////////
559/// Get the variables values from its title.
560
562{
563 TIter next(fVarList);
564 TParallelCoordVar* var = nullptr;
565 while(((var = (TParallelCoordVar*)next()) != nullptr) && (var->GetTitle() != vartitle)) { }
566 if(!var) return nullptr;
567 else return var->GetValues();
568}
569
570////////////////////////////////////////////////////////////////////////////////
571/// Get the variables values from its index.
572
574{
575 if(i<0 || (UInt_t)i>fNvar) return nullptr;
576 else return ((TParallelCoordVar*)fVarList->At(i))->GetValues();
577}
578
579////////////////////////////////////////////////////////////////////////////////
580/// Initialise the data members of TParallelCoord.
581
583{
584 fNentries = 0;
585 fVarList = nullptr;
586 fSelectList = nullptr;
587 SetBit(kVertDisplay,true);
588 SetBit(kCurveDisplay,false);
589 SetBit(kPaintEntries,true);
590 SetBit(kLiveUpdate,false);
591 SetBit(kGlobalScale,false);
592 SetBit(kCandleChart,false);
593 SetBit(kGlobalLogScale,false);
594 fTree = nullptr;
595 fCurrentEntries = nullptr;
596 fInitEntries = nullptr;
597 fCurrentSelection = nullptr;
598 fNvar = 0;
599 fDotsSpacing = 0;
600 fCurrentFirst = 0;
601 fCurrentN = 0;
602 fCandleAxis = nullptr;
603 fWeightCut = 0;
604 fLineWidth = 1;
605 fLineColor = kGreen-8;
606 fTreeName = "";
607 fTreeFileName = "";
608}
609
610////////////////////////////////////////////////////////////////////////////////
611/// Paint the parallel coordinates graph.
612
614{
615 if (!GetTree()) return;
616 gPad->Range(0,0,1,1);
617 TFrame *frame = gPad->GetFrame();
618 frame->SetLineColor(gPad->GetFillColor());
621 PaintEntries(nullptr);
622 TIter next(fSelectList);
624 while((sel = (TParallelCoordSelect*)next())) {
625 if(sel->GetSize()>0 && sel->TestBit(TParallelCoordSelect::kActivated)) {
627 }
628 }
629 }
630 gPad->RangeAxis(0,0,1,1);
631
633 TParallelCoordVar* var=nullptr;
634 while((var = (TParallelCoordVar*)nextVar())) {
635 var->Paint();
636 }
637}
638
639////////////////////////////////////////////////////////////////////////////////
640/// Loop over the entries and paint them.
641
643{
644 if (fVarList->GetSize() < 2) return;
645 Int_t i=0;
646 Long64_t n=0;
647
648 Double_t *x = new Double_t[fNvar];
649 Double_t *y = new Double_t[fNvar];
650
651 TGraph *gr = nullptr;
652 TPolyLine *pl = nullptr;
653 TAttLine *evline = nullptr;
654
655 if (TestBit (kCurveDisplay)) {gr = new TGraph(fNvar); evline = (TAttLine*)gr;}
656 else {pl = new TPolyLine(fNvar); evline = (TAttLine*)pl;}
657
658 if (fDotsSpacing == 0) evline->SetLineStyle(1);
659 else evline->SetLineStyle(11);
660 if (!sel){
661 evline->SetLineWidth(GetLineWidth());
662 evline->SetLineColor(GetLineColor());
663 } else {
664 evline->SetLineWidth(sel->GetLineWidth());
665 evline->SetLineColor(sel->GetLineColor());
666 }
668
669 TFrame *frame = gPad->GetFrame();
670 Double_t lx = ((frame->GetX2() - frame->GetX1())/(fNvar-1));
671 Double_t ly = ((frame->GetY2() - frame->GetY1())/(fNvar-1));
672 Double_t a,b;
673 TRandom r;
674
676 TListIter next(fVarList);
677 bool inrange = true;
678 // Loop to check whenever the entry must be painted.
679 if (sel) {
680 while ((var = (TParallelCoordVar*)next())){
681 if (!var->Eval(n,sel)) inrange = false;
682 }
683 }
684 if (fWeightCut > 0) {
685 next.Reset();
686 Int_t entryweight = 0;
687 while ((var = (TParallelCoordVar*)next())) entryweight+=var->GetEntryWeight(n);
688 if (entryweight/(Int_t)fNvar < fWeightCut) inrange = false;
689 }
690 if(!inrange) continue;
691 i = 0;
692 next.Reset();
693 // Loop to set the polyline points.
694 while ((var = (TParallelCoordVar*)next())) {
695 var->GetEntryXY(n,x[i],y[i]);
696 ++i;
697 }
698 // beginning to paint the first point at a random distance
699 // to avoid artefacts when increasing the dots spacing.
700 if (fDotsSpacing != 0) {
701 if (TestBit(kVertDisplay)) {
702 a = (y[1]-y[0])/(x[1]-x[0]);
703 b = y[0]-a*x[0];
704 x[0] = x[0]+lx*r.Rndm();
705 y[0] = a*x[0]+b;
706 } else {
707 a = (x[1]-x[0])/(y[1]-y[0]);
708 b = x[0]-a*y[0];
709 y[0] = y[0]+ly*r.Rndm();
710 x[0] = a*y[0]+b;
711 }
712 }
713 if (pl) pl->PaintPolyLine(fNvar,x,y);
714 else gr->PaintGraph(fNvar,x,y,"C");
715 }
716
717 if (pl) delete pl;
718 if (gr) delete gr;
719 delete [] x;
720 delete [] y;
721}
722
723////////////////////////////////////////////////////////////////////////////////
724/// Delete a variable from the graph.
725
732
733////////////////////////////////////////////////////////////////////////////////
734/// Delete the variable "vartitle" from the graph.
735
737{
738 TIter next(fVarList);
739 TParallelCoordVar* var=nullptr;
740 while((var = (TParallelCoordVar*)next())) {
741 if (!strcmp(var->GetTitle(),vartitle)) break;
742 }
743 if(!var) {
744 Error("RemoveVariable","\"%s\" not a variable",vartitle);
745 return false;
746 } else {
747 RemoveVariable(var);
748 delete var;
749 return true;
750 }
751}
752
753////////////////////////////////////////////////////////////////////////////////
754/// Reset the tree entry list to the initial one..
755
757{
758 if(!fTree) return;
762 fCurrentFirst = 0;
764 TString varexp = "";
765 TIter next(fVarList);
766 while (auto var = (TParallelCoordVar*)next())
767 varexp.Append(TString::Format(":%s",var->GetTitle()));
768 varexp.Remove(TString::kLeading,':');
769 fTree->Draw(varexp.Data(),"","goff");
770 next.Reset();
771 TSelectorDraw* selector = (TSelectorDraw*)((TTreePlayer*)fTree->GetPlayer())->GetSelector();
772 Int_t i = 0;
773 while (auto var = (TParallelCoordVar*)next()) {
774 var->SetValues(fNentries, selector->GetVal(i++));
775 }
776 if (fSelectList) { // FIXME It would be better to update the selections by deleting
777 fSelectList->Delete(); // the meaningless ranges (selecting everything or nothing for example)
778 fCurrentSelection = nullptr; // after applying a new entrylist to the tree.
779 }
780 gPad->Modified();
781 gPad->Update();
782}
783
784////////////////////////////////////////////////////////////////////////////////
785/// Save the entry lists in a root file "filename.root".
786
788{
790 if (sfile.IsNull())
791 sfile.Form("%s_parallelcoord_entries.root", fTree->GetName());
792
794 TFile *f = TFile::Open(sfile.Data());
795 if (f) {
796 Warning("SaveEntryLists", "%s already exists.", sfile.Data());
797 if (!overwrite)
798 return;
799 Warning("SaveEntryLists", "Overwriting.");
800 f = new TFile(sfile.Data(), "RECREATE");
801 } else {
802 f = new TFile(sfile.Data(), "CREATE");
803 }
804 gDirectory = f;
805 fInitEntries->Write("initentries");
806 fCurrentEntries->Write("currententries");
807 f->Close();
808 delete f;
810 Info("SaveEntryLists", "File \"%s\" written.", sfile.Data());
811}
812
813////////////////////////////////////////////////////////////////////////////////
814/// Save the TParallelCoord in a macro.
815
817{
818 // Save the entrylists.
819 TString filename = TString::Format("%s_parallelcoord_entries.root", fTree->GetName());
820 SaveEntryLists(filename, true); // FIXME overwriting by default.
821 SaveTree(fTreeFileName, true); // FIXME overwriting by default.
822
823 if (!gROOT->ClassSaved(Class())) {
824 out << " TFile *para_f = nullptr, *para_entries = nullptr;\n";
825 out << " TTree* para_tree = nullptr;\n";
826 out << " TEntryList *para_currententries = nullptr;\n";
827 out << " TParallelCoordSelect *para_sel = nullptr;\n";
828 out << " TParallelCoordVar* para_var = nullptr;\n";
829 out << " TSelectorDraw *para_selector = nullptr;\n";
830 out << " TParallelCoord *para = nullptr;\n";
831 }
832 out << " // Create a TParallelCoord.\n";
833 out << " para_f = TFile::Open(\"" << TString(fTreeFileName).ReplaceSpecialCppChars() << "\");\n";
834 out << " para_tree = (TTree *)para_f->Get(\"" << fTreeName << "\");\n";
835 out << " para = new TParallelCoord(para_tree, " << fNentries << ");\n";
836 out << " // Load the entrylists.\n";
837 out << " para_entries = TFile::Open(\"" << TString(filename).ReplaceSpecialCppChars() << "\");\n";
838 out << " para_currententries = (TEntryList *)para_entries->Get(\"currententries\");\n";
839 out << " para_tree->SetEntryList(para_currententries);\n";
840 out << " para->SetInitEntries((TEntryList*)para_entries->Get(\"initentries\"));\n";
841 out << " para->SetCurrentEntries(para_currententries);\n";
842 TIter next(fSelectList);
843 out << " para->GetSelectList()->Delete();\n";
844 while (auto sel = (TParallelCoordSelect *)next()) {
845 out << " para->AddSelection(\"" << TString(sel->GetTitle()).ReplaceSpecialCppChars() << "\");\n";
846 out << " para_sel = (TParallelCoordSelect*)para->GetSelectList()->Last();\n";
847 sel->SaveLineAttributes(out, "para_sel", -1, -1, 1);
848 }
851 while (auto var = (TParallelCoordVar *)nextbis()) {
852 if (!varexp.IsNull())
853 varexp.Append(":");
854 varexp.Append(var->GetTitle());
855 }
856 out << " para_tree->Draw(\"" << varexp.ReplaceSpecialCppChars() << "\", \"\", \"goff\");\n";
857 out << " para_selector = (TSelectorDraw *)((TTreePlayer *)para_tree->GetPlayer())->GetSelector();\n";
858 nextbis.Reset();
859 Int_t i = 0;
860 while (auto var = (TParallelCoordVar *)nextbis()) {
861 out << " //***************************************\n";
862 out << " // Create the axis \"" << var->GetTitle() << "\".\n";
863 out << " para->AddVariable(para_selector->GetVal(" << i++ << "), \"" << TString(var->GetTitle()).ReplaceSpecialCppChars() << "\");\n";
864 out << " para_var = (TParallelCoordVar *)para->GetVarList()->Last();\n";
865 var->SavePrimitive(out, "pcalled");
866 }
867 out << " //***************************************\n";
868 out << " // Set the TParallelCoord parameters.\n";
869 out << " para->SetCurrentFirst(" << fCurrentFirst << ");\n";
870 out << " para->SetCurrentN(" << fCurrentN << ");\n";
871 out << " para->SetWeightCut(" << fWeightCut << ");\n";
872 out << " para->SetDotsSpacing(" << fDotsSpacing << ");\n";
873 out << " para->SetLineColor(" << TColor::SavePrimitiveColor(GetLineColor()) << ");\n";
874 out << " para->SetLineWidth(" << GetLineWidth() << ");\n";
875 out << " para->SetBit(TParallelCoord::kVertDisplay, " << TestBit(kVertDisplay) << ");\n";
876 out << " para->SetBit(TParallelCoord::kCurveDisplay, " << TestBit(kCurveDisplay) << ");\n";
877 out << " para->SetBit(TParallelCoord::kPaintEntries, " << TestBit(kPaintEntries) << ");\n";
878 out << " para->SetBit(TParallelCoord::kLiveUpdate, " << TestBit(kLiveUpdate) << ");\n";
879 out << " para->SetBit(TParallelCoord::kGlobalLogScale, " << TestBit(kGlobalLogScale) << ");\n";
881 out << " para->SetGlobalScale(true);\n";
883 out << " para->SetCandleChart(true);\n";
885 out << " para->SetGlobalLogScale(true);\n";
886 out << " \n";
887 SavePrimitiveDraw(out, "para", option);
888}
889
890////////////////////////////////////////////////////////////////////////////////
891/// Save the tree in a file if fTreeFileName == "".
892
894{
895 if (!fTreeFileName.IsNull())
896 return;
898 if (sfile.IsNull())
899 sfile.Form("%s.root",fTree->GetName());
900
901 TFile* f = TFile::Open(sfile.Data());
902 if (f) {
903 Warning("SaveTree","%s already exists.", sfile.Data());
904 if (!overwrite) return;
905 else Warning("SaveTree","Overwriting.");
906 f = new TFile(sfile.Data(),"RECREATE");
907 } else {
908 f = new TFile(sfile.Data(),"CREATE");
909 }
910 gDirectory = f;
913 Info("SaveTree", "File \"%s\" written.",sfile.Data());
914}
915
916////////////////////////////////////////////////////////////////////////////////
917/// Update the position of the axes.
918
920{
921 if(!gPad) return;
922 bool vert = TestBit (kVertDisplay);
923 TFrame *frame = gPad->GetFrame();
924 if (fVarList->GetSize() > 1) {
925 if (vert) {
926 frame->SetX1(1.0/((Double_t)fVarList->GetSize()+1));
927 frame->SetX2(1-frame->GetX1());
928 frame->SetY1(0.1);
929 frame->SetY2(0.9);
930 gPad->RangeAxis(1.0/((Double_t)fVarList->GetSize()+1),0.1,1-frame->GetX1(),0.9);
931 } else {
932 frame->SetX1(0.1);
933 frame->SetX2(0.9);
934 frame->SetY1(1.0/((Double_t)fVarList->GetSize()+1));
935 frame->SetY2(1-frame->GetY1());
936 gPad->RangeAxis(0.1,1.0/((Double_t)fVarList->GetSize()+1),0.9,1-frame->GetY1());
937 }
938
939 Double_t horSpace = (frame->GetX2() - frame->GetX1())/(fNvar-1);
940 Double_t verSpace = (frame->GetY2() - frame->GetY1())/(fNvar-1);
941 Int_t i=0;
942 TIter next(fVarList);
943
945 while((var = (TParallelCoordVar*)next())){
946 if (vert) var->SetX(gPad->GetFrame()->GetX1() + i*horSpace,TestBit(kGlobalScale));
947 else var->SetY(gPad->GetFrame()->GetY1() + i*verSpace,TestBit(kGlobalScale));
948 ++i;
949 }
950 } else if (fVarList->GetSize()==1) {
951 frame->SetX1(0.1);
952 frame->SetX2(0.9);
953 frame->SetY1(0.1);
954 frame->SetY2(0.9);
956 else ((TParallelCoordVar*)fVarList->First())->SetY(0.5,TestBit(kGlobalScale));
957 }
958}
959
960////////////////////////////////////////////////////////////////////////////////
961/// Set the same histogram axis binning for all axis.
962
964{
965 TIter next(fVarList);
967 while((var = (TParallelCoordVar*)next())) var->SetHistogramBinning(n);
968}
969
970////////////////////////////////////////////////////////////////////////////////
971/// Set the same histogram axis height for all axis.
972
974{
975 TIter next(fVarList);
977 while((var = (TParallelCoordVar*)next())) var->SetHistogramHeight(h);
978}
979
980////////////////////////////////////////////////////////////////////////////////
981/// All axes in log scale.
982
984{
985 if (lt == TestBit(kGlobalLogScale)) return;
987 TIter next(fVarList);
989 while ((var = (TParallelCoordVar*)next())) var->SetLogScale(lt);
991}
992
993////////////////////////////////////////////////////////////////////////////////
994/// Constraint all axes to the same scale.
995
997{
999 if (fCandleAxis) {
1000 delete fCandleAxis;
1001 fCandleAxis = nullptr;
1002 }
1003 if (gl) {
1004 Double_t min,max;
1005 min = GetGlobalMin();
1006 max = GetGlobalMax();
1007 if (TestBit(kGlobalLogScale) && min<=0) min = 0.00001*max;
1008 if (TestBit(kVertDisplay)) {
1009 if (!TestBit(kGlobalLogScale)) fCandleAxis = new TGaxis(0.05,0.1,0.05,0.9,min,max);
1010 else fCandleAxis = new TGaxis(0.05,0.1,0.05,0.9,min,max,510,"G");
1011 } else {
1012 if (!TestBit(kGlobalLogScale)) fCandleAxis = new TGaxis(0.1,0.05,0.9,0.05,min,max);
1013 else fCandleAxis = new TGaxis(0.1,0.05,0.9,0.05,min,max,510,"G");
1014 }
1015 fCandleAxis->Draw();
1016 SetGlobalMin(min);
1017 SetGlobalMax(max);
1018 TIter next(fVarList);
1019 TParallelCoordVar* var;
1020 while ((var = (TParallelCoordVar*)next())) var->GetHistogram();
1021 }
1022 gPad->Modified();
1023 gPad->Update();
1024}
1025
1026////////////////////////////////////////////////////////////////////////////////
1027/// Set the same histogram axis line width for all axis.
1028
1030{
1031 TIter next(fVarList);
1032 TParallelCoordVar *var;
1033 while((var = (TParallelCoordVar*)next())) var->SetHistogramLineWidth(lw);
1034}
1035
1036////////////////////////////////////////////////////////////////////////////////
1037/// Set a candle chart display.
1038
1040{
1043 TIter next(fVarList);
1044 TParallelCoordVar* var;
1045 while ((var = (TParallelCoordVar*)next())) {
1046 var->SetBoxPlot(can);
1047 var->SetHistogramLineWidth(0);
1048 }
1049 if (fCandleAxis) delete fCandleAxis;
1050 fCandleAxis = nullptr;
1052 if (can) {
1053 if (TestBit(kVertDisplay)) fCandleAxis = new TGaxis(0.05,0.1,0.05,0.9,GetGlobalMin(),GetGlobalMax());
1054 else fCandleAxis = new TGaxis(0.1,0.05,0.9,0.05,GetGlobalMin(),GetGlobalMax());
1055 fCandleAxis->Draw();
1056 } else {
1057 if (fCandleAxis) {
1058 delete fCandleAxis;
1059 fCandleAxis = nullptr;
1060 }
1061 }
1062 gPad->Modified();
1063 gPad->Update();
1064}
1065
1066////////////////////////////////////////////////////////////////////////////////
1067/// Set the first entry to be displayed.
1068
1070{
1071 if(f<0 || f>fNentries) return;
1072 fCurrentFirst = f;
1074 TIter next(fVarList);
1075 TParallelCoordVar* var;
1076 while ((var = (TParallelCoordVar*)next())) {
1077 var->GetMinMaxMean();
1078 var->GetHistogram();
1080 }
1081}
1082
1083////////////////////////////////////////////////////////////////////////////////
1084/// Set the number of entry to be displayed.
1085
1087{
1088 if(n<=0) return;
1090 else fCurrentN = n;
1091 TIter next(fVarList);
1092 TParallelCoordVar* var;
1093 while ((var = (TParallelCoordVar*)next())) {
1094 var->GetMinMaxMean();
1095 var->GetHistogram();
1097 }
1098}
1099
1100////////////////////////////////////////////////////////////////////////////////
1101/// Set the selection being edited.
1102
1104{
1106 TIter next(fSelectList);
1108 while((sel = (TParallelCoordSelect*)next()) && strcmp(sel->GetTitle(),title))
1109 if (sel) fCurrentSelection = sel;
1110 return sel;
1111}
1112
1113////////////////////////////////////////////////////////////////////////////////
1114/// Set the selection being edited.
1115
1121
1122////////////////////////////////////////////////////////////////////////////////
1123/// Set dots spacing. Modify the line style 11.
1124/// If the canvas support transparency dot spacing is ignored.
1125
1127{
1128 if (gPad->GetCanvas()->SupportAlpha()) return;
1129 if (s == fDotsSpacing) return;
1130 fDotsSpacing = s;
1131 gStyle->SetLineStyleString(11, TString::Format("%d %d",4,s*8));
1132}
1133
1134////////////////////////////////////////////////////////////////////////////////
1135/// Set the entry lists of "para".
1136
1138{
1139 para->SetCurrentEntries(enlist);
1140 para->SetInitEntries(enlist);
1141}
1142
1143////////////////////////////////////////////////////////////////////////////////
1144/// Force all variables to adopt the same max.
1145
1147{
1148 TIter next(fVarList);
1149 TParallelCoordVar* var;
1150 while ((var = (TParallelCoordVar*)next())) {
1151 var->SetCurrentMax(max);
1152 }
1153}
1154
1155////////////////////////////////////////////////////////////////////////////////
1156/// Force all variables to adopt the same min.
1157
1159{
1160 TIter next(fVarList);
1161 TParallelCoordVar* var;
1162 while ((var = (TParallelCoordVar*)next())) {
1163 var->SetCurrentMin(min);
1164 }
1165}
1166
1167////////////////////////////////////////////////////////////////////////////////
1168/// If true, the pad is updated while the motion of a dragged range.
1169
1171{
1173 TIter next(fVarList);
1174 TParallelCoordVar* var;
1175 while((var = (TParallelCoordVar*)next())) var->SetLiveRangesUpdate(on);
1176}
1177
1178////////////////////////////////////////////////////////////////////////////////
1179/// Set the vertical or horizontal display.
1180
1182{
1183 if (vert == TestBit (kVertDisplay)) return;
1185 if (!gPad) return;
1186 TFrame* frame = gPad->GetFrame();
1187 if (!frame) return;
1188 UInt_t ui = 0;
1189 Double_t horaxisspace = (frame->GetX2() - frame->GetX1())/(fNvar-1);
1190 Double_t veraxisspace = (frame->GetY2() - frame->GetY1())/(fNvar-1);
1191 TIter next(fVarList);
1192 TParallelCoordVar* var;
1193 while ((var = (TParallelCoordVar*)next())) {
1194 if (vert) var->SetX(frame->GetX1() + ui*horaxisspace,TestBit(kGlobalScale));
1195 else var->SetY(frame->GetY1() + ui*veraxisspace,TestBit(kGlobalScale));
1196 ++ui;
1197 }
1198 if (TestBit(kCandleChart)) {
1199 if (fCandleAxis) delete fCandleAxis;
1200 if (TestBit(kVertDisplay)) fCandleAxis = new TGaxis(0.05,0.1,0.05,0.9,GetGlobalMin(),GetGlobalMax());
1201 else fCandleAxis = new TGaxis(0.1,0.05,0.9,0.05,GetGlobalMin(),GetGlobalMax());
1202 fCandleAxis->Draw();
1203 }
1204 gPad->Modified();
1205 gPad->Update();
1206}
1207
1208////////////////////////////////////////////////////////////////////////////////
1209/// Unzoom all variables.
1210
1212{
1213 TIter next(fVarList);
1214 TParallelCoordVar* var;
1215 while((var = (TParallelCoordVar*)next())) var->Unzoom();
1216}
@ 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
Definition RtypesCore.h:69
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:374
@ kGreen
Definition Rtypes.h:66
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define gDirectory
Definition TDirectory.h:384
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:406
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:2557
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:4130
Define a Frame.
Definition TFrame.h:19
void Draw(Option_t *option="") override
Draw this frame with its current attributes.
Definition TFrame.cxx:67
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:1987
void Reset()
Iterator of linked list.
Definition TList.h:191
void Reset() override
Reset list iterator.
Definition TList.cxx:1160
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:820
TObject * First() const override
Return the first object in the list. Returns 0 when list is empty.
Definition TList.cxx:657
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:468
TObject * At(Int_t idx) const override
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx:355
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:174
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:205
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
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:139
void ToLower()
Change string to lower-case.
Definition TString.cxx:1182
TString & ReplaceSpecialCppChars()
Find special characters which are typically used in printf() calls and replace them by appropriate es...
Definition TString.cxx:1114
const char * Data() const
Definition TString.h:376
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:704
@ kLeading
Definition TString.h:276
Bool_t IsNull() const
Definition TString.h:414
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:2378
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:632
void SetLineStyleString(Int_t i, const char *text)
Set line style string using the PostScript convention.
Definition TStyle.cxx:1485
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:79
TFile * GetCurrentFile() const
Return pointer to the current file.
Definition TTree.cxx:5480
TVirtualTreePlayer * GetPlayer()
Load the TTreePlayer (if not already done).
Definition TTree.cxx:6308
void Draw(Option_t *opt) override
Default Draw method for all objects.
Definition TTree.h:432
virtual void SetEntryList(TEntryList *list, Option_t *opt="")
Set an EntryList.
Definition TTree.cxx:9140
virtual Double_t * GetV1()
Definition TTree.h:577
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:9858
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
std::ostream & Info()
Definition hadd.cxx:171
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