1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
\section{Overview}
\Index{Python} is an object-oriented scripting language~\cite{Python} that is
well suited both as a language for embedding scripts into BALL applications and
as a rapid prototyping language using the underlying BALL objects.
BALL provides Python bindings for most of its classes in order to allow
\Index{Rapid Methodology Development} (RMD). Some of the functionality BALL
provides (\eg template classes, iterators) is unavailable due to the
fundamental differences between the two languages. However, the majority of
the classes is available and workarounds exist for some of the template- and
iterator-related problems.
Since release 1.2 of BALL, the Python support is enabled by default. The
remainder of this section assumes that you are somewhat familiar with the most
important language concepts of Python.
BALL relies on SIP~\cite{SIP} \index{SIP} version 4.6.0 to translate its class
headers semi-automatically into Python wrapper classes. For each \CPP class
SIP creates a subclass defining the Python interface and a Python class
using that \CPP interface class. The Python class has the same name as the
\CPP class, so porting code from \CPP to Python (and vice versa) gets trivial.
The \CPP code
\begin{lstlisting}{}
System S;
HINFile f("test.hin");
f >> S;
\end{lstlisting}
\noindent
translates to the Python code
\begin{lstlisting}{}
S = System()
f = HINFile("test.hin")
f >> S;
\end{lstlisting}
\noindent
In this example, the main difference is how \CPP and Python handle
constructors. Another important difference concerns iterators. The STL-like
kernel iterators of BALL map to a set of functions (called extractors). An
extractor traverses the whole container and creates a Python sequence object
from it. Instead of having an \class{AtomIterator} iterating over all atoms of
a residue
\begin{lstlisting}{}
AtomIterator ai = residue.beginAtom();
for (; +ai; ++ai)
{
std::cout << ai->getName() << std::endl;
}
\end{lstlisting}
\noindent
an \function{atoms} extractor is used to create a sequence object containing
all objects of the residue in Python:
\begin{lstlisting}{}
for atom in atoms(residue):
print atom.getName()
\end{lstlisting}
For the template problem, we pre-instantiated some of the
commonly used instances, \eg \class{Unary\-Processor\-<Atom>} maps to the
\class{AtomProcessor} class and classes derived from it in Python.
The BALLView application contains an interactive interpreter window
if BALL was compiled with Python support. You can even access the
data structures of the viewer from there. Assuming that you are
currently displaying a structure in the viewer, you can retrieve a
reference to the first system displayed through the somewhat cryptic
command
\begin{lstlisting}{}
system = MainControl::getInstance(0)\\
.getCompositeManager().getComposites()[0].
\end{lstlisting}
\noindent
Since this is not very convenient, we added a Python startup script that is
always executed when \mbox{BALLView} starts up. It can be found under
\file{BALL/data/startup.py}. By using one of the methods defined in this file,
it is possible to obtain the first \class{System} by simply calling
\begin{lstlisting}{}
system = getSystem(0).
\end{lstlisting}
\noindent
This is very useful for extracting properties of loaded molecules and other
datasets you are currently displaying, but not recommended if you start
modifying internals of the viewer. You should also not try to destroy those
objects in the viewer, or you will be rewarded with a core dump. Currently
there is no further documentation of the Python support available.
\section{Installation}
Download, configure, and install the \Index{SIP} version 4.6.0 or later from
\URL{http://www.ballview.org/Downloads/Contrib/} or from~\cite{SIP}.
Run the configure script with the command ''python configure.py -x" to disable
the Qt support. It is important to compile BALL with the same \CPP compiler SIP
and Qt were compiled with. You can then enable the Python support of BALL
by specifying the option \mbox{"\option{--with-python=<path>}"}, where
{\tt path} should point to the executable of an installed Python (version at
least 2.5). You will also have to specify the path to the SIP executable, its
headers, and its library ({\tt libsip.a|so}). Adding these four options might
look something like this on your system:
\begin{lstlisting}{}
./configure \
--with-python=/opt/bin/python2.5\
--with-sip=/opt/bin/sip\
--with-sip-incl=/opt/include/sip\
--with-sip-lib=/opt/lib
\end{lstlisting}
\noindent
After configuring and building BALL, you should then change to {\tt
BALL/source/PYTHON/EXTENSIONS}. Here, you will have to run
\begin{lstlisting}{}
make sip
make depend
make
make install
\end{lstlisting}
\noindent
in order to build the Python bindings, which are then installed to
{\tt BALL/lib/<platform>}. You can then execute the {\tt pyballinit.py} script in
{\tt BALL/source/PYTHON/EXTENSIONS} to get an interactive Python shell with
the BALL bindings or just start the Python interpreter and import the BALL
bindings through
\begin{lstlisting}{}
from BALL import *
\end{lstlisting}
\noindent
Note, that you have to add the directory where the bindings are installed to
Python's module search path ({\tt sys.path}).
|