File: example1.tex

package info (click to toggle)
ball 1.5.0%2Bgit20180813.37fc53c-11
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 239,924 kB
  • sloc: cpp: 326,149; ansic: 4,208; python: 2,303; yacc: 1,778; lex: 1,099; xml: 958; sh: 322; javascript: 164; makefile: 88
file content (386 lines) | stat: -rw-r--r-- 13,987 bytes parent folder | download | duplicates (9)
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
\section{Building Molecules}

Since BALL is intended for Molecular Modeling, the classes representing atoms,
bonds, and molecules are of central importance. In this first example, we will
construct a water molecule ``by hand'' to illustrate the use of these classes.
Typical applications would read molecular structures from a file. This will be
shown in the second example.

\noindent
The whole source code for the first example is given in
Listing~\ref{lst:tutorial1}. To start the construction of a water molecule, we
first create an (empty) \Index{atom}. Atoms are represented by the class
\class{Atom}.

\begin{lstlisting}{}
  Atom* oxygen = new Atom;
\end{lstlisting}
	
\noindent
Atoms have a number of attributes. As we created this atom without specifying
any of its properties, these attributes are set to their defaults. 
Table \ref{table:atomattributes} lists the attributes of an atom along with its
\newtermdef{accessors} (methods to access or modify an attribute) and default
values.

\begin{table} [h]
\centering
\begin{tabular}{|l|l|l|c|}
\hline
\bf Attribute &	\bf Type   & \bf Accessors          & \bf Default value\\
\hline
name          & String     & \accessor{setName}     & {\tt ""}\\
              &            & \accessor{getName}     & \\
element       & Element    & \accessor{setElement}  & {\tt Element::UNKNOWN}\\
              &            & \accessor{getElement}  & \\
charge        & float      & \accessor{setCharge}   & 0.0\\
              &            & \accessor{getCharge}   & \\
radius        & float      & \accessor{setRadius}   & 0.0\\
              &            & \accessor{getRadius}   & \\
type name     & String     & \accessor{setTypeName} & {\tt ""}\\
              &            & \accessor{getTypeName} & \\
type          & Atom::Type & \accessor{setType}     & {\tt Atom::INVALID\_TYPE}\\
              &            & \accessor{getType}     & \\
position      & Vector3    & \accessor{setPosition} & (0, 0, 0)\\
              &            & \accessor{getPosition} & \\
velocity      & Vector3    & \accessor{setVelocity} & (0, 0, 0)\\
              &            & \accessor{getVelocity} & \\
force         & Vector3    & \accessor{setForce}    & (0, 0, 0) \\
              &            & \accessor{getForce}    & \\
\hline
\end{tabular}
\caption[Attributes of an atom]
{Atttributes of an atom along with its accessors and default values.}
\label{table:atomattributes}
\end{table}

\noindent
For example, we can assign the \Index{element} for our new atom:

\begin{lstlisting}{}
  oxygen->setElement(PTE[Element::O]);
\end{lstlisting}

\noindent
The expression {\tt PTE[\class{Element}::O]} returns an instance of class
\class{Element}. It is assigned to our atom using the \method{setElement}
method. We leave our new atom at the default position (0, 0, 0) and create two
new atoms, which will be the still missing hydrogen atoms:

\begin{lstlisting}{}
  Atom* hydrogen1 = new Atom;
  Atom* hydrogen2 = new Atom;
  hydrogen1->setElement(PTE[Element::H]);
  hydrogen2->setElement(PTE[Element::H]);
\end{lstlisting}
	
\noindent
Now we have to assign the correct coordinates to the two hydrogen atoms.  The
method \method{setPosition} takes an instance of \class{Vector3} as an
argument. This class is used to represent coordinates and vectors in
three--dimensional space. An object of type \class{Vector3} can be constructed
from three floating point numbers which represent the $x$, $y$, and $z$
coordinates. Thus, we can assign the coordinates as follows:
 
\begin{lstlisting}{}
  hydrogen1->setPosition(Vector3(-0.95, 0.00, 0.0));
  hydrogen2->setPosition(Vector3( 0.25, 0.87, 0.0));
\end{lstlisting}

\noindent
Now, our three atoms are of the right type and at the right positions. However,
we do not yet have a molecule, so let's create one:

\begin{lstlisting}{}
  Molecule* water = new Molecule;
\end{lstlisting}

\noindent
Molecules are representd by the \class{Molecule} class. Each instance of this
class may contain an arbitrary number of atoms. Using the \method{insert}
method, we can construct a molecule from our atoms:

\begin{lstlisting}{}
  water->insert(*oxygen);
  water->insert(*hydrogen1);
  water->insert(*hydrogen2);
\end{lstlisting}

\noindent
For a complete water molecule, we still need two \Index{bonds}. This can be
achieved with the method \method{createBond}:
	
