Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
hist105_TExec_dynamic_slice.py
Go to the documentation of this file.
1## \file
2## \ingroup tutorial_hist
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 Cling
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, Sergey Linev
20
21import sys
22import ctypes
23
24from ROOT import gRandom, gPad, gROOT
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.FeedbackMode( kTRUE )
46
47 px = gPad.GetEventX()
48 py = gPad.GetEventY()
49 upx = gPad.AbsPixeltoX( px )
50 upy = gPad.AbsPixeltoY( py )
51
52 uxmin, uxmax = gPad.GetUxmin(), gPad.GetUxmax()
53 uymin, uymax = gPad.GetUymin(), gPad.GetUymax()
54
55 # erase old position and paint lines at current position
56 if self._old != None:
57 gPad.PaintLine( uxmin, self._old[1], uxmax, self._old[1] )
58 gPad.PaintLine( self._old[0], uymin, self._old[0], uymax )
59 gPad.PaintLine( uxmin, upy, uxmax, upy )
60 gPad.PaintLine( upx, uymin, upx, uymax )
61
62 self._old = upx, upy
63
64 x = gPad.PadtoX( upx )
65 y = gPad.PadtoY( upy )
66
67 padsav = gPad
68
69 # create or set the display canvases
70 if not self._cX:
71 self._cX = TCanvas( 'c2', 'Projection Canvas in X', 730, 10, 700, 500 )
72 else:
73 self._DestroyPrimitive( 'X' )
74
75 if not self._cY:
76 self._cY = TCanvas( 'c3', 'Projection Canvas in Y', 10, 550, 700, 500 )
77 else:
78 self._DestroyPrimitive( 'Y' )
79
80 self.DrawSlice( h, y, 'Y' )
81 self.DrawSlice( h, x, 'X' )
82
83 padsav.cd()
84
85 def _DestroyPrimitive( self, xy ):
86 proj = getattr( self, '_c'+xy ).GetPrimitive( 'Projection '+xy )
87 if proj:
88 proj.IsA().Destructor( proj )
89
90 def DrawSlice( self, histo, value, xy ):
91 yx = xy == 'X' and 'Y' or 'X'
92
93 # draw slice corresponding to mouse position
94 canvas = getattr( self, '_c'+xy )
96 canvas.cd()
97
98 bin = getattr( histo, 'Get%saxis' % xy )().FindBin( value )
99 hp = getattr( histo, 'Projection' + yx )( '', bin, bin )
100 hp.SetFillColor( 38 )
101 hp.SetName( 'Projection ' + xy )
102 hp.SetTitle( xy + 'Projection of bin=%d' % bin )
103 hp.Fit( 'gaus', 'ql' )
104 hp.GetFunction( 'gaus' ).SetLineColor( kRed )
105 hp.GetFunction( 'gaus' ).SetLineWidth( 6 )
107
108
109if __name__ == '__main__':
110 # create a new canvas.
111
112 c1 = TCanvas('c1', 'Dynamic Slice Example', 10, 10, 700, 500 )
113 c1.SetFillColor( 42 )
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 = ctypes.c_double( 0.1 ), ctypes.c_double( 0.101 )
120 for i in range( 50000 ):
121 # pass ctypes doubles by reference, then retrieve their modified values with .value
122 gRandom.Rannor( x, y )
124 hpxpy.Draw( 'COL' )
125
126 # Add a TExec object to the canvas (explicit use of __main__ is for IPython)
127 import __main__
129 c1.AddExec( 'dynamic', 'TPython::Exec( "slicer()" );' )
130 c1.Update()
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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:345