Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TParallelCoordVar.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 "TParallelCoordVar.h"
13#include "TParallelCoord.h"
14#include "TParallelCoordRange.h"
15
16#include "TLatex.h"
17#include "TLine.h"
18#include "TVirtualPad.h"
19#include "TVirtualX.h"
20#include "TMath.h"
21#include "TH1.h"
22#include "TStyle.h"
23#include "TBox.h"
24#include "TCollection.h"
25#include "TList.h"
26#include "TFrame.h"
27#include "TCanvas.h"
28#include "TMarker.h"
29
30#include <cstdio>
31#include <iostream>
32
33/** \class TParallelCoordVar
34
35TParallelCoord axes. Class containing a variable for the TParallelCoord.
36
37Options can be defined each axis separately using the right mouse click. These
38options can be applied to every axes using the editor.
39
40 - Axis width: If set to 0, the axis is simply a line. If higher, a color
41 histogram is drawn on the axis.
42 - Axis histogram height: If not 0, a usual bar histogram is drawn on the plot.
43
44The order in which the variables are drawn is essential to see the clusters. The
45axes can be dragged to change their position. A zoom is also available. The
46logarithm scale is also available by right clicking on the axis.
47*/
48
49////////////////////////////////////////////////////////////////////////////////
50/// Default constructor.
51
57
58////////////////////////////////////////////////////////////////////////////////
59///Destructor.
60
62{
63 if (fHistogram) delete fHistogram;
64 if (fRanges){
65 TIter next(fRanges);
68 fRanges->Delete();
69 delete fRanges;
70 }
71 if (fVal) delete [] fVal;
72}
73
74////////////////////////////////////////////////////////////////////////////////
75/// Normal constructor. By default, the title and the name are the expression
76/// given to TTree::Draw. The name can be changed by the user (the label on the
77/// plot) but not the title.
78
80 :TNamed(title,title), TAttLine(1,1,1), TAttFill(kOrange+9,3001)
81{
82 Init();
83 fId = id;
85 fRanges = new TList();
87
89
90 for(Long64_t ui = 0;ui<fParallel->GetNentries();++ui) fVal[ui]=val[ui];
91
95}
96
97////////////////////////////////////////////////////////////////////////////////
98/// Add a range to the current selection on the axis.
99
101{
102 if (!range) {
104 if (select) {
105 range = new TParallelCoordRange(this,0,0,select);
106 fRanges->Add(range);
107 range->GetSelection()->Add(range);
108 } else {
109 Error("AddRange","You must create a selection before adding ranges.");
110 }
111 } else {
112 fRanges->Add(range);
113 range->GetSelection()->Add(range);
114 }
115}
116
117////////////////////////////////////////////////////////////////////////////////
118/// Delete variables.
119
121{
123 delete this;
124}
125
126////////////////////////////////////////////////////////////////////////////////
127/// Computes the distance from the axis.
128
130{
131 if(!gPad) return 9999;
132 Double_t xx = gPad->AbsPixeltoX(px);
133 Double_t yy = gPad->AbsPixeltoY(py);
134 Double_t dist = 9999;
135
136 if (fX1==fX2) {
137 if (yy>fY1+0.01 && yy<fY2-0.01) dist = TMath::Abs(xx - fX1);
138 } else {
139 if (xx>fX1+0.01 && xx<fX2-0.01) dist = TMath::Abs(yy - fY1);
140 }
141 if (dist<=0.005) return 0;
142 else return 9999;
143}
144
145////////////////////////////////////////////////////////////////////////////////
146/// Draw the axis.
147
152
153////////////////////////////////////////////////////////////////////////////////
154/// Check if the entry is within the range(s) of "select". Two ranges on a
155/// single axis are conjugated as a "or": to be selected, the entry must be in
156/// one of the ranges.
157
159{
160 if (fRanges->GetSize() > 0){
161 TIter next(fRanges);
162 bool inarange = false;
163 bool noOwnedRange = true;
165 while ((range = (TParallelCoordRange*)next())){
166 if(select->Contains(range)) {
167 noOwnedRange = false;
168 if(range->IsIn(fVal[evtidx])) inarange = true;
169 }
170 }
171 if (noOwnedRange) return true;
172 else return inarange;
173 }
174 else return true;
175}
176
177////////////////////////////////////////////////////////////////////////////////
178/// Execute the corresponding entry.
179
181{
182 if (!gPad) return;
183 if (!gPad->IsEditable() && entry!=kMouseEnter) return;
184
185 static Int_t pxold, pyold;
186 static Int_t zoom; // -1:nothing zoomed or translated, 0:translating the axis, 1:zooming
187 static Int_t pzoomold;
188 static bool first = true;
189
190 Int_t px1,px2,py1,py2,n=-1;
191 px1 = gPad->XtoAbsPixel(fX1);
192 px2 = gPad->XtoAbsPixel(fX2);
193 py1 = gPad->YtoAbsPixel(fY1);
194 py2 = gPad->YtoAbsPixel(fY2);
195
196 if(fX1 == fX2) {
197 if(gPad->AbsPixeltoX(px)-fX1 > 0) gPad->SetCursor(kArrowVer);
198 else gPad->SetCursor(kArrowHor);
199 } else {
200 if(gPad->AbsPixeltoY(py)-fY1 > 0) gPad->SetCursor(kArrowHor);
201 else gPad->SetCursor(kArrowVer);
202 }
203
204 gVirtualX->SetLineColor(-1);
205 switch (entry) {
206 case kButton1Down:
207 if (fX1==fX2){
208 ((TCanvas*)gPad)->Selected(gPad,fParallel,1);
209 if(gPad->AbsPixeltoX(px)-fX1 > 0){
210 zoom = 1;
211 gVirtualX->DrawLine(gPad->XtoAbsPixel(fX1-0.05),py,gPad->XtoAbsPixel(fX1+0.05),py);
212 first = true;
213 pzoomold = py;
214 } else {
215 zoom = 0;
216 gVirtualX->DrawLine(px,py1,px,py2);
217 }
218 } else {
219 if(gPad->AbsPixeltoY(py)-fY1 > 0){
220 zoom = 1;
221 gVirtualX->DrawLine(px,gPad->YtoAbsPixel(fY1-0.05),px,gPad->YtoAbsPixel(fY1+0.05));
222 first=true;
223 pzoomold = px;
224 } else {
225 zoom = 0;
226 gVirtualX->DrawLine(px1,py,px2,py);
227 }
228 }
229 pxold = px;
230 pyold = py;
231 break;
232 case kButton1Up: {
233 Double_t xx = gPad->AbsPixeltoX(px);
234 Double_t yy = gPad->AbsPixeltoY(py);
235 TFrame *frame = gPad->GetFrame();
236 if (fX1==fX2) {
237 if(zoom == 0){
238 Double_t axisSpace = (frame->GetX2() - frame->GetX1())/(fParallel->GetNvar() - 1);
239 Double_t pos = (xx - frame->GetX1())/axisSpace;
240 if (pos < 0) n = -1;
241 else n = (Int_t)pos;
242 } else {
244 Double_t max = GetValuefromXY(xx,gPad->AbsPixeltoY(pzoomold));
245 if(TMath::Abs(min-max) < 0.00001) return; // Avoid zooming if the axis is just clicked.
247 if (min>max) {
248 Double_t mem = min;
249 min = max; max = mem;
250 }
253 } else {
254 SetCurrentLimits(min,max);
255 }
256 }
257 } else {
258 if(zoom == 0) {
259 Double_t axisSpace = (frame->GetY2() - frame->GetY1())/(fParallel->GetNvar() - 1);
260 Double_t pos = (yy-frame->GetY1())/axisSpace;
261 if (pos < 0) n= -1;
262 else n = (Int_t)pos;
263 } else {
265 Double_t max = GetValuefromXY(gPad->AbsPixeltoX(pzoomold),yy);
266 SetCurrentLimits(min,max);
267 }
268 }
269 if(zoom == 0){
270 if (n>=0 && (UInt_t)n>=fParallel->GetNvar()) --n;
271 else if (n<fParallel->GetVarList()->IndexOf(this)) ++n;
272 fParallel->GetVarList()->Remove(this);
273 fParallel->GetVarList()->AddAt(this,n);
274 }
275 gPad->Modified();
276 break;
277 }
278 case kMouseMotion:
279 pxold=px;
280 pyold=py;
281 break;
282 case kButton1Motion:
283 if(fX1==fX2){
284 if(zoom==0){
285 gPad->SetCursor(kArrowHor);
286 gVirtualX->DrawLine(pxold,py1,pxold,py2);
287 gVirtualX->DrawLine(px,py1,px,py2);
288 } else if(zoom==1) {
289 gPad->SetCursor(kArrowVer);
290 if(!first) gVirtualX->DrawLine(gPad->XtoAbsPixel(fX1-0.05),pyold,gPad->XtoAbsPixel(fX1+0.05),pyold);
291 gVirtualX->DrawLine(gPad->XtoAbsPixel(fX1-0.05),py,gPad->XtoAbsPixel(fX1+0.05),py);
292 first = false;
293 }
294 } else {
295 if(zoom==0){
296 gPad->SetCursor(kArrowVer);
297 gVirtualX->DrawLine(px1,pyold,px2,pyold);
298 gVirtualX->DrawLine(px1,py,px2,py);
299 } else if(zoom==1){
300 gPad->SetCursor(kArrowHor);
301 if(!first) gVirtualX->DrawLine(pxold,gPad->YtoAbsPixel(fY1-0.05),pxold,gPad->YtoAbsPixel(fY1+0.05));
302 gVirtualX->DrawLine(px,gPad->YtoAbsPixel(fY1-0.05),px,gPad->YtoAbsPixel(fY1+0.05));
303 first = false;
304 }
305 }
306 pxold = px;
307 pyold = py;
308 break;
309 }
310}
311
312////////////////////////////////////////////////////////////////////////////////
313/// Get the position of the variable on the graph for the n'th entry.
314
316{
317 if(fX1==fX2){
318 x = fX1;
319 if (fMinCurrent != fMaxCurrent) {
320 if (TestBit(kLogScale)) y = fY1 + (fY2 - fY1) *
322 else y = fY1 + (fY2 - fY1) *
324 } else {
325 y = fY1 + 0.5*(fY2-fY1);
326 }
327 } else {
328 y = fY1;
329 if (fMinCurrent != fMaxCurrent) {
330 if (TestBit(kLogScale)) x = fX1 + (fX2 - fX1) *
332 else x = fX1 + (fX2 - fX1) *
334 } else {
335 x = fX1 + 0.5*(fX2-fX1);
336 }
337 }
338}
339
340////////////////////////////////////////////////////////////////////////////////
341/// Get the entry weight: The weight of an entry for a given variable
342/// is the bin content of the histogram bin the entry is going through.
343
349
350////////////////////////////////////////////////////////////////////////////////
351/// Create or recreate the histogram.
352
354{
355 if (fHistogram) delete fHistogram;
356 fHistogram = nullptr;
357 fHistogram = new TH1F("hpa", "hpa", fNbins, fMinCurrent, fMaxCurrent+0.0001*(fMaxCurrent-fMinCurrent));
358 fHistogram->SetDirectory(nullptr);
361 for(Long64_t li=first; li<first+nentries;++li) {
363 }
364 return fHistogram;
365}
366
367////////////////////////////////////////////////////////////////////////////////
368/// Get mean, min and max of those variable.
369
371{
372 Double_t min,max,ave = 0;
373 min = DBL_MAX;
374 max = -DBL_MAX;
375 Long64_t first,nentries;
376 first = fParallel->GetCurrentFirst();
378 for(Long64_t li=first; li<first+nentries;++li){
379 if(fVal[li]<min) min = fVal[li];
380 if(fVal[li]>max) max = fVal[li];
381 ave+=fVal[li];
382 }
383
385 fMinCurrent = fMinInit = min;
386 fMaxCurrent = fMaxInit = max;
387}
388
389////////////////////////////////////////////////////////////////////////////////
390/// Returns info about this axis.
391
393{
394 static char info[128];
395 info[0] = 0;
396
397 if (!gPad) return info;
398 Double_t xx = gPad->AbsPixeltoX(px);
399 Double_t yy = gPad->AbsPixeltoY(py);
400 if (fX1 == fX2) {
401 if (yy<fY1) {
402 snprintf(info,128,"%s = %f", GetTitle(), fMinCurrent);
403 } else if (yy>fY2) {
404 snprintf(info,128,"%s = %f", GetTitle(), fMaxCurrent);
405 } else {
407 Double_t pos = (yy-fY1)/axislength;
408 snprintf(info,128,"%s = %f", GetTitle(), fMinCurrent + pos*(fMaxCurrent-fMinCurrent));
409 }
410 } else {
411 if (xx<fX1) {
412 snprintf(info,128,"%s = %f", GetTitle(), fMinCurrent);
413 } else if(xx>fX2) {
414 snprintf(info,128,"%s = %f", GetTitle(), fMaxCurrent);
415 } else {
417 Double_t pos = (xx-fX1)/axislength;
418 snprintf(info,128,"%s = %f", GetTitle(), pos*(fMaxCurrent-fMinCurrent));
419 }
420 }
421 return info;
422}
423
424////////////////////////////////////////////////////////////////////////////////
425/// Get the box plot values (quantiles).
426
428{
429 Double_t *quantiles = new Double_t[3];
430 quantiles[0]=0.; quantiles[1]=0.; quantiles[2] = 0.;
431 Double_t *prob = new Double_t[3];
432 prob[0]=0.25; prob[1]=0.5; prob[2] = 0.75;
436 else {
437 Double_t* val = new Double_t[nentries];
438 Int_t selected = 0;
439 if(fMinInit<=0) {
440 for (Long64_t n=first;n<first+nentries;++n) {
441 if (fVal[n] >= fMinCurrent) {
442 if (TestBit(kLogScale)) val[selected] = TMath::Log10(fVal[n]);
443 else val[selected] = fVal[n];
444 ++selected;
445 }
446 }
447 } else {
448 for (Long64_t n=first;n<first+nentries;++n) {
449 if (TestBit(kLogScale)) val[selected] = TMath::Log10(fVal[n]);
450 else val[selected] = fVal[n];
451 ++selected;
452 }
453 }
454 TMath::Quantiles(selected,3,val,quantiles,prob,false);
455 delete [] val;
456 }
457 fQua1 = quantiles[0];
458 fMed = quantiles[1];
459 fQua3 = quantiles[2];
460 delete [] quantiles;
461 delete [] prob;
462}
463
464////////////////////////////////////////////////////////////////////////////////
465/// Get the value corresponding to the position.
466
468{
469 Double_t pos;
470 if (fMinCurrent == fMaxCurrent) return fMinCurrent;
471 if (fX1 == fX2) {
472 if (y<=fY1) pos = fMinCurrent;
473 else if (y>=fY2) pos = fMaxCurrent;
474 else pos = fMinCurrent + ((y-fY1)/(fY2-fY1))*(fMaxCurrent-fMinCurrent);
475 } else {
476 if (x<=fX1) pos = fMinCurrent;
477 else if (x>=fX2) pos = fMaxCurrent;
478 else pos = fMinCurrent + ((x-fX1)/(fX2-fX1))*(fMaxCurrent-fMinCurrent);
479 }
480 return pos;
481}
482
483////////////////////////////////////////////////////////////////////////////////
484/// Get a position corresponding to the value on the axis.
485
487{
489
490 if (fX1==fX2) {
491 x = fX1;
492 if (fMinCurrent != fMaxCurrent) {
493 if (TestBit(kLogScale)) y = fY1 + (fY2 - fY1) *
495 else y = fY1 + (fY2 - fY1) *
497 } else {
498 y = fY1 + 0.5*(fY2-fY1);
499 }
500 } else {
501 y = fY1;
502 if (fMinCurrent != fMaxCurrent) {
503 if (TestBit(kLogScale)) x = fX1 + (fX2 - fX1) *
505 else x = fX1 + (fX2 - fX1) *
507 } else {
508 x = fX1 + 0.5*(fX2-fX1);
509 }
510 }
511}
512
513////////////////////////////////////////////////////////////////////////////////
514/// Initialise the TParallelVar variables.
515
517{
518 fX1 = 0;
519 fX2 = 0;
520 fY1 = 0;
521 fY2 = 0;
522 fId = 0;
523 fVal = nullptr;
524 fMean = 0;
525 fMinInit = 0;
526 fMinCurrent = 0;
527 fMaxInit = 0;
528 fMaxCurrent = 0;
529 fMed = 0;
530 fQua1 = 0;
531 fQua3 = 0;
532 fNentries = 0;
533 fParallel = nullptr;
534 fHistogram = nullptr;
535 fNbins = 100;
536 fHistoLW = 2;
537 fHistoHeight = 0.5;
538 fRanges = nullptr;
539 SetBit(kLogScale,false);
540 SetBit(kShowBox,false);
541 SetBit(kShowBarHisto,true);
542}
543
544////////////////////////////////////////////////////////////////////////////////
545/// Paint the axis.
546
548{
549 TIter next(fRanges);
551 while ((range = (TParallelCoordRange*)next())) range->Paint(option);
552
555 PaintLabels();
556}
557
558////////////////////////////////////////////////////////////////////////////////
559/// Paint the boxes in the case of a candle chart.
560
562{
563 TLine *line = new TLine();
565 line->SetLineWidth(1);
566 TBox *box = new TBox();
567 box->SetLineWidth(1);
568 box->SetLineColor(GetLineColor());
569 box->SetLineStyle(1);
570 box->SetFillStyle(0);
571
572 TFrame* frame = gPad->GetFrame();
573
575 if (fParallel->GetNvar() > 1) {
576 if (fX1==fX2) boxSize = fHistoHeight*((frame->GetY2()-frame->GetY1())/(fParallel->GetNvar()-1));
577 else boxSize = fHistoHeight*((frame->GetX2()-frame->GetX1())/(fParallel->GetNvar()-1));
578 if (boxSize >= 0.03) boxSize = 0.03;
579 }
580 else boxSize = 0.03;
581
582 Double_t qua1,med,qua3,max,min;
584 if (TestBit(kLogScale)) {
590 } else {
591 a = fMinCurrent;
595 }
596 if(fX1==fX2) {
597 qua1 = fY1 + ((fQua1-a)/b)*(fY2-fY1);
598 qua3 = fY1 + ((fQua3-a)/b)*(fY2-fY1);
599 med = fY1 + ((fMed-a)/b)*(fY2-fY1);
600 max = fY1 + ((maxinit-a)/b)*(fY2-fY1);
601 min = fY1 + ((mininit-a)/b)*(fY2-fY1);
602 } else {
603 qua1 = fX1 + ((fQua1-a)/b)*(fX2-fX1);
604 qua3 = fX1 + ((fQua3-a)/b)*(fX2-fX1);
605 med = fX1 + ((fMed-a)/b)*(fX2-fX1);
606 max = fX1 + ((maxinit-a)/b)*(fX2-fX1);
607 min = fX1 + ((mininit-a)/b)*(fX2-fX1);
608 }
609
610 // min and max lines.
611 if (fX1==fX2) {
614 } else {
617 }
618
619 // lines from min and max to the box.
620 line->SetLineStyle(7);
621 if (fX1==fX2) {
622 if (min<frame->GetY1()) min = frame->GetY1();
623 if (max>frame->GetY2()) max = frame->GetY2();
624 line->PaintLine(fX1,min,fX1,qua1);
625 line->PaintLine(fX1,qua3,fX1,max);
626 } else {
627 if (min<frame->GetX1()) min = frame->GetX1();
628 if (max>frame->GetX2()) max = frame->GetX2();
629 line->PaintLine(min,fY1,qua1,fY2);
630 line->PaintLine(qua3,fY1,max,fY2);
631 }
632
633 // Box
634 if(fX1==fX2) box->PaintBox(fX1-boxSize,qua1,fX1+boxSize,qua3);
635 else box->PaintBox(qua1,fY1-boxSize,qua3,fY1+boxSize);
636
637 // Median line
638 line->SetLineStyle(1);
641
642 // Paint average
643 if (!TestBit(kLogScale) || (TestBit(kLogScale) && fMean > 0)) {
644 Double_t mean;
645 if (TestBit(kLogScale)) mean = TMath::Log10(fMean);
646 else mean = fMean;
647 TMarker *mark = nullptr;
648 if(fX1==fX2) mark = new TMarker(fX1,fY1 + ((mean-a)/b)*(fY2-fY1),24);
649 else mark = new TMarker(fX1 + ((mean-a)/b)*(fX2-fX1),fY1,24);
650 mark->Paint();
651 delete mark;
652 }
653
654 delete line;
655 delete box;
656}
657
658////////////////////////////////////////////////////////////////////////////////
659/// Paint the histogram on the axis.
660
662{
663 Int_t i;
664
665 TFrame *frame = gPad->GetFrame();
666
667 if (!fHistogram) GetHistogram();
668
669 // Paint the axis body.
671 // Paint the axis body using bar chart.
672 TBox *b = new TBox();
673 b->SetFillStyle(GetFillStyle());
674 b->SetFillColor(GetFillColor());
675 b->SetLineStyle(1);
676 b->SetLineColor(GetFillColor());
677 b->SetLineWidth(1);
680 if (fX1 == fX2) {
681 // Vertical case.
685 Double_t y1 = fY1,x2,y2;
686 for (i=1; i<=fNbins; i++) {
688 ((frame->GetX2()-frame->GetX1())/(fParallel->GetNvar()-1));
690 else y2=y1+dy;
691 b->PaintBox(fX1,y1,x2,y2,"l");
692 y1=y2;
693 v += dv;
694 }
695 } else {
696 // Horizontal case.
700 Double_t x1 = fX1,x2,y2;
701 for (i=1; i<=fNbins; i++) {
702 y2 = fY1+((fHistogram->GetBinContent(i)-hmin)/(hmax-hmin))*fHistoHeight*((frame->GetY2()-frame->GetY1())/(fParallel->GetNvar()-1));
704 else x2=x1+dx;
705 b->PaintBox(x1,fY1,x2,y2,"l");
706 x1=x2;
707 v+=dv;
708 }
709 }
710 delete b;
711 }
712 if (fHistoLW==0 && !TestBit(kShowBox)) {
713 // Paint the axis body as a simple line.
714 TLine* l = new TLine(fX1,fY1,fX2,fY2);
718 l->Paint();
719 delete l;
720 } else if (fHistoLW!=0){
721 // Paint the axis body using the color palette.
722 TLine *lb = new TLine();
723 lb->SetLineWidth(fHistoLW);
728 if (fX1 == fX2) {
729 // Vertical case.
731 Double_t y1 = fY1,y2;
734 for (i=1; i<=fNbins; i++) {
737 else y2=y1+dy;
738 lb->SetLineColor(gStyle->GetColorPalette(theColor));
739 lb->PaintLine(fX1,y1,fX1,y2);
740 y1=y2;
741 v+=dv;
742 }
743 } else {
744 // Horizontal case.
748 Double_t x1 = fX1,x2;
749 for (i=1; i<=fNbins; i++) {
751 lb->SetLineColor(gStyle->GetColorPalette(theColor));
753 else x2=x1+dx;
754 lb->PaintLine(x1,fY1,x2,fY1);
755 x1=x2;
756 v+=dv;
757 }
758 }
759 delete lb;
760 }
761}
762
763////////////////////////////////////////////////////////////////////////////////
764/// Paint the axis labels and titles.
765
767{
768 TLatex* t = new TLatex();
769 TFrame *frame = gPad->GetFrame();
770 t->SetTextSize(0.03);
771 if (fX1==fX2) {
772 t->SetText(fX1,frame->GetY1() - 0.04 - t->GetTextSize(),GetName());
774 if (fX1-0.5*tlength<0.01) {
775 t->SetTextAlign(11);
776 t->SetText(0.01, frame->GetY1() - 0.04 - t->GetTextSize(), GetName());
777 t->Paint();
778 } else if (fX1+0.5*tlength > 0.99) {
779 t->SetTextAlign(31);
780 t->SetText(0.99,frame->GetY1() - 0.04 - t->GetTextSize(),GetName());
781 t->Paint();
782 } else {
783 t->SetTextAlign(21);
784 t->PaintLatex(fX1,frame->GetY1() - 0.04 - t->GetTextSize(),0,0.03,GetName());
785 }
787 t->SetTextAlign(21);
788 t->PaintLatex(fX1,frame->GetY2() + 0.005,0,0.025,Form("%g",fMaxCurrent));
789 t->SetTextAlign(23);
790 t->PaintLatex(fX1,frame->GetY1() - 0.005,0,0.025,Form("%g",fMinCurrent));
791 }
792 } else {
793 t->SetText(fX1-0.04,fY1+0.02,GetName());
794 t->SetTextSize(0.03);
796 if (fX1-0.04-tlength<0.01) {
797 t->SetTextAlign(12);
798 t->SetText(0.01,fY1+0.02,GetName());
799 t->Paint();
800 } else {
801 t->SetTextAlign(32);
802 t->PaintLatex(fX1-0.04,fY1+0.02,0,0.03,GetName());
803 }
805 t->SetTextAlign(12);
806 t->PaintLatex(0.01,fY1-0.02,0,0.025,Form("%g",fMinCurrent));
807 t->SetTextAlign(32);
808 t->PaintLatex(0.99,fY1-0.02,0,0.025,Form("%g",fMaxCurrent));
809 }
810 }
811 delete t;
812}
813
814////////////////////////////////////////////////////////////////////////////////
815/// Print the axis main data.
816
817void TParallelCoordVar::Print(Option_t* /*option*/) const
818{
819 printf("**************variable #%d**************\n",fParallel->GetVarList()->IndexOf(this));
820 printf("at x1=%f, y1=%f, x2=%f, y2=%f.\n",fX1,fY1,fX2,fY2);
821 printf("min = %f, Q1 = %f, Med = %f, Q3 = %f, Max = %f\n", fMinInit, fQua1, fMed, fQua3, fMaxInit);
822}
823
824////////////////////////////////////////////////////////////////////////////////
825/// Save the TParallelCoordVar as a macro. Can be used only in the context
826/// of TParallelCoord::SavePrimitive (pointer "TParallelCoord* para" is
827/// defined in TParallelCoord::SavePrimitive) with the option "pcalled".
828
829void TParallelCoordVar::SavePrimitive(std::ostream &out, Option_t *options)
830{
831 TString opt = options;
832 if (opt.Contains("pcalled")) {
833 out << " para_var->SetBit(TParallelCoordVar::kLogScale," << TestBit(kLogScale) << ");\n";
834 out << " para_var->SetBit(TParallelCoordVar::kShowBox," << TestBit(kShowBox) << ");\n";
835 out << " para_var->SetBit(TParallelCoordVar::kShowBarHisto," << TestBit(kShowBarHisto) << ");\n";
836 out << " para_var->SetHistogramBinning(" << fNbins << ");\n";
837 out << " para_var->SetHistogramLineWidth(" << fHistoLW << ");\n";
838 out << " para_var->SetInitMin(" << fMinInit << ");\n";
839 out << " para_var->SetInitMax(" << fMaxInit << ");\n";
840 out << " para_var->SetHistogramHeight(" << fHistoHeight << ");\n";
841 out << " para_var->GetMinMaxMean();\n";
842 out << " para_var->GetHistogram();\n";
843 SaveFillAttributes(out, "para_var", -1, -1);
844 SaveLineAttributes(out, "para_var", -1, -1, -1);
845 if (TestBit(kShowBox))
846 out << " para_var->GetQuantiles();\n";
847 TIter next(fRanges);
848 Int_t i = 1;
849 while (auto range = static_cast<TParallelCoordRange *>(next())) {
850 out << " //***************************************\n";
851 out << " // Create the " << i++ << "th range owned by the axis \"" << GetTitle() << "\".\n";
852 out << " para_sel = para->GetSelection(\"" << range->GetSelection()->GetTitle() << "\");\n";
854 TString::Format("para_var, %g, %g, para_sel", range->GetMin(), range->GetMax()));
855 out << " para_var->AddRange(para_newrange);\n";
856 out << " para_sel->Add(para_newrange);\n";
857 }
858 }
859}
860
861////////////////////////////////////////////////////////////////////////////////
862/// Set the axis to display a candle.
863
865{
867 if (box) SetHistogramHeight(0.5);
868 else {
871 }
872}
873
874////////////////////////////////////////////////////////////////////////////////
875/// Set the histogram binning.
876
878{
879 if (n < 0 || n == fNbins) return;
880 fNbins = n;
881 GetHistogram();
882}
883
884////////////////////////////////////////////////////////////////////////////////
885/// Set the height of the bar histogram.
886
895
896////////////////////////////////////////////////////////////////////////////////
897/// Set the current minimum of the axis.
898
903
904////////////////////////////////////////////////////////////////////////////////
905/// Set the current maximum of the axis.
906
911
912////////////////////////////////////////////////////////////////////////////////
913/// Set the limits within which one the entries must be painted.
914
916{
917 if (min>max) {
918 Double_t mem = min;
919 min = max;
920 max = mem;
921 }
922 if(TestBit(kLogScale) && max<=0) return;
923 if(TestBit(kLogScale) && min<=0) min = 0.00001*max;
924 fMinCurrent = min;
925 fMaxCurrent = max;
926
927 delete fHistogram;
928 fHistogram = nullptr;
929 GetHistogram();
930
934 }
935}
936
937////////////////////////////////////////////////////////////////////////////////
938/// If true, the pad is updated while the motion of a dragged range.
939
946
947////////////////////////////////////////////////////////////////////////////////
948/// Set the axis in log scale.
949
951{
952 if (log == TestBit (kLogScale)) return;
953 if (fMaxInit < 0) SetBit(kLogScale,false);
954 else if (log) {
955 if (fMaxCurrent < 0 ) fMaxCurrent = fMaxInit;
956 if (fMinCurrent < 0 ) fMinCurrent = 0.00001*fMaxCurrent;
957 SetBit(kLogScale,true);
960 } else {
961 SetBit(kLogScale,false);
964 }
965 GetQuantiles();
966 GetHistogram();
967}
968
969////////////////////////////////////////////////////////////////////////////////
970/// Set the variable values.
971
973{
974 if (fVal) delete [] fVal;
975 fVal = new Double_t[length];
977 for (Long64_t li = 0; li < length; ++li) fVal[li] = val[li];
979 GetHistogram();
981}
982
983////////////////////////////////////////////////////////////////////////////////
984/// Set the X position of the axis in the case of a vertical axis.
985/// and rotate the axis if it was horizontal.
986
988{
989 TFrame *frame = gPad->GetFrame();
990 if (!gl) {
991 fY1 = frame->GetY1();
992 fY2 = frame->GetY2();
993 } else {
996 fY1 = frame->GetY1() + ((fMinCurrent-gmin)/(gmax-gmin))*(frame->GetY2()-frame->GetY1());
997 fY2 = frame->GetY1() + ((fMaxCurrent-gmin)/(gmax-gmin))*(frame->GetY2()-frame->GetY1());
998 }
999 fX1 = fX2 = x;
1000}
1001
1002////////////////////////////////////////////////////////////////////////////////
1003/// Set the Y position of the axis in the case of a horizontal axis.
1004/// and rotate the axis if it was vertical.
1005
1007{
1008 TFrame *frame = gPad->GetFrame();
1009 if (!gl) {
1010 fX1 = frame->GetX1();
1011 fX2 = frame->GetX2();
1012 } else {
1015 fX1 = frame->GetX1() + ((fMinCurrent-gmin)/(gmax-gmin))*(frame->GetX2()-frame->GetX1());
1016 fX2 = frame->GetX1() + ((fMaxCurrent-gmin)/(gmax-gmin))*(frame->GetX2()-frame->GetX1());
1017 }
1018 fY1 = fY2 = y;
1019}
@ kMouseMotion
Definition Buttons.h:23
@ kButton1Motion
Definition Buttons.h:20
@ kButton1Up
Definition Buttons.h:19
@ kButton1Down
Definition Buttons.h:17
@ kMouseEnter
Definition Buttons.h:23
@ kArrowVer
Definition GuiTypes.h:375
@ kArrowHor
Definition GuiTypes.h:375
#define b(i)
Definition RSha256.hxx:100
#define a(i)
Definition RSha256.hxx:99
#define h(i)
Definition RSha256.hxx:106
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:60
double Double_t
Double 8 bytes.
Definition RtypesCore.h:74
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:84
const char Option_t
Option string (const char)
Definition RtypesCore.h:81
@ kOrange
Definition Rtypes.h:67
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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 hmin
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t hmax
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 length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
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 GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
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
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2571
R__EXTERN TStyle * gStyle
Definition TStyle.h:442
#define gPad
#define gVirtualX
Definition TVirtualX.h:379
Fill Area Attributes class.
Definition TAttFill.h:21
virtual Color_t GetFillColor() const
Return the fill area color.
Definition TAttFill.h:32
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition TAttFill.h:33
virtual void SaveFillAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1001)
Save fill attributes as C++ statement(s) on output stream out.
Definition TAttFill.cxx:240
Line Attributes class.
Definition TAttLine.h:21
virtual Color_t GetLineColor() const
Return the line color.
Definition TAttLine.h:36
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition TAttLine.h:46
virtual Width_t GetLineWidth() const
Return the line width.
Definition TAttLine.h:38
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition TAttLine.h:47
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition TAttLine.h:44
virtual void SaveLineAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1, Int_t widdef=1)
Save line attributes as C++ statement(s) on output stream out.
Definition TAttLine.cxx:289
virtual Float_t GetTextSize() const
Return the text size.
Definition TAttText.h:39
virtual void SetTextAlign(Short_t align=11)
Set the text alignment.
Definition TAttText.h:48
virtual void SetTextSize(Float_t tsize=1)
Set the text size.
Definition TAttText.h:53
Create a Box.
Definition TBox.h:22
Double_t GetX1() const
Definition TBox.h:51
Double_t GetX2() const
Definition TBox.h:52
Double_t GetY1() const
Definition TBox.h:53
Double_t GetY2() const
Definition TBox.h:54
The Canvas class.
Definition TCanvas.h:23
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Define a Frame.
Definition TFrame.h:19
1-D histogram with a float per channel (see TH1 documentation)
Definition TH1.h:878
virtual void SetDirectory(TDirectory *dir)
By default, when a histogram is created, it is added to the list of histogram objects in the current ...
Definition TH1.cxx:9170
virtual Double_t GetMaximum(Double_t maxval=FLT_MAX) const
Return maximum value smaller than maxval of bins in the range, unless the value has been overridden b...
Definition TH1.cxx:8778
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition TH1.cxx:3489
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH1.cxx:5239
virtual Double_t GetMinimum(Double_t minval=-FLT_MAX) const
Return minimum value larger than minval of bins in the range, unless the value has been overridden by...
Definition TH1.cxx:8868
To draw Mathematical Formula.
Definition TLatex.h:20
Double_t GetXsize()
Return size of the formula along X in pad coordinates when the text precision is smaller than 3.
Definition TLatex.cxx:2586
virtual void PaintLatex(Double_t x, Double_t y, Double_t angle, Double_t size, const char *text)
Main drawing function.
Definition TLatex.cxx:2152
void Paint(Option_t *option="") override
Paint.
Definition TLatex.cxx:2130
Use the TLine constructor to create a simple line.
Definition TLine.h:22
virtual void PaintLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Draw this line with new coordinates.
Definition TLine.cxx:344
void Paint(Option_t *option="") override
Paint this line with its current attributes.
Definition TLine.cxx:334
A doubly linked list.
Definition TList.h:38
void AddAt(TObject *obj, Int_t idx) override
Insert object at position idx in the list.
Definition TList.cxx:413
void Add(TObject *obj) override
Definition TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:952
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:600
Manages Markers.
Definition TMarker.h:22
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
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:204
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:203
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:886
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1096
static void SavePrimitiveConstructor(std::ostream &out, TClass *cl, const char *variable_name, const char *constructor_agrs="", Bool_t empty_line=kTRUE)
Save object constructor in the output stream "out".
Definition TObject.cxx:776
A TParallelCoordRange is a range used for parallel coordinates plots.
static TClass * Class()
A TParallelCoordSelect is a specialised TList to hold TParallelCoordRanges used by TParallelCoord.
void Paint(Option_t *option="") override
Paint the axis.
TH1F * fHistogram
! Histogram holding the variable distribution.
TH1F * GetHistogram()
Create or recreate the histogram.
char * GetObjectInfo(Int_t px, Int_t py) const override
Returns info about this axis.
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.
Double_t GetValuefromXY(Double_t x, Double_t y)
Get the value corresponding to the position.
void PaintBoxPlot()
Paint the boxes in the case of a candle chart.
void PaintLabels()
Paint the axis labels and titles.
void ExecuteEvent(Int_t entry, Int_t px, Int_t py) override
Execute the corresponding entry.
void SetBoxPlot(bool box)
Set the axis to display a candle.
void PaintHistogram()
Paint the histogram on the axis.
Double_t fY1
y1 coordinate of the axis.
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 fX1
x1 coordinate of the axis.
~TParallelCoordVar() override
Destructor.
void SavePrimitive(std::ostream &out, Option_t *options) override
Save the TParallelCoordVar as a macro.
Double_t fMaxInit
Memory of the maximum when first initialized.
void SetCurrentMax(Double_t max)
Set the current maximum of the axis.
void SetLogScale(bool log)
Set the axis in log scale.
TList * fRanges
List of the TParallelRange owned by TParallelCoordVar.
void GetQuantiles()
Get the box plot values (quantiles).
Double_t fMinCurrent
Current used minimum.
void SetHistogramHeight(Double_t h=0)
Set the height of the bar histogram.
void DeleteVariable()
Delete variables.
TParallelCoordVar()
Default constructor.
Double_t fMinInit
Memory of the minimum when first initialized.
TParallelCoord * fParallel
Pointer to the TParallelCoord which owns the TParallelCoordVar.
Int_t fId
Id identifying the variable for the editor.
Int_t fNbins
Number of bins in fHistogram.
Long64_t fNentries
Number of stored entries values.
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...
Double_t * fVal
![fNentries] Entries values for the variable.
Int_t fHistoLW
Line width used to draw the histogram line.
Double_t fMean
Average.
Double_t fY2
y2 coordinate of the axis.
void SetHistogramLineWidth(Int_t lw=2)
Double_t fX2
x2 coordinate of the axis.
void Init()
Initialise the TParallelVar variables.
void GetXYfromValue(Double_t value, Double_t &x, Double_t &y)
Get a position corresponding to the value on the axis.
void Print(Option_t *option="") const override
Print the axis main data.
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 Draw(Option_t *option="") override
Draw the axis.
Double_t fQua1
First quantile (Q1).
void SetValues(Long64_t length, Double_t *val)
Set the variable values.
Double_t fQua3
Third quantile (Q3).
void SetHistogramBinning(Int_t n=100)
Set the histogram binning.
Double_t fMed
Median value (Q2).
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Computes the distance from the axis.
void SetCurrentLimits(Double_t min, Double_t max)
Set the limits within which one the entries must be painted.
Double_t fHistoHeight
Histogram Height.
Double_t fMaxCurrent
Current used maximum.
Parallel Coordinates class.
TParallelCoordSelect * GetCurrentSelection()
Return the selection currently being edited.
Double_t GetGlobalMin()
return the global minimum.
Long64_t GetNentries()
Long64_t GetCurrentFirst()
Long64_t GetCurrentN()
TList * GetVarList()
Double_t GetGlobalMax()
return the global maximum.
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.
void RemoveVariable(TParallelCoordVar *var)
Delete a variable from the graph.
void CleanUpSelections(TParallelCoordRange *range)
Clean up the selections from the ranges which could have been deleted when a variable has been delete...
@ kGlobalScale
Every variable is on the same scale.
@ kCandleChart
To produce a candle chart.
virtual Int_t IndexOf(const TObject *obj) const
Return index of object in collection.
Basic string class.
Definition TString.h:137
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:2460
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:642
Int_t GetColorPalette(Int_t i) const
Return color number i in current palette.
Definition TStyle.cxx:1102
Int_t GetNumberOfColors() const
Return number of colors in the color palette.
Definition TStyle.cxx:1176
virtual void SetText(Double_t x, Double_t y, const char *text)
Definition TText.h:74
TLine * line
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition fillpatterns.C:1
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
void Quantiles(Int_t n, Int_t nprob, Double_t *x, Double_t *quantiles, Double_t *prob, Bool_t isSorted=kTRUE, Int_t *index=nullptr, Int_t type=7)
Computes sample quantiles, corresponding to the given probabilities.
Definition TMath.cxx:1207
Double_t Log10(Double_t x)
Returns the common (base-10) logarithm of x.
Definition TMath.h:775
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:122
TLine l
Definition textangle.C:4