\begin{lstlisting}{}
  oxygen->createBond(*hydrogen1);
  oxygen->createBond(*hydrogen2);
\end{lstlisting}

or

\begin{lstlisting}{}
  hydrogen2->createBond(*oxygen);
\end{lstlisting}

\noindent
To verify that everything worked as expected, we might print the number of
atoms in the molecule or the number of bonds for each atom:
	
\begin{lstlisting}{}
  cout << "# of atoms in water: " 
       << water->countAtoms() << endl;
  cout << "# of bonds of oxygen: " 
       << oxygen->countBonds() << endl;
  cout << "# of bonds of hydrogen1: " 
       << hydrogen1->countBonds() << endl;
  cout << "# of bonds of hydrogen2: " 
       << hydrogen2->countBonds() << endl;
\end{lstlisting}

\noindent
The method \method{countAtoms} is available for all kernel classes that might
contain atoms and returns the total number of atoms for this object. The
method \method{countBonds} returns the number of bonds the atom shares. An
atom can have at most eight bonds.

We can also verify the bond distances:
\begin{lstlisting}{}
  float distance = oxygen->getDistance(*hydrogen1);

  cout << "bond length: " << distance << endl;
\end{lstlisting}
	
\noindent
\method{getPosition} is the complementary method of \method{setPosition}: it
returns the current position of an atom. The return value is again of type
\class{Vector3}. The length of this vector is then returned by the
\method{getLength} method. 

Water molecules rarely occur alone, so we are going to create further water molecules.
All BALL kernel classes are container classes and support \newterm{deep
copying}, \ie when assigned or copy constructed their contents are copied as
well. So, we can easily create a new water molecule:

\begin{lstlisting}{}
  Molecule* water2 = new Molecule(*water);
\end{lstlisting}
	
\noindent
This molecule is an exact copy of our original water molecule. Especially, the
atoms have the same position as in the original. So we want to shift the whole
molecule to another position.  In principle, we could access all atoms in the
copy and add a constant translation vector to their position. However, there
is a simpler way. BALL provides so--called \newterm{processors}. These
processors may be applied to any of the kernel objects and perform an
operation on any objects they encounter. For example the
\class{TranslationProcessor} performs a simple translation on every atom it
finds. The use of the processors is very simple.  All kernel classes define an
\method{apply} method which takes a processor as an argument. In order to
translate our second water molecule by a certain distance, we first create a
\class{TranslationProcessor}:

\begin{lstlisting}{}
  TranslationProcessor translation(Vector3(5, 0, 0));
\end{lstlisting}
	
\noindent
The translation vector is specified as the argument of the constructor. Now we
may translate the atoms of our water molecule by a simple call to \method{apply}

\begin{lstlisting}{}
  water2->apply(translation);
\end{lstlisting}

\noindent
Another important kernel class besides atoms and molecules is \class{System}.
A system is a collection of atoms, molecules, or any other kernel objects. For
example, we can store our two water molecules in a system object:

\begin{lstlisting}{}
  System S;
  S.insert(*water);
  S.insert(*water2);
\end{lstlisting}

\begin{figure}[t]
  \centering
  \includegraphics[width=\textwidth]{tut1_screenshot}
  \caption{Screenshot of BALLView showing the result of the first example
           ({\tt tutorial1.C})}
  \label{fig:tut1-screenshot}
\end{figure}

\noindent
We can now manipulate the two water molecules simultaneously. For example a
further application of the translation processor to the system would apply
the translation to both molecules.
But now we would like to have a look at what we built. So we might write our
system to a file and inspect it with a molecule viewer (\eg BALLView).
BALL supports a variety of file formats. For example we could write the system
to a HyperChem HIN file~\cite{HyperChem}: \label{useofstreams}

\begin{lstlisting}{}
  HINFile outfile("water.hin", std::ios::out);
  outfile << S;
  outfile.close();
\end{lstlisting}

\noindent
These three lines of code create a \class{HINFile} object which is used to
read and write HyperChem files. The first line opens a file named {\tt
water.hin} for output ({\tt std::ios::out}; if the second argument is omitted the
file is opened for reading only). The second line uses the stream operator 
{\tt <<} \index{operator {\tt <<}} to write the contents of system {\tt S} to 
this file. The file is closed in the third line.

\noindent 
As all molecules and atoms we created are inside the system, they are deleted
automatically as soon as the system is deleted.

If this short program is run it creates the following output:

\begin{lstlisting}[frameround=]{}
  # of atoms in water: 3
  # of bonds of oxygen: 2
  # of bonds of hydrogen1: 1
  # of bonds of hydrogen2: 1
  bond distance: 0.95
\end{lstlisting}

\noindent
It also creates a file named {\tt water.hin} which contains the two water
molecules. Fig.~\ref{fig:tut1-screenshot} shows the contents of this file
in the BALLView viewer.

