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 <iostream>
17
18#include "TLatex.h"
19#include "TLine.h"
20#include "TVirtualPad.h"
21#include "TVirtualX.h"
22#include "TMath.h"
23#include "TH1.h"
24#include "TStyle.h"
25#include "TBox.h"
26#include "TCollection.h"
27#include "TList.h"
28#include "TFrame.h"
29#include "TCanvas.h"
30#include "TMarker.h"
31#include "snprintf.h"
32
33
34/** \class TParallelCoordVar
35
36TParallelCoord axes. Class containing a variable for the TParallelCoord.
37
38Options can be defined each axis separately using the right mouse click. These
39options can be applied to every axes using the editor.
40
41 - Axis width: If set to 0, the axis is simply a line. If higher, a color
42 histogram is drawn on the axis.
43 - Axis histogram height: If not 0, a usual bar histogram is drawn on the plot.
44
45The order in which the variables are drawn is essential to see the clusters. The
46axes can be dragged to change their position. A zoom is also available. The
47logarithm scale is also available by right clicking on the axis.
48*/
49
50////////////////////////////////////////////////////////////////////////////////
51/// Default constructor.
52
58
59////////////////////////////////////////////////////////////////////////////////
60///Destructor.
61
63{
64 if (fHistogram) delete fHistogram;
65 if (fRanges){
66 TIter next(fRanges);
69 fRanges->Delete();
70 delete fRanges;
71 }
72 if (fVal) delete [] fVal;
73}
74
75////////////////////////////////////////////////////////////////////////////////
76/// Normal constructor. By default, the title and the name are the expression
77/// given to TTree::Draw. The name can be changed by the user (the label on the
78/// plot) but not the title.
79
81 :TNamed(title,title), TAttLine(1,1,1), TAttFill(kOrange+9,3001)
82{
83 Init();
84 fId = id;
86 fRanges = new TList();
88
90
91 for(Long64_t ui = 0;ui<fParallel->GetNentries();++ui) fVal[ui]=val[ui];
92
96}
97
98////////////////////////////////////////////////////////////////////////////////
99/// Add a range to the current selection on the axis.
100
102{
103 if (!range) {
105 if (select) {
106 range = new TParallelCoordRange(this,0,0,select);
107 fRanges->Add(range);
108 range->GetSelection()->Add(range);
109 } else {
110 Error("AddRange","You must create a selection before adding ranges.");
111 }
112 } else {
113 fRanges->Add(range);
114 range->GetSelection()->Add(range);
115 }
116}
117
118////////////////////////////////////////////////////////////////////////////////
119/// Delete variables.
120
122{
124 delete this;
125}
126
127////////////////////////////////////////////////////////////////////////////////
128/// Computes the distance from the axis.
129
131{
132 if(!gPad) return 9999;
133 Double_t xx = gPad->AbsPixeltoX(px);
134 Double_t yy = gPad->AbsPixeltoY(py);
135 Double_t dist = 9999;
136
137 if (fX1==fX2) {
138 if (yy>fY1+0.01 && yy<fY2-0.01) dist = TMath::Abs(xx - fX1);
139 } else {
140 if (xx>fX1+0.01 && xx<fX2-0.01) dist = TMath::Abs(yy - fY1);
141 }
142 if (dist<=0.005) return 0;
143 else return 9999;
144}
145
146////////////////////////////////////////////////////////////////////////////////
147/// Draw the axis.
148
153
154////////////////////////////////////////////////////////////////////////////////
155/// Check if the entry is within the range(s) of "select". Two ranges on a
156/// single axis are conjugated as a "or": to be selected, the entry must be in
157/// one of the ranges.
158
160{
161 if (fRanges->GetSize() > 0){
162 TIter next(fRanges);
163 bool inarange = false;
164 bool noOwnedRange = true;
166 while ((range = (TParallelCoordRange*)next())){
167 if(select->Contains(range)) {
168 noOwnedRange = false;
169 if(range->IsIn(fVal[evtidx])) inarange = true;
170 }
171 }
172 if (noOwnedRange) return true;
173 else return inarange;
174 }
175 else return true;
176}
177
178////////////////////////////////////////////////////////////////////////////////
179/// Execute the corresponding entry.
180
182{
183 if (!gPad) return;
184 if (!gPad->IsEditable() && entry!=kMouseEnter) return;
185
186 static Int_t pxold, pyold;
187 static Int_t zoom; // -1:nothing zoomed or translated, 0:translating the axis, 1:zooming
188 static Int_t pzoomold;
189 static bool first = true;
190
191 Int_t px1,px2,py1,py2,n=-1;
192 px1 = gPad->XtoAbsPixel(fX1);
193 px2 = gPad->XtoAbsPixel(fX2);
194 py1 = gPad->YtoAbsPixel(fY1);
195 py2 = gPad->YtoAbsPixel(fY2);
196
197 if(fX1 == fX2) {
198 if(gPad->AbsPixeltoX(px)-fX1 > 0) gPad->SetCursor(kArrowVer);
199 else gPad->SetCursor(kArrowHor);
200 } else {
201 if(gPad->AbsPixeltoY(py)-fY1 > 0) gPad->SetCursor(kArrowHor);
202 else gPad->SetCursor(kArrowVer);
203 }
204
205 gVirtualX->SetLineColor(-1);
206 switch (entry) {
207 case kButton1Down:
208 if (fX1==fX2){
209 ((TCanvas*)gPad)->Selected(gPad,fParallel,1);
210 if(gPad->AbsPixeltoX(px)-fX1 > 0){
211 zoom = 1;
212 gVirtualX->DrawLine(gPad->XtoAbsPixel(fX1-0.05),py,gPad->XtoAbsPixel(fX1+0.05),py);
213 first = true;
214 pzoomold = py;
215 } else {
216 zoom = 0;
217 gVirtualX->DrawLine(px,py1,px,py2);
218 }
219 } else {
220 if(gPad->AbsPixeltoY(py)-fY1 > 0){
221 zoom = 1;
222 gVirtualX->DrawLine(px,gPad->YtoAbsPixel(fY1-0.05),px,gPad->YtoAbsPixel(fY1+0.05));
223 first=true;
224 pzoomold = px;
225 } else {
226 zoom = 0;
227 gVirtualX->DrawLine(px1,py,px2,py);
228 }
229 }
230 pxold = px;
231 pyold = py;
232 break;
233 case kButton1Up: {
234 Double_t xx = gPad->AbsPixeltoX(px);
235 Double_t yy = gPad->AbsPixeltoY(py);
236 TFrame *frame = gPad->GetFrame();
237 if (fX1==fX2) {
238 if(zoom == 0){
239 Double_t axisSpace = (frame->GetX2() - frame->GetX1())/(fParallel->GetNvar() - 1);
240 Double_t pos = (xx - frame->GetX1())/axisSpace;
241 if (pos < 0) n = -1;
242 else n = (Int_t)pos;
243 } else {
245 Double_t max = GetValuefromXY(xx,gPad->AbsPixeltoY(pzoomold));
246 if(TMath::Abs(min-max) < 0.00001) return; // Avoid zooming if the axis is just clicked.
248 if (min>max) {
249 Double_t mem = min;
250 min = max; max = mem;
251 }
254 } else {
255 SetCurrentLimits(min,max);
256 }
257 }
258 } else {
259 if(zoom == 0) {
260 Double_t axisSpace = (frame->GetY2() - frame->GetY1())/(fParallel->GetNvar() - 1);
261 Double_t pos = (yy-frame->GetY1())/axisSpace;
262 if (pos < 0) n= -1;
263 else n = (Int_t)pos;
264 } else {
266 Double_t max = GetValuefromXY(gPad->AbsPixeltoX(pzoomold),yy);
267 SetCurrentLimits(min,max);
268 }
269 }
270 if(zoom == 0){
271 if (n>=0 && (UInt_t)n>=fParallel->GetNvar()) --n;
272 else if (n<fParallel->GetVarList()->IndexOf(this)) ++n;
273 fParallel->GetVarList()->Remove(this);
274 fParallel->GetVarList()->AddAt(this,n);
275 }
276 gPad->Modified();
277 break;
278 }
279 case kMouseMotion:
280 pxold=px;
281 pyold=py;
282 break;
283 case kButton1Motion:
284 if(fX1==fX2){
285 if(zoom==0){
286 gPad->SetCursor(kArrowHor);
287 gVirtualX->DrawLine(pxold,py1,pxold,py2);
288 gVirtualX->DrawLine(px,py1,px,py2);
289 } else if(zoom==1) {
290 gPad->SetCursor(kArrowVer);
291 if(!first) gVirtualX->DrawLine(gPad->XtoAbsPixel(fX1-0.05),pyold,gPad->XtoAbsPixel(fX1+0.05),pyold);
292 gVirtualX->DrawLine(gPad->XtoAbsPixel(fX1-0.05),py,gPad->XtoAbsPixel(fX1+0.05),py);
293 first = false;
294 }
295 } else {
296 if(zoom==0){
297 gPad->SetCursor(kArrowVer);
298 gVirtualX->DrawLine(px1,pyold,px2,pyold);
299 gVirtualX->DrawLine(px1,py,px2,py);
300 } else if(zoom==1){
301 gPad->SetCursor(kArrowHor);
302 if(!first) gVirtualX->DrawLine(pxold,gPad->YtoAbsPixel(fY1-0.05),pxold,gPad->YtoAbsPixel(fY1+0.05));
303 gVirtualX->DrawLine(px,gPad->YtoAbsPixel(fY1-0.05),px,gPad->YtoAbsPixel(fY1+0.05));
304 first = false;
305 }
306 }
307 pxold = px;
308 pyold = py;
309 break;
310 }
311}
312
313////////////////////////////////////////////////////////////////////////////////
314/// Get the position of the variable on the graph for the n'th entry.
315
317{
318 if(fX1==fX2){
319 x = fX1;
320 if (fMinCurrent != fMaxCurrent) {
321 if (TestBit(kLogScale)) y = fY1 + (fY2 - fY1) *
323 else y = fY1 + (fY2 - fY1) *
325 } else {
326 y = fY1 + 0.5*(fY2-fY1);
327 }
328 } else {
329 y = fY1;
330 if (fMinCurrent != fMaxCurrent) {
331 if (TestBit(kLogScale)) x = fX1 + (fX2 - fX1) *
333 else x = fX1 + (fX2 - fX1) *
335 } else {
336 x = fX1 + 0.5*(fX2-fX1);
337 }
338 }
339}
340
341////////////////////////////////////////////////////////////////////////////////
342/// Get the entry weight: The weight of an entry for a given variable
343/// is the bin content of the histogram bin the entry is going through.
344
350
351////////////////////////////////////////////////////////////////////////////////
352/// Create or recreate the histogram.
353
355{
356 if (fHistogram) delete fHistogram;
357 fHistogram = nullptr;
358 fHistogram = new TH1F("hpa", "hpa", fNbins, fMinCurrent, fMaxCurrent+0.0001*(fMaxCurrent-fMinCurrent));
359 fHistogram->SetDirectory(nullptr);
362 for(Long64_t li=first; li<first+nentries;++li) {
364 }
365 return fHistogram;
366}
367
368////////////////////////////////////////////////////////////////////////////////
369/// Get mean, min and max of those variable.
370
372{
373 Double_t min,max,ave = 0;
374 min = DBL_MAX;
375 max = -DBL_MAX;
376 Long64_t first,nentries;
377 first = fParallel->GetCurrentFirst();
379 for(Long64_t li=first; li<first+nentries;++li){
380 if(fVal[li]<min) min = fVal[li];
381 if(fVal[li]>max) max = fVal[li];
382 ave+=fVal[li];
383 }
384
386 fMinCurrent = fMinInit = min;
387 fMaxCurrent = fMaxInit = max;
388}
389
390////////////////////////////////////////////////////////////////////////////////
391/// Returns info about this axis.
392
394{
395 static char info[128];
396 info[0] = 0;
397
398 if (!gPad) return info;
399 Double_t xx = gPad->AbsPixeltoX(px);
400 Double_t yy = gPad->AbsPixeltoY(py);
401 if (fX1 == fX2) {
402 if (yy<fY1) {
403 snprintf(info,128,"%s = %f", GetTitle(), fMinCurrent);
404 } else if (yy>fY2) {
405 snprintf(info,128,"%s = %f", GetTitle(), fMaxCurrent);
406 } else {
408 Double_t pos = (yy-fY1)/axislength;
409 snprintf(info,128,"%s = %f", GetTitle(), fMinCurrent + pos*(fMaxCurrent-fMinCurrent));
410 }
411 } else {
412 if (xx<fX1) {
413 snprintf(info,128,"%s = %f", GetTitle(), fMinCurrent);
414 } else if(xx>fX2) {
415 snprintf(info,128,"%s = %f", GetTitle(), fMaxCurrent);
416 } else {
418 Double_t pos = (xx-fX1)/axislength;
419 snprintf(info,128,"%s = %f", GetTitle(), pos*(fMaxCurrent-fMinCurrent));
420 }
421 }
422 return info;
423}
424
425////////////////////////////////////////////////////////////////////////////////
426/// Get the box plot values (quantiles).
427
429{
430 Double_t *quantiles = new Double_t[3];
431 quantiles[0]=0.; quantiles[1]=0.; quantiles[2] = 0.;
432 Double_t *prob = new Double_t[3];
433 prob[0]=0.25; prob[1]=0.5; prob[2] = 0.75;
437 else {
438 Double_t* val = new Double_t[nentries];
439 Int_t selected = 0;
440 if(fMinInit<=0) {
441 for (Long64_t n=first;n<first+nentries;++n) {
442 if (fVal[n] >= fMinCurrent) {
443 if (TestBit(kLogScale)) val[selected] = TMath::Log10(fVal[n]);
444 else val[selected] = fVal[n];
445 ++selected;
446 }
447 }
448 } else {
449 for (Long64_t n=first;n<first+nentries;++n) {
450 if (TestBit(kLogScale)) val[selected] = TMath::Log10(fVal[n]);
451 else val[selected] = fVal[n];
452 ++selected;
453 }
454 }
455 TMath::Quantiles(selected,3,val,quantiles,prob,false);
456 delete [] val;
457 }
458 fQua1 = quantiles[0];
459 fMed = quantiles[1];
460 fQua3 = quantiles[2];
461 delete [] quantiles;
462 delete [] prob;
463}
464
465////////////////////////////////////////////////////////////////////////////////
466/// Get the value corresponding to the position.
467
469{
470 Double_t pos;
471 if (fMinCurrent == fMaxCurrent) return fMinCurrent;
472 if (fX1 == fX2) {
473 if (y<=fY1) pos = fMinCurrent;
474 else if (y>=fY2) pos = fMaxCurrent;
475 else pos = fMinCurrent + ((y-fY1)/(fY2-fY1))*(fMaxCurrent-fMinCurrent);
476 } else {
477 if (x<=fX1) pos = fMinCurrent;
478 else if (x>=fX2) pos = fMaxCurrent;
479 else pos = fMinCurrent + ((x-fX1)/(fX2-fX1))*(fMaxCurrent-fMinCurrent);
480 }
481 return pos;
482}
483
484////////////////////////////////////////////////////////////////////////////////
485/// Get a position corresponding to the value on the axis.
486
488{
490
491 if (fX1==fX2) {
492 x = fX1;
493 if (fMinCurrent != fMaxCurrent) {
494 if (TestBit(kLogScale)) y = fY1 + (fY2 - fY1) *
496 else y = fY1 + (fY2 - fY1) *
498 } else {
499 y = fY1 + 0.5*(fY2-fY1);
500 }
501 } else {
502 y = fY1;
503 if (fMinCurrent != fMaxCurrent) {
504 if (TestBit(kLogScale)) x = fX1 + (fX2 - fX1) *
506 else x = fX1 + (fX2 - fX1) *
508 } else {
509 x = fX1 + 0.5*(fX2-fX1);
510 }
511 }
512}
513
514////////////////////////////////////////////////////////////////////////////////
515/// Initialise the TParallelVar variables.
516
518{
519 fX1 = 0;
520 fX2 = 0;
521 fY1 = 0;
522 fY2 = 0;
523 fId = 0;
524 fVal = nullptr;
525 fMean = 0;
526 fMinInit = 0;
527 fMinCurrent = 0;
528 fMaxInit = 0;
529 fMaxCurrent = 0;
530 fMed = 0;
531 fQua1 = 0;
532 fQua3 = 0;
533 fNentries = 0;
534 fParallel = nullptr;
535 fHistogram = nullptr;
536 fNbins = 100;
537 fHistoLW = 2;
538 fHistoHeight = 0.5;
539 fRanges = nullptr;
540 SetBit(kLogScale,false);
541 SetBit(kShowBox,false);
542 SetBit(kShowBarHisto,true);
543}
544
545////////////////////////////////////////////////////////////////////////////////
546/// Paint the axis.
547
549{
550 TIter next(fRanges);
552 while ((range = (TParallelCoordRange*)next())) range->Paint(option);
553
556 PaintLabels();
557}
558
559////////////////////////////////////////////////////////////////////////////////
560/// Paint the boxes in the case of a candle chart.
561
563{
564 TLine *line = new TLine();
566 line->SetLineWidth(1);
567 TBox *box = new TBox();
568 box->SetLineWidth(1);
569 box->SetLineColor(GetLineColor());
570 box->SetLineStyle(1);
571 box->SetFillStyle(0);
572
573 TFrame* frame = gPad->GetFrame();
574
576 if (fParallel->GetNvar() > 1) {
577 if (fX1==fX2) boxSize = fHistoHeight*((frame->GetY2()-frame->GetY1())/(fParallel->GetNvar()-1));
578 else boxSize = fHistoHeight*((frame->GetX2()-frame->GetX1())/(fParallel->GetNvar()-1));
579 if (boxSize >= 0.03) boxSize = 0.03;
580 }
581 else boxSize = 0.03;
582
583 Double_t qua1,med,qua3,max,min;
585 if (TestBit(kLogScale)) {
591 } else {
592 a = fMinCurrent;
596 }
597 if(fX1==fX2) {
598 qua1 = fY1 + ((fQua1-a)/b)*(fY2-fY1);
599 qua3 = fY1 + ((fQua3-a)/b)*(fY2-fY1);
600 med = fY1 + ((fMed-a)/b)*(fY2-fY1);
601 max = fY1 + ((maxinit-a)/b)*(fY2-fY1);
602 min = fY1 + ((mininit-a)/b)*(fY2-fY1);
603 } else {
604 qua1 = fX1 + ((fQua1-a)/b)*(fX2-fX1);
605 qua3 = fX1 + ((fQua3-a)/b)*(fX2-fX1);
606 med = fX1 + ((fMed-a)/b)*(fX2-fX1);
607 max = fX1 + ((maxinit-a)/b)*(fX2-fX1);
608 min = fX1 + ((mininit-a)/b)*(fX2-fX1);
609 }
610
611 // min and max lines.
612 if (fX1==fX2) {
615 } else {
618 }
619
620 // lines from min and max to the box.
621 line->SetLineStyle(7);
622 if (fX1==fX2) {
623 if (min<frame->GetY1()) min = frame->GetY1();
624 if (max>frame->GetY2()) max = frame->GetY2();
625 line->PaintLine(fX1,min,fX1,qua1);
626 line->PaintLine(fX1,qua3,fX1,max);
627 } else {
628 if (min<frame->GetX1()) min = frame->GetX1();
629 if (max>frame->GetX2()) max = frame->GetX2();
630 line->PaintLine(min,fY1,qua1,fY2);
631 line->PaintLine(qua3,fY1,max,fY2);
632 }
633
634 // Box
635 if(fX1==fX2) box->PaintBox(fX1-boxSize,qua1,fX1+boxSize,qua3);
636 else box->PaintBox(qua1,fY1-boxSize,qua3,fY1+boxSize);
637
638 // Median line
639 line->SetLineStyle(1);
642
643 // Paint average
644 if (!TestBit(kLogScale) || (TestBit(kLogScale) && fMean > 0)) {
645 Double_t mean;
646 if (TestBit(kLogScale)) mean = TMath::Log10(fMean);
647 else mean = fMean;
648 TMarker *mark = nullptr;
649 if(fX1==fX2) mark = new TMarker(fX1,fY1 + ((mean-a)/b)*(fY2-fY1),24);
650 else mark = new TMarker(fX1 + ((mean-a)/b)*(fX2-fX1),fY1,24);
651 mark->Paint();
652 delete mark;
653 }
654
655 delete line;
656 delete box;
657}
658
659////////////////////////////////////////////////////////////////////////////////
660/// Paint the histogram on the axis.
661
663{
664 Int_t i;
665
666 TFrame *frame = gPad->GetFrame();
667
668 if (!fHistogram) GetHistogram();
669
670 // Paint the axis body.
672 // Paint the axis body using bar chart.
673 TBox *b = new TBox();
674 b->SetFillStyle(GetFillStyle());
675 b->SetFillColor(GetFillColor());
676 b->SetLineStyle(1);
677 b->SetLineColor(GetFillColor());
678 b->SetLineWidth(1);
681 if (fX1 == fX2) {
682 // Vertical case.
686 Double_t y1 = fY1,x2,y2;
687 for (i=1; i<=fNbins; i++) {
689 ((frame->GetX2()-frame->GetX1())/(fParallel->GetNvar()-1));
691 else y2=y1+dy;
692 b->PaintBox(fX1,y1,x2,y2,"l");
693 y1=y2;
694 v += dv;
695 }
696 } else {
697 // Horizontal case.
701 Double_t x1 = fX1,x2,y2;
702 for (i=1; i<=fNbins; i++) {
703 y2 = fY1+((fHistogram->GetBinContent(i)-hmin)/(hmax-hmin))*fHistoHeight*((frame->GetY2()-frame->GetY1())/(fParallel->GetNvar()-1));
705 else x2=x1+dx;
706 b->PaintBox(x1,fY1,x2,y2,"l");
707 x1=x2;
708 v+=dv;
709 }
710 }
711 delete b;
712 }
713 if (fHistoLW==0 && !TestBit(kShowBox)) {
714 // Paint the axis body as a simple line.
715 TLine* l = new TLine(fX1,fY1,fX2,fY2);
719 l->Paint();
720 delete l;
721 } else if (fHistoLW!=0){
722 // Paint the axis body using the color palette.
723 TLine *lb = new TLine();
724 lb->SetLineWidth(fHistoLW);
728 Int_t ncolors = gStyle->GetNumberOfColors();
729 if (fX1 == fX2) {
730 // Vertical case.
732 Double_t y1 = fY1,y2;
735 for (i=1; i<=fNbins; i++) {
736 theColor = (Int_t)( ((fHistogram->GetBinContent(i)-hmin)/(hmax-hmin))*(ncolors-1) );
738 else y2=y1+dy;
739 lb->SetLineColor(gStyle->GetColorPalette(theColor));
740 lb->PaintLine(fX1,y1,fX1,y2);
741 y1=y2;
742 v+=dv;
743 }
744 } else {
745 // Horizontal case.
749 Double_t x1 = fX1,x2;
750 for (i=1; i<=fNbins; i++) {
751 theColor = (Int_t)( ((fHistogram->GetBinContent(i)-hmin)/(hmax-hmin))*(ncolors-1) );
752 lb->SetLineColor(gStyle->GetColorPalette(theColor));
754 else x2=x1+dx;
755 lb->PaintLine(x1,fY1,x2,fY1);
756 x1=x2;
757 v+=dv;
758 }
759 }
760 delete lb;
761 }
762}
763
764////////////////////////////////////////////////////////////////////////////////
765/// Paint the axis labels and titles.
766
768{
769 TLatex* t = new TLatex();
770 TFrame *frame = gPad->GetFrame();
771 t->SetTextSize(0.03);
772 if (fX1==fX2) {
773 t->SetText(fX1,frame->GetY1() - 0.04 - t->GetTextSize(),GetName());
775 if (fX1-0.5*tlength<0.01) {
776 t->SetTextAlign(11);
777 t->SetText(0.01, frame->GetY1() - 0.04 - t->GetTextSize(), GetName());
778 t->Paint();
779 } else if (fX1+0.5*tlength > 0.99) {
780 t->SetTextAlign(31);
781 t->SetText(0.99,frame->GetY1() - 0.04 - t->GetTextSize(),GetName());
782 t->Paint();
783 } else {
784 t->SetTextAlign(21);
785 t->PaintLatex(fX1,frame->GetY1() - 0.04 - t->GetTextSize(),0,0.03,GetName());
786 }
788 t->SetTextAlign(21);
789 t->PaintLatex(fX1,frame->GetY2() + 0.005,0,0.025,Form("%g",fMaxCurrent));
790 t->SetTextAlign(23);
791 t->PaintLatex(fX1,frame->GetY1() - 0.005,0,0.025,Form("%g",fMinCurrent));
792 }
793 } else {
794 t->SetText(fX1-0.04,fY1+0.02,GetName());
795 t->SetTextSize(0.03);
797 if (fX1-0.04-tlength<0.01) {
798 t->SetTextAlign(12);
799 t->SetText(0.01,fY1+0.02,GetName());
800 t->Paint();
801 } else {
802 t->SetTextAlign(32);
803 t->PaintLatex(fX1-0.04,fY1+0.02,0,0.03,GetName());
804 }
806 t->SetTextAlign(12);
807 t->PaintLatex(0.01,fY1-0.02,0,0.025,Form("%g",fMinCurrent));
808 t->SetTextAlign(32);
809 t->PaintLatex(0.99,fY1-0.02,0,0.025,Form("%g",fMaxCurrent));
810 }
811 }
812 delete t;
813}
814
815////////////////////////////////////////////////////////////////////////////////
816/// Print the axis main data.
817
818void TParallelCoordVar::Print(Option_t* /*option*/) const
819{
820 printf("**************variable #%d**************\n",fParallel->GetVarList()->IndexOf(this));
821 printf("at x1=%f, y1=%f, x2=%f, y2=%f.\n",fX1,fY1,fX2,fY2);
822 printf("min = %f, Q1 = %f, Med = %f, Q3 = %f, Max = %f\n", fMinInit, fQua1, fMed, fQua3, fMaxInit);
823}
824
825////////////////////////////////////////////////////////////////////////////////
826/// Save the TParallelCoordVar as a macro. Can be used only in the context
827/// of TParallelCoord::SavePrimitive (pointer "TParallelCoord* para" is
828/// defined in TParallelCoord::SavePrimitive) with the option "pcalled".
829
830void TParallelCoordVar::SavePrimitive(std::ostream &out, Option_t *options)
831{
832 TString opt = options;
833 if (opt.Contains("pcalled")) {
834 out << " para_var->SetBit(TParallelCoordVar::kLogScale," << TestBit(kLogScale) << ");\n";
835 out << " para_var->SetBit(TParallelCoordVar::kShowBox," << TestBit(kShowBox) << ");\n";
836 out << " para_var->SetBit(TParallelCoordVar::kShowBarHisto," << TestBit(kShowBarHisto) << ");\n";
837 out << " para_var->SetHistogramBinning(" << fNbins << ");\n";
838 out << " para_var->SetHistogramLineWidth(" << fHistoLW << ");\n";
839 out << " para_var->SetInitMin(" << fMinInit << ");\n";
840 out << " para_var->SetInitMax(" << fMaxInit << ");\n";
841 out << " para_var->SetHistogramHeight(" << fHistoHeight << ");\n";
842 out << " para_var->GetMinMaxMean();\n";
843 out << " para_var->GetHistogram();\n";
844 SaveFillAttributes(out, "para_var", -1, -1);
845 SaveLineAttributes(out, "para_var", -1, -1, -1);
846 if (TestBit(kShowBox))
847 out << " para_var->GetQuantiles();\n";
848 TIter next(fRanges);
849 Int_t i = 1;
850 while (auto range = static_cast<TParallelCoordRange *>(next())) {
851 out << " //***************************************\n";
852 out << " // Create the " << i++ << "th range owned by the axis \"" << GetTitle() << "\".\n";
853 out << " para_sel = para->GetSelection(\"" << range->GetSelection()->GetTitle() << "\");\n";
855 TString::Format("para_var, %g, %g, para_sel", range->GetMin(), range->GetMax()));
856 out << " para_var->AddRange(para_newrange);\n";
857 out << " para_sel->Add(para_newrange);\n";
858 }
859 }
860}
861
862////////////////////////////////////////////////////////////////////////////////
863/// Set the axis to display a candle.
864
866{
868 if (box) SetHistogramHeight(0.5);
869 else {
872 }
873}
874
875////////////////////////////////////////////////////////////////////////////////
876/// Set the histogram binning.
877
879{
880 if (n < 0 || n == fNbins) return;
881 fNbins = n;
882 GetHistogram();
883}
884
885////////////////////////////////////////////////////////////////////////////////
886/// Set the height of the bar histogram.
887
896
897////////////////////////////////////////////////////////////////////////////////
898/// Set the current minimum of the axis.
899
904
905////////////////////////////////////////////////////////////////////////////////
906/// Set the current maximum of the axis.
907
912
913////////////////////////////////////////////////////////////////////////////////
914/// Set the limits within which one the entries must be painted.
915
917{
918 if (min>max) {
919 Double_t mem = min;
920 min = max;
921 max = mem;
922 }
923 if(TestBit(kLogScale) && max<=0) return;
924 if(TestBit(kLogScale) && min<=0) min = 0.00001*max;
925 fMinCurrent = min;
926 fMaxCurrent = max;
927
928 delete fHistogram;
929 fHistogram = nullptr;
930 GetHistogram();
931
935 }
936}
937
938////////////////////////////////////////////////////////////////////////////////
939/// If true, the pad is updated while the motion of a dragged range.
940
947
948////////////////////////////////////////////////////////////////////////////////
949/// Set the axis in log scale.
950
952{
953 if (log == TestBit (kLogScale)) return;
954 if (fMaxInit < 0) SetBit(kLogScale,false);
955 else if (log) {
956 if (fMaxCurrent < 0 ) fMaxCurrent = fMaxInit;
957 if (fMinCurrent < 0 ) fMinCurrent = 0.00001*fMaxCurrent;
958 SetBit(kLogScale,true);
961 } else {
962 SetBit(kLogScale,false);
965 }
966 GetQuantiles();
967 GetHistogram();
968}
969
970////////////////////////////////////////////////////////////////////////////////
971/// Set the variable values.
972
974{
975 if (fVal) delete [] fVal;
976 fVal = new Double_t[length];
978 for (Long64_t li = 0; li < length; ++li) fVal[li] = val[li];
980 GetHistogram();
982}
983
984////////////////////////////////////////////////////////////////////////////////
985/// Set the X position of the axis in the case of a vertical axis.
986/// and rotate the axis if it was horizontal.
987
989{
990 TFrame *frame = gPad->GetFrame();
991 if (!gl) {
992 fY1 = frame->GetY1();
993 fY2 = frame->GetY2();
994 } else {
997 fY1 = frame->GetY1() + ((fMinCurrent-gmin)/(gmax-gmin))*(frame->GetY2()-frame->GetY1());
998 fY2 = frame->GetY1() + ((fMaxCurrent-gmin)/(gmax-gmin))*(frame->GetY2()-frame->GetY1());
999 }
1000 fX1 = fX2 = x;
1001}
1002
1003////////////////////////////////////////////////////////////////////////////////
1004/// Set the Y position of the axis in the case of a horizontal axis.
1005/// and rotate the axis if it was vertical.
1006
1008{
1009 TFrame *frame = gPad->GetFrame();
1010 if (!gl) {
1011 fX1 = frame->GetX1();
1012 fX2 = frame->GetX2();
1013 } else {
1016 fX1 = frame->GetX1() + ((fMinCurrent-gmin)/(gmax-gmin))*(frame->GetX2()-frame->GetX1());
1017 fX2 = frame->GetX1() + ((fMaxCurrent-gmin)/(gmax-gmin))*(frame->GetX2()-frame->GetX1());
1018 }
1019 fY1 = fY2 = y;
1020}
@ 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:374
@ kArrowHor
Definition GuiTypes.h:374
#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:59
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
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
@ kOrange
Definition Rtypes.h:68
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:2495
R__EXTERN TStyle * gStyle
Definition TStyle.h:442
#define gPad
#define gVirtualX
Definition TVirtualX.h:337
#define snprintf
Definition civetweb.c:1579
Fill Area Attributes class.
Definition TAttFill.h:20
virtual Color_t GetFillColor() const
Return the fill area color.
Definition TAttFill.h:31
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition TAttFill.h:32
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:238
Line Attributes class.
Definition TAttLine.h:20
virtual Color_t GetLineColor() const
Return the line color.
Definition TAttLine.h:35
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition TAttLine.h:44
virtual Width_t GetLineWidth() const
Return the line width.
Definition TAttLine.h:37
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition TAttLine.h:45
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition TAttLine.h:42
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:274
virtual Float_t GetTextSize() const
Return the text size.
Definition TAttText.h:38
virtual void SetTextAlign(Short_t align=11)
Set the text alignment.
Definition TAttText.h:44
virtual void SetTextSize(Float_t tsize=1)
Set the text size.
Definition TAttText.h:49
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:879
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:8965
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:8573
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition TH1.cxx:3315
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH1.cxx:5063
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:8663
To draw Mathematical Formula.
Definition TLatex.h:18
Double_t GetXsize()
Return size of the formula along X in pad coordinates when the text precision is smaller than 3.
Definition TLatex.cxx:2569
virtual void PaintLatex(Double_t x, Double_t y, Double_t angle, Double_t size, const char *text)
Main drawing function.
Definition TLatex.cxx:2113
void Paint(Option_t *option="") override
Paint.
Definition TLatex.cxx:2091
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:428
void Paint(Option_t *option="") override
Paint this line with its current attributes.
Definition TLine.cxx:418
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:303
void Add(TObject *obj) override
Definition TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:819
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:467
Manages Markers.
Definition TMarker.h:22
void Paint(Option_t *option="") override
Paint this marker with its current attributes.
Definition TMarker.cxx:307
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:202
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:864
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1071
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:771
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:138
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
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:773
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:124
TLine l
Definition textangle.C:4