Logo ROOT   6.18/05
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
20
21import sys
22
23from ROOT import gRandom, gPad, gROOT, gVirtualX
24from ROOT import kTRUE, kRed
25from ROOT import TCanvas, TH2, TH2F, Double
26
27
28class DynamicExec:
29
30 def __init__( self ):
31 self._cX = None
32 self._cY = None
33 self._old = None
34
35 def __call__( self ):
36
37 h = gPad.GetSelected();
38 if not h:
39 return
40
41 if not isinstance( h, TH2 ):
42 return
43
44 gPad.GetCanvas().FeedbackMode( kTRUE )
45
46 # erase old position and draw a line at current position
47 px = gPad.GetEventX()
48 py = gPad.GetEventY()
49
50 uxmin, uxmax = gPad.GetUxmin(), gPad.GetUxmax()
51 uymin, uymax = gPad.GetUymin(), gPad.GetUymax()
52 pxmin, pxmax = gPad.XtoAbsPixel( uxmin ), gPad.XtoAbsPixel( uxmax )
53 pymin, pymax = gPad.YtoAbsPixel( uymin ), gPad.YtoAbsPixel( uymax )
54
55 if self._old != None:
56 gVirtualX.DrawLine( pxmin, self._old[1], pxmax, self._old[1] )
57 gVirtualX.DrawLine( self._old[0], pymin, self._old[0], pymax )
58 gVirtualX.DrawLine( pxmin, py, pxmax, py )
59 gVirtualX.DrawLine( px, pymin, px, pymax )
60
61 self._old = px, py
62
63 upx = gPad.AbsPixeltoX( px )
64 x = gPad.PadtoX( upx )
65 upy = gPad.AbsPixeltoY( py )
66 y = gPad.PadtoY( upy )
67
68 padsav = gPad
69
70 # create or set the display canvases
71 if not self._cX:
72 self._cX = TCanvas( 'c2', 'Projection Canvas in X', 730, 10, 700, 500 )
73 else:
74 self._DestroyPrimitive( 'X' )
75
76 if not self._cY:
77 self._cY = TCanvas( 'c3', 'Projection Canvas in Y', 10, 550, 700, 500 )
78 else:
79 self._DestroyPrimitive( 'Y' )
80
81 self.DrawSlice( h, y, 'Y' )
82 self.DrawSlice( h, x, 'X' )
83
84 padsav.cd()
85
86 def _DestroyPrimitive( self, xy ):
87 proj = getattr( self, '_c'+xy ).GetPrimitive( 'Projection '+xy )
88 if proj:
89 proj.IsA().Destructor( proj )
90
91 def DrawSlice( self, histo, value, xy ):
92 yx = xy == 'X' and 'Y' or 'X'
93
94 # draw slice corresponding to mouse position
95 canvas = getattr( self, '_c'+xy )
96 canvas.SetGrid()
97 canvas.cd()
98
99 bin = getattr( histo, 'Get%saxis' % xy )().FindBin( value )
100 hp = getattr( histo, 'Projection' + yx )( '', bin, bin )
101 hp.SetFillColor( 38 )
102 hp.SetName( 'Projection ' + xy )
103 hp.SetTitle( xy + 'Projection of bin=%d' % bin )
104 hp.Fit( 'gaus', 'ql' )
105 hp.GetFunction( 'gaus' ).SetLineColor( kRed )
106 hp.GetFunction( 'gaus' ).SetLineWidth( 6 )
107 canvas.Update()
108
109
110if __name__ == '__main__':
111 # create a new canvas.
112 c1 = TCanvas('c1', 'Dynamic Slice Example', 10, 10, 700, 500 )
113 c1.SetFillColor( 42 )
114 c1.SetFrameFillColor( 33 )
115
116 # create a 2-d histogram, fill and draw it
117 hpxpy = TH2F( 'hpxpy', 'py vs px', 40, -4, 4, 40, -4, 4 )
118 hpxpy.SetStats( 0 )
119 x, y = Double( 0.1 ), Double( 0.101 )
120 for i in range( 50000 ):
121 gRandom.Rannor( x, y )
122 hpxpy.Fill( x, y )
123 hpxpy.Draw( 'COL' )
124
125 # Add a TExec object to the canvas (explicit use of __main__ is for IPython)
126 import __main__
127 __main__.slicer = DynamicExec()
128 c1.AddExec( 'dynamic', 'TPython::Exec( "slicer()" );' )
129 c1.Update()
The Canvas class.
Definition: TCanvas.h:31
2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:248
f1 SetLineWidth(4)
const char * Double
lv SetLineColor(kBlue)