To compile this small example, we still have to include a few header files.
The complete file is shown in Listing~\ref{lst:tutorial1} on
Page~\pageref{lst:tutorial1} and can be found in \mbox{{\tt
BALL/source/TUTORIAL/tutorial1.C}}.

First, we have to include \file{iostream} as we use {\tt cout} and {\tt endl}
to print some text. Then, we have to include the headers for the BALL kernel
classes \class{Atom}, \class{Bond}, \class{Molecule}, \class{System}, and
\class{PTE}. The headers for the HyperChem file support are found in the
directory \directory{BALL/FORMAT} and the headers for the
\class{TranslationProcessor} class are found in
{\tt BALL/STRUCTURE/geometricProperties.h}.

As all BALL classes are hidden in the \namespace{BALL} namespace, we have to
give access to this namespace with the command 
\begin{lstlisting}{}
  using namespace BALL;
\end{lstlisting}
Similarly, we also use the namespace \namespace{std} which contains {\tt cout}
and {\tt endl}.

If you have BALL installed, you might now try to compile this example. Simply
change to the directory \directory{BALL/source/TUTORIAL} which contains all
the examples from this tutorial and type 
\begin{lstlisting}[frameround=]{}
  make tutorial1
  ./tutorial1
\end{lstlisting}
This should build and execute the example. Please remember to set the
environment variable {\tt LD\_LIBRARY\_PATH} to the directory where your
libraries are installed.

After the successful execution of the example, a file named {\tt water.hin}
should appear in the current directory. This file contains the two water
molecules. You might inspect it with the molecule viewer \mbox{BALLView}.
Fig.~\ref{fig:tut1-screenshot} shows a screenshot of \mbox{BALLView} 
displaying the two water molecules.

\newpage
\begin{lstlisting}[captionpos=t,caption={The complete source code of the first example.}\label{lst:tutorial1}]{}
// tutorial example 1
// ------------------
// build two water molecules and write them to a file

// needed for cout
#include <iostream>

// the BALL kernel classes
#include <BALL/KERNEL/atom.h>
#include <BALL/KERNEL/bond.h>
#include <BALL/KERNEL/molecule.h>
#include <BALL/KERNEL/system.h>
#include <BALL/KERNEL/PTE.h>

// reading and writing of HyperChem files
#include <BALL/FORMAT/HINFile.h>

// the TranslationProcessor
#include <BALL/STRUCTURE/geometricTransformations.h>

// we use the BALL namespace and the std namespace
using namespace BALL;
using namespace std;

int main()
{
  // we create a new atom called oxygen
  // and set its element to oxygen (PTE[Element::O])
  Atom* oxygen = new Atom;
  oxygen->setElement(PTE[Element::O]);

  // now we create two hydrogen atoms...
  Atom* hydrogen1 = new Atom;
  Atom* hydrogen2 = new Atom;
  hydrogen1->setElement(PTE[Element::H]);
  hydrogen2->setElement(PTE[Element::H]);

  // ...and move them to approximately correct positions
  hydrogen1->setPosition(Vector3(-0.95, 0.00, 0.0));
  hydrogen2->setPosition(Vector3( 0.25, 0.87, 0.0));

  // We create our water molecule...
  Molecule* water = new Molecule;

  // ...and insert the three atoms into the molecule.
  water->insert(*oxygen);
  water->insert(*hydrogen1);
  water->insert(*hydrogen2);

  // Then we build the two O-H bonds
  oxygen->createBond(*hydrogen1);
  oxygen->createBond(*hydrogen2);

  // Some statistics: Molecule::countAtoms() 
  // returns the number of atoms, Atom::countBonds() 
  // the number of bonds the atom shares
  cout << "# of atoms in water: " 
       << water->countAtoms() << endl;
  cout << "# of bonds in oxygen: " 
       << oxygen->countBonds() << endl;
  cout << "# of bonds of hydrogen1: " 
       << hydrogen1->countBonds() << endl;
  cout << "# of bonds of hydrogen2: " 
       << hydrogen2->countBonds() << endl;

  // compute the bond length
  float distance = oxygen->getDistance(*hydrogen1);

  cout << "bond length: " << distance << endl;

  // Now we copy our molecule using a copy constructor.
  Molecule* water2 = new Molecule(*water);

  // A translation processor moves the second molecule
  // 5 Angstrom along the x axis
  TranslationProcessor translation(Vector3(5, 0, 0));
  water2->apply(translation);

  // We insert our two molecules into a system
  System* S = new System;
  S->insert(*water);
  S->insert(*water2);

  // and write this system to a HyperChem file
  HINFile outfile("water.hin", std::ios::out);
  outfile << *S;
  outfile.close();

  // We delete the system. This also deletes 
  // the molecules and the atoms therein
  delete S;
}
\end{lstlisting}