Logo ROOT  
Reference Guide
DynamicSlice.py
Go to the documentation of this file.
1## \file
2## \ingroup tutorial_pyroot
3## \notebook
4## Example of function called when a mouse event occurs in a pad.
5## When moving the mouse in the canvas, a second canvas shows the
6## projection along X of the bin corresponding to the Y position
7## of the mouse. The resulting histogram is fitted with a gaussian.
8## A "dynamic" line shows the current bin position in Y.
9## This more elaborated example can be used as a starting point
10## to develop more powerful interactive applications exploiting CINT
11## as a development engine.
12##
13## Note that a class is used to hold on to the canvas that display
14## the selected slice.
15##
16## \macro_image
17## \macro_code
18##
19## \author Rene Brun, Johann Cohen-Tanugi, Wim Lavrijsen, Enric Tejedor
20
21import sys
22import ctypes
23
24from ROOT import gRandom, gPad, gROOT, gVirtualX
25from ROOT import kTRUE, kRed
26from ROOT import TCanvas, TH2, TH2F
27
28
29class DynamicExec:
30
31 def __init__( self ):
32 self._cX = None
33 self._cY = None
34 self._old = None
35
36 def __call__( self ):
37
38 h = gPad.GetSelected();
39 if not h:
40 return
41
42 if not isinstance( h, TH2 ):
43 return
44
45 gPad.GetCanvas().FeedbackMode( kTRUE )
46
47 # erase old position and draw a line at current position
48 px = gPad.GetEventX()
49 py = gPad.GetEventY()
50
51 uxmin, uxmax = gPad.GetUxmin(), gPad.GetUxmax()
52 uymin, uymax = gPad.GetUymin(), gPad.GetUymax()
53 pxmin, pxmax = gPad.XtoAbsPixel( uxmin ), gPad.XtoAbsPixel( uxmax )
54 pymin, pymax = gPad.YtoAbsPixel( uymin ), gPad.YtoAbsPixel( uymax )
55
56 if self._old != None:
57 gVirtualX.DrawLine( pxmin, self._old[1], pxmax, self._old[1] )
58 gVirtualX.DrawLine( self._old[0], pymin, self._old[0], pymax )
59 gVirtualX.DrawLine( pxmin, py, pxmax, py )
60 gVirtualX.DrawLine( px, pymin, px, pymax )
61
62 self._old = px, py
63
64 upx = gPad.AbsPixeltoX( px )
65 x = gPad.PadtoX( upx )
66 upy = gPad.AbsPixeltoY( py )
67 y = gPad.PadtoY( upy )
68
69 padsav = gPad
70
71 # create or set the display canvases
72 if not self._cX:
73 self._cX = TCanvas( 'c2', 'Projection Canvas in X', 730, 10, 700, 500 )
74 else:
75 self._DestroyPrimitive( 'X' )
76
77 if not self._cY:
78 self._cY = TCanvas( 'c3', 'Projection Canvas in Y', 10, 550, 700, 500 )
79 else:
80 self._DestroyPrimitive( 'Y' )
81
82 self.DrawSlice( h, y, 'Y' )
83 self.DrawSlice( h, x, 'X' )
84
85 padsav.cd()
86
87 def _DestroyPrimitive( self, xy ):
88 proj = getattr( self, '_c'+xy ).GetPrimitive( 'Projection '+xy )
89 if proj:
90 proj.IsA().Destructor( proj )
91
92 def DrawSlice( self, histo, value, xy ):
93 yx = xy == 'X' and 'Y' or 'X'
94
95 # draw slice corresponding to mouse position
96 canvas = getattr( self, '_c'+xy )
97 canvas.SetGrid()
98 canvas.cd()
99
100 bin = getattr( histo, 'Get%saxis' % xy )().FindBin( value )
101 hp = getattr( histo, 'Projection' + yx )( '', bin, bin )
102 hp.SetFillColor( 38 )
103 hp.SetName( 'Projection ' + xy )
104 hp.SetTitle( xy + 'Projection of bin=%d' % bin )
105 hp.Fit( 'gaus', 'ql' )
106 hp.GetFunction( 'gaus' ).SetLineColor( kRed )
107 hp.GetFunction( 'gaus' ).SetLineWidth( 6 )
108 canvas.Update()
109
110
111if __name__ == '__main__':
112 # create a new canvas.
113 c1 = TCanvas('c1', 'Dynamic Slice Example', 10, 10, 700, 500 )
114 c1.SetFillColor( 42 )
115 c1.SetFrameFillColor( 33 )
116
117 # create a 2-d histogram, fill and draw it
118 hpxpy = TH2F( 'hpxpy', 'py vs px', 40, -4, 4, 40, -4, 4 )
119 hpxpy.SetStats( 0 )
120 x, y = ctypes.c_double( 0.1 ), ctypes.c_double( 0.101 )
121 for i in range( 50000 ):
122 # pass ctypes doubles by reference, then retrieve their modified values with .value
123 gRandom.Rannor( x, y )
124 hpxpy.Fill( x.value, y.value )
125 hpxpy.Draw( 'COL' )
126
127 # Add a TExec object to the canvas (explicit use of __main__ is for IPython)
128 import __main__
129 __main__.slicer = DynamicExec()
130 c1.AddExec( 'dynamic', 'TPython::Exec( "slicer()" );' )
131 c1.Update()
Option_t Option_t SetLineWidth
Option_t Option_t SetLineColor
The Canvas class.
Definition: TCanvas.h:23
2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:257