The python dynamic language is widely used for scientific programming,
including high performance and distributed parallel code (for reference, see
the projects on http://www.scipy.org).
It is the second most popular dynamic language (after
perl) and enjoys a wide-spread use as a "glue
language": practically every library and application these days comes with
python bindings (and if not, they can be easily written or generated,
see e.g. http://www.swig.org).
PyROOT, a python extension module, provides the bindings for the ROOT
class library in a generic way using the CINT dictionary.
This design choice allows the use of any ROOT classes from the python
interpreter, and thus the "glue-ing" of ROOT libraries with any non-ROOT
library or application that provide python bindings.
Furthermore, PyROOT can be loaded into the CINT interpreter to allow (as
of now still rudimentary) access to python classes, and direct access to the
python interpreter.
The best way to get a flavor of what PyROOT is, can do, and to understand
what benefits it brings, is through a few examples.
The PyQt library, see
http://www.riverbankcomputing.co.uk/pyqt, provides python bindings for the
Qt cross-platform GUI framework
(http://www.trolltech.com).
With PyROOT and PyQt, adding ROOT application
layer code to a Qt GUI, becomes child's play.
The following example shows how a python class can be used to have ROOT
code respond to a click on a Qt widget.
Example 1. Glue-ing Qt and ROOT through python
importsys, ROOTfromqtimport* theApp = QApplication( sys.argv ) box = QVBox() box.resize( QSize( 40, 10 ).expandedTo( box.minimumSizeHint() ) )classmyButton( QPushButton ):def__init__( self, label, master ): QPushButton.__init__( self, label, master ) self.setFont( QFont('Times', 18, QFont.Bold ) )defbrowse( self ): self.b = ROOT.TBrowser() bb = myButton('browser', box ) QObject.connect( bb, SIGNAL('clicked()'), bb.browse ) theApp.setMainWidget( box ) box.show() theApp.exec_loop()
![]() | Note |
|---|---|
GUI frameworks are a special case, as |
When the example is run, a Qt button is displayed,
and when the button is clicked, a TBrowser instance is created and will appear
on the screen.
PyROOT takes care of feeding system events to ROOT widgets, so the
TBrowser instance and the button behave properly when you interact with them.
There are several tools for scientific analysis that come with bindings that
allow the use of these tools from the python interpreter.
PyROOT provides this for users who want to do analysis in python with
ROOT.
The following example shows how to fill and display a ROOT histogram while
working in python.
Of course, actual data for histogramming and display may come from anywhere
else (instead of from gRandom) through other bindings, e.g. from a C++
program, or an ATHENA algorithm.
Example 2. Displaying a ROOT histogram from python
fromROOTimportgRandom, TCanvas, TH1F c1 = TCanvas('c1','Example', 200, 10, 700, 500 ) hpx = TH1F('hpx','px', 100, -4, 4 )foriinxrange( 25000 ): px = gRandom.Gaus() hpx.Fill( px ) hpx.Draw() c1.Update()
When run, the code above will display a 1-dimensional histogram showing a
Gaussian distribution.
More examples like the one above are distributed with ROOT under the
tutorials directory.
Access to python objects from CINT is not completely fleshed out.
Currently, ROOT objects and builtin types can freely cross the boundary
between the two interpreters, but other objects are much more restricted.
For example, for a python object to cross, it has to be a class instance,
and its class has to be known to CINT first (i.e. the class has to cross
first, before the instance can).
All other cross-coding is based on strings that are run on the python
interpreter and vice versa.
Example 3. Accessing the python interpreter from ROOT
// either load PyROOT explicitly or rely on auto-loadinggSystem->Load("libPyROOT"); TPython::Exec("print 1 + 1");// prints '2'// create a TBrowser on the python side, and transfer it back and forthTBrowser* b = (void*)TPython::Eval("ROOT.TBrowser()"); TPython::Bind( b,"b");// builtin variables can cross-over (after the call i == 2)inti = TPython::Eval("1 + 1");
It is possible to switch between interpreters by calling "TPython::Prompt()"
from CINT side, while returning back to it by "exiting" the python
interpreter with ^D (EOF).
State is preserved between successive switches, and string based cross calls
can nest as long as shared resources are properly handled.
This concludes the quick overview. All examples are fleshed out in more detail in the following sections.