Open Babel
Open Babel
1 Introduction 3
1.1 Goals of the Open Babel project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Frequently Asked Questions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3 Thanks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
i
5.2 Filtering structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
5.3 Substructure and similarity searching a large dataset . . . . . . . . . . . . . . . . . . . . . . . . . . 42
8 2D Depiction 63
8.1 Molecular graphics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
9 3D Structure Generation 65
9.1 Generate a single conformer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
9.2 Generate multiple conformers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
13 Stereochemistry 121
13.1 Accessing stereochemistry information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
13.2 The Config() object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
ii
13.3 Modifying the stereochemistry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
13.4 Stereo perception . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
13.5 Miscellaneous stereo functions in the API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
19 Descriptors 209
19.1 Numerical descriptors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
19.2 Textual descriptors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
19.3 Descriptors for filtering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
iii
20.2 Special charge models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
Bibliography 239
iv
, Release 3.0.1
The latest version of this documentation is available in several formats from http://openbabel.org/docs/dev/.
Contents 1
, Release 3.0.1
2 Contents
Chapter 1
Introduction
Open Babel is a chemical toolbox designed to speak the many languages of chemical data. It’s an open, collaborative
project allowing anyone to search, convert, analyze, or store data from molecular modeling, chemistry, solid-state
materials, biochemistry, or related areas.
Open Babel is a project to facilitate the interconversion of chemical data from one format to another – including file
formats of various types. This is important for the following reasons:
• Multiple programs are often required in realistic workflows. These may include databases, modeling or compu-
tational programs, visualization programs, etc.
• Many programs have individual data formats, and/or support only a small subset of other file types.
• Chemical representations often vary considerably:
– Some programs are 2D. Some are 3D. Some use fractional k-space coordinates.
– Some programs use bonds and atoms of discrete types. Others use only atoms and electrons.
– Some programs use symmetric representations. Others do not.
– Some programs specify all atoms. Others use “residues” or omit hydrogen atoms.
• Individual implementations of even standardized file formats are often buggy, incomplete or do not completely
match published standards.
As a free, and open source project, Open Babel improves by way of helping others. It gains by way of its users,
contributors, developers, related projects, and the general chemical community. We must continually strive to support
these constituencies.
We gratefully accept contributions in many forms – from bug reports, complaints, and critiques, which help us improve
what we do poorly, to feature suggestions, code contributions, and other efforts, which direct our future development.
• For end users, we seek to provide a range of utility, from simple (or complex) file interconversion, to indexing,
databasing, and transforming chemical and molecular data.
• For developers, we seek to provide an easy-to-use free and open source chemical library. This assists a variety of
chemical software, from molecular viewers and visualization tools and editors to databases, property prediction
tools, and in-house development.
3
, Release 3.0.1
To this end, we hope that our tools reflect several key points:
• As much chemical information and files should be read and understood by Open Babel. This means that we
should always strive to support as many concepts as possible in a given file format, and support for additional
file formats is beneficial to the community as a whole.
• Releases should be made to be “as good as we can make it” each and every time.
• Improving our code and our community to bring in additional contributions in many forms helps both developers
and end-users alike. Making development easy for new contributors will result in better tools for users as well.
1.2.1 General
Put simply, Open Babel is a free, open-source version of the Babel chemistry file translation program. Open Babel is
a project designed to pick up where Babel left off, as a cross-platform program and library designed to interconvert
between many file formats used in molecular modeling, computational chemistry, and many related areas.
Open Babel includes two components, a command-line utility and a C++ library. The command-line utility is intended
to be used as a replacement for the original babel program, to translate between various chemical file formats. The
C++ library includes all of the file-translation code as well as a wide variety of utilities to foster development of other
open source scientific software.
Your choice. It’s probably easier to call it Open Babel since that’s what it is–an open version of Babel. But if you like
one-word, mixed-case project names, then go for OpenBabel. In that case, the space is just too small to be printed.
How does this relate to the original Babel and OELib, the “next” Babel?
The original Babel was written by Pat Walters and Matt Stahl, based on the “convert” program by Ajay Shah, and
is still a remarkable application. Both Pat and Matt have moved on to other work. The original Babel is hosted
by Smog.com on a Babel homepage, by the Computational Chemistry List (CCL) and of course by Open Babel at
SourceForge.net.
Along the way, the two original authors started a rewrite of Babel into C++ they called OBabel, which was never
really publicly released. But Matt used some of these ideas in OELib, which was generously released under the GNU
GPL by his employer, OpenEye Software, and the last known version of this OELib is still available from our file
repository. OpenEye decided that for their purposes OELib needed a rewrite (now called OEChem), but this would
be closed-source to include some advanced algorithms. So the GPL’ed version of OELib would not be maintained.
Instead, the free version of OELib was renamed and has become “Open Babel” with the blessing of Matt and other
contributors.
Open Babel has evolved quite a lot since its birth in 2001.
4 Chapter 1. Introduction
, Release 3.0.1
As of this writing, the latest version is Open Babel 3.0.1. This is a stable version suitable for widespread use and
development.
One common misconception about the GNU GPL license for Open Babel is that it requires users to release any code
that uses the Open Babel library. This is completely untrue. There are no restrictions on use of Open Babel code for
personal projects, regardless of where you work (academia, industry, . . . wherever).
However, if you intend on releasing a software package that uses Open Babel code, the GPL requires that your package
be released under the GNU GPL license. The distinction is between use and distribution. See What’s in it for me to
contribute? below for more on the licensing issues.
The file formats currently supported are some of the more common file formats and, admittedly, those we use in our
work. If you’d like to see other file formats added, we need one of:
• documentation on the file format
• working code to read the file format or translate it
• example files in the new file format and in some other format
The latter obviously is the easiest with text file formats. Binary files take some time to reverse engineer without
documentation or working code. Also consider pointing developers to this FAQ and the “What’s in it for me?” section.
When I convert from SMILES to MOL2/PDB/etc., why are all of the coordinates zero?
The SMILES format contains 2D information on the molecule. That is, it says which atoms are connected to which
other atoms, and what type of bonds are present. MOL2, PDB and several other formats contain 3D coordinate
information not present in the SMILES format. Since Open Babel does not attempt to generate 3D structure by
default, all of the coordinates are set to zero. However, it is possible to generate 3D structure with the release of Open
Babel 2.2.0 using the --gen3d option.
It’s an open project, so if features are suggested or donated, they’ll be considered as much as anything else on the
drawing board. Some things are pretty clear from the roadmap.
If your product is closed-source or otherwise incompatible with the GPL, you unfortunately cannot link directly to the
code library. You can, however, distribute Open Babel in unmodified form with your products to use the command-line
interface. This is fairly easy because the Open Babel babel program allow reading from the standard input and writing
to the standard output (functioning as a POSIX pipe).
If you decide to distribute binaries, you should either offer users the source if they want, or point them to the Open
Babel website. Note that if you modify the source, you obviously can’t point back to the Open Babel website – the
GPL requires that you distribute the changed source. (Or you can convince us to incorporate the changes and point
back to us.)
What’s not to like with this deal? You can have Open Babel translate foreign file formats for you and can point users
at the website for distribution. You don’t need to write tons of code for all these formats and bug reports can be passed
back to us.
Of course, there’s one catch. You’ll most likely need to add feature-rich support for your file formats. So if you
contribute a small amount of code under the GPL to read/write your files, everything else is handled by Open Babel.
It’s a win-win for everyone. The community benefits by having feature-rich translation code and open file formats.
Your company and its programs benefit by the ability to read just about every format imaginable. Users benefit by
using the programs they need for the tasks they need.
If you’re an academic developer, you certainly should read the previous answer too. It takes little work on your part to
interface with Open Babel and you get a lot in return.
But even if you’re just an academic user, there’s a lot of reasons to contribute. Most of us deal with a variety of file
formats in our work. So it’s useful to translate these cleanly. If a format isn’t currently supported by Open Babel, see
above. If you find bugs please report them. Since it’s open source, you can patch the code yourself, recompile and
have the problem fixed very quickly.
If you’re inclined to write code, the GPL is an excellent option for the academic. You’re the original copyright holder,
so you can do whatever you want with the code, in addition to selling it. But if you’ve also licensed it under the GPL,
no one can distribute it as proprietary (i.e., closed-source) software without your agreement. Fellow academics can
use it directly, learn from it, improve it and contribute back to you. Isn’t that why many of us went into science?
Once licensed under the GPL, the code must remain free to interested parties. If someone modifies it, that code must
still remain under the GPL, free for all.
Certainly the answers for closed-source software and academics also apply for you. Beyond that, if your code is
compatible with the GPL, you can directly use Open Babel and all of the API. This is already happening with the
Avogadro molecular editor, available under the GPL, and many others (see related projects). There’s a lot of code in
Open Babel beyond file translation and more to come. Why reinvent the wheel?
6 Chapter 1. Introduction
, Release 3.0.1
The short answer is that OpenEye Scientific Software employs Matt Stahl, one of the authors of the original Babel.
They released a library called OELib under the GPL that did many things that Babel did. Later they decided to release
the next version of OELib as a closed-source project–their choice for their code. We took the version of OELib still
under GPL and went from there.
If you’d like to see Open Babel licensed differently, we’d suggest asking OpenEye if they’d consider releasing the old
code under a new license, e.g. the LGPL. At that point, we’d consider whether Open Babel should be relicensed or
not. Obviously all copyright holders must agree to the new license.
It’s worth noting that since OpenEye is developing a closed-source library called OEChem and implies one reason for
purchase is in closed-source development products. So we think it’s highly unlikely that OpenEye would allow Open
Babel to become a competitor by relicensing under the LGPL.
The Free Software Foundation maintains a FAQ list about the GNU GPL. The FAQ attempts to address common
questions in an easy-to-read (i.e., not in legal language) form.
1.3 Thanks
Open Babel would not be what it is without the help of a cast of many. We are fundamentally a community project
and aim to offer open development, responsive to users and contributors alike.
In addition to contributors of all sorts, a variety of related projects keep us on our toes. We would also like to thank
everyone who has cited Open Babel in academic and technical literature, posters, and presentations.
• Rich Apodaca
• Joshua Ballanco
• Michael Banck
• Ross Braithwaite
• Daniil Bratashov
• Francesco Bresciani
• Jean Brefort
• Alex Clark
• Joe Corkery
• Steve Constable
• Donald Curtis
• Andrew Dalke
• Daen de Leon
• Menno Deij
• Christian Ehrlicher
• Nick England
• Vincent Favre-Nicolin
• Maxim Fedorovsky
• Fabien Fontaine
• Malcolm Gillies
• Richard Gillilan
• Brian Goldman
1.3. Thanks 7
, Release 3.0.1
• Rajarshi Guha
• Richard Hall
• Bob Hanson
• Marcus Hanwell
• Tommi Hassinen
• Bryan Herger
• David Hoekman
• Geoffrey Hutchison
• Benoît Jacob
• Craig James
• Mikael Johansson
• Stefan Kebekus
• Elmar Krieger
• Erik Kruus
• Daniel Leidert
• Christian Laggner
• Greg Landrum
• Eugene Leitl
• Teng Lin
• Zhiguo Liu
• Daniel Mansfield
• David Mathog
• Gerde Menche
• Dominik Mierzejewski
• Chris Morley
• Paul Mortenson
• Peter Murray-Rust
• Carsten Niehaus
• Anthony Nicholls
• Noel O’Boyle
• Sergei Patchkovskii
• Frank Peters
• Steffen Reith
• Louis Richard
• Roger Sayle
• Ernst-Georg Schmid
• Ajay Shah
• Kevin Shepherd
• Sangwoo Shim
• Andrew Smellie
• Matt Sprague
• Matt Stahl
• Chris Swain
• S Joshua Swamidass
• Bob Tolbert
• Sergey Trepalin
• Tim Vandermeersch
• Ugo Varetto
• Martin Vogt
• Izhar Wallach
• Fredrik Wallner
• Pat Walters
• Pawel Wolinski
• Joerg Kurt Wegner
8 Chapter 1. Introduction
, Release 3.0.1
There are probably many more who have contributed to Babel, OBabel, OELib or directly to Open Babel who are not
listed here. Please help us keep this list updated. THANKS!
1.3. Thanks 9
, Release 3.0.1
10 Chapter 1. Introduction
Chapter 2
Install Open Babel
Open Babel runs on Windows, Linux and MacOSX. You can either install a binary package (the easiest option) or
compile Open Babel yourself (also easy, but much more geek cred).
2.1.1 Windows
Open Babel is available as a binary installer for Windows, both 64-bit (preferred) or 32-bit (indicated by x86 in the
filename). It includes several command-line tools as well as a graphical user interface (GUI). The latest version can
be download from GitHub.
Advanced users may be interested in compiling Open Babel themselves (see Compiling Open Babel).
2.1.2 Linux
Open Babel binary packages are available from many Linux distributions including Ubuntu, OpenSUSE and Fedora.
In general, we recommend using the latest release of Open Babel (currently 3.0.1). If this is not available for your
Linux distribution, you should compile Open Babel yourself .
Open Babel is written in C++. Compiling is the process of turning this C++ into instructions that the computer’s
processor can understand, machine code.
Although pre-compiled (or “binary”) packages are available for several platforms, there are several reasons you might
want to compile Open Babel yourself:
• The current release (3.0.1) of Open Babel is not available for your platform. We recommend always using the
latest release.
• You want more control over the features available. For example, perhaps you want the Python bindings but these
were not included in your distribution.
• You want to use the latest development code.
11
, Release 3.0.1
• You want to add a new feature. It is easy to add new formats or operations to Open Babel as it has a plugin
architecture (see Adding plugins).
• You just want to compile stuff yourself. We understand.
Open Babel can be compiled on Linux, MacOSX, BSDs and other Unixes, and also on Windows (with Cygwin,
MinGW or MSVC).
2.2.1 Requirements
The basic build procedure is the same for all platforms and will be described first. After this, we will look at variations
for particular platforms.
1. The recommended way to build Open Babel is to use a separate source and build directory; for example,
openbabel-2.3.2 and build. The first step is to create these directories:
2. Now you need to run cmake to configure the build. The following will configure the build to use all of the
default options:
$ cd build
$ cmake ../openbabel-2.3.2
3. If you need to specify an option, use the -D switch to cmake. For example, the following line sets the value of
CMAKE_INSTALL_PREFIX and CMAKE_BUILD_TYPE:
$ make
Have a coffee while the magic happens. If you have a multi-processor machine and would prefer an expresso,
try a parallel build instead:
5. And finally, as root (or using sudo) you should install it:
# make install
With the right sort of environment variable magic (see below), you can actually use Open Babel straight from the
build folder. But life is a bit easier if you install it somewhere, either system-wide or locally.
By default, Open Babel is installed in /usr/local/ on a Unix-like system. This requires root access (or sudo).
Even if you do have root access, you may not want to overwrite an existing installation or you may want to avoid
conflicts with a version of Open Babel installed by your package manager.
The solution to all of these problems is to do a local install into a directory somewhere in your home folder. An
additional advantage of a local install is that if you ever want to uninstall it, all you need to do is delete the installation
directory; removing the files from a global install is more work.
1. To configure cmake to install into ~/Tools/openbabel-install, for example, you would do the fol-
lowing:
2. Then you can run make and make install without needing root access:
The GUI is built using the wxWidgets toolkit. Assuming that you have already installed this (see Requirements above),
you just need to configure cmake as follows:
When you run make and make install, the GUI will be automatically built and installed alongside the main Open
Babel library and tools.
Eigen required
If you wish to compile the language bindings supplied in the release, Eigen version 2 or newer is required (see
Requirements above).
2.2.6 Cygwin
The basic build instructions up above work just fine so long as you use the CMake provided by Cygwin rather than a
native Windows installation.
If you get an error about undefined reference to '_xmlFreeTextReader', you need to specify the
location of the XML libraries with the -DLIBXML2_LIBRARIES option:
The language bindings don’t seem to work under Cygwin. If you can get them to work, let us know. Also remember
that anything that uses Cygwin runs slower than a native build using MinGW or MSVC++, so if speed is an issue you
might prefer to compile with MinGW or MSVC++.
2.2.7 MinGW
Open Babel builds out of the box with MinGW. It’s an awkward system to set up though, so here are some step-by-step
instructions. . . TODO
The main Windows build used by Open Babel uses the Microsoft Visual C++ compiler (MSVC).
1. Set up the following environment variables:
a. Add the CMake bin directory to the PATH.
b. (Optional, see Requirements above) Set EIGEN2_INCLUDE_DIR to the location of the top level Eigen
directory (if installed).
c. (Optional, required for GUI) Set WXWIN to the top level directory of wxWidgets (if installed).
2. Install the Microsoft Visual C++ 2010 (or newer) compiler.
We use the Visual C++ 2010 (10.0) Express Edition (available for free).
3. Open a command prompt, and change directory to the windows-vc2008 subdirectory. To configure cmake,
and generate the VC++ project files, run default_build.bat.
4. Double-click on windows-vc2008/build/openbabel.sln to start MSVC++. At the top of the window
just below the menu bar, choose Release in the drop-down box.
5. On the left-hand side, right-click on the ALL_BUILD target, and choose Build.
CMake caches some variables from run-to-run. How can I wipe the cache to start from scratch?
Delete CMakeCache.txt in the build directory. This is also a very useful file to look into if you have any problems.
CMake should find these automatically if they are installed system-wide. If you need to specify them, try using
the -DLIBXML2_LIBRARIES=wherever option with CMake to specify the location of the DLL or SO file, and
-DLIBXML2_INCLUDE_DIR=wherever to specify the location of the header files.
CMake should find these automatically if they are installed system-wide. If you need to specify them, try us-
ing the -DZLIB_LIBRARY=wherever option with CMake to specify the location of the DLL or SO file, and
-DZLIB_INCLUDE_DIR=wherever to specify the location of the header files.
What environment variables affect how Open Babel finds formats, plugins and libraries?
LD_LIBRARY_PATH - Used to find the location of the libopenbabel.so file. You should set this if you get
error messages about not being able to find libopenbabel.so.
BABEL_LIBDIR - Used to find plugins such as the file formats If obabel -L formats does not list any file
formats, then you need to set this environment variable to the directory where the file formats were installed,
typically /usr/local/lib/openbabel/.
BABEL_DATADIR - Used to find the location of the data files used for fingerprints, forcefields, etc. If you get
errors about not being able to find some .txt files, then you should set this to the name of the folder containing
files such as patterns.txt and MACCS.txt. These are typically installed to /usr/local/share/
openbabel.
The CMake option -DENABLE_TESTS=ON or OFF will look after this. To actually run the tests, use make tests.
-DCMAKE_BUILD_TYPE=Debug does a debug build (gcc -g). To revert to a regular build use
-DCMAKE_BUILD_TYPE=Release.
Just specify the target when running Make. The following just builds the Python bindings:
$ make _openbabel
Use the -DRUN_SWIG=ON option with CMake. This requires SWIG 2.0 or newer. If the SWIG executable is not on
the PATH, you will need to specify its location with -DSWIG_EXECUTABLE=wherever.
Use the -DBUILD_DOCS=ON option with CMake. If the Doxygen executable is not on the PATH, you will need to
specify its location with -DDOXYGEN_EXECUTABLE=wherever.
obabel is a command-line program for interconverting between many file formats used in molecular modeling and
computational chemistry and related areas. It can also be used for filtering molecules and for simple manipulation of
chemical data.
3.1 Synopsis
• obabel [-H <help-options>]
• obabel [-i <input-ID>] infile [-o <output-ID>] [-O outfile] [OPTIONS]
3.2 Options
19
, Release 3.0.1
Conversion options
Note: If only input and output files are given, Open Babel will guess the file type from the filename extension. For
information on the file formats supported by Open Babel, please see Supported File Formats and Options. If text is
provided using the -: notation, SMILES are assumed by default if an input format is not specified.
--fillUC <param> For a crystal structure, add atoms to fill the entire unit cell based on the unique
positions, the unit cell and the spacegroup. The parameter can either be strict
(the default), which only keeps atoms inside the unit cell, or keepconnect,
which fills the unit cell but keeps the original connectivity.
--filter <criteria> Filter based on molecular properties. See Filtering molecules from a multi-
molecule file for examples and a list of criteria.
--gen2d Generate 2D coordinates
--gen3d Generate 3D coordinates. You can specify the speed of prediction. See Specifying
the speed of 3D coordinate generation.
-h Add hydrogens (make all hydrogen explicit)
--highlight <substructure color> Highlight substructures in 2D depictions. Valid colors are black,
gray, white, red, green, blue, yellow, cyan, purple, teal and olive. Additional
colors may be specified as hexadecimal RGB values preceded by #. Multiple
substructures and corresponding colors may be specified.
-i <format-ID> Specifies input format. See Supported File Formats and Options.
-j, --join Join all input molecules into a single output molecule entry
-k Translate computational chemistry modeling keywords. See the computational
chemistry formats (Computational chemistry formats), for example GAMESS In-
put (gamin, inp) and Gaussian Input (com, gau, gjc, gjf).
-l <#> For multiple entry input, stop import with molecule # as the last entry
--largest <#N descriptor> Only convert the N molecules which have the largest values of the specified
descriptor. Preceding the descriptor by ~ inverts this filter.
-m Produce multiple output files, to allow:
• Splitting one input file - put each molecule into consecutively numbered
output files
• Batch conversion - convert each of multiple input files into a specified out-
put format
--minimize <options> Forcefield energy minimization. See Forcefield energy and minimization.
-o <format-ID> Specifies output format. See Supported File Formats and Options.
-p <pH> Add hydrogens appropriate for pH (use transforms in phmodel.txt)
--partialcharge <charge-method> Calculate partial charges by the specified method. List available
methods using obabel -L charges.
--property <name value> Add or replace a property (for example, in an SD file)
-r Remove all but the largest contiguous fragment (strip salts)
--readconformer Combine adjacent conformers in multi-molecule input into a single molecule. If a
molecule has the same structure as the preceding molecule, as determined from its
SMILES, it is not output but its coordinates are added to the preceding molecule
as an additional conformer. There can be multiple groups of conformers, but the
molecules in each group must be adjacent.
-s <SMARTS> Convert only molecules matching the SMARTS pattern specified
-s <filename.xxx> Convert only molecules with the molecule in the file as a substructure
--separate Separate disconnected fragments into individual molecular records
3.2. Options 21
, Release 3.0.1
--smallest <#N descriptor> Only convert the N molecules which have the smallest values of the spec-
ified descriptor. Preceding the descriptor by ~ inverts this filter.
--sort Output molecules ordered by the value of a descriptor. See Sorting molecules.
--title <title> Add or replace molecular title
--unique, --unique <param> Do not convert duplicate molecules. See Remove duplicate molecules.
--writeconformers Output multiple conformers as separate molecules
-x <options> Format-specific output options. use -H <format-ID> to see options allowed
by a particular format, or see the appropriate section in Supported File Formats
and Options.
-v <SMARTS> Convert only molecules NOT matching the SMARTS pattern specified
-z Compress the output with gzip (not on Windows)
3.3 Examples
The examples below assume the files are in the current directory. Otherwise you may need to include the full path to
the files e.g. /Users/username/Desktop/mymols.sdf and you may need to put quotes around the filenames
(especially on Windows, where they can contain spaces).
Standard conversion:
obabel ethanol.xyz -O ethanol.pdb
babel ethanol.xyz ethanol.pdb
Conversion if the files do not have an extension that describes their format:
obabel -ixyz ethanol.aa -opdb -O ethanol.bb
babel -ixyz ethanol.aa -opdb ethanol.bb
Molecules from multiple input files (which can have different formats) are normally combined in the output file:
obabel ethanol.xyz acetal.sdf benzene.cml -O allmols.smi
Multiple input files can be converted in batch format too. To convert all files ending in .xyz (*.xyz) to PDB files,
you can type:
obabel *.xyz -opdb -m
Open Babel will not generate coordinates unless asked, so while a conversion from SMILES to SDF will generate a
valid SDF file, the resulting file will not contain coordinates. To generate coordinates, use either the --gen3d or the
--gen2d option:
If you want to remove all hydrogens (i.e. make them all implicit) when doing the conversion the command would be:
If you want to add hydrogens (i.e. make them all explicit) when doing the conversion the command would be:
If you want to add hydrogens appropriate for pH7.4 when doing the conversion the command would be:
The protonation is done on an atom-by-atom basis so molecules with multiple ionizable centers will have all centers
ionized.
Of course you don’t actually need to change the file type to modify the hydrogens. If you want to add all hydrogens
the command would be:
Some functional groups e.g. nitro or sulphone can be represented either as [N+]([O-])=O or N(=O)=O. To convert
all to the dative bond form:
If you only want to convert a subset of molecules you can define them using -f and -l. To convert molecules 2-4 of
the file mymols.sdf type:
Alternatively you can select a subset matching a SMARTS pattern, so to select all molecules containing bromobenzene
use:
You can also select the subset that do not match a SMARTS pattern, so to select all molecules not containing bro-
mobenzene use:
You can of course combine options, so to join molecules and add hydrogens type:
Files compressed with gzip are read transparently, whether or not they have a .gz suffix:
On platforms other than Windows, the output file can be compressed with gzip, but note if you don’t specify the .gz
suffix it will not be added automatically, which could cause problems when you try to open the file:
This next example reads the first 50 molecules in a compressed dataset and prints out the SMILES of those containing
a pyridine ring, together with the index in the file, the ID (taken from an SDF property) as well as the output index:
3.3. Examples 23
, Release 3.0.1
N1(CCN(CC1)c1c(cc2c3c1OCC(n3cc(c2=O)C(=O)O)C)F)C 3 100146 1
c1(c(=O)c2c(n(c1)OC)c(c(N1CC(CC1)CNCC)c(c2)F)F)C(=O)O 6 100195 2
S(=O)(=O)(Nc1ncc(cc1)C)c1c2c(c(N(C)C)ccc2)ccc1 22 100589 3
c1([nH]c2c(c1)cccc2)C(=O)N1CCN(c2c(N(CC)CC)cccn2)CC1 46 101536 4
Individual file formats may have additional formatting options. These are listed in the documentation for the individual
formats (see Supported File Formats and Options) or can be shown using the -H <format-Id> option, e.g. -H
cml.
To use these additional options, input format options are preceded by -a, e.g. -as. Output format options, which are
much more common, are preceded by -x, e.g. -xn. So to read the 2D coordinates (rather than the 3D) from a CML
file and generate an SVG file displaying the molecule on a black background, the relevant options are used as follows:
The command line option --append adds extra information to the title of the molecule.
The information can be calculated from the structure of the molecule or can originate from a property attached to the
molecule (in the case of CML and SDF input files). It is used as follows:
MW is the ID of a descriptor which calculates the molecular weight of the molecule, and CAT_NO is a property of the
molecule from the SDF input file. The values of these are added to the title of the molecule. For input files with many
molecules these additions are specific to each molecule. (Note that the related option --addtotitle simply adds
the same text to every title.)
The append option only takes one parameter, which means that it may be necessary to enclose all of the descriptor IDs
or property names together in a single set of quotes.
If the name of the property in the SDF file (internally the Attribute in OBPairData) contains spaces, these spaces
should be replaced by underscore characters, ‘_’. So the example above would also work for a property named CAT
NO.
By default, the extra items are added to the title separated by spaces. But if the first character in the parameter is a
punctuation character other than ‘_’, it is used as the separator instead. If the list starts with “t”, a tab character is used
as a separator.
The command line option --conformer allows performing conformer searches using a range of different algorithms
and options:
or if you also wish to generate 3D coordinates, followed by conformer searching try something like this:
It takes one parameter which probably needs to be enclosed in double quotes to avoid confusing the shell or operating
system. (You don’t need the quotes with the Windows GUI.) The parameter contains one or more conditional tests.
By default, these have all to be true for the molecule to be converted. As well as this implicit AND behaviour, you
can write a full Boolean expression (see below). As you can see, there can be spaces or not in sensible places and the
conditional tests could be separated by a comma or semicolon.
obabel -L descriptors
Faster filtering
Open Babel provides a number of utility file formats (see Supported File Formats and Options). Of these, using the
copy format as the output format is particularly useful when filtering (see Copy raw text (copy)). This copies the
content of the molecular file directly from input to output. If you are not converting the molecules between different
formats, this procedure is much faster and avoids any possibility of information loss.
In addition, if you are converting SDF files and are filtering based on the title, you should consider using -aT (see
MDL MOL format (mdl, mol, sd, sdf)). Rather than perceiving the chemistry of the entire molecule, this option will
only read in the title.
The descriptor names are case-insensitive. With the property names currently, you need to get the case right. Both
types of identifier can contain letters, numbers and underscores, ‘_’. Properties can contain spaces, but then when
writing the name in the filter parameter, you need to replace them with underscores. So in the example above, the test
would also be suitable for a property ‘ROTATABLE BOND’.
Open Babel uses a SDF-like property (internally this is stored in the class OBPairData) in preference to a descriptor if
one exists in the molecule. So with the example file, which can be found here:
converts only a molecule with a property logP=10.900, since the others do not have this property and logP, being also
a descriptor, is calculated and is always much less than 5.
If a property does not have a conditional test, then it returns true only if it exists. So:
converts only those molecules with a ROTATABLE_BOND property and a molecular weight less than 130. If you
wanted to also include all the molecules without ROTATABLE_BOND defined, use:
The ! means negate. AND can be & or &&, OR can be | or ||. The brackets are not strictly necessary here because
& has precedent over | in the normal way. If the result of a test doesn’t matter, it is parsed but not evaluated. In the
example, the expression in the brackets is not evaluated for molecules without a ROTATABLE_BOND property. This
doesn’t matter here, but if evaluation of a descriptor involved a lot of computation, it would pay to include it late in
the boolean expression so that there is a chance it is skipped for some molecules.
Descriptors must have a conditional test and it is an error if they don’t. The default test, as used by MW or logP, is a
numerical one, but the parsing of the text, and what the test does is defined in each descriptor’s code (a virtual function
in the OBDescriptor class). Three examples of this are described in the following sections.
The descriptor title, when followed by a string (here enclosed by single quotes), does a case-sensitive string compari-
son. (‘ethanol’ wouldn’t match anything in the example file.) The comparison does not have to be just equality:
converts molecules with titles Dimethyl Ether and Ethanol in the example file.
It is not always necessary to use the single quotes when the meaning is unambiguous: the two examples above work
without them. But a numerical, rather than a string, comparison is made if both operands can be converted to numbers.
This can be useful:
will convert the molecules with titles 56 123 and 126, which is probably what you wanted.
converts only 123 and 126 because a string comparison is being made.
String comparisons can use * as a wildcard if used as the first or last character of the string (anywhere else a * is
a normal character). So --filter "title='*ol'" will match molecules with titles ‘methanol’, ‘ethanol’ etc.
and --filter "title='eth*' will match ‘ethanol’, ‘ethyl acetate’, ‘ethical solution’ etc. Use a * at both the
first and last characters to test for the occurrence of a string, so --filter "title='*ol*'" will match ‘oleum’,
‘polonium’ and ‘ethanol’.
This descriptor will do a SMARTS test (substructure and more) on the molecules. The smarts ID can be abbreviated
to s and the = is optional. More than one SMARTS test can be done:
This provides a more flexible alternative to the existing -s and -v options, since the SMARTS descriptor test can be
combined with other tests.
will convert only ethanol. It uses the default parameters for InChI comparison, so there may be some messages from
the InChI code. There is quite a lot of flexibility on how the InChI is presented (you can miss out the non-essential
bits):
The comparison of the InChI string is done only as far as the parameter’s length. This means that we can take advantage
of InChI’s layered structure:
For information on using obabel for substructure searching and similarity searching, see Molecular fingerprints and
similarity searching.
The --sort option is used to output molecules ordered by the value of a descriptor:
If the descriptor desc provides a numerical value, the molecule with the smallest value is output first. For descriptors
that provide a string output the order is alphabetical, but for the InChI descriptor a more chemically informed order is
used (e.g. “CH4” is before than “C2H6”, “CH4” is less than “ClH” hydrogen chloride).
The order can be reversed by preceding the descriptor name with ~, e.g.:
As a shortcut, the value of the descriptor can be appended to the molecule name by adding a + to the descriptor, e.g.:
The --unique option is used to remove, i.e. not output, any chemically identical molecules during conversion:
The optional parameter param defines what is regarded as “chemically identical”. It can be the name of any descriptor,
although not many are likely to be useful. If param is omitted, the InChI descriptor is used. Other useful descriptors
are ‘cansmi’ and ‘cansmiNS’ (canonical SMILES, with and without stereochemical information),’title’ and truncated
InChI (see below).
A message is output for each duplicate found:
Clearly, this is more useful if each molecule has a title. The (#1) is the number of duplicates found so far.
If you wanted to identify duplicates but not output the unique molecules, you could use the null format:
It is possible to relax the criterion by which molecules are regarded as “chemically identical” by using a truncated
InChI specification as param. This takes advantage of the layered structure of InChI. So to remove duplicates, treating
stereoisomers as the same molecule:
Truncated InChI specifications start with / and are case-sensitive. param can be a concatenation of these e.g. /
nochg/noiso:
The input molecules do not have to be in a single file. So to collect all the unique molecules from a set of MOL files:
There is a limited amount of support for representing common chemical groups by an alias, e.g. benzoic acid as
Ph-COOH, with two alias groups. Internally in Open Babel, the molecule usually has a ‘real’ structure with the alias
names present as only an alternative representation. For MDL MOL and SD files alias names can be read from or
written to an ‘A’ line. The more modern RGroup representations are not yet recognized. Reading is transparent; the
alias group is expanded and the ‘real’ atoms given reasonable coordinates if the the molecule is 2D or 3D. Writing in
alias form, rather than the ‘real’ structure, requires the use of the -xA option. SVGFormat will also display any aliases
present in a molecule if the -xA option is set.
The alias names that are recognized are in the file superatoms.txt which can be edited.
Normal molecules can have certain common groups given alternative alias representation using the --genalias
option. The groups that are recognized and converted are a subset of those that are read. Displaying or writing them
still requires the -xA option. For example, if aspirin.smi contained O=C(O)c1ccccc1OC(=O)C, it could be
displayed with the aliases COOH and OAc by:
Open Babel supports a number of forcefields which can be used for energy evaluation as well as energy minimization.
The available forcefields as listed as follows:
C:\>obabel -L forcefields
GAFF General Amber Force Field (GAFF).
Ghemical Ghemical force field.
MMFF94 MMFF94 force field.
MMFF94s MMFF94s force field.
UFF Universal Force Field.
To evaluate a molecule’s energy using a forcefield, use the --energy option. The energy is put in an OB-
PairData object “Energy” which is accessible via an SDF or CML property or --append (to title). Use --ff
<forcefield_id> to select a forcefield (default is Ghemical) and --log for a log of the energy calculation. The
simplest way to output the energy is as follows:
To perform forcefield minimization, the --minimize option is used. The following shows typical usage:
Note that for both --energy and --minimize, hydrogens are made explicit before energy evaluation.
The --align option aligns molecules to the first molecule provided. It is typically used with the -s option to specify
an alignment based on a substructure:
Here, only molecules matching the specified SMARTS pattern are converted and are aligned by having all their atom
coordinates modified. The atoms that are used in the alignment are those matched by SMARTS in the first output
molecule. The subsequent molecules are aligned so that the coordinates of atoms equivalent to these are as nearly as
possible the same as those of the pattern atoms. The atoms in the various molecules can be in any order. Tha alignment
ignores hydrogen atoms but includes symmetry. Note that the standalone program obfit has similar functionality.
The first input molecule could also be part of the data set:
This form is useful for ensuring that a particular substructure always has the same orientation in a 2D display of a set
of molecules. 0D molecules, for example from SMILES, are given 2D coordinates before alignment.
See documentation for the -s option for its other possible parameters. For example, the matching atoms could be
those of a molecule in a specified file.
If the -s option is not used, all of the atoms in the first molecule are used as pattern atoms. The order of the atoms
must be the same in all the molecules.
The output molecules have a property (represented internally as OBPairData) called rmsd, which is a measure of the
quality of the fit. To attach it to the title of each molecule use --append rmsd.
To output the two conformers closest to the first conformer in a dataset:
When you use the --gen3d option, you can specify the speed and quality. The following shows typical usage:
option description
fastest No cleanup
fast Force field cleanup (100 cycles)
med (default) Force field cleanup (100 cycles) + Fast rotor search (only one permutation)
slow Force field cleanup (250 cycles) + Fast rotor search (permute central rotors)
slowest Force field cleanup (500 cycles) + Slow rotor search
better Same as slow
best Same as slowest
dist, dg Use distance geometry method (unstable)
You can also specify the speed by an integer from 1 (slowest) to 5 (fastest).
The obabel command line program converts chemical objects (currently molecules or reactions) from one file format
to another. The Open Babel graphical user interface (GUI) is an alternative to using the command line and has the
same capabilities. Since Open Babel 2.3, the GUI is available cross-platform on Windows, Linux and MacOSX. On
Windows, you can find it in the Start Menu in the Open Babel folder; on Linux and MacOSX, the GUI can be started
with the obgui command.
Since the functionality of the GUI mirrors that of obabel, you should consult the previous chapter to learn about
available features and how to use them. This chapter describes the general use of the GUI and then focuses on features
that are specific to the GUI.
Although the GUI presents many options, the basic operation is straightforward:
• Select the type of the type of the input file from the dropdown list.
• Click the “. . . ” button and select the file. Its contents are displayed in the textbox below.
• Choose the output format and file in a similar way. You can merely display the output without saving it by not
selecting an output file or by checking “Output below only..”.
• Click the “Convert” button.
The message window below the button gives the number of molecules converted, and the contents of the output file
are displayed.
By default, all the molecules in an input file are converted if the output format allows multiple molecules.
4.2 Options
The options in the middle are those appropriate for the type of chemical object being converted (molecule or reaction)
and the input and output formats. They are derived from the description text that is displayed with the -Hxxx option
in the command line interface and with the “Format info” buttons here. You can switch off the display of any of the
various types of option using the View menu if the screen is getting too cluttered.
33
, Release 3.0.1
You can select multiple input files in the input file dialog in the normal way (for example, using the Control key in
Windows). In the input filename box, each filename is displayed relative to the path shown just above the box, which
is the path of the first file. You can display any of the files by moving the highlight with Tab/Shift Tab, Page Up/Down,
the mouse wheel, or by double clicking.
Selecting one or more new file names normally removes those already present, but they can instead be appended by
holding the Control key down when leaving the file selection dialog.
Files can be also be dragged and dropped (e.g. from Windows Explorer), adding the file when the Control key is
pressed, replacing the existing files when it is not.
Normally each file is converted according to its extension and the input files do not have to be all the same, but if you
want to use non-standard file names set the checkbox “Use this format for all input files. . . ”
If you want to combine multiple molecules (from one or more files) into a single molecule with disconnected parts,
use option “Join all input molecules. . . ”
When input filenames are typed in directly, any of them can contain the wildcard characters * and ?. Typing Enter
will replace these by a list of the matching files. The wildcarded names can be restored by typing Enter while holding
down the Shift key. The original or the expanded versions will behave the same when the “Convert” button is pressed.
By including the wildcard * in both the input and output filenames you can carry out batch conversion. Suppose
there were files first.smi, second.smi, third.smi. Using *.smi as the input filename and *.mol as the
output filename would produce three files first.mol, second.mol and third.mol. If the output filename was
NEW_*.mol, then the output files would be NEW_first.mol, etc.
By checking the “Input below. . . ” checkbox you can type the input text directly. The text box changes colour to remind
you that it is this text and not the contents of any files that will be converted.
The output file name can be fully specified with a path, but if it is not, then it is considered to be relative to the input
file path.
The chemical structures being converted can be displayed (as SVG) in an external program. By default this is Firefox
but it can be changed from an item on the View menu (for instance, Opera and Chrome work fine). When “Display
in firefox” (under the output file name) is checked, the structures will be shown in a new Firefox tab. With multiple
molecules the display can be zoomed (mousewheel) and panned (dragging with mouse button depressed). Up to 100
molecules are easily handled but with more the system may be slow to manipulate. It may also be slow to generate,
especially if 2D atom coordinates have to be calculated (e.g.from SMILES). A new Firefox tab is opened each time
Convert is pressed.
It is likely that you will only be interested in a subset of the large range of formats handled by Open Babel. You
can restrict the choice offered in the dropdown boxes, which makes routine selection easier. Clicking “Select set of
formats” on the View menu allows the formats to be displayed to be selected. Subsequently, clicking “Use restricted
set of formats” on the View menu toggles this facility on and off.
Using a restricted set overcomes an irritating bug in the Windows version. In the file Open and Save dialogs the
files displayed can be filtered by the current format, All Chemical Formats, or All Files. The All Chemical Formats
filter will only display the first 30 possible formats (alphabetically). The All Files will indeed display all files and the
conversion processes are unaffected.
Most of the interface parameters, such as the selected format and the window size and position, are remembered
between sessions.
Using the View menu, the input and output text boxes can be set not to wrap the text. At present you have to restart the
program for this to take effect.
The message box at the top of the output text window receives program output on error and audit logging, and some
progress reports. It can be expanded by dragging down the divider between the windows.
In the Windows distribution, there are three chemical files included to try out:
• serotonin.mol which has 3D atom coordinates
• oxamide.cml which is 2D and has a large number of properties that will be seen when converting to SDF
• FourSmallMols.cml which (unsurprisingly) contains four molecules with no atom coordinates and can be used
to illustrate the handling of multiple molecules:
Setting the output format to SMI (which is easy to see), you can convert only the second and third molecules by
entering 2 and 3 in the appropriate option boxes. Or convert only molecules with C-O single bonds by entering
CO in the SMARTS option box.
This chapter gives step-by-step descriptions on how to use Open Babel’s graphical user interface (GUI) to carry out
some common tasks. It may also be used as the basis of a practical on cheminformatics, and to this end several
questions are interspersed with the tutorial text.
For more information on the GUI itself, see the previous chapter.
The most common use of Open Babel is to convert chemical file formats. The following examples show how this is
done.
• Set the output file format to MOL and the output filename to file:4ins.mol in the Work folder
• Now click CONVERT
37
, Release 3.0.1
Rather than use input and output files, it is possible to paste the contents of a chemical file format into the input box,
and see the results of the conversion in the output box.
Here we will try this with the SMILES format, and illustrate how stereochemistry is handled by SMILES:
Screenshot
There are four bonds from each stereocentre. Open Babel carefully chooses which bond to set as the stereobond
by considering whether the bond connects two stereocentres, whether the bond is part of a ring, and the angular
distance between bonds.
In the resulting depiction, note that Open Babel only sets a single stereobond for a chiral centre. This is not ambiguous
- it means that the stereobond is either above or below the plane, with the remaining three bonds the opposite site of
the plane.
Q. Can you figure out whether the depiction of the tetrahedral centre is consistent with the SMILES string?
Note: Open Babel 2.3.2 introduces a twisted double bond to indicate unknown cis/trans stereochemistry (e.g. IC=CF).
See here for more info.
Setup
We are going to use a dataset of 16 benzodiazepines. These all share the following substructure (image from
Wikipedia):
• Create a folder on the Desktop called Work and save benzodiazepines.sdf there
• Set up a conversion from SDF to SMI and set benzodiazepines.sdf as the input file
• Tick Display in Firefox
• Click CONVERT
Remove duplicates
If you look carefully at the depictions of the first and last molecules (top left and bottom right) you will notice that
they depict the same molecule.
Q. Look at the SMILES strings for the first and last molecules. If the two molecules are actually the same, why are
the two SMILES strings different? (Hint: try using CAN - canonical SMILES instead of SMI.)
We can remove duplicates based on the InChI (for example):
• Tick the box beside remove duplicates by descriptor and enter inchi as the descriptor
• Click CONVERT
Duplicates can be removed based on any of the available descriptors. The full list can be found in the menu under
Plugins, descriptors.
Q. Are any of the other descriptors useful for removing duplicates?
Filtering by substructure
The SMILES string for this molecule is c1ccccc1F. This is also a valid SMARTS string.
Q. Use the SMARTSviewer at the ZBH Center for Bioinformatics, University of Hamburg, to verify the meaning
of the SMARTS string c1ccccc1F.
Filtering a dataset of molecules by substructure is particularly useful if you need to remove molecules with prob-
lematic functional groups. For example, particular functional groups are associated with toxicological problems.
Filter by descriptor
Screenshot
As discussed above, Open Babel provides several descriptors. Here we will focus on the molecular weight, MW.
To begin with, let’s show the molecular weights in the depiction:
• Clear the existing title by entering a single space into the box Add or replace molecule title
• Set the title to the molecular weight by entering MW into the box Append properties or descriptors in list to title
• Click CONVERT
You should see the molecular weight below each molecule in the depiction. Notice also that the SMILES output has
the molecular weight beside each molecule. This could be useful for preparing a spreadsheet with the SMILES string
and various calculated properties.
Now let’s sort by molecular weight:
Filter by property
The SDF format, in common with some other file formats, allows property fields for each molecule. Open Babel
allows the user to filter using these, add the value to the title, remove or replace values.
Q. If | (the pipe symbol, beside Z on the UK keyboard) signifies Boolean OR, how would you instead convert all
those molecules that do not have molecular weights between 300 and 320?
Note: Open Babel 2.3.2 allows specific substructures to be highlighted in a depiction. It also allows depictions to be
aligned based on a substructure.
Open Babel provides a format called the fs -- fastsearch index which should be used when searching large
datasets (like ChEMBL) for molecules similar to a particular query. There are faster ways of searching (like using a
chemical database) but FastSearch is convenient, and should give reasonable performance for most people.
To demonstrate similarity searching, we will use the first 1000 molecules in the latest release of ChEMBL:
• Download the 2D SDF version of ChEMBL, chembl_nn.sdf.gz, from the ChEMBLdb download site and
save in your Work folder. (Note: this is a gzipped file, but Open Babel will handle this without problems.)
• Set up an SDF to SDF conversion, set chembl_nn.sdf.gz as the input file and 1000_chembl.sdf as the
output file.
• Only convert the first 1000 molecules by entering 1000 in the box End import at molecule # specified.
• Click CONVERT
We can going to use the following structure for substructure and similarity searching. It can be represented by the
SMILES string Nc1ccc(N)cc1.
Behind the scenes, the FastSearch index simply stores a path-based binary fingerprint for each molecule. When
used to search, similarity is measured based on the Tanimoto coefficient. For exact search, hits are verified by Open
Babel’s graph isomorphism matcher.
Next, we will create a FastSearch index for this dataset of 1000 molecules:
• Convert 1000_chembl.sdf from SDF to FS format, with an output filename of 1000_chembl.fs
By using this FastSearch index, the speed of substructure and similarity searching is much improved. First of all, let’s
do a substructure search:
• Set up a conversion from FS to SMILES with 1000_chembl.fs as the input file. Tick the box for Output
below only and Display in Firefox
• Enter Nc1ccc(N)cc1 into the box Convert only if match SMARTS or mol in file
• Click CONVERT
Q. How does the speed of the substructure search compare to if you used 1000_chembl.sdf as the input file
instead?
Next, let’s find the 5 most similar molecules to the same query. The Tanimoto coefficient of a path-based fingerprint
is used as the measurement of similarity. This has a value from 0.0 to 1.0 (maximum similarity) and we will display
the value below each molecule:
• Set up the FS to SMILES conversion as before, and again enter Nc1ccc(N)cc1 into the box Convert only if
match SMARTS or mol in file
• Enter 5 into the box Do similarity search: #mols or # as min Tanimoto
• Tick the box Add Tanimoto coefficient to title in similarity search
• Click CONVERT
Q. Look at the 5 most similar molecules. Can you tell why they were regarded as similar to the query?
Molecular fingerprints are a way of encoding the structure of a molecule. The most common type of fingerprint
is a series of binary digits (bits) that represent the presence or absence of particular substructures in the molecule.
Comparing fingerprints allows you to determine the similarity between two molecules, to find matches to a query
substructure, etc.
Open Babel provides several fingerprints of different types:
• Fingerprint format: the path-based fingerprint FP2; substructure based fingerprints FP3, FP4 and MACCS;
user-defined substructures
• Multilevel Neighborhoods of Atoms (MNA) (mna): a circular fingerprint
• MolPrint2D format (mpd): a circular fingerprint
• Spectrophores™: a fingerprint that encodes the 3D structure of a molecule
The next two sections describe the Fingerprint format and Spectrophores in depth. For the others, see the relevant
sections listed above.
The Fingerprint format (fpt) is a utility file format that provides access to a number of substructure-based fingerprints,
and that enables the user to carry out similarity and substructure searching. You can see the available fingerprints using
the following command:
$ babel -L fingerprints
FP2 Indexes linear fragments up to 7 atoms.
FP3 SMARTS patterns specified in the file patterns.txt
FP4 SMARTS patterns specified in the file SMARTS_InteLigand.txt
MACCS SMARTS patterns specified in the file MACCS.txt
45
, Release 3.0.1
For each of these fragments the atoms, bonding and whether they constitute a complete ring is
recorded and saved in a set so that there is only one of each fragment type. Chemically identical
versions, (i.e. ones with the atoms listed in reverse order and rings listed starting at different atoms)
are identified and only a single canonical fragment is retained.
Each remaining fragment is assigned a hash number from 0 to 1020 which is used to set a bit in a
1024 bit vector
• FP3 uses a series of SMARTS queries stored in patterns.txt
• FP4 uses a series of SMARTS queries stored in SMARTS_InteLigand.txt
• MACCS uses the SMARTS patterns in MACCS.txt
Note: Note that you can tailor the latter three fingerprints to your own needs by adding your own SMARTS queries
to these files. On UNIX and Mac systems, these files are frequently found in /usr/local/share/openbabel
under a directory for each version of Open Babel.
See also:
The sections on the fingerprint and fastsearch formats contain additional detail.
Small datasets
For relatively small datasets (<10,000’s) it is possible to do similarity searches without the need to build a similarity
index, however larger datasets (up to a few million) can be searched rapidly once a fastsearch index has been built.
On small datasets these fingerprints can be used in a variety of ways. The following command gives you the Tanimoto
coefficient between a SMILES string in mysmiles.smi and all the molecules in mymols.sdf:
The default fingerprint used is the FP2 fingerprint. You change the fingerprint using the f output option as follows:
The -s option of babel is used to filter by SMARTS string. If you wanted to know the similarity only to the
substituted bromobenzenes in mymols.sdf then you might combine commands like this (note: if the query molecule
does not match the SMARTS string this will not work as expected, as the first molecule in the database that matches
the SMARTS string will instead be used as the query):
If you don’t specify a query file, babel will just use the first molecule in the database as the query:
MOL_00000067
MOL_00000083 Tanimoto from MOL_00000067 = 0.810811
MOL_00000105 Tanimoto from MOL_00000067 = 0.833333
MOL_00000296 Tanimoto from MOL_00000067 = 0.425926
MOL_00000320 Tanimoto from MOL_00000067 = 0.534884
MOL_00000328 Tanimoto from MOL_00000067 = 0.511111
MOL_00000338 Tanimoto from MOL_00000067 = 0.522727
MOL_00000354 Tanimoto from MOL_00000067 = 0.534884
MOL_00000378 Tanimoto from MOL_00000067 = 0.489362
MOL_00000391 Tanimoto from MOL_00000067 = 0.489362
10 molecules converted
Large datasets
On larger datasets it is necessary to first build a fastsearch index. This is a new file that stores a database of fingerprints
for the files indexed. You will still need to keep both the new .fs fastsearch index and the original files. However, the
new index will allow significantly faster searching and similarity comparisons. The index is created with the following
command:
This builds mymols.fs with the default fingerprint (unfolded). The following command uses the index to find the 5
most similar molecules to the molecule in query.mol:
Small datasets
This command will find all molecules containing 1,2-dicyanobenzene and return the results as SMILES strings:
If all you want output are the molecule names then adding -xt will return just the molecule names:
The parameter of the -s option in these examples is actually SMARTS, which allows a richer matching specification,
if required. It does mean that the aromaticity of atoms and bonds is significant; use [#6] rather than C to match both
aliphatic and aromatic carbon.
The -s option’s parameter can also be a file name with an extension. The file must contain a molecule, which means
only substructure matching is possible (rather than full SMARTS). The matching is also slightly more relaxed with
respect to aromaticity.
Large datasets
First of all, you need to create a fastsearch index (see above). The index is created with the following command:
Substructure searching is as for small datasets, except that the fastsearch index is used instead of the original file. This
command will find all molecules containing 1,2-dicyanobenzene and return the results as SMILES strings:
If all you want output are the molecule names then adding -xt will return just the molecule names:
This case study uses a combination of the techniques described above for similarity searching using large databases and
using small databases. Note that we are using the default fingerprint for all of these analyses. The default fingerprint
is FP2, a path-based fingerprint (somewhat similar to the Daylight fingerprints).
(1) Download Version 2 of ChEMBLdb from ftp://ftp.ebi.ac.uk/pub/databases/chembl/ChEMBLdb/releases/.
(2) After unzipping it, make a fastsearch index (this took 18 minutes on my machine for the 500K+ molecules):
(3) Let’s use the first molecule in the sdf file as a query. Using Notepad (or on Linux, head -79 chembl_02.
sdf) extract the first molecule and save it as first.sdf. Note that the molecules in the ChEMBL sdf do not
have titles; instead, their IDs are stored in the “chebi_id” property field.
(4) This first molecule is 100183. Check its ChEMBL page. It’s pretty weird, but is there anything similar in
ChEMBLdb? Let’s find the 5 most similar molecules:
(5) The results are stored in mostsim.sdf, but how similar are these molecules to the query?:
(6) That’s all very well, but it would be nice to show the ChEBI IDs. Let’s set the title field of mostsim.sdf to
the content of the “chebi_id” property field, and repeat step 5:
(7) Here are the ChEMBL pages for these molecules: 100183, 124893, 206983, 207022, 607087. I think it is
fair to say that they are pretty similar. In particular, the output states that 206983 and 207022 are possible
superstructures of the query molecule, and that is indeed true.
(8) How many of the molecules in the dataset are superstructures of the molecule in first.sdf? To do this and
to visualize the large numbers of molecules produced, we can output to SVG format (see SVG 2D depiction
(svg)):
Note that obabel has been used here because of its more flexible option handling.
This command does a substructure search and puts the 47 matching structures in the file out.svg.
This can be viewed in a browser like Firefox, Opera or Chrome (but not Internet Explorer). The display
will give an overall impression of the set of molecules but details can be seen by zooming in with the
mousewheel and panning by dragging with a mouse button depressed.
(9) The substructure that is being matched can be highlighted in the output molecules by adding another parameter
to the -s option. Just for variety, the display is also changed to a black background, ‘uncolored’ (no element-
specific coloring), and terminal carbon not shown explicitly. (Just refresh your browser to see the modified
display.)
This highlighting option also works when the -s option is used without fastsearch on small datasets.
(10) The substructure search here has two stages. The indexed fingerprint search quickly produces 62 matches from
the 500K+ molecules in the dataset. Each of these is then checked by a slow detailed isomorphism check. There
are 15 false positives from the fingerprint stage. These are of no significance, but you can see them using:
The fingerprint search is unaffected but the selection in the second stage is inverted.
6.2 Spectrophores™
6.2.1 Introduction
Spectrophores1 are one-dimensional descriptors generated from the property fields surrounding the molecules. This
technology allows the accurate description of molecules in terms of their surface properties or fields. Comparison of
molecules’ property fields provides a robust structure-independent method of aligning actives from different chemical
classes. When applied to molecules such as ligands and drugs, Spectrophores can be used as powerful molecular
descriptors in the fields of chemoinformatics, virtual screening, and QSAR modeling.
Commercial support for Spectrophores is available from Silicos NV, the developers of the Spectrophore technology.
Silicos is a fee-for-service company empowering open source chemo-informatics virtual screening technologies for
the discovery of novel lead compounds and database characterization. Silicos fully endorses the concept of open
innovation and open source software development, and provides its clients with a wide variety of computational
chemistry-based lead discovery services, including Open Babel support, training and code development. Please
visit Silicos for more details.
The computation of Spectrophores is independent of the position and orientation of the molecule and this enables
easy and fast comparison of Spectrophores between different molecules. Molecules having similar three-dimensional
properties and shapes always yield similar Spectrophores. A Spectrophore is calculated by surrounding the three-
dimensional conformation of the molecule by a three-dimensional arrangement of points, followed by calculating the
interaction between each of the atom properties and the surrounding the points. The three-dimensional arrangement of
the points surrounding the molecule can be regarded as an ‘artificial’ cage or receptor, and the interaction calculated
between the molecule and the cage can be regarded as an artificial representation of an affinity value between molecule
and cage. Because the calculated interaction is dependent on the relative orientation of the molecule within the cage,
the molecule is rotated in discrete angles and the most favorable interaction value is kept as final result. The angular
stepsize at which the molecule is rotated along its three axis can be specified by the user and influences the accuracy
of the method.
The Spectrophore code was developed by Silicos NV, and donated to the OpenBabel project in July 2010 (see sidebar
for information on commercial support). Spectrophores can be generated either using the command-line application
obspectrophore (see next section) or through the API (OBSpectrophore, as described in the :obapi:‘API
documentation <OBSpectrophore>‘).
6.2.2 obspectrophore
Usage
Parameter details
Spectrophores will be calculated for each molecule in the input file. The filetype
is automatically detected from the file extension.
-n <type> The type of normalization that should be performed
Valid values are (without quotes):
• No (default)
• ZeroMean
• UnitStd
• ZeroMeanAndUnitStd
-a <accuracy> The required accuracy expressed as the angular stepsize
Only the following discrete values are allowed: 1, 2, 5, 10, 15, 20 (default), 30,
36, 45, 60
-s <type> The kind of cages that should be used
The cage type is specified in terms of the underlying pointgroup: P1 or P-1. Valid
values are (without quotes):
• No (default)
• Unique
• Mirror
• All
-r <resolution> The required resolution expressed as a real positive number
The default value is 3.0 Angstrom. Negative values or a value of 0 generates an
error message.
-h Displays help
6.2.3 Implementation
Atomic properties
The calculation of a Spectrophore™ starts by calculating the atomic contributions of each property from which one
wants to calculate a Spectrophore. In the current implementation, four atomic properties are converted into a Spec-
trophore; these four properties include the atomic partial charges, the atomic lipophilicities, the atomic shape devia-
tions and the atomic electrophilicities. The atomic partial charges and atomic electrophilicity properties are calculated
using the electronegativity equalisation method (EEM) as described by Bultinck and coworkers [bll2002] [blc2003].
Atomic lipophilic potential parameters are calculated using a rule-based method. Finally, the atomic shape deviation
is generated by calculating, for each atom, the atom’s deviation from the average molecular radius. This is done in a
four step process:
• The molecular center of geometry (COG) is calculated
• The distances between each atom and the molecular COG are calculated
• The average molecular radius is calculated by averaging all the atomic distances
• The distances between each atom and the COG are then divided by the average molecular radius and centered
on zero
6.2. Spectrophores™ 51
, Release 3.0.1
Following the calculation of all required atomic properties, the next step in the calculation of a Spectrophore consists
of determining the total interaction value V(c,p) between each of the atomic contributions of property p with a set of
interaction points on an artificial cage c surrounding the molecular conformation.
For this purpose, each of these interaction points i on cage c is assigned a value P(c,i) which is either +1 or -1, with the
constraint that the sum of all interaction points on a particular cage should be zero. In a typical Spectrophore calcula-
tion, a cage is represented as a rectangular box encompassing the molecular conformation in all three dimensions, with
the centers of the box edges being the interaction points. Such a configuration gives twelve interaction points per cage,
and, in the case of a non-stereospecific distribution of the interaction points, leads to 12 different cages. Although
there are no particular requirements as to the dimensions of the rectangular cage, the distance between the interaction
points and the geometrical extremes of the molecule should be such that a meaningful interaction value between each
cage point and the molecular entity can be calculated. In this respect, the default dimensions of the cage are constantly
adjusted to enclose the molecule at a minimum distance of 3 A along all dimensions. This cage size can be modified
by the user and influences the resolution of the Spectrophore.
The total interaction value V(c,p) between the atomic contribution values A(j,p) of property p for a given molecular
conformation and the cage interaction values P(c,i) for a given cage c is calculated according a standard interaction
energy equation. It takes into account the Euclidean distance between each atom and each cage point. This total
interaction V(c,p) for a given property p and cage c for a given molecular conformation is minimized by sampling
the molecular orientation along the three axis in angular steps and the calculation of the interaction value for each
orientation within the cage.
The final total interaction V(c,p) for a given cage c and property p corresponds to the lowest interaction value obtained
this way, and corresponds to the c’th value in the one-dimensional Spectrophore vector calculated for molecular
property p. As a result, a Spectrophore is organized as a vector of minimized interaction values V, each of these
organized in order of cages and property values. Since for a typical Spectrophore implementation twelve different
cages are used, the total length of a Spectrophore vector equals to 12 times the number of properties. Since four
different properties are used in the current implementation (electrostatic, lipophilic, electrophilic potentials, and an
additional shape index as described before), this leads to a total Spectrophore length of 48 real values per molecular
conformation.
Since Spectrophore descriptors are dependent on the actual three-dimensional conformation of the molecule, a typical
analysis includes the calculation of Spectrophores from a reasonable set of different conformations. It is then up to
the user to decide on the most optimal strategy for processing the different Spectrophore vectors. In a typical virtual
screening application, calculating the average Spectrophore vector from all conformations of a single molecule may
be a good strategy; other applications have benefit from calculating a weighted average or the minimal values. For
each molecule in the input file, a Spectrophore is calculated and printed to standard output as a vector of 48 numbers
(in the case of a non-stereospecific Spectrophore. The 48 doubles are organised into 4 sets of 12 doubles each:
• numbers 01-11: Spectrophore values calculated from the atomic partial charges;
• numbers 13-24: Spectrophore values calculated from the atomic lipophilicity properties;
• numbers 25-36: Spectrophore values calculated from the atomic shape deviations;
• numbers 37-48: Spectrophore values calculated from the atomic electrophilicity properties;
Accuracy
As already mentioned, the total interaction between cage and molecule for a given property is minimized by sampling
the molecular orientation in angular steps of a certain magnitude. As a typical angular step size, 20 degrees was found
to be the best compromise between accuracy and computer speed. Larger steps sizes are faster to calculate but have
the risk of missing the global interaction energy minimum, while smaller angular steps sizes do sample the rotational
space more thoroughly but at a significant computational cost. The accuracy can be specified by the user using the -a
option.
Resolution
Spectrophores capture information about the property fields surrounding the molecule, and the amount of detail that
needs to be captured can be regulated by the user. This is done by altering the minimal distance between the molecule
and the surrounding cage. The resolution can be specified by the user with the -r option. The default distance along
all dimensions is 3.0 Angstrom. The larger the distance, the lower the resolution.
With a higher resolution, more details of the property fields surrounding the molecule are contained by the Spec-
trophore. On the other hand, low resolution settings may lead to a more general representation of the property fields,
with little or no emphasis on small local variations within the fields. Using a low resolution can be the method of choice
during the initial virtual screening experiments in order to get an initial, but not so discriminative, first selection. This
initial selection can then further be refined during subsequent virtual screening steps using a higher resolution. In this
setting, small local differences in the fields between pairs of molecules will be picked up much more easily.
The absolute values of the individual Spectrophore data points are dependent on the used resolution. Low resolution
values lead to small values of the calculated individual Spectrophore data points, while high resolutions will lead to
larger data values. It is therefore only meaningful to compare only Spectrophores that have been generated using the
same resolution settings or after some kind of normalization is performed. Computation time is not influenced by the
specified resolution and hence is identical for all different resolution settings.
Stereospecificity
Some of the cages that are used to calculated Spectrophores have a stereospecific distribution of the interaction points.
The resulting interaction values resulting from these cages are therefore sensitive to the enantiomeric configuration
of the molecule within the cage. The fact that both stereoselective as well as stereo non-selective cages can be used
makes it possible to include or exclude stereospecificity in the virtual screening search. Depending on the desired
output, the stereospecificity of Spectrophores can be specified by the user using the -s option:
6.2. Spectrophores™ 53
, Release 3.0.1
• No stereospecificity (default): Spectrophores are generated using cages that are not stereospecific. For most
applications, these Spectrophores will suffice.
• Unique stereospecificity: Spectrophores are generated using unique stereospecific cages.
• Mirror stereospecificity: Mirror stereospecific Spectrophores are Spectrophores resulting from the mirror
enantiomeric form of the input molecules.
The differences between the corresponding data points of unique and mirror stereospecific Spectrophores are very
small and require very long calculation times to obtain a sufficiently high quality level. This increased quality level
is triggered by the accuracy setting and will result in calculation times being increased by at least a factor of 100.
As a consequence, it is recommended to apply this increased accuracy only in combination with a limited number
of molecules, and when the small differences between the stereospecific Spectrophores are really critical. However,
for the vast majority of virtual screening applications, this increased accuracy is not required as long as it is not
the intention to draw conclusions about differences in the underlying molecular stereoselectivity. Non-stereospecific
Spectrophores will therefore suffice for most applications.
Normalisation
It may sometimes be desired to focus on the relative differences between the Spectrophore data points rather than
focussing on the absolute differences. In these cases, normalization of Spectrophores may be required. The current
implementation offers with the -n option the possibility to normalize in four different ways:
• No normalization (default)
• Normalization towards zero mean
• Normalization towards standard deviation
• Normalization towards zero mean and unit standard deviation
In all these cases, normalization is performed on a ‘per-property’ basis, which means that the data points belonging
to the same property set are treated as a single set and that normalization is only performed on the data points within
each of these sets and not across all data points.
Normalization may be important when comparing the Spectrophores of charged molecules with those of neutral
molecules. For molecules carrying a global positive charge, the resulting Spectrophore data points of the charge
and electrophilicity properties will both be shifted in absolute value compared to the corresponding data points of
the respective neutral species. Normalization of the Spectrophores removes the original magnitude differences for
the data points corresponding to the charge and electrophilicity properties of charged and neutral species. Therefore,
if the emphasis of the virtual screening consists of the identification of molecules with similar property fields with-
out taking into account differences in absolute charge, then Spectrophores should be normalized towards zero mean.
However, if absolute charge differences should be taken into account to differentiate between molecules, unnormalized
Spectrophores are recommended.
The Chemistry Toolkit Rosetta is the brainchild of Andrew Dalke. It is a website that illustrates how to program
various chemical toolkits to do a set of tasks. To make it easily understandable, these tasks are probably on the simpler
side of those in the real world. The Rosetta already contains several examples of using the Open Babel Python bindings
to carry out tasks.
Here we focus on the use of the command line application obabel to accomplish the tasks listed in the Rosetta.
Inevitably we will struggle with more complicated tasks; however this section is intended to show how far you can go
simply using obabel, and to illustrate some of its less common features. Some of the tasks cannot be done exactly
as specified, but they are are usually close enough to useful.
Note that except for the examples involving piping, the GUI could also be used. Also the copy output format at present
works only for files with Unix line endings.
For each record from the benzodiazepine file, print the total number of heavy atoms in each record (that
is, exclude hydrogens). The output is one output line per record, containing the count as an integer. If at
all possible, show how to read directly from the gzip’ed input SD file.
The txt format outputs only the title but we set that to nothing and then append the result. The atoms descriptor counts
the number of atoms after the -d option has removed the hydrogens. The -l5 limits the output to the first 5 molecules,
in case you really didn’t want to print out results for all 12386 molecules.
Parse two SMILES strings and convert them to canonical form. Check that the results give the same string.
giving:
55
, Release 3.0.1
Cn1cnc2c1c(=O)n(C)c(=O)n2C
Cn1cnc2c1c(=O)n(C)c(=O)n2C
2 molecules converted
7.3 Report how many SD file records are within a certain molecular
weight range
Read the benzodiazepine file and report the number of records which contain a molecular weight between
300 and 400.
Convert a SMILES file into an SD file. The conversion must do its best to use the MDL conventions for
the SD file, including aromaticity perception. Note that the use of aromatic bond types in CTABs is only
allowed for queries, so aromatic structures must be written in a Kekule form. Because the stereochemistry
of molecules in SD files is defined solely by the arrangement of atoms, it is necessary to assign either 2D
or 3D coordinates to the molecule before generating output. The coordinates do not have to be reasonable
(i.e. it’s ok if they would make a chemist scream in horror), so long as the resulting structure is chemically
correct.
The data will come from the gzip’ed SD file of the benzodiazepine data set. Use the first structure as
the query structure, and use the rest of the file as the targets to find the 10 most similar structures. The
output is sorted by similarity, from most similar to least. Each target match is on its own line, and the line
contains the similarity score in the first column in the range 0.00 to 1.00 (preferably to 2 decimal places),
then a space, then the target ID, which is the title line from the SD file.
The similarity search of the index file for the 10 most similar molecules is done. The output is to Title format (txt),
with the -aa option of Fastsearch format (fs) adding the Tanimoto score:
623918 1
450820 1
1688 1
20351792 0.993007
9862446 0.986111
398658 0.97931
398657 0.97931
6452650 0.978873
450830 0.978873
3016 0.978873
10 molecules converted
The Tanimoto coefficient comes second, rather than first as requested and is not formatted to two decimal places, but
the information is still there.
Open Babel also supports outputting SVG, which is resolution independent as a vector format.:
Read record 3016 from the benzodiazepine SD file. Find all atoms which match the SMARTS
“c1ccc2c(c1)C(=NCCN2)c3ccccc3” and highlight them in red. All other atoms must be drawn in black.
The resulting image should be 200x250 pixels and on a white background. The resulting image file should
be in PNG (preferred) or GIF format.
Open Babel can output 2D structures as PNG. The compressed data file can be used as input. The -d makes hydrogen
implicit and the -xu removes the element-specific coloring. Width and height are set with the -xw and -xh options.
This is slow (about a minute) because each molecule is fully interpreted, although in most cases only the title is
required. The task can be done 10 times faster by using the uncompressed file, converting only the title (the -aT
option) and copying the SD text to standard out when a match occurs. This is piped to a second command which
outputs the structure.:
Open Babel also supports outputting SVG, which is resolution independent as a vector format.:
Use the first 16 structures of the benzodiazepine SD file to make a 4x4 grid of depictions as a single image.
The first structure is in the upper-left corner, the second is to its right, and so on. Each depiction should
include the title field of the corresponding record, which in this case is the PubChem identifier.
Use “[#7]~1~[#6]~[#6]~[#7]~[#6]~[#6]~2~[#6]~[#6]~[#6]~[#6]~[#6]12” as the common SMARTS
substructure. This is the fused ring of the benzodiazepine system but without bond type or atom aro-
maticity information. Use the first molecule as the reference depiction. All other depictions must have the
depiction of their common substructure aligned to the reference.
Since Open Babel 2.3.1 this can be done in one line:
obabel benzodiazepine.sdf.gz -O out.png -l16 --align -d -xu -xw 400 -xh 400
-s"[#7]~1~[#6]~[#6]~[#7]~[#6]~[#6]~2~[#6]~[#6]~[#6]~[#6]~[#6]12 green"
The depiction has some cosmetic tweaks: the substructure is highlighted in green; -d removes hydrogen; -xu removes
the element specific coloring. Open Babel also supports outputting SVG, which is resolution independent as a vector
format.:
In earlier versions the obfit program can be used. First extract the first molecule for the reference and the first 16 to
be displayed:
Then use the program obfit, which is distributed with Open Babel:
obfit "[#7]~1~[#6]~[#6]~[#7]~[#6]~[#6]~2~[#6]~[#6]~[#6]~[#6]~[#6]12"
firstbenzo.sdf sixteenbenzo.sdf > 16out.sdf
Display the 16 molecules (with implicit hydrogens) as SVG (earlier versions of Open Babel do not support PNG):
The sample database will be gzip’ed SD file of the benzodiazepine data set. The query structure will be
defined as “C1C=C(NC=O)C=CC=1”.
The default FP2 fingerprint is sensitive to whether a bond is aromatic or not. So this Kekule structure needs to be
converted to its aromatic form. As this happens automatically on conversion, the easiest way is to store the SMILES
string in a file, and use this file to specify the search pattern.
Prepare an index (of the unzipped data file):
obabel benzodiazepine.sdf -ofs
Do the substructure search. A very large number of molecules match the query, so the maximum number of hits has
to be increased with the -al 9000 option. By virtue of the ~ it is the false positives that are output (to nowhere) but
their number is reported:
obabel benzodiazepine.fs -onul -s ~substruct.smi -al 9000
8531 candidates from fingerprint search phase
12 molecules converted
The goal of this task is get an idea of how to do a set of SMARTS matches when the data comes in from
an external table.
Write a function or method named “TPSA” which gets its data from the file “tpsa.tab”. The function
should take a molecule record as input, and return the TPSA value as a float. Use the function to calcu-
late the TPSA of “CN2C(=O)N(C)C(=O)C1=C2N=CN1C”. The answer should be 61.82, which agrees
exactly with Ertl’s online TPSA tool but not with PubChem’s value of 58.4.
Open Babel’s command line cannot parse tables with custom formats. But the TPSA descriptor, defined by a table in
the file psa.txt, is already present and can be used as follows:
obabel -:CN2C(=O)N(C)C(=O)C1=C2N=CN1C -osmi --append TPSA
giving:
Cn1c(=O)n(C)c(=O)c2c1ncn2C 61.82
1 molecule converted
The table in tpsa.tab and Open Babel’s psa.txt have the same content but different formats. The first few rows
of tpsa.tab are:
psa SMARTS description
23.79 [N0;H0;D1;v3] N#
23.85 [N+0;H1;D1;v3] [NH]=
26.02 [N+0;H2;D1;v3] [NH2]-
7.10. Perform a substructure search on an SDF file and report the number of false positives 59
, Release 3.0.1
[N]#* 23.79
[NH]=* 23.85
[NH2]-* 26.02
It is possible to add new descriptors without having to recompile. If another property, myProp, could be calculated
using a table in myprop.txt with the same format as psa.txt, then a descriptor could set up by adding the
following item to plugindefines.txt:
OBGroupContrib
myProp # name of descriptor
myprop.txt # data file
Coolness index # brief description
The following would then output molecules in increasing order of myProp with the value added to the title:
The input file is SD file from the benzodiazepine data set. Every record contains the
tags PUBCHEM_CACTVS_HBOND_DONOR, PUBCHEM_CACTVS_HBOND_ACCEPTOR and PUB-
CHEM_MOLECULAR_WEIGHT, and most of the records contain the tag PUBCHEM_XLOGP3.
The program must create a new SD file which is the same as the input file but with a new tag data field
named “RULE5”. This must be “1” if the record passes Lipinski’s rule, “0” if it does not, and “no logP”
if the PUBCHEM_XLOGP3 field is missing.
This exercise is a bit of a stretch for the Open Babel command-line. However, the individual lines may be instructional,
since they are more like the sort of task that would normally be attempted.
The first command converts only molecules passing Lipinski’s rule, putting them in out1.sdf, and adding an addi-
tional property, RULE5, with a value of 1.
The second command converts only molecules that do not have a property PUBCHEM_XLOGP3.
The third command converts only molecules that do have a PUBCHEM_XLOGP3 and which fail Lipinski’s rule.
Use cat or type at the command prompt to concatenate the three files out1.sdf, out2.sdf, out3.sdf.
These operations are slow because the chemistry of each molecule is fully converted. As illustrated below, the filtering
alone could have been done more quickly using the uncompressed file and the -aP option, which restricts the reading
of the SDF file to the title and properties only, and then copying the molecule’s SDF text verbatim with -o copy.
But adding the additional property is not then possible:
A number of the Chemical Toolkit Rosetta tasks cannot be attempted as the obabel tool does not (currently!) have
the necessary functionality. These include the following:
• Detect and report SMILES and SDF parsing errors
• Ring counts in a SMILES file
• Unique SMARTS matches against a SMILES string
• Find the graph diameter
• Break rotatable bonds and report the fragments
• Change stereochemistry of certain atoms in SMILES file
To handle these tasks, you need to use the Open Babel library directly. This is the subject of the next section.
As the old Chinese proverb has it, a molecular depiction is worth a thousand words. This chapter covers everything
relevant to using Open Babel to generate or read/write a 2D depiction, expected by most chemists for print or website
purposes.
When we talk about a depiction in cheminformatics, there are really two different concepts covered by this term:
1. Graphical display of a molecule’s structure as a 2D image (such as the PNG and SVG formats). Here is an
example:
2. Storage of the 2D coordinates (and associated stereo symbols) associated with Concept 1 (using formats such
63
, Release 3.0.1
as Mol and Mol2). Here is the connection table from the corresponding Mol file for the above depiction:
3 2 0 0 0 0 0 0 0 0999 V2000
0.8660 -0.5000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
1.7321 -0.0000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
0.0000 0.0000 0.0000 Cl 0 0 0 0 0 0 0 0 0 0 0 0
1 2 2 0 0 0 0
1 3 1 0 0 0 0
Note: The focus in this chapter is on 2D depiction and not 3D. It is of course possible to generate and store 3D
coordinates in many of the file formats supported by Open Babel, but the only support for depiction is the Povray
format, used to create ray-traced ball-and-stick diagrams of molecules. Other Open Source chemistry projects such as
Avogadro, PyMOL, and Jmol cover this area very well.
As of Open Babel 2.3.2, there are three output formats for displaying a 2D image:
1. PNG format: This is a bitmap format used to create images of a certain pixel width. These images can be
inserted into Word documents or displayed on web pages.
2. SVG format: This is a vector format, which can be scaled to generate images of any size without loss of quality.
In particular, Open Babel’s SVG images can be interactively zoomed and panned using a modern web browser.
3. ASCII format: This is a depiction of a molecule using ASCII text. This can be useful if you are logged into a
remote server, or are working at the command-line, and just need a basic check of the identity of a molecule.
All of these formats support multimolecule files. The PNG and SVG formats arrange the molecules into rows and
columns (you can specify the number of rows or columns if you wish), while the ASCII format just uses a single
column. The remainder of this chapter will concentrate on the PNG and SVG formats; for more information on the
ASCII format, see the format description [ref].
64 Chapter 8. 2D Depiction
Chapter 9
3D Structure Generation
Open Babel provides support for generating a reasonable 3D structure just given connectivity information. It also has
the ability to generate multiple conformers for each molecule. These topics are discussed below.
There are several steps involved in generating a low-energy conformer from a 0D or 2D structure.
9.1.1 OBBuilder
The :obapi:‘OBBuilder‘ class is the part of Open Babel that can take a 2D or 0D structure and generate a 3D structure.
The 3D structure is made very quickly using a combination of rules (e.g. sp3 atoms should have four bonds arranged
in a tetrahedron) and common fragments (e.g. cyclohexane is shaped like a chair).
The 3D structures that come straight out of OBBuilder may be useful for some purposes but most people will want
to “clean them up”. This is because they may have clashes or have high energy structures due to some strain. The
conformer search or geometry optimization methods described below are typically used after calling OBBuilder.
Full discussion of the methods for coordinate generation is available in ‘Fast, efficient fragment-based coordinate
generation for Open Babel’ *J. Cheminf.* (2019) **11**, Art. 49.<https://doi.org/10.1186/s13321-019-0372-5>.
Please cite this paper if you use the coordinate generation features in Open Babel.
The functionality of OBBuilder is not directly available through obabel but it is used as the necessary first step of the
Gen3D operation discussed below.
Given a 3D structure, the goal of conformer searching is to find a low energy conformation. This may be useful
as a “clean-up” procedure after an initial 3D structure generation. Note that conformer searching does not alter
stereochemistry.
The Open Babel library provides access to several algorithms for conformer searching. All of these algorithms adopt
the torsion-driving approach; that is, conformations are generated by setting torsion angles to one of a number of
allowed values. The allowed values are listed in the data file torlib.txt; for example, C-C bonds in alkanes have
three allowed values: -60, 60 and 180.
65
, Release 3.0.1
>>> ff = ob.OBForceField.FindForceField("mmff94")
>>> ff.Setup(obmol)
True
>>> print(ff.Energy())
15.179054202
>>> ff.SystematicRotorSearch(100)
>>> print(ff.Energy())
10.8861155747
9.1.3 Gen3D
To illustrate how some of the above methods might be used in practice, consider the gen3d operation. This operation
(invoked using --gen3d at the commandline) generates 3D structures for 0D or 2D structures using the following
series of steps, all of which have been described above:
1. Use the OBBuilder to create a 3D structure using rules and fragment templates
2. Do 250 steps of a steepest descent geometry optimization with the MMFF94 forcefield
3. Do 200 iterations of a Weighted Rotor conformational search (optimizing each conformer with 25 steps of a
steepest descent)
4. Do 250 steps of a conjugate gradient geometry optimization
Taken together, all of these steps ensure that the generated structure is likely to be the global minimum energy con-
former. However, for many applications where 100s if not 1000s of molecules need to be processed, gen3d is rather
slow:
1. --fastest only generate coordinates, no force field or conformer search
In contrast to conformer searching, the goal of conformer generation is not simply to find a low energy conformation
but to generate several different conformations. Such conformations may be required by another piece of software
such as some protein-ligand docking and pharmacophore programs. They may also be useful if considering writing
some sort of shape comparison method.
Open Babel has two distinct conformer generating codes:
1. Confab: A systematic conformer generator that generates all diverse low-energy conformers.
2. Genetic algorithm: This is a stochastic conformer generator that generates diverse conformers either on an
energy or RMSD basis
A genetic algorithm is a general computational method to find a globally optimum solution to some multiparameter
problem. It involves a population of conformers which after a series of generations, iteratively arrive at an optimal
solution in terms of either RMSD diversity or energy.
Information about using this method is available at the command-line using: obabel -L conformer. Although
labelled as “Conformer Searching”, if you choose the genetic algorithm method (which is the default) then you can
save the conformers in the final generation using --writeconformers. For example, the following line creates
30 conformers optimized for RMSD diversity:
In this case --score rmsd was not strictly necessary as RMSD diversity was the default in any case.
9.2.2 Confab
Confab systematically generates all diverse low-energy conformers for molecules. To run Confab use the --confab
operation, and to assess the results by calculating RMSDs to reference structures, use the confabreport output format.
confab operator
The inputfile should contain one or more 3D structures (note that 2D structures will generate erroneous results).
Generated conformers are written to the outputfile. All of the conformers for a particular molecule will have the same
title as the original molecule.
--rcutoff <rmsd> RMSD cutoff (default 0.5 Angstrom)
--ecutoff <energy> Energy cutoff (default 50.0 kcal/mol)
--conf <#confs> Max number of conformers to test (default is 1 million)
--original Include the input conformation as the first conformer
--verbose Verbose - display information on torsions found
confabreport format
Example
The example file, bostrom.sdf, contains 36 molecules which have from 1 to 11 rotatable bonds (see Bostrom, Green-
wood, Gottfries, J Mol Graph Model, 2003, 21, 449).
We can generate and test up to 100K conformers using Confab as follows:
**Molecule 1
..title = 1a28_STR_1_A_1__C__
..number of rotatable bonds = 1
..tot conformations = 12
..tot confs tested = 12
..below energy threshold = 10
..generated 3 conformers
0 molecules converted
To check how many of the generated conformers are within 1.0 A RMSD of the original structures, we can use the
confabreport format as follows:
..Molecule 1
..title = 1a28_STR_1_A_1__C__
..number of confs = 3
..minimum rmsd = 0.0644801
..confs less than cutoffs: 0.2 0.5 1 1.5 2 3 4 100
..1 1 3 3 3 3 3 3
..cutoff (1) passed = Yes
**Summary
..number of molecules = 36
..less than cutoff(1) = 35
52271 molecules converted
Used by a number of features, such as 3D coordinate generation, conformer searching, etc., Open Babel provides
support for a variety of all-atom molecular mechanics force fields. The key idea is to use classical mechanics to
rapidly simulate molecular systems.
Each force field method is parameterized for a set of possible molecules (e.g., proteins, organic molecules, etc.),
building in assumptions about how various aspects of the molecules contribute to the overall potential energy.
The total potential energy of the system is usually given as a sum of multiple components, including some or all of
(but not limited to):
• Bond stretching
• Angle bending
• Dihedral torsions
• Out-of-plane bending
• Van der Waals repulsion
• Atomic partial charges (electrostatic)
Open Babel supports several force field methods. In general, we recommend use of either the Generalized Amber
Force Field (gaff) or MMFF94 Force Field (mmff94) for organic molecules, and the Universal Force Field (uff) for
other types of molecules.
The AMBER force field (or more accurately, family of force fields used with the AMBER software are designed
mainly for biomolecules (i.e., proteins, DNA, RNA, carbohydrates, etc.).
A general set of parameters for small organic molecules to allow simulations of drugs and small molecule ligands in
conjugtion with biomolecules is provided by GAFF. Parameters exist for almost all molecules made of C, N, O, H, S,
P, F, Cl, Br, and I, and are compatible with the AMBER functional forms.
Typically, GAFF expects partial charges assigned using quantum chemistry (i.e., HF/6-31G* RESP charges or AM1-
BCC). The Open Babel implementation can use other partial charges as available, although with lower resulting
accuracy.
In general, GAFF is expected to provide accuracy (in terms of geometry and energies) on par or better than the
MMFF94 Force Field (mmff94).
71
, Release 3.0.1
Note: If you use GAFF, you should cite the appropriate paper: Wang, J., Wolf, R. M.; Caldwell, J. W.;Kollman, P. A.;
Case, D. A. “Development and testing of a general AMBER force field”. Journal of Computational Chemistry, 2004
v. 25, 1157-1174.
The Ghemical force field matches an existing open source package, which provided a force field for geometry op-
timization and molecular dynamics similar to the Tripos-5.2 force field method (which is proprietary). It performs
acceptably on providing geometries of organic-like molecules.
We recommend use of either the Generalized Amber Force Field (gaff) or MMFF94 Force Field (mmff94) for organic
molecules, and the Universal Force Field (uff) for other types of molecules.
The MMFF94 force field (and the related MMFF94s) were developed by Merck and are sometimes called the Merck
Molecular Force Field, although MMFF94 is no longer considered an acronym.
The method provides good accuracy across a range of organic and drug-like molecules. The core parameterization was
provided by high-quality quantum calculations, rather than experimental data, across ~500 test molecular systems.
The method includes parameters for a wide range of atom types including the following common organic elements:
C, H, N, O, F, Si, P, S, Cl, Br, and I. It also supports the following common ions: Fe+2 , Fe+3 , F- , Cl- , Br- , Li+ , Na+ , K+ ,
Zn+2 , Ca+2 , Cu+1 , Cu+2 , and Mg+2 . The Open Babel implementation should automatically perform atom typing and
recognize these elements.
MMFF94 performs well at optimizing geometries, bond lengths, angles, etc. and includes electrostatic and hydrogen-
bonding effects.
Note: If you use MMFF94 you should cite the appropriate papers:
1. Thomas A. Halgren, J. Comput. Chem., 17, 490-519 (1996).
2. Thomas A. Halgren, J. Comput. Chem., 17, 520-552 (1996).
3. Thomas A. Halgren, J. Comput. Chem., 17, 553-586 (1996).
4. Thomas A. Halgren and Robert B. Nachbar, J. Comput. Chem., 17, 587-615 (1996).
5. Thomas A. Halgren, J. Comput. Chem., 17, 616-641 (1996).
Some experiments and most theoretical calculations show significant pyramidal “puckering” at nitrogens in isolated
structures. The MMFF94s (static) variant has slightly different out-of-plane bending and dihedral torsion parameters
to planarize certain types of delocalized trigonal N atoms, such as aromatic aniline. This provides a better match to
the time-average molecular geometry in solution or crystal structures.
If you are comparing force-field optimized molecules to crystal structure geometries, we recommend using the
MMFF94s variant for this reason. All other parameters are identical.
However, if you are perfoming “docking” simulations, consideration of active solution conformations, or other types
of computational studies, we recommend using the MMFF94 variant, since one form or another of the N geometry
will predominate.
Note: If you use MMFF94s, you should also cite the following paper that details that method:
6. Thomas A. Halgren, J. Comput. Chem., 20, 720-729 (1999).
One problem with traditional force fields is a limited set of elements and atom types. The Universal Force Field (UFF)
was developed to provide a set of rules and procedures for producing appropriate parameters across the entire periodic
table.
While some implementations of UFF use the QEq partial charge model, the original manuscript and authors of UFF
determined the parameterization without an electrostatic model. Consequently, by default the Open Babel implemen-
tation does not use electrostatic interactions.
Note: If you use UFF, you should cite the appropriate paper:
Rappe, A. K.; Casewit, C. J.; Colwell, K. S.; Goddard, W. A. III; Skiff, W. M.; “UFF, a full periodic table force field
for molecular mechanics and molecular dynamics simulations.” J Am Chem Soc, 1992 v. 114, 10024-10039.
Behind the obabel command line program lies a complete cheminformatics toolkit, the Open Babel library. Using
this library, you can write your own custom scripts and software for yourself or others.
Note: Any software that uses the Open Babel library must abide by terms of the GNU Public License version 2. This
includes all of the supporting language bindings (for example, Python scripts) as well as C++ programs. To summarise,
if you are considering distributing your software to other people, you must make your source code available to them
on request.
Open Babel is a C++ library and can easily be used from C++. In addition it can be accessed from Python, Perl, Ruby,
CSharp and Java. These are referred to as language bindings (the Python bindings, etc.) and they were automatically
generated from the C++ library using SWIG. For Python we also provide a module (Pybel) that makes it easier to
access features of the bindings.
The API (Application Programming Interface) is the set of classes, methods and variables that a programming library
provides to the user. The Open Babel API is implemented in C++, but the same set of classes, methods and variables
are accessed through the various language bindings.
The API documentation is automatically generated from the source code using the Doxygen tool. The following links
point to the various versions of the documentation:
• API for the current release
• API for the development version (updated nightly, with error report showing errors in documentation)
• API for specific versions: 2.0, 2.1, 2.2, 2.3
The Open Babel toolkit uses a version numbering that indicates how the API has changed over time:
• Bug fix releases (e.g., 2.0.0, vs. 2.0.1) do not change API at all.
• Minor versions (e.g., 2.0 vs. 2.1) will add function calls, but will be otherwise backwards-compatible.
• Major versions (e.g. 2 vs 3) are not backwards-compatible, and have changes in the API.
Overall, our goal is for the Open Babel API to remain stable over as long a period as possible. This means that users
can be confident that their code will continue to work despite the release of new versions with additional features, file
75
, Release 3.0.1
formats and bug fixes. For example, at the time of writing we have been on the version 2 series for almost five years
(since November 2005). In other words, a program written using Open Babel almost five years ago still works with
the latest release.
11.2 C++
Here’s an example C++ program that uses the Open Babel toolkit to convert between two chemical file formats:
#include <iostream>
#include <openbabel/obconversion.h>
using namespace std;
ifstream ifs(argv[1]);
if(!ifs)
{
cout << "Cannot open input file\n";
return 1;
}
ofstream ofs(argv[2]);
if(!ofs)
{
cout << "Cannot open output file\n";
return 1;
}
OpenBabel::OBConversion conv(&ifs, &ofs);
if(!conv.SetInAndOutFormats("CML","MOL"))
{
cout << "Formats not available\n";
return 1;
}
int n = conv.Convert();
cout << n << " molecules converted\n";
return 0;
}
Using Makefiles
The following Makefile can be used to compile the above example, assuming that it’s saved as example.cpp.
You need to have already installed Open Babel somewhere. If the include files or the library are not automatically
found when running make, you can specify the location as shown by the commented out statements in CFLAGS and
LDFLAGS below.
CC = g++
CFLAGS = -c # -I /home/user/Tools/openbabel/install/include/openbabel-2.0
LDFLAGS = -lopenbabel # -L /home/user/Tools/openbabel/install/lib
all: example
example: example.o
$(CC) $(LDFLAGS) example.o -o example
example.o: example.cpp
$(CC) $(CFLAGS) $(LDFLAGS) example.cpp
clean:
rm -rf example.o example
Using CMake
Rather than create a Makefile yourself, you can get CMake to do it for you. The nice thing about using CMake is that
it can generate not only Makefiles, but also project files for MSVC++, KDevelop and Eclipse (among others). The
following CMakeLists.txt can be used to generate any of these. The commented out lines can be used to specify
the location of the Open Babel library and include files if necessary.
cmake_minimum_required(VERSION 2.6)
add_executable(example example.cpp)
target_link_libraries(example openbabel)
# target_link_libraries(example /home/user/Tools/openbabel/install/lib/libopenbabel.
˓→so)
# include_directories(/home/user/Tools/openbabel/install/include/openbabel-2.0)
Let’s say we want to print out the molecular weights of every molecule in an SD file. Why? Well, we might want
to plot a histogram of the distribution, or see whether the average of the distribution is significantly different (in the
statistical sense) compared to another SD file.
#include <iostream>
#include <openbabel/obconversion.h>
#include <openbabel/mol.h>
11.2. C++ 77
, Release 3.0.1
mol.Clear();
notatend = obconversion.Read(&mol);
}
return(0);
}
Let’s say that we want to get the average bond length or dihedral angle over particular types of atoms in a large
molecule. So we’ll use SMARTS to match a set of atoms and loop through the matches. The following example
does this for sulfur-carbon-carbon-sulfur dihedral angles in a polymer and the carbon-carbon bond lengths between
the monomer units:
OBMol obMol;
OBBond *b1;
OBConversion obConversion;
OBFormat *inFormat;
OBSmartsPattern smarts;
smarts.Init("[#16D2r5][#6D3r5][#6D3r5][#16D2r5]");
string filename;
vector< vector <int> > maplist;
vector< vector <int> >::iterator matches;
double dihedral, bondLength;
if (smarts.Match(obMol))
{
dihedral = 0.0;
bondLength = 0.0;
maplist = smarts.GetUMapList();
for (matches = maplist.begin(); matches != maplist.end(); matches++)
{
dihedral += fabs(obMol.GetTorsion((*matches)[0],
(*matches)[1],
(*matches)[2],
(*matches)[3]));
b1 = obMol.GetBond((*matches)[1], (*matches)[2]);
bondLength += b1->GetLength();
}
cout << filename << ": Average Dihedral " << dihedral / maplist.size()
<< " Average Bond Length " << bondLength / maplist.size()
<< " over " << maplist.size() << " matches\n";
}
}
11.3 Python
11.3.1 Introduction
The Python interface to Open Babel is perhaps the most popular of the several languages that Open Babel supports.
We provide two Python modules that can be used to access the functionality of Open Babel toolkit:
1. The openbabel module:
This contains the standard Python bindings automatically generated using SWIG from the C++ API.
See The openbabel module.
2. The Pybel module:
This is a light-weight wrapper around the classes and methods in the openbabel module. Pybel
provides more convenient and Pythonic ways to access the Open Babel toolkit. See Pybel.
You don’t have to choose between them though - they can be used together.
Windows
1. First you need to download and install the main Open Babel executable and library as described in Install a
binary package.
2. Next, use pip to install the Python bindings:
pip install -U openbabel
Note: Python is available as either a 32-bit or 64-bit version. You need to install the corresponding version of Open
Babel in step 1.
If you want to display 2D depictions using Pybel (rather than just write to a file), you need to install the Pillow library:
pip install -U pillow
Open a Windows command prompt, and type the following commands to make sure that everything is installed okay.
If you get an error message, there’s something wrong and you should email the mailing list with the output from these
commands.
C:\Documents and Settings\Noel> obabel -V
Open Babel 3.0.0 -- Oct 7 2019 -- 20:18:16
11.3. Python 79
, Release 3.0.1
Directory of C:\Users\Noel\AppData\Roaming\OpenBabel-3.0.0\data
OpenBabel01010918183D
7 6 0 0 0 0 0 0 0 0999 V2000
1.0166 -0.0354 -0.0062 C 0 0 0 0 0
2.5200 -0.1269 0.0003 C 0 0 0 0 0
3.0871 -1.2168 0.0026 O 0 0 0 0 0
3.2979 1.4258 0.0015 Br 0 0 0 0 0
0.6684 1.0007 0.0052 H 0 0 0 0 0
0.6255 -0.5416 0.8803 H 0 0 0 0 0
0.6345 -0.5199 -0.9086 H 0 0 0 0 0
1 2 1 0 0 0
1 5 1 0 0 0
1 6 1 0 0 0
1 7 1 0 0 0
2 4 1 0 0 0
2 3 2 0 0 0
M END
$$$$
>>> mol.draw() # If you installed PIL, this will display its structure
>>> (Hit CTRL+Z followed by Enter to exit)
See Compile language bindings for information on how to configure CMake to compile the Python bindings. This can
be done either globally or locally.
You may need to add the location of libopenbabel.so (on my system, the location is /usr/local/lib) to
the environment variable LD_LIBRARY_PATH if you get the following error when you try to import the OpenBabel
library at the Python prompt:
$ python
>>> from openbabel import openbabel
Traceback (most recent call last):
File "<stdin>", line 1, in
File "/usr/lib/python2.4/site-packages/openbabel.py", line 9, in
import _openbabel
ImportError: libopenbabel.so.3: cannot open shared object file: No such file or
˓→directory
If you want to display 2D depictions using Pybel (rather than just write to a file), you need the Pillow library, and the
Python Tkinter library (part of the standard library). These should be available through your package manager, e.g. on
Ubuntu, Pillow is provided by ‘python-pil’ and ‘python-pil.imagetk’, while Tkinter is provided by ‘python-tk’.
The openbabel module provides direct access to the C++ Open Babel library from Python. This binding is generated
using the SWIG package and provides access to almost all of the Open Babel interfaces via Python, including the base
classes OBMol, OBAtom, OBBond, and OBResidue, as well as the conversion framework OBConversion. As such,
essentially any call in the C++ API is available to Python scripts with very little difference in syntax. As a result, the
principal documentation is the C++ API documentation.
Examples
Here we give some examples of common Python syntax for the openbabel module and pointers to the appropriate
sections of the API documentation.
The example script below creates atoms and bonds one-by-one using the :obapi:‘OBMol‘, :obapi:‘OBAtom‘, and
:obapi:‘OBBond‘ classes.
mol = openbabel.OBMol()
print(mol.NumAtoms()) #Should print 0 (atoms)
a = mol.NewAtom()
a.SetAtomicNum(6) # carbon atom
a.SetVector(0.0, 1.0, 2.0) # coordinates
b = mol.NewAtom()
mol.AddBond(1, 2, 1) # atoms indexed from 1
print(mol.NumAtoms()) #Should print 2 (atoms)
print(mol.NumBonds()) Should print 1 (bond)
mol.Clear();
More commonly, Open Babel can be used to read in molecules using the :obapi:‘OBConversion‘ framework. The
following script reads in molecular information (a SMI file) from a string, adds hydrogens, and writes out an MDL file
as a string.
11.3. Python 81
, Release 3.0.1
obConversion = openbabel.OBConversion()
obConversion.SetInAndOutFormats("smi", "mdl")
mol = openbabel.OBMol()
obConversion.ReadString(mol, "C1=CC=CS1")
mol.AddHydrogens()
print(mol.NumAtoms()) Should print 9 (atoms) after adding hydrogens
outMDL = obConversion.WriteString(mol)
The following script writes out a file using a filename, rather than reading and writing to a Python string.
obConversion = openbabel.OBConversion()
obConversion.SetInAndOutFormats("pdb", "mol2")
mol = openbabel.OBMol()
obConversion.ReadFile(mol, "1ABC.pdb.gz") # Open Babel will uncompress automatically
mol.AddHydrogens()
print(mol.NumAtoms())
print(mol.NumBonds())
print(mol.NumResidues())
obConversion.WriteFile(mol, '1abc.mol2')
Using iterators
A number of Open Babel toolkit classes provide iterators over various objects; these classes are identifiable by the
suffix “Iter” in the list of toolkit classes in the API:
• OBAtomAtomIter and OBAtomBondIter - given an OBAtom, iterate over all neighboring OBAtoms or OB-
Bonds
• OBMolAtomIter, OBMolBondIter, OBMolAngleIter, OBMolTorsionIter, OBMolRingIter - given an OBMol,
iterate over all OBAtoms, OBBonds, OBAngles, OBTorsions or OBRings.
• OBMolAtomBFSIter - given an OBMol and the index of an atom, OBMolAtomBFSIter iterates over all the
neighbouring atoms in a breadth-first manner. It differs from the other iterators in that it returns two values - an
OBAtom, and the ‘depth’ of the OBAtom in the breadth-first search (this is useful, for example, when creating
circular fingerprints)
• OBMolPairIter - given an OBMol, iterate over all pairs of OBAtoms separated by more than three bonds
• OBResidueIter - given an OBMol representing a protein, iterate over all OBResidues
• OBResidueAtomIter - given an OBResidue, iterate over all OBAtoms
These iterator classes can be used using the typical Python syntax for iterators:
Note that OBMolTorsionIter returns atom IDs which are off by one. That is, you need to add one to each ID to
get the correct ID. Also, if you add or remove atoms, you will need to delete the existing TorsionData before using
OBMolTorsionIter. This is done as follows:
mol.DeleteData(openbabel.TorsionData)
Some Open Babel toolkit methods, for example :obapi:‘OBMol::Rotate() <OpenBabel::OBMol::Rotate>‘, require
an array of doubles. It’s not possible to directly use a list of floats when calling such a function from Python. Instead,
you need to first explicitly create a C array using the double_array() function:
If you want to access any subclass of OBGenericData (such as :obapi:‘OBPairData‘ or :obapi:‘OBUnitCell‘) as-
sociated with a molecule, you need to ‘cast’ the :obapi:‘OBGenericData‘ returned by :obapi:‘OBMol.GetData()
<OpenBabel::OBMol::GetData>‘ using the toPairData(), toUnitCell() (etc.) functions:
unitcell = openbabel.toUnitCell(obMol.GetData(openbabel.UnitCell))
print(unitcell.GetAlpha(), unitcell.GetSpaceGroup())
Rather than use the :obapi:‘FastSearch‘ class directly, it’s easiest to use the :obapi:‘OpenInAndOutFiles() <Open-
Babel::OBConversion::OpenInAndOutFiles>‘ method as follows:
11.3. Python 83
, Release 3.0.1
If you are using the Python numerical extension, numpy, and you try to pass values from a numpy array to Open Babel,
it may not work unless you convert the values to Python built-in types first:
import numpy
from openbabel import openbabel
mol = openbabel.OBMol()
atom = mol.NewAtom()
11.3.4 Pybel
Pybel provides convenience functions and classes that make it simpler to use the Open Babel libraries from Python,
especially for file input/output and for accessing the attributes of atoms and molecules. The Atom and Molecule
classes used by Pybel can be converted to and from the OBAtom and OBMol used by the openbabel module.
These features are discussed in more detail below.
The rationale and technical details behind Pybel are described in O’Boyle et al [omh2008]. To support further devel-
opment of Pybel, please cite this paper if you use Pybel to obtain results for publication.
Information on the Pybel API can be found at the interactive Python prompt using the help() function. The full API
is also listed in the next section (see Pybel API).
To use Pybel, use from openbabel import pybel.
It is always possible to access the OBMol or OBAtom on which a Molecule or Atom is based, by accessing the
appropriate attribute, either .OBMol or .OBAtom. In this way, it is easy to combine the convenience of pybel
with the many additional capabilities present in openbabel. See Combining Pybel with openbabel.py below.
Molecules have the following attributes: atoms, charge, data, dim, energy, exactmass, formula,
molwt, spin, sssr, title and unitcell (if crystal data). The atoms attribute provides a list of the
Atoms in a Molecule. The data attribute returns a dictionary-like object for accessing and editing the data
fields associated with the molecule (technically, it’s a MoleculeData object, but you can use it like it’s a reg-
ular dictionary). The unitcell attribute gives access to any unit cell data associated with the molecule (see
:obapi:‘OBUnitCell‘). The remaining attributes correspond directly to attributes of OBMols: e.g. formula is equiv-
alent to :obapi:‘OBMol::GetFormula() <OpenBabel::OBMol::GetFormula>‘. For more information on what
these attributes are, please see the Open Babel C++ documentation for :obapi:‘OBMol‘.
For example, let’s suppose we have an SD file containing descriptor values in the data fields:
Molecules have a write() method that writes a representation of a Molecule to a file or to a string. See Input/Output
below. They also have a calcfp() method that calculates a molecular fingerprint. See Fingerprints below.
The draw() method of a Molecule generates 2D coordinates and a 2D depiction of a molecule. It uses the OASA
library by Beda Kosata to do this. The default options are to show the image on the screen (show=True), not
to write to a file (filename=None), to calculate 2D coordinates (usecoords=False) but not to store them
(update=False).
The addh() and removeh() methods allow hydrogens to be added and removed.
If a molecule does not have 3D coordinates, they can be generated using the make3D() method. By default, this
includes 50 steps of a geometry optimisation using the MMFF94 forcefield. The list of available forcefields is stored
in the forcefields variable. To further optimise the structure, you can use the localopt() method, which by
default carries out 500 steps of an optimisation using MMFF94. Note that hydrogens need to be added before calling
localopt().
11.3. Python 85
, Release 3.0.1
The calcdesc() method of a Molecule returns a dictionary containing descriptor values for LogP, Polar Surface
Area (“TPSA”) and Molar Refractivity (“MR”). A list of the available descriptors is contained in the variable descs.
If only one or two descriptor values are required, you can specify the names as follows: calcdesc(["LogP",
"TPSA"]). Since the data attribute of a Molecule is also a dictionary, you can easily add the result of calcdesc()
to an SD file (for example) as follows:
For convenience, a Molecule provides an iterator over its Atoms. This is used as follows:
Atoms have the following attributes: atomicmass, atomicnum, coords, exactmass, formalcharge,
heavyvalence, heterovalence, hyb, idx, implicitvalence, isotope, partialcharge, spin,
type, valence, vector. The .coords attribute provides a tuple (x, y, z) of the atom’s coordinates. The remain-
ing attributes are as for the Get methods of :obapi:‘OBAtom‘.
Input/Output
One of the strengths of Open Babel is the number of chemical file formats that it can handle (see Supported File
Formats and Options). Pybel provides a dictionary of the input and output formats in the variables informats and
outformats where the keys are the three-letter codes for each format (e.g. pdb) and the values are the descriptions
(e.g. Protein Data Bank format).
Pybel greatly simplifies the process of reading and writing molecules to and from strings or files. There are two
functions for reading Molecules:
1. readstring() reads a Molecule from a string
2. readfile() provides an iterator over the Molecules in a file
Here are some examples of their use. Note in particular the use of next() to access the first (and possibly only)
molecule in a file:
If a single molecule is to be written to a molecule or string, the write() method of the Molecule should be used:
1. mymol.write(format) returns a string
2. mymol.write(format, filename) writes the Molecule to a file. An optional additional parameter,
overwrite, should be set to True if you wish to overwrite an existing file.
For files containing multiple molecules, the Outputfile class should be used instead. This is initialised with a
format and filename (and optional overwrite parameter). To write a Molecule to the file, the write() method
of the Outputfile is called with the Molecule as a parameter. When all molecules have been written, the close()
method of the Outputfile should be called.
Here are some examples of output using the Pybel methods and classes:
>>> print(mymol.write("smi"))
'CCCC'
>>> mymol.write("smi", "outputfile.txt")
>>> largeSDfile = Outputfile("sdf", "multipleSD.sdf")
>>> largeSDfile.write(mymol)
>>> largeSDfile.write(myothermol)
>>> largeSDfile.close()
Fingerprints
SMARTS matching
Pybel also provides a simplified API to the Open Babel SMARTS pattern matcher. A Smarts object is created, and
the findall() method is then used to return a list of the matches to a given Molecule.
Here is an example of its use:
11.3. Python 87
, Release 3.0.1
It is easy to combine the ease of use of Pybel with the comprehensive coverage of the Open Babel toolkit that
openbabel.py provides. Pybel is really a wrapper around openbabel.py, with the result that the OBAtom
and OBMol used by openbabel.py can be interconverted to the Atom and Molecule used by Pybel.
The following example shows how to read a molecule from a PDB file using Pybel, and then how to use openbabel.
py to add hydrogens. It also illustrates how to find out information on what methods and classes are available, while
at the interactive Python prompt.
The next example is an extension of one of the openbabel.py examples at the top of this page. It shows how a
molecule could be created using openbabel.py, and then written to a file using Pybel:
mol = openbabel.OBMol()
a = mol.NewAtom()
a.SetAtomicNum(6) # carbon atom
a.SetVector(0.0, 1.0, 2.0) # coordinates
b = mol.NewAtom()
mol.AddBond(1, 2, 1) # atoms indexed from 1
pybelmol = pybel.Molecule(mol)
pybelmol.write("sdf", "outputfile.sdf")
pybel - A Python module that simplifies access to the Open Babel API
Global variables: informats, outformats, descs, fps, forcefields, operations
Functions: readfile(), readstring()
Classes: Atom, Molecule, Outputfile, Fingerprint, Smarts, MoleculeData
Note: The openbabel.py module can be accessed through the ob global variable.
class pybel.Atom(OBAtom)
Represent an atom.
Required parameter: OBAtom – an Open Babel :obapi:‘OBAtom‘
Attributes: atomicmass, atomicnum, coords, exactmass, formalcharge, heavyvalence,
heterovalence, hyb, idx, implicitvalence, isotope, partialcharge, spin, type,
valence, vector.
The underlying Open Babel :obapi:‘OBAtom‘ can be accessed using the attribute:
OBAtom
atomicmass
Atomic mass
atomicnum
Atomic number
coords
Coordinates of the atom
exactmass
Exact mass
formalcharge
Formal charge
heavyvalence
Number of non-hydrogen atoms attached
heterovalence
Number of heteroatoms attached
hyb
The hybridization of this atom: 1 for sp, 2 for sp2, 3 for sp3, . . .
For further details see :obapi:‘OBAtom::GetHyb() <OpenBabel::OBAtom::GetHyb>‘
idx
The index of the atom in the molecule (starts at 1)
implicitvalence
The maximum number of connections expected for this molecule
isotope
The isotope for this atom if specified; 0 otherwise.
partialcharge
Partial charge
spin
Spin multiplicity
type
Atom type
valence
Number of explicit connections
vector
Coordinates as a :obapi:‘vector3‘ object.
class pybel.Fingerprint(fingerprint)
A molecular fingerprint.
11.3. Python 89
, Release 3.0.1
tanimoto = a | b
The underlying fingerprint object can be accessed using the attribute fp.
bits
A list of bits set in the fingerprint
class pybel.Molecule(OBMol)
Represent a Pybel Molecule.
Required parameter: OBMol – an Open Babel :obapi:‘OBMol‘ or any type of Cinfony Molecule
Attributes: atoms, charge, conformers, data, dim, energy, exactmass, formula, molwt,
spin, sssr, title, unitcell.
Methods: addh(), calcfp(), calcdesc(), draw(), localopt(), make3D(), removeh(),
write()
The underlying Open Babel :obapi:‘OBMol‘ can be accessed using the attribute: OBMol
An iterator (__iter__()) is provided that iterates over the atoms of the molecule. This allows constructions
such as the following:
addh()
Add hydrogens.
atoms
A list of atoms of the molecule
calcdesc(descnames=[])
Calculate descriptor values.
Optional parameter:
descnames – a list of names of descriptors See the descs variable for a list of available descrip-
tors.
If descnames is not specified, all available descriptors are calculated.
calcfp(fptype=’FP2’)
Calculate a molecular fingerprint.
Optional parameters:
fptype – the fingerprint type (default is FP2). See the fps variable for a list of of available finger-
print types.
charge
The charge on the molecule
conformers
Conformers of the molecule
data
Access the molecule’s data through a dictionary-like object, MoleculeData.
dim
Are the coordinates 2D, 3D or 0D?
draw(show=True, filename=None, update=False, usecoords=False)
Create a 2D depiction of the molecule.
Optional parameters:
show – display on screen (default is True)
filename – write to file (default is None)
update – update the coordinates of the atoms This sets the atom coordinates to those deter-
mined by the structure diagram generator (default is False)
usecoords – use the current coordinates This causes the current coordinates to be used instead
of calculating new 2D coordinates (default is False)
OASA is used for 2D coordinate generation and depiction. Tkinter and Python Imaging Library are re-
quired for image display.
energy
The molecule’s energy
exactmass
The exact mass
formula
The molecular formula
localopt(forcefield=’mmff94’, steps=500)
Locally optimize the coordinates.
Optional parameters:
forcefield – default is mmff94. See the forcefields variable for a list of available forcefields.
steps – default is 500
If the molecule does not have any coordinates, make3D() is called before the optimization. Note that the
molecule needs to have explicit hydrogens. If not, call addh().
make3D(forcefield=’mmff94’, steps=50)
Generate 3D coordinates.
Optional parameters:
forcefield – default is mmff94. See the forcefields variable for a list of available forcefields.
steps – default is 50
Once coordinates are generated, hydrogens are added and a quick local optimization is carried out with 50
steps and the MMFF94 forcefield. Call localopt() if you want to improve the coordinates further.
molwt
The molecular weight
removeh()
Remove hydrogens.
spin
The spin multiplicity
11.3. Python 91
, Release 3.0.1
sssr
The Smallest Set of Smallest Rings (SSSR)
title
The molecule title
unitcell
Access any unit cell data
write(format=’smi’, filename=None, overwrite=False)
Write the molecule to a file or return a string.
Optional parameters:
format – chemical file format See the outformats variable for a list of available output formats
(default is smi)
filename – default is None
overwrite – overwrite the output file if it already exists? Default is False.
If a filename is specified, the result is written to a file. Otherwise, a string is returned containing the result.
To write multiple molecules to the same file you should use the Outputfile class.
class pybel.MoleculeData(obmol)
Store molecule data in a dictionary-type object
Required parameters: obmol – an Open Babel :obapi:‘OBMol‘
Methods and accessor methods are like those of a dictionary except that the data is retrieved on-the-fly from the
underlying :obapi:‘OBMol‘.
Example:
clear()
has_key(key)
items()
iteritems()
keys()
update(dictionary)
values()
class pybel.Outputfile(format, filename, overwrite=False, opt=None)
Represent a file to which output is to be sent.
Although it’s possible to write a single molecule to a file by calling the write() method of a Molecule, if
multiple molecules are to be written to the same file you should use the Outputfile class.
Required parameters:
format – chemical file format See the outformats variable for a list of available output formats
filename
Optional parameters:
overwrite – overwrite the output file if it already exists? Default is False
opt – a dictionary of format-specific options For format options with no parameters, specify the value
as None.
Methods: write(), close()
close()
Close the output file to further writing.
write(molecule)
Write a molecule to the output file.
Required parameters: molecule – A Molecule
class pybel.Smarts(smartspattern)
A Smarts Pattern Matcher
Required parameters: smartspattern - A SMARTS pattern
Methods: findall()
Example:
The numbers returned are the indices (starting from 1) of the atoms that match the SMARTS pattern. In this
case, there are three matches for each of the three ethyl groups in the molecule.
findall(molecule)
Find all matches of the SMARTS pattern to a particular molecule.
Required parameters: molecule - A Molecule
pybel.descs = ['LogP', 'MR', 'TPSA']
A list of supported descriptors
pybel.forcefields = ['uff', 'mmff94', 'ghemical']
A list of supported forcefields
pybel.fps = ['FP2', 'FP3', 'FP4']
A list of supported fingerprint types
pybel.informats = {}
A dictionary of supported input formats
11.3. Python 93
, Release 3.0.1
pybel.operations = ['Gen3D']
A list of supported operations
pybel.outformats = {}
A dictionary of supported output formats
pybel.readfile(format, filename, opt=None)
Iterate over the molecules in a file.
Required parameters:
format – chemical file format See the informats variable for a list of available input formats
filename
Optional parameters:
opt – a dictionary of format-specific options For format options with no parameters, specify the value
as None.
You can access the first molecule in a file using the next() method of the iterator (or the next() keyword in Python
3):
You can iterate over the molecules in a file as shown in the following code snippet:
>>> atomtotal = 0
>>> for mol in readfile("sdf", "head.sdf"):
... atomtotal += len(mol.atoms)
...
>>> print(atomtotal)
43
Optional parameters:
opt – a dictionary of format-specific options For format options with no parameters, specify
the value as None.
Example:
11.3.6 Examples
Let’s say we want to print out the molecular weights of every molecule in an SD file. Why? Well, we might want
to plot a histogram of the distribution, or see whether the average of the distribution is significantly different (in the
statistical sense) compared to another SD file.
openbabel.py
obconversion = ob.OBConversion()
obconversion.SetInFormat("sdf")
obmol = ob.OBMol()
notatend = obconversion.ReadFile(obmol,"../xsaa.sdf")
while notatend:
print(obmol.GetMolWt())
obmol = ob.OBMol()
notatend = obconversion.Read(obmol)
Pybel
Find information on all of the atoms and bonds connected to a particular atom
First of all, look at all of the classes in the Open Babel API that end with “Iter”. You should use these whenever you
need to do something like iterate over all of the atoms or bonds connected to a particular atom, iterate over all the
atoms in a molecule, iterate over all of the residues in a protein, and so on.
As an example, let’s say we want to find information on all of the bond orders and atoms connected to a particular
OBAtom called ‘obatom’. The idea is that we iterate over the neighbouring atoms using OBAtomAtomIter, and then
find the bond between the neighbouring atom and ‘obatom’. Alternatively, we could have iterated over the bonds
(OBAtomBondIter), but we would need to look at the indices of the two atoms at the ends of the bond to find out
which is the neighbouring atom:
• Noel O’Blog - Hack that SD file, Just How Unique are your Molecules Part I and Part II, Calculate circular
fingerprints with Pybel, Molecular Graph-ics with Pybel, and Generating InChI’s Mini-Me, the InChIKey.
• Filter erroneous structures from the ZINC database
11.3. Python 95
, Release 3.0.1
An implementation of RECAP
TJ O’Donnell (of gNova) has written an implementation of the RECAP fragmentation algorithm in 130 lines of Python.
The code is at [1].
TJ’s book, “Design and Use of Relational Databases in Chemistry”, also contains examples of Python code using
Open Babel to create and query molecular databases (see for example the link to Open Babel code in the Appendix).
11.4 Java
The openbabel.jar file in the Open Babel distribution allows you to use the Open Babel C++ library from Java
or any of the other JVM languages (Jython, JRuby, BeanShell, etc.).
Let’s begin by looking at an example program that uses Open Babel. The following program carries out file format
conversion, iteration over atoms and SMARTS pattern matching:
import org.openbabel.*;
Output:
11.4.2 Installation
Windows
openbabel.jar is installed along with the OpenBabelGUI on Windows, typically in C:/Program Files
(x86)/OpenBabel-2.3.2. As an example of how to use openbabel.jar, download OBTest.java and compile
and run it as follows:
11.4. Java 97
, Release 3.0.1
The following instructions describe how to compile and use these bindings on MacOSX and Linux:
1. openbabel.jar is included in the Open Babel source distribution in scripts/java. To compile a Java
application that uses this (e.g. the example program shown above), use a command similar to the following:
2. To run the resulting Test.class on MacOSX or Linux you first need to compile the Java bindings as de-
scribed in the section Compile language bindings. This creates lib/libopenbabel_java.so in the build
directory.
3. Add the location of openbabel.jar to the environment variable CLASSPATH, not forgetting to append the
location of Test.class (typically “.”):
export CLASSPATH=/home/user/Tools/openbabel-2.3.2/scripts/java/openbabel.jar:.
11.4.3 API
openbabel.jar provides direct access to the C++ Open Babel library from Java through the namespace
org.openbabel. This binding is generated using the SWIG package and provides access to almost all of the Open
Babel interfaces from Java, including the base classes :obapi:‘OBMol‘, :obapi:‘OBAtom‘, :obapi:‘OBBond‘, and
:obapi:‘OBResidue‘, as well as the conversion framework :obapi:‘OBConversion‘.
Essentially any call in the C++ API is available to Java programs with very little difference in syntax. As a result, the
principal documentation is the Open Babel C++ API documentation. A few differences exist, however:
• Global variables, global functions and constants in the C++ API can be found in
org.openbabel.openbabel_java. The variables are accessible through get methods.
• When accessing various types of :obapi:‘OBGenericData‘, you will need to cast them to the particular subclass
using the global functions, toPairData, toUnitCell, etc.
• The Java versions of the iterator classes in the C++ API (that is, all those classes ending in Iter) implement the
Iterator and Iterable interfaces. This means that the following foreach loop is possible:
• To facilitate use of the :obapi:‘OBMolAtomBFSIter‘, OBAtom has been extended to incorporate a Current-
Depth value, accessible through a get method:
11.5 Perl
11.5.1 Installation
The Perl bindings are available only on MacOSX and Linux. (We could not get them to work on Windows.) See
Compile language bindings for information on how to configure CMake to compile and install the Perl bindings.
The Chemistry::OpenBabel module is designed to allow Perl scripts to use the C++ Open Babel library. The bindings
are generated using the SWIG package and provides access to almost all of the Open Babel interfaces via Perl, includ-
ing the base classes OBMol, OBAtom, OBBond, and OBResidue, as well as the conversion framework OBConversion.
PerlMol
For developing chemistry in Perl, you should also look at the PerlMol project.
As such, essentially any call in the C++ API is available to Perl access with very little difference in syntax. This
guide is designed to give examples of common Perl syntax for Chemistry::OpenBabel and pointers to the appropriate
sections of the API documentation.
The example script below creates atoms and bonds one-by-one using the OBMol, OBAtom, and OBBond classes.
#!/usr/bin/perl
use Chemistry::OpenBabel;
$obMol->NewAtom();
$numAtoms = $obMol->NumAtoms(); # now 1 atom
$obMol->NewAtom();
$obMol->AddBond(1, 2, 1); # bond between atoms 1 and 2 with bond order 1
$numBonds = $obMol->NumBonds(); # now 1 bond
$obMol->Clear();
More commonly, Open Babel can be used to read in molecules using the OBConversion framework. The following
script reads in molecular information from a SMILES string, adds hydrogens, and writes out an MDL file as a string.
#!/usr/bin/perl
11.5. Perl 99
, Release 3.0.1
$obMol->AddHydrogens();
$numAtoms = $obMol->NumAtoms(); # now 9 atoms
my $outMDL = $obConversion->WriteString($obMol);
The following script writes out a file using a filename, rather than reading and writing to a Perl string.
#!/usr/bin/perl
use Chemistry::OpenBabel;
$obMol->AddHydrogens();
$obConversion->WriteFile($obMol, "1abc.mol2");
11.5.3 Examples
Let’s say we want to print out the molecular weights of every molecule in an SD file. Why? Well, we might want
to plot a histogram of the distribution, or see whether the average of the distribution is significantly different (in the
statistical sense) compared to another SD file.
use Chemistry::OpenBabel;
100 Chapter 11. Write software using the Open Babel library
, Release 3.0.1
This script shows an example of deleting and modifying atoms to transform one structure to a related one. It operates
on a set of substituted thiophenes, deletes the sulfur atom (note that R1 and R2 may contain sulfur, so the SMARTS
pattern is designed to constrain to the ring sulfur), etc. The result is a substituted ethylene, as indicated in the diagrams.
use Chemistry::OpenBabel;
$obConversion->SetInAndOutFormats("xyz", "mol");
$obConversion->ReadFile($obMol, $filename);
for (1..$obMol->NumAtoms()) {
$atom = $obMol->GetAtom($_);
# look to see if this atom is a thiophene sulfur atom
if ($atom->MatchesSMARTS("[#16D2]([#6D3H1])[#6D3H1]")) {
$sulfurIdx = $atom->GetIdx();
# see if this atom is one of the carbon atoms bonded to a thiophene sulfur
} elsif ($atom->MatchesSMARTS("[#6D3H1]([#16D2][#6D3H1])[#6]") ) {
if ($c2Idx == 0) { $c2Idx = $atom->GetIdx(); }
else {$c5Idx = $atom->GetIdx(); }
}
}
# Get the actual atom objects -- indexing will change as atoms are added and deleted!
$sulfurAtom = $obMol->GetAtom($sulfurIdx);
$c2Atom = $obMol->GetAtom($c2Idx);
$c5Atom = $obMol->GetAtom($c5Idx);
$obMol->DeleteAtom($sulfurAtom);
$obMol->DeleteHydrogens($c2Atom);
$obMol->DeleteHydrogens($c5Atom);
$obConversion->WriteFile($obMol, "$filename.mol");
OBDotNet is a compiled assembly that allows Open Babel to be used from the various .NET languages (e.g. Visual
Basic, C#, IronPython, IronRuby, and J#) on Windows, Linux and MacOSX. The current version is OBDotNet 0.4.
11.6.1 Installation
Windows
The OBDotNet.dll assembly provided on Windows was compiled using the .NET framework v3.5 for the x86
platform. To use it, you will need to compile your code using .NET v3.5 or newer and you will also need to target x86
(/platform:x86).
The following instructions describe how to compile a simple C# program that uses OBDotNet:
1. First you need to download and install the OpenBabelGUI version 2.3.2
2. Next create an example CSharp program that uses the Open Babel API (see below for one or use this link). Let’s
call this example.cs.
3. Copy OBDotNet.dll from the Open Babel installation into the same folder as example.cs.
4. Open a command prompt at the location of example.cs and compile it as follows:
C:\Work> C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe
/reference:OBDotNet.dll /platform:x86 example.cs
5. Run the created executable, example.exe, to discover the molecule weight of propane:
C:\Work> example.exe
44.09562
If you prefer to use the MSVC# GUI, note that the Express edition does not have the option to choose x86 as a
target. This will be a problem if you are using a 64-bit operating system. There’s some information at Coffee Driven
Development on how to get around this.
On Linux and MacOSX you need to use Mono, the open source implementation of the .NET framework, to compile
the bindings. The following instructions describe how to compile and use these bindings:
1. OBDotNet.dll is included in the Open Babel source distribution in scripts/csharp. To compile a
CSharp application that uses this (e.g. the example program shown below), use a command similar to the
following:
102 Chapter 11. Write software using the Open Babel library
, Release 3.0.1
2. To run this on MacOSX or Linux you need to compile the CSharp bindings as described in the section Compile
language bindings. This creates lib/libopenbabel_csharp.so in the build directory.
3. Add the location of OBDotNet.dll to the environment variable MONO_PATH. Add the location of
libopenbabel_csharp.so to the environment variable LD_LIBRARY_PATH. Additionally, if you have
not installed Open Babel globally you should set BABEL_LIBDIR to the location of the Open Babel library and
BABEL_DATADIR to the data directory.
4. Run example.exe:
$ ./example.exe
44.09562
The API is almost identical to the Open Babel C++ API. Differences are described here.
Using iterators
In OBDotNet, iterators are provided as methods of the relevant class. The full list is as follows:
• OBMol has .Atoms(), .Bonds(), .Residues(), and .Fragments(). These corre-
spond to :obapi:‘OBMolAtomIter‘, :obapi:‘OBMolBondIter‘, :obapi:‘OBResidueIter‘ and
:obapi:‘OBMolAtomDFSIter‘ respectively.
• OBAtom has .Bonds() and .Neighbours(). These correspond to :obapi:‘OBAtomBondIter‘ and
:obapi:‘OBAtomAtomIter‘ respectively.
Such iterators are used as follows:
Other iterators in the C++ API not listed above can still be used through their IEnumerator methods.
Handling OBGenericData
To cast :obapi:‘OBGenericData‘ to a specific subclass, you should use the .Downcast <T> method, where T is a
subclass of OBGenericData.
11.6.3 Examples
The following sections show how the same example application would be programmed in C#, Visual Basic and Iron-
Python. The programs print out the molecular weight of propane (represented by the SMILES string “CCC”).
C#
using System;
using OpenBabel;
namespace MyConsoleApplication
{
class Program
{
static void Main(string[] args)
{
OBConversion obconv = new OBConversion();
obconv.SetInFormat("smi");
OBMol mol = new OBMol();
obconv.ReadString(mol, "CCC");
System.Console.WriteLine(mol.GetMolWt());
}
}
}
Visual Basic
Imports OpenBabel
Module Module1
Sub Main()
Dim OBConv As New OBConversion()
Dim Mol As New OBMol()
OBConv.SetInFormat("smi")
OBConv.ReadString(Mol, "CCC")
System.Console.Write("The molecular weight of propane is " & Mol.GetMolWt())
End Sub
End Module
IronPython
import clr
clr.AddReference("OBDotNet.dll")
import OpenBabel as ob
conv = ob.OBConversion()
conv.SetInFormat("smi")
mol = ob.OBMol()
conv.ReadString(mol, "CCC")
print(mol.GetMolWt())
104 Chapter 11. Write software using the Open Babel library
, Release 3.0.1
11.7 Ruby
As with the other language bindings, just follow the instructions at Compile language bindings to build the Ruby
bindings.
Like any Ruby module, the Open Babel bindings can be used from a Ruby script or interactively using irb as follows:
$ irb
irb(main):001:0> require 'openbabel'
=> true
irb(main):002:0> c=OpenBabel::OBConversion.new
=> #<OpenBabel::OBConversion:0x2acedbadd020>
irb(main):003:0> c.set_in_format 'smi'
=> true
irb(main):004:0> benzene=OpenBabel::OBMol.new
=> #<OpenBabel::OBMol:0x2acedbacfa10>
irb(main):005:0> c.read_string benzene, 'c1ccccc1'
=> true
irb(main):006:0> benzene.num_atoms
=> 6
Open Babel 3.0 breaks the API in a number of cases, and introduces some new behavior behind-the-scenes. These
changes were necessary to fix some long standing issues impacting chemical accuracy as well as performance.
Here we describe the main changes, and how to change existing code to adapt.
The babel executable has been removed, and obabel should be used instead. Essentially obabel is a modern
version of babel with additional capabilities and a more standard interface. Typically the only change needed is to
place -O before the output filename:
More than one can be used, and a molecule title can be included if enclosed in quotes:
In OB 3.x, both openbabel.py and pybel.py live within the openbabel module:
# OB 2.x
import openbabel as ob
import pybel
# OB 3.0
from openbabel import openbabel as ob
from openbabel import pybel
While more verbose, the new arrangement is in line with standard practice and helps avoid conflict with a different
Python project, PyBEL.
The API for interconverting atomic numbers and element symbols has been replaced for performance reasons. The
OBElementTable class has been removed and its associated functions are now available through the OBElements
namespace:
// OB 2.x
OBElementTable etab;
const char *elem = etab.GetSymbol(6);
unsigned int atomic_num = etab.GetAtomicNum(elem);
// OB 3.0
#include <openbabel/elements.h>
const char *elem = OBElements::GetSymbol(6);
unsigned int atomic_num = OBElements::GetAtomicNum(elem);
Furthermore, the OBAtom API convenience functions for testing for particular elements (e.g. IsHydrogen()) have
been removed. Instead, OBAtom::GetAtomicNum() should be used along with an element constant or atomic
number:
// OB 2.x
if (atom->IsCarbon()) {...
// OB 3.0
if (atom->GetAtomicNum() == OBElements.Carbon) {...
// or
if (atom->GetAtomicNum() == 6) {...
Handling of isotope information now longer uses OBIsotopeTable but is accessed through the OBElements
namespace:
// OB 2.x
OBIsotopeTable isotab;
isotab.GetExactMass(6, 14);
(continues on next page)
106 Chapter 11. Write software using the Open Babel library
, Release 3.0.1
// OB 3.0
double exact = OBElements.GetExactMass(OBElements.Carbon, 14);
In OB 2.x, atom class information was stored as part of an OBAtomClassData object attached to an OBMol
and accessed via OBMol.GetData("Atom Class"). In OB 3.0, atom class information is instead stored as
an OBPairInteger associated with an OBAtom and accessed via OBAtom.GetData("Atom Class").
OB 2.x referred to the function that returned the explicit degree of an atom as GetValence(). This was confusing,
at best. To find the explicit valence, the BOSum() method was required. OB 3.0 avoids this confusion by renaming
methods associated with degree or valence:
• OBAtom::GetExplicitValence() (OB 2.x BOSum())
• OBAtom::GetExplicitDegree() (OB 2.x GetValence())
• OBAtom::GetHvyDegree() (OB 2.x GetHvyValence())
• OBAtom::GetHeteroDegree() (OB 2.x GetHeteroValence())
The “Unset” methods for molecule, atom and bond flags have been removed. Instead, a value of false should be
passed to the corresponding “Set” method. For example, OBMol::UnsetAromaticPerceived() in OB 2.x is
now OBMol::SetAromaticPerceived(false).
Several deprecated methods have been removed. For the most part, an equivalent function with a different name is
present in the API:
• OBBond::GetBO()/SetBO() removed. OBBond::GetBondOrder()/SetBondOrder() should be
used instead.
• OBAtom::GetCIdx() removed. OBAtom::GetCoordinateIdx() should be used instead.
• OBBitVec::Empty() removed. OBBitVec::IsEmpty() should be used instead.
• OBBitVec::BitIsOn() removed. OBBitVec::BitIsSet() should be used instead.
With OB 3.0, the number of implicit hydrogens is stored as a property of the atom. This value can be interrogated and
set independently of any other property of the atom. This is how other mature cheminformatics toolkits handle implicit
hydrogens. In contrast, in OB 2.x this was a derived property worked out from valence rules and some additional flags
set on an atom to indicate non-standard valency.
From the point of view of the user, the advantage of the 2.x approach was that the user never needed to consider the
implicit hydrogens; their count was calculated based on the explicit atoms (a behavior known as “floating valence”).
The disadvantage was that it was difficult for the user to specify non-standard valencies, may have papered-over
problems with the data, gave rise to subtle bugs which were not easily addressed and had poorer performance.
As an example of how the behavior has changed, let’s look at creating a bond. If we read the SMILES string C.C,
create a bond between the two atoms and write out the SMILES string, we get different answers for OB 2.x (CC) versus
OB 3.0 ([CH4][CH4]). OB 2.x just works out the count based on standard valence rules. With OB 3.0, there were
four implicit hydrogens on each carbon before we made the bond, and there still are four - they didn’t go anywhere
and weren’t automatically adjusted.
While this may seem like a major change, adapting code to handle the change should be straightforward: adding or
removing a bond should be accompanied by incrementing or decrementing the implicit hydrogen count by the bond
order. This also applies to deleting an atom, since this deletes any bonds connected to it. Note that care should be
taken not to set the hydrogen count to a negative value when decrementing.
For the particular case of creating a new atom, it is worth noting that the implicit hydrogen count defaults to zero and
that users must set it themselves if necessary. To help with this situation a convenience function has been added to
OBAtom that sets the implicit hydrogen count to be consistent with normal valence rules. TODO
Regarding specific API functions, the following have been removed:
• OBAtom::SetImplicitValence(), GetImplicitValence()
• OBAtom::IncrementImplicitValence(), DecrementImplicitValence()
• OBAtom::ForceNoH(), HasNoHForce(), ForceImplH(), HasImplHForced()
• OBAtom::ImplicitHydrogenCount()
The following have been added:
• OBAtom::SetImplicitHCount(), GetImplicitHCount()
Molecule modification no longer clears the aromaticity perception flag. If the user wishes to force reperception after
modification, then they should call OBMol::SetAromaticPerceived(false).
108 Chapter 11. Write software using the Open Babel library
Chapter 12
Cheminformatics 101
Cheminformatics is a cross between Computer Science and Chemistry – the process of storing and retrieving informa-
tion about chemical compounds.
Information Systems are concerned with storing, retrieving, and searching information, and with storing relationships
between bits of data. For example:
109
, Release 3.0.1
Rela- Year Carter Answer: What’s the logP(o/w) of Answer: logP(o/W) = 2.62
tion- was elected Elected in 1976
ship
substructure is usually a functional group, “scaffold”, or core structure representing a class of molecules. This
too is a hard problem, much harder than most text searches, for reasons that go to the very root of mathematics
and the theory of computability.
4. Similarity search
Some databases can find similar-sounding or misspelled words, such as “Find Lincon” or “find Cincinati”,
which respectively might find Abraham Lincoln and Cincinnati. Many chemical information systems can find
molecules similar to a given molecule, ranked by similarity. There are several ways to measure molecular
similarity, discussed further in the section on Molecular Similarity.
One of the greatest achievements in chemistry was the development of the valence model of chemistry, where a
molecule is represented as atoms joined by semi-rigid bonds that can be single, double, or triple. This simple mental
model has little resemblance to the underlying quantum-mechanical reality of electrons, protons and neutrons, yet it
has proved to be a remarkably useful approximation of how atoms behave in close proximity to one another, and has
been the foundation of chemical instruction for well over a century.
The valence model is also the foundation of modern chemical information systems. When a Computer Scientist
approaches a problem, the first task is to figure out a datamodel that represents the problem to be solved as information.
To the Computer Scientist, the valence model naturally transforms into a graph, where the nodes are atoms and the
edges are bonds. Computer Scientists know how to manipulate graphs - mathematical graph theory and computer
science have been closely allied since the invention of the digital computer.
There are atoms and space. Everything else is opinion.
—Democritus
However, the valence model of chemistry has many shortcomings. The most obvious is aromaticity, which quickly
required adding the concept of a non-integral “aromatic” distributed bond, to the single/double/triple bonds of the
simple valence model. And that was just the start - tautomers, ferrocenes, charged molecules and a host of other
common molecules simply don’t fit the valence model well.
This complicates life for the computer scientist. As we shall see, they are the source of most of the complexity of
modern cheminformatics systems.
Most of the early (and some modern) representations of molecules were in a connection table, literally, a table enu-
merating the atoms, and a table enumerating the bonds and which atoms each bond connected. Here is an example of
connection-table (CTAB) portion of an MDL “SD” file (the data portion is not shown here):
MOLCONV
3 2 0 0 1 0 1 V2000
5.9800 -0.0000 -0.0000 Br 0 0 0 0 0 0
4.4000 -0.6600 0.8300 C 0 0 0 0 0 0
3.5400 -1.3500 -0.1900 C 0 0 0 0 0 0
1 2 1 0
2 3 1 0
This simple example illustrates most of the key features. The molecule has three atoms, two bonds, and is provided
with three-dimensional (x,y,z) coordinates. MDL provides extensive documentation for their various CTFile formats
if you are interested in the details.
Connection tables can capture the valence model of chemistry fairly well, but they suffer from three problems:
1. They are very inefficient, taking on the order of a dozen or two of bytes of data per atom and per bond. Newer line
notations (discussed below) represent a molecules with an average of 1.2 to 1.5 bytes per atom, or 6-8 bytes per atom
if coordinates are added.
2. Many suffered from lack of specificity. For example, since hydrogens are often not specified, there can be ambiguity
as to the electronic state of some molecules, because the connection-table format does not explicitly state the valence
assumptions.
3. Most mix the concept of connectivity (what the atoms are and how they are connected) with other data such as 2D
and 3D coordinates. For example, if you had two different conformers of a molecule, most connection tables would
require you to specify the entire molecule twice, even though the connection table is identical in both.
1H = CH4 Methane
2H = CH3-CH3 Ethane
3H = CH3-CH2-CH3 Propane
QVR BG CG DG EG FG = C7HCl5O2 Pentachlorbenzoate
WLN was the first line notation to feature a canonical form, that is, the rules for WLN meant there
was only one “correct” WLN for any particular molecule. Those versed in WLN were able to
write molecular structure in a line format, communicate molecular structure to one another and to
computer programs. Unfortunately, WLN’s complexity prevented widespread adoption. The rules
for correct specification of WLN filled a small book, encoding those rules into a computer proved
difficult, and the rules for the canonicalization were computationally intractable.
SMILES - Simplified Molecular Input Line Entry System The best-known line notation today is
SMILES. It was by Arthur and David Weininger in response to a need for a simpler, more “hu-
man accessible” notation than WLN. While SMILES is not trivial to learn and write, most chemists
can create correct SMILES with just a few minutes training, and the entire SMILES language can
be learned in an hour or two. You can read more details here. Here are some examples:
C methane
CC ethane
C=C ethene
Oc1ccccc1 phenol
SMILES, like WLN, has a canonical form, but unlike WLN, Weininger relied on the computer,
rather than the chemist, to convert a non-canonical SMILES to a canonical SMILES. This important
separation of duties was key to making SMILES easy to enter. (Read more about canonicalization
below.)
InChI InChI is the latest and most modern of the line notations. It resolves many of the chemical ambi-
guities not addressed by SMILES, particularly with respect to stereo centers, tautomers and other of
the “valence model problems” mentioned above.
You can read more about InChI at the Official Web Site, or on the Unofficial InChI FAQ page.
12.2.4 Canonicalization
A critical feature of line notations is canonicalization - the ability to choose one “blessed” representation from among
the many. Consider:
OCC ethanol
CCO ethanol
Both of these SMILES represent the same molecule. If we could all agree that one of these was the “correct” or
“canonical” SMILES for ethanol, then we would always store it the same way in our database. More importantly, if
we want to ask, “Is ethanol in our database” we know that it will only be there once, and that we can generate the
canonical SMILES for ethanol and look it up.
(Note that in theory one can create a canonical connection table, too, but it’s not as useful since informatics systems
usually have trouble indexing BLOBs - large objects.)
Why are line notations preferred over connection-table formats? In theory, either could express the same information.
But there are practical difference, mostly related to the complexity of “parsing” a connection table. If you know that
the whole molecule is on one line of a file, it’s easy to parse.
Line notations are also very nice for database applications. Relational databases have datatypes that, roughly speaking,
are divided into numbers, text, and “everything else”, also known as “BLOBs” (Binary Large OBjects). You can store
line notations in the “text” fields much more easily than connection tables.
Line notations also have pragmatic advantages. Modern Unix-like systems (such as UNIX, Linux and Cygwin) have
a number of very powerful “filter” text-processing programs that can be “piped” together (connected end-to-end) to
perform important tasks. For example, to count the number of molecules containing aliphatic nitrogen in a SMILES
file, I can simply:
grep N file.smi | wc
(grep looks for a particular expression, in this case N, and prints any line that contains it, and wc (“word count”)
counts the number of words and lines.)
This is just a simple example of the power available via “script” programs using “filters” on Unix-like systems. Unix
filters are much less useful for connection-table formats, because each molecule is spread over many lines.
In addition to a typographical way to represent molecules, we also need a way to enter queries about molecules, such
as, “Find all molecules that contain a phenol.”
With text, we’re familiar with the concept of typing a partial word, such as “ford” to find “Henry Ford” as well as “John
Hartford”. For chemistry, we can also specify partial structures, and find anything that contains them. For example:
eMolecules, Inc.
eMolecules is a one-stop shop for suppliers and information for over 8 million chemical compounds. Under the
hood is a chemical registration technology based on Open Babel.
The simplest query language for chemistry is SMILES itself: Just specify a structure, such as Oc1ccccc1, and search.
This is how eMolecules’ basic searching works (see Sidebar). It’s simple and, because of the high-performance indexes
in eMolecules, is also very fast.
However, for general-purpose cheminformatics, one needs more power. What if the substructure you’re looking for
isn’t a valid molecule? For example ClccBr (1,2- substitution on an aromatic ring) isn’t a whole molecule, since the
concept of aromaticity is only sensible in the context of a whole ring system.
Or what if the thing we’re looking for isn’t a simple atom such as Br, but rather a concept like “Halogen”? Or, “A
terminal methyl”?
To address this, cheminformatics systems have special query languages, such as SMARTS (SMiles ARbitrary Target
Specification). SMARTS is a close cousin to SMILES, but it has expressions instead of simple atoms and bonds. For
example, [C,N] will find an atom that is either carbon or nitrogen.
Trade Names Names such as Tylenol™ and Valium™ are given to compounds and formulations by manufacturers
for marketing and sales purposes, and for regulatory purposes.
Common names Names such as “aspirin” or “alcohol” for substances that are in widespread use.
Indexing is pre-computing the answers to portions of expected questions before they’re asked, so that when the question
comes, it can be answered quickly.
Take your favorite search engine (AOL, Yahoo!, Google, MSN, . . . ) for example. Without indexing, they might wait
until you ask for “John Hartford Bluegrass”, then start searching the web, and in a year or two find all the web pages
about the deceased banjo/fiddle player and steamboat captain. That would probably not impress you.
Instead, these search engines search the web before you ask your question, and build an index of the words they find.
When you type in “Bluegrass John Hartford”, they already know all of the pages that have “John”, all of the pages
with “Hartford”, and all of the pages with “Bluegrass”. Instead of searching, they examine their index, and find pages
that are on all three lists, and quickly find your results. (NB: It’s actually a lot more complex, but this illustrates the
main idea of indexing.)
Instead of indexing words, cheminformatics systems index substructures. Although there are many schemes for doing
this, cheminformatics systems all use the same fundamental principle: they decompose the molecule into smaller bits,
and index those.
Roughly speaking, a cheminformatics system will index each of the substructures (fragments) above, so that every
molecule that contains each fragment is known.
When a query is entered, the cheminformatics system breaks apart the query using the same technique, to find all of
the fragments in the query. It then checks its index for each fragment, and combines the lists it finds to get only those
molecules that have all of those fragments.
This doesn’t mean that all molecules returned by the index actually are matches. In the language of databases, we say
the index will return false positives, candidate molecules that don’t actually match the substructure search.
Consider our example of searching for “John Hartford” - the index might return many pages that have both “John”
and “Hartford”, yet have nothing to do with bluegrass music or steamboats. For example, it might return a page
containing, “President John F. Kennedy visited Hartford, Connecticut today. . . ”. To confirm that the search system
has found something relevant, it must check the pages return from the index to ensure that the specific phrase “John
Hartford” is present. However, notice that this is much faster than searching every page, since the overwhelming
majority of web pages were instantly rejected because they have neither “John” nor “Hartford” on them.
Similarly, a chemical fragment index serves to find only the most likely molecules for our substructure match - anything
that the index didn’t find is definitely not a match. But we still have to examine each of the molecules returned by the
indexing system and verify that the complete substructure for which we are searching is present.
Searching through a page of text for the words “John Hartford” is pretty easy for a modern computer. Although
false positives returned by the index are a nuisance and impair performance, they are not a catastrophe. Not so for
substructure matching. Unfortunately, substructure matching falls into a category of “hard” mathematical problems,
which means false positives from the index are a big problem.
Substructure matching (finding a certain functional group within a molecule) is an example of what mathematicians
call graph isomorphism, and is in a class of problems called NP Complete. Roughly speaking, this means the time
it takes to do a substructure search is non-polynomial, i.e. exponential in the number of atoms and bonds. To see
why this is a computational disaster, compare two tasks, one that takes polynomial time, k1 *N2 , versus one that takes
exponential time k2 *2N . Our polynomial task is bad enough: If we double N, it takes four times as long to solve. But
the exponential task is worse: Every time we add an atom it doubles. So going from one atom to two doubles the time,
and going from 100 atoms to 101 atoms doubles the time. Even if we can get k2 down to a millionth of k1 , we’re still
in trouble - a million is just 220 or twenty atoms away.
It has been mathematically proven that substructure searching is in the set of NP Complete problems, so there’s no
point wasting our time searching for a polynomial algorithm. The good news is that most molecules have “low con-
nectivity”, meaning most atoms have fewer than four bonds, unlike the weird and twisted graphs that mathematicians
consider. In practice, most substructure matching can be done in polynomial time around N2 or N3 . But even with this
improvement, substructure matching is an “expensive” time-consuming task for a computer.
The key point is that indexing is particularly important for cheminformatics systems. The typical modern computer
can only examine a few thousand molecules per second, so examining millions of molecules one-by-one is out of the
question. The indexing done by a modern cheminformatics system is the key to its performance.
Substructure searching is a very powerful technique, but sometimes it misses answers for seemingly trivial differences.
We saw this earlier with the following:
Query Target
We’re looking for steroids. . . But we don’t find this one because of the double bond
It is somewhat like searching for “221b Baker Street” and finding nothing because the database contains “221B Baker
Street” and the system doesn’t consider “b” and “B” a match.
A good similarity search would find the target structure shown above, because even though it is not a substructure
match, it is highly similar to our query.
There are many ways to measure similarity.
2D topology The best-known and most widely used similarity metrics compare the two-dimensional topology, that
is, they only use the molecule’s atoms and bonds without considering its shape.
Tanimoto similarity is perhaps the best known as it is easy to implement and fast to compute. An excellent
summary of 2D similarity metrics can be found in section 5.3 of the Daylight Theory Manual.
3D configuration One of the most important uses of similarity is in the discovery of new drugs, and a molecule’s
shape is critical to it’s medicinal value (see QSAR).
3D similarity searches compare the configuration (also called the “conformation”) of a molecule to other
molecules. The “electronic surface” of the molecule is the important bit - the part that can interact with other
molecules. 3D searches compare the surfaces of two molecules, and how polarized or polarizable each bit of the
surface is.
3D similarity searches are uncommon, for two reasons: It’s difficult and it’s slow. The difficulty comes from the
complexity of molecular interactions - a molecule is not a fixed shape, but rather a dynamic object that changes
according to its environment. And the slowness comes from the difficulty: To get better results, scientists
employ more and more complex programs.
Physical Properties The above 2D and 3D similarity are based on the molecule’s structure. Another technique com-
pares the properties - either computed or measured or both - and declares that molecules with many properties
in common are likely to have similar structure. It is the idea of QSAR taken to the database.
Clustering “Clustering” is the process of differentiating a set of things into groups where each group has common
features. Molecules can be clustered using a variety of techniques, such as common 2D and/or 3D features.
Note that clustering is not a similarity metric per se (the topic of this section), but it may use various similarity
metrics when computing clusters. It is included here because it can be used as a “cheap substitute”. That is, when
someone wants to find compounds similar to a known compound, you can show them the group (the cluster) to
which the compound belongs. It allows you to pre-compute the clusters, spending lots of computational time up
front, and then give answers very quickly.
Many cheminformatics databases have one or more similarity searches available.
2. The contents of the second bottle were carefully analyzed and found to contain a racemic mixture of the
stereoisomers.
3. The stereoisomers of the third bottle are unknown. It may be pure, or have one predominant form, or be a
racemic mixture.
4. The fourth bottle was obtained by running part of the contents of bottle #2 through a chromatographic separation.
It is isotopically pure, but you don’t know which stereoisomer.
5. The fifth bottle is the other fraction from the same separation of #4. It is also isotopically pure, but you don’t
know which stereoisomer, but you know it’s the opposite of #4.
Which of these five bottles contain the same compound, and which are different? That is the essential task of a
chemical registry system, which would consider all five to be different. After all, you probably have data about each
bottle (that’s why you have them), and you must be able to record it and not confuse it with the other bottles.
In this example above, consider what is known and not known:
A cheminformatics system has no way to record the contents of the five bottles; it is only concerned with structure.
By contrast, a chemical registration system can record both what is known as well as what is not known. This is the
critical difference between the two.
Open Babel stores stereochemistry as the relative arrangement of a set of atoms in space. For example, for a tetrahe-
dral stereocenter, we store information like “looking from atom 2, atoms 4, 5 and 6 are arranged clockwise around
atom 3”. This section describes how a user can work with or manipulate this information. This might be useful to
invert a particular center, replace a substituent at a stereocenter, enumerate stereoisomers or determine the number of
unspecified stereocenters.
Although Open Babel has data structures to support a variety of forms of stereochemistry, currently little use is made
of any stereochemistry other than tetrahedral and cis/trans (and square planar to a certain degree).
We will look first of all at how stereochemistry information is stored, accessed, and modified. Then we describe how
this information is deduced from the chemical structure. This chapter should be read in combination with the API
documentation (see the Stereochemistry overview page found under “Modules”).
Each record of stereochemistry information around an atom or bond is stored as StereoData associated with the OB-
Mol. First of all, let’s look at direct access to the StereoData. The following code counts the number of tetrahedral
centers with specified stereochemistry, as well as the number of double bonds with specified cis/trans stereochemistry:
num_cistrans = 0
num_tetra = 0
if stereotype == ob.OBStereo.CisTrans:
cistrans = ob.toCisTransStereo(stereodata)
if cistrans.IsSpecified():
num_cistrans += 1
121
, Release 3.0.1
All of the stereo handling code uses Ids to reference atoms and bonds, rather than indices. An Open Babel atom
has an index (OBAtom::GetIdx()) and an Id (OBAtom::GetId()). The former runs from 1 to the number of
atoms. The latter can be anything (don’t assume it’s the Idx-1), but is unique within the molecule. If you delete an
atom, the indices change, but the Ids do not. For this reason, all stereo is stored using Ids so that stereo information
is not invalidated by changes to the molecule. When the stereochemistry description involves implicit hydrogens or
lone pairs, the special atom Id OBStereo::ImplicitRef (numerically, -2 or 4294967294 if accessed via
the bindings) is used.
The code above is quite verbose, and requires iteration through all of the stereo data. To make it simpler to access stereo
data for a particular atom or bond, a facade class OBStereoFacade can instead be used, which provides convenience
functions for these operations:
num_cistrans = 0
num_tetra = 0
facade = ob.OBStereoFacade(m)
Note that every time you create a new OBStereoFacade, a certain amount of work is done building up the corre-
spondance between atoms/bonds and stereo data. For this reason, a single OBStereoFacade should be created for a
molecule and reused.
The description of the stereochemical configuration is accessed via a Config() object associated with each Stere-
oData. The contents of this object will be different depending on the specific type of stereochemistry, e.g.
OBCisTransStereo::Config (OBCisTransConfig from Python) records the begin and end Ids of the asso-
ciated bond, the Ids of the attached atoms, the spatial relationship of those atoms, and whether stereo is specified.
Let’s read the SMILES string F[C@@](Cl)(Br)I and access the stereo. When we read this SMILES string, the
tetrahedral center will be the second atom, that with Idx 2.:
smi = "F[C@@](Cl)(Br)I"
mol = pybel.readstring("smi", smi).OBMol
secondatom = mol.GetAtom(2)
atomid = secondatom.GetId()
stereofacade = ob.OBStereoFacade(mol)
print("Does this atom have tet stereo info?", stereofacade.
˓→HasTetrahedralStereo(atomid))
tetstereo = stereofacade.GetTetrahedralStereo(atomid)
config = tetstereo.GetConfig()
print("The stereocenter is at atom Id {}".format(config.center))
print("Is the configuration specified? {}".format("Yes" if config.specified else "No
˓→"))
print("Looking from atom Id {0}, the atoms Ids {1} are arranged clockwise".
˓→format(config.from_or_towards, config.refs))
Which prints:
How do I know that I’m looking from atom Id 0, and that the atom Ids are arranged clockwise? From the documentation
for OBTetrahedralStereo::GetConfig, which states that this is the default. You may be used to thinking
“How are these atoms arranged looking from here?”. With GetConfig(), you are instead making the request “Give me
the atoms in clockwise order looking from here”. It follows from this that you should never need to test the value of the
winding, the direction, or the from/towards atom; you provide these, and their values will be whatever you provided.
For example, you could instead ask for the anticlockwise arrangement of atoms looking towards the atom with Id 0:
Which prints:
Looking towards atom Id 0, the atoms Ids (2, 3, 4) are arranged anticlockwise
To check whether two Configs represent the same stereo configuration, use the equality operator:
It should be noted that the Config objects returned by GetConfig() are copies of the stereo configuration. That is, mod-
ifying them has no affect on the stereochemistry of the molecule (see the next section). As a result, it is straightforward
to keep a copy of the stereo configuration, modify the molecule, and then check whether the modification has altered
the stereochemistry using the equality operator of the Config.
We discuss below the interaction between 2D and 3D structural information and how stereochemistry is perceived.
For now, let’s avoid these issues by using a 0D structure and modifying its stereochemistry:
config.specified = False
tetstereo.SetConfig(config)
print(mol.write("smi", opt={"nonewline": True}))
which prints:
C[C@@H](Cl)F
C[C@H](Cl)F
CC(Cl)F
How did I know that setting the relative arrangement to anti-clockwise would invert the stereo? Again, as described
above, by default GetConfig() returns the atoms in clockwise order. Another way to invert the stereo would be to swap
two of the refs, or to set the direction from ‘from’ to ‘towards’.
Until now we have not mentioned where this stereo information came from; we have read a SMILES string and
somehow the resulting molecule has stereo data associated with it.
Stereo perception is the identification of stereo centers from the molecule and its associated data, which
may include 3D coordinates, stereobonds and existing stereo data. Passing an OBMol to the global
function PerceiveStereo triggers stereo perception, and sets a flag marking stereo as perceived
(OBMol::SetChiralityPerceived(true)). If, in the first place, stereo was already marked as perceived
then stereo perception is not performed. Any operations that require stereo information should call PerceiveStereo
before accessing stereo information.
Behind the scenes, the code for stereo perception is quite different depending on the dimensionality
(OBMol::GetDimension()) of the molecule.
3D structures
Perhaps the most straightforward is when the structure has 3D coordinates. In this case, a symmetry analysis identifies
stereogenic centers whose stereoconfigurations are then perceived from the coordinates. Some file formats such as the
MOL file allow atoms and double bonds to be marked as have unspecified stereochemistry, and this information is
applied to the detected stereocenters. For the specific case of the MOL file, the flag in the atom block that marks this
is ignored by default (as required by the specification) but an option (s) is provided to read it:
$ obabel -:"I/C=C/C[C@@](Br)(Cl)F" --gen3d -omol | obabel -imol -osmi
I/C=C/C[C@@](Br)(Cl)F
$ obabel -:"IC=CCC(Br)(Cl)F" --gen3d -omol | obabel -imol -osmi
(continues on next page)
As just described, the flow of information is from the 3D coordinates to Open Babel’s internal record of stereo centers,
and this flow is triggered by calling stereo perception (which does nothing if the stereo is marked as already perceived).
It follows from this that altering the coordinates after stereo perception (e.g. by reflecting through an axis, thereby
inverting chirality) has no affect on the internal stereo data. If operations are performed on the molecule that require
stereo is be reperceived, then OBMol::SetChiralityPerceived(false) should be called.
It should also be clear from the discussion above that changing the stereo data (e.g. using SetConfig() to invert a
tetrahedral stereocenter) has no affect on the molecule’s coordinates (though it may affect downstream processing,
such as the information written to a SMILES string). If this is needed, the user will have to manipulate the coordinates
themselves, or generate coordinates for the whole molecule using the associated library functions (e.g. the --gen3d
operation).
2D structures
2D structures represent a depiction of a molecule, where stereochemistry is usually indicated by wedge or hash bonds.
It is sometimes indicated by adopting particular conventions (e.g. the Fischer or Haworth projection of monosaccha-
rides). It should be noted that Open Babel does not support any of these conventions, nor does it support the use of
wedge or hash bonds for perspective drawing (e.g. where a thick bond is supported by two wedges). This may change
in future, of course, but it’s worth noting that Open Babel is not the only toolkit with these limitations and so what you
think you are storing in your database may not be what the ‘computer’ thinks it is.
Stereo centers are identified based on a symmetry analysis, and their configuration inferred either from the geometry
(for cis/trans bonds) or from bonds marked as wedge/hash (tetrahedral centers). File format readers record information
about which bonds were marked as wedges or hashes and this can be accessed with OBBond:IsWedge/IsHash, where
the Begin atom of the bond is considered the origin of the wedge/hash. Similar to the situation with 3D perception,
changing a bond from a wedge to a hash (or vice versa) has no affect on the stereo objects once stereo has been
perceived, but triggering reperception will regenerate the desired stereo data.
It should also be noted that the file writers regenerate the wedges or hashes from the stereo data at the point of writing;
in other words, the particular location of the wedge/hash (or even whether it is present) may change on writing.
This was done to ensure that the written structure accurately represents Open Babel’s internal view of the molecule;
passing wedges/hashes through unchanged may not represent this (consider the case where a wedge bond is attached
to a tetrahedral center which cannot be a stereocenter).
0D structures
A SMILES string is sometimes referred to as describing a 0.5D structure, as it can describe the relative arrangement
of atoms around stereocenters. The SMILES reader simply reads and records this information as stereo data, and then
the molecule is marked as having stereo perceived (unless the S option is passed - see below).
Being able to skip the symmetry analysis associated with stereo perception means that SMILES strings can be read
quickly - a useful feature if dealing with millions of molecules. However, if you wish to identify additional stereocen-
ters whose stereo configuration is unspecified, or if the SMILES strings come from an untrusted source and stereo may
have been incorrectly specified (e.g. on a tetrahedral center with two groups the same), then you may wish to trigger
perception.
Without any additional information, stereo cannot be perceived from a structure that has neither 2D nor 3D coordi-
nates. Triggering stereo perception on such a structure will generate stereo data if stereogenic centers are present,
but their configuration will be marked as unspecified. However, where existing stereo data is present (e.g. after read-
ing a SMILES string), that data will be retained if the stereocenter is identified by the perception routine as a true
stereocenter. This can be illustrated using the S option to the SMILES reader, which tells it not to mark the stereo as
perceived on reading; as a result, reperception will occur if triggered by a writer yielding different results in the case
of an erroneously specified stereocenter:
• OBAtom::IsChiral - this is a convenience function that checks whether there is any tetrahedral stereo data
associated with a particular atom. OBStereoFacade should be used in preference to this.
The purpose of this section is to give an overview of how Open Babel handles aromaticity. Given that atoms can be
aromatic, bonds can be aromatic, and that molecules have a flag for aromaticity perceived, it’s important to understand
how these all work together.
Like many other toolkits, Open Babel stores aromaticity information separate from bond order information. This
means that there isn’t a special bond order to indicate aromatic bond. Instead, aromaticity is stored as a flag on an
atom as well as a flag on a bond. You can access and set this information using the following API functions:
• OBAtom::IsAromatic(), OBAtom::SetAromatic(), OBBond::UnsetAromatic()
• OBBond::IsAromatic(), OBBond::SetAromatic(), OBBond::UnsetAromatic()
There is a catch though, or rather a key point to note. OBMols have a flag to indicate whether aromaticity has been
perceived. This is set via the following API functions:
• OBMol::SetAromaticPerceived(), OBMol::UnsetAromaticPerceived()
The value of this flag determines the behaviour of the OBAtom and OBBond IsAromatic() functions.
• If the flag is set, then IsAromatic() simply returns the corresponding value of the atom or bond flag.
• If unset, then IsAromatic() triggers aromaticity perception (from scratch), and then returns the value of the flag.
It’s convenient to use the term “perception”, but what we mean is to apply an aromaticity model. Currently Open
Babel only has a single aromaticity model, which is close to the Daylight aromaticity model. An aromaticity model
describes how many pi electrons are contributed by each atom; if this sums to 4n+2 within a cycle, then all atoms and
bonds in that cycle will be marked as aromatic.
Applying a model involves creating an instance of OBAromaticTyper(), and calling AssignAromaticFlags() passing
an OBMol as a parameter. This wipes any existing flags, sets the atom and bond flags according to the model, and
marks the aromaticity as perceived.
127
, Release 3.0.1
If you wish (and know what you are doing), you can apply your own aromaticity model by setting various atoms and
bonds as aromatic and then marking the molecule as having aromaticity perceived. Naturally, not all models will make
sense chemically. Even more problematic is the situation where no Kekulé form exists that corresponds to the aromatic
form. And finally, there is the philosophical question of the meaning of an aromatic atom without aromatic bonds, and
vice versa.
Putting the pieces together, let’s look at the interaction between SMILES reading/writing and the handling of aro-
maticity.
Writing SMILES
Unless Kekulé SMILES are requested (via the k output option), the SMILES writer will always write an aromatic
SMILES string. IsAromatic() will be called on atoms and bonds to determine whether to use lowercase letters. As
described earlier, this will trigger aromaticity perception according to the default model if the molecules is not marked
as having its aromaticity perceived.
Reading SMILES
The situation when reading SMILES is a bit more involved. If the SMILES string contains lowercase characters and
aromatic bonds, this information is used to mark atoms and bonds as aromatic. The molecule is then kekulized to
assign bond orders to aromatic bonds. Next, unless the a option is supplied, the molecule is marked as having its
aromaticity unperceived.
That last step might seem strange. Why, after going to the trouble of reading the aromaticity and using it to kekulize,
do we then effectively ignore it?
The reason is simply this: when writing an aromatic SMILES, we usually want to use our own aromaticity model and
not that present in the input SMILES string. Otherwise, SMILES strings for the same molecule from different sources
(that may use different aromaticity models) would not yield the same canonical SMILES string.
Of course, if the SMILES string came from Open Babel in the first place, we are doing unnecessary work when we
keep reapplying the same aromaticity model. In this case, you can speed things up by using the a option, so that the
aromaticity information present in the input is retained. The following examples show this in action:
Perhaps surprisingly, modifying the structure has no effect on the existing aromaticity flags; deleting an atom does
not mark aromaticity as unperceived, nor indeed does any other change to the structure such as changing the atomic
number of an atom or setting its charge; nor does the use of Begin/EndModify() affect the aromaticity flags. The only
way to ensure that aromaticity is reperceived after modifying the structure is to explicitly mark it as unperceived.
The rationale for this is that an efficient toolkit should avoid unnecessary work. The toolkit does not know if a
particular modification invalidates any aromaticity already perceived, or even if it did know, it cannot know whether
the user actually wishes to invalidate it. It’s up to the user to tell the toolkit. This places more responsibility in the
hands of the user, but also more power.
To illustrate, let’s consider what happens when the user reads benzene from the SMILES string c1ccccc1, and then
modifies the structure by deleting an aromatic atom.
As this is an aromatic SMILES string, the SMILES reader will mark all atoms and bonds as aromatic. Next, the
molecule itself is marked as not having aromaticity perceived (see previous section). After reading, we can trigger
aromaticity perception by calling IsAromatic() on an atom; now, in addition to the atoms and bonds being marked as
aromatic, the molecule itself will be marked as having aromaticity perceived.
If at this point we delete a carbon and write out a SMILES string, what will the result be? You may expect something
like [CH]=CC=C[CH] (or C=CC=CC if we also adjust the hydrogen count on the neighbor atoms) but instead it will
be [cH]ccc[cH] (or ccccc if hydrogens were adjusted).
This follows from the discussion above - structural modifications have no effect on aromaticity flags. If instead the
user wishes the SMILES writer to reperceive aromaticity, all that is necessary is to mark the molecule as not having
aromaticity perceived, in which case the Kekulé form will instead be obtained.
Hydrogen deficient molecules, radicals, carbenes, etc., are not well catered for by chemical software aimed at phar-
maceuticals. But radicals are important reaction intermediates in living systems as well as many other fields, such as
polymers, paints, oils, combustion and atmospheric chemistry. The examples given here are small molecules, relevant
to the last two applications.
Chemistry software to handle radicals is complicated by the common use of implicit hydrogen when describing
molecules. How is the program to know when you type “O” whether you mean an oxygen atom or water? This
ambiguity leads some to say that hydrogens should always be explicit in any chemical description. But this is not the
way that most chemists work. A straight paraffinic chain from which a hydrogen had been abstracted might commonly
Open Babel accepts molecules with explicit or implicit hydrogens and can convert between the two. It will also handle
radicals (and other hydrogen-deficient species) with implicit hydrogen by using internally a property of an atom,
_spinmultiplicity, modelled on the RAD property in MDL MOL files and also used in CML. This can be regarded in
the present context as a measure of the hydrogen deficiency of an atom. Its value is:
• 0 for normal atoms,
• 2 for radical (missing one hydrogen) and
• 1 or 3 for carbenes and nitrenes (missing two hydrogens).
It happens that for some doubly deficient species, like carbene CH2 and oxygen atoms, the singlet and triplet species
are fairly close in energy and both may be significant in certain applications such as combustion, atmospheric or
preparative organic chemistry, so it is convenient that they can be described separately. There are of course an in-
finity of other electronic configurations of molecules but Open Babel has no special descriptors for them. However,
even more hydrogen-deficient atoms are indicated by the highest possible value of spinmultiplicity (C atom has spin
multiplicity of 5). (This extends MDL’s RAD property which has a maximum value of 3.)
131
, Release 3.0.1
If the spin multiplicity of an atom is not input explicitly, it is set (in :obapi:‘OBMol::AssignSpinMultiplicity()
<OpenBabel::OBMol::AssignSpinMultiplicity>‘) when the input format is MOL, SMI, CML or Therm. This rou-
tine is called after all the atoms and bonds of the molecule are known. It detects hydrogen deficiency in an atom and
assigns spin multiplicity appropriately. But because hydrogen may be implicit it only does this for atoms which have at
least one explicit hydrogen or on atoms which have had :obapi:‘ForceNoH() <OpenBabel::OBAtom::ForceNoH>‘
called for them - which is effectively zero explicit hydrogens. The latter is used, for instance, when SMILES inputs
[O] to ensure that it is seen as an oxygen atom (spin multiplicity=3) rather than water. Otherwise, atoms with no
explicit hydrogen are assumed to have a spin multiplicity of 0, i.e with full complement of implicit hydrogens.
In deciding which atoms should be have spin multiplicity assigned, hydrogen atoms which have an isotope specifica-
tion (D,T or even 1H) do not count. So SMILES N[2H] is NH2 D (spin multiplicity left at 0, so with a full content
of implicit hydrogens), whereas N[H] is NH (spin multiplicity=3). A deuterated radical like NHD is represented by
[NH][2H].
Once the spin multiplicity has been set on an atom, the hydrogens can be implicit even if it is a radical. For instance,
the following mol file, with explicit hydrogens, is one way of representing the ethyl radical:
ethyl radical
OpenBabel04010617172D
Has explicit hydrogen and implicit spin multiplicity
7 6 0 0 0 0 0 0 0 0999 V2000
0.0000 0.0000 0.0000 C 0 0 0 0 0
0.0000 0.0000 0.0000 C 0 0 0 0 0
0.0000 0.0000 0.0000 H 0 0 0 0 0
0.0000 0.0000 0.0000 H 0 0 0 0 0
0.0000 0.0000 0.0000 H 0 0 0 0 0
0.0000 0.0000 0.0000 H 0 0 0 0 0
0.0000 0.0000 0.0000 H 0 0 0 0 0
1 2 1 0 0 0
1 3 1 0 0 0
1 4 1 0 0 0
1 5 1 0 0 0
2 6 1 0 0 0
2 7 1 0 0 0
M END
When read by Open Babel the spinmultiplicity is set to 2 on the C atom 2. If the hydrogens are made implicit, perhaps
by the -d option, and the molecule output again, an alternative representation is produced:
ethyl radical
OpenBabel04010617192D
Has explicit spin multiplicity and implicit hydrogen
2 1 0 0 0 0 0 0 0 0999 V2000
0.0000 0.0000 0.0000 C 0 0 0 0 0
0.0000 0.0000 0.0000 C 0 0 0 0 0
1 2 1 0 0 0
M RAD 1 2 2
M END
Although radical structures can be represented in SMILES by specifying the hydrogens explicitly, e.g. [CH3] is
the methyl radical, some chemists have apparently felt the need to devise non-standard extensions that represent the
radical centre explicitly. Open Babel will recognize C[O.] as well as C[O] as the methoxy radical CH3 O during
input, but the non-standard form is not supported in output.
By default, radical centres are output in explict hydrogen form, e.g. C[CH2] for the ethyl radical. All the atoms will
be in explict H form, i.e. [CH3][CH2], if :obapi:‘AddHydrogens() <OpenBabel::OBMol::AddHydrogens>‘ or
the -h option has been specified. The output is always standard SMILES, although other programs may not interpret
radicals correctly.
Open Babel supports another SMILES extension for both input and output: the use of lower case atomic symbols to
represent radical centres. (This is supported on the ACCORD Chemistry Control and maybe elsewhere.) So the ethyl
radical is Cc and the methoxy radical is Co. This form is input transparently and can be output by using the -xr
option “radicals lower case”. It is a useful shorthand in writing radicals, and in many cases is easier to read since the
emphasis is on the radical centre rather than the number of hydrogens which is less chemically significant.
In addition, this extension interprets multiple lower case c without ring closure as a conju-
gated carbon chain, so that cccc is input as 1,3-butadiene. Lycopene (the red in tomatoes) is
Cc(C)cCCc(C)cccc(C)cccc(C)ccccc(C)cccc(C)cccc(C)CCcc(C)C (without the stereochemical
specifications). This conjugated chain form is not used on output - except in the standard SMILES aromatic form,
c1ccccc1 benzene.
It is interesting to note that the lower case extension actually improves the chemical representation in a few cases. The
allyl radical C3 H5 would be conventionally [CH2]=[CH][CH2] (in its explict H form), but could be represented
as ccc with the extended syntax. The latter more accurately represents the symmetry of the molecule caused by
delocalisation.
This extension is not as robust or as carefully considered as standard SMILES and should be used with restraint.
A structure that uses c as a radical centre close to aromatic carbons can be confusing to read, and Open Babel’s
SMILES parser can also be confused. For example, it recognizes c1ccccc1c as the benzyl radical, but it doesn’t
like c1cc(c)ccc1. Radical centres should not be involved in ring closure: for cyclohexyl radical C1cCCCC1 is ok,
but c1CCCCC1 is not.
16.1 Overview
Open Babel is developed using open, community-oriented development made possible by an active community –
developers, testers, writers, implementers and most of all users. No matter which ‘er’ you happen to be, or how much
time you can provide, you can make valuable contributions.
Not sure where to start? This section aims to give you some ideas.
Provide input
If you find Open Babel useful, there’s a chance that others will also. You can help us by:
• promoting and citing Open Babel in talks and publications
• writing blog posts about Open Babel
• helping with documentation and our website
• building your own software on Open Babel
To get started, just send an email to our mailing list.
Code a storm
As an open source project, Open Babel has a very open development process. This means that many contributors have
helped with the project with a variety of help – some for long periods of time, and some with small, single changes.
All types of assistance has been valuable to the growth of the project over the years.
135
, Release 3.0.1
New developers are always very welcome to OpenBabel so if you’re interested, just send an email to the developer list
(join here) about what you would like to work on, or else we can come up with some ideas for areas where you could
contribute. Here are some possibilities:
• Implement the latest algorithms described in the literature
• Add a new file format (see How to add a new file format)
• Perform ‘software archaeology’ (see Software Archaeology)
• Fix some bugs
• Add a requested feature
• Implement a feature from our roadmap
Due to its open nature of its development, Open Babel contains code contributed by a wide variety of developers (see
Thanks). This section describes some general guidelines and “best practices” for code developers.
For new and existing developers here are some useful resources:
• GitHub project page
• Development version API documentation
• Development version Sphinx documentation
To download and update the latest version of the Open Babel source code, you need Git. Git is the name of the project
used to maintain the Open Babel version control repository. There are many clients for Git, including command-line
and GUI applications.
This creates a directory called openbabel-dev, which contains the latest source code from Open Babel.
(2) Configure and compile this using CMake (see Compiling Open Babel).
(3) After some time passes, and you want the latest bug fixes or new features, you may want to update your source
code. To do this, go into the openbabel-dev directory you created above, and type:
git pull -u
Since version 2.0, Open Babel has had a modular structure. Particularly for the use of Open Babel as a chemical file
format converter, it aims to:
• separate the chemistry, the conversion process and the user interfaces, reducing, as far as possible, the depen-
dency of one on another.
• put all the code for each chemical format in one place (usually a single cpp file) and make the addition of new
formats simple.
• allow the format conversion of not just molecules, but also any other chemical objects, such as reactions.
Fig. 1: The structure of the Open Babel codebase broken down into modules
• The Chemical core, which contains OBMol etc. and has all the chemical structure description and manipulation.
This bit is the heart of the application and its API can be used as a chemical toolbox. It has no input/output
capabilities.
• The Formats, which read and write to files of different types. These classes are derived from a common base
class, OBFormat, which is in the Conversion Control module. They also make use of the chemical routines in
the Chemical Core module. Each format file contains a global object of the format class. When the format is
loaded the class constructor registers the presence of the class with OBConversion. This means the formats are
plugins - new formats can be added without changing any framework code.
• Common Formats include OBMoleculeFormats and XMLBaseFormat from which most other formats (like
Format A and Format B in the diagram) are derived. Independent formats like Format C are also possible.
• The Conversion control, which also keeps track of the available formats, the conversion options and the input
and output streams. It can be compiled without reference to any other parts of the program. In particular, it
knows nothing of the Chemical core: mol.h is not included.
• The User interface, which may be a command line (in main.cpp), a Graphical User Interface(GUI), especially
suited to Windows users and novices, or may be part of another program which uses OpenBabel’s input and
output facilities. This depends only on the Conversion control module (obconversion.h is included), but not on
the Chemical core or on any of the Formats.
• The Fingerprint API, as well as being usable in external programs, is employed by the fastsearch and fingerprint
formats.
• The Fingerprints, which are bit arrays which describe an object and which facilitate fast searching. They are
also built as plugins, registering themselves with their base class OBFingerprint which is in the Fingerprint API.
• The Error handling can be used throughout the program to log and display errors and warnings (see below).
It is possible to build each box in the diagram as a separate DLL or shared library and the restricted dependencies can
help to limit the amount of recompilation. For the formats or the fingerprints built in this way it may be possible to use
only those whose DLL or so files are present when the program starts. Several formats or fingerprints may be present
in a single dynamic library.
Alternatively, and most commonly, the same source code can be built into a single executable. The restricted depen-
dencies still provide easier program maintenance.
This segregation means that a module can directly call code only in other modules connected to it by forward arrows.
So some discipline is needed when adding new code, and sometimes non-obvious work-arounds are necessary. For
instance, since the user interface doesn’t know about the Chemical Core, if it were necessary to set any parameters in
it, then this would have to be done through a pseudo format OBAPIInterface.
Sometimes one format needs to use code from another format, for example, rxnformat needs to read mol files with
code from mdlformat. The calling format should not use the code directly but should do it through a OBConversion
object configured with the appropriate helper format.
The objects passed between the modules in the diagram above are polymorphic :obapi:‘OBBase‘ pointers. This means
that the conversion framework can be used by any object derived from OBBase (which essentially means anything -
chemical or not). Most commonly these refer to OBMol objects, less commonly to OBReaction objects, but could be
extended to anything else without needing to change any existing code.
The general philosophy of the Open Babel project is to attempt to gracefully recover from error conditions. Depending
on the severity of the error, a message may or may not be sent to the user – users can filter out developer debugging
messages and minor errors, but should be notified of significant problems.
Errors and warnings in Open Babel are handled internally by a flexible system motivated by a few factors:
• End users often do not wish to be deluged by debugging or other messages during operation.
• Other developers may wish to redirect or filter error/warning output (e.g., in a GUI).
• The operation of Open Babel should be open to developers and users alike to monitor an “audit trail” of opera-
tions on files and molecules, and debug the program and library itself when the need arises.
Multiple error/warning levels exist and should be used by code. These are defined in the :obapi:‘obMessageLevel‘
enum as follows:
• obError – for critical errors (e.g., cannot read a file)
• obWarning – for non-critical problems (e.g., molecule appears empty)
• obInfo – for informative messages (e.g., file is a non-standard format)
• obAuditMsg – for messages auditing methods which destroy or perceive molecular data (e.g., kekulization,
atom typing, etc.)
• obDebug – for messages only useful for debugging purposes
The default filter level is set to obWarning, which means that users are told of critical errors, but not non-standard
formatting of input files.
A global error handler :obapi:‘obErrorLog‘ (an instance of :obapi:‘OBMessageHandler‘) is defined and should be
used as shown in the API documentation for the :obapi:‘OBMessageHandler‘ class.
mol.BeginModify();
double x,y,z;
OBAtom *atom;
vector<string> vs;
atom = mol.NewAtom();
x = atof((char*)vs[1].c_str());
y = atof((char*)vs[2].c_str());
z = atof((char*)vs[3].c_str());
This code reads in a list of atoms with XYZ coordinates and the atomic number in the first column (vs[0]). Since
hundreds or thousands of atoms could be added to a molecule, followed by creating bonds, the code is enclosed in a
BeginModify()/EndModify() pair.
16.3 Documentation
Documenting Open Babel is an important and ongoing task. As an open source project, code must be documented,
both for other developers to use the API and for others to follow your code. This includes clear documentation on the
interfaces of particular classes and methods (that is, the API documentation) but also tutorials and examples of using
the Open Babel library to accomplish clear tasks.
Beyond the documentation described above, as an open-source project involving many, many contributors, the internal
code should be clearly commented and easy to read (in English, preferably, since this is the common language of
developers on the project).
The golden rule is write the documentation, then code to the specs.
You should never, ever start writing code unless you’ve specified, clearly and exactly, what your code will do. This
makes life easier for you (i.e., you know exactly what the code should do), and for others reading your code.
This mantra also facilitates writing tests (see Adding a new test).
When modifying old code, please take a little time to improve the documentation of the function.
Even an “obvious” function must be documented, if for no other reason than to say, “This function does what you
think, and has no side effects.”
Take :obapi:‘OBAtom::SetAtomicNum() <OpenBabel::OBAtom::SetAtomicNum>‘ - should be “obvious”, right?
Wrong.
• Does it affect the charge?
• The spin multiplicity?
• The implicit valence?
• The hybridization?
• What happens if I do SetHybridization(3) and then SetAtomicNum(1)?
• Does the molecule have to be in the modify state?
• If the molecule is not in the modify state, is it put into the modify state by SetAtomicNum()?
• Does SetAtomicNum() cause a recomputation of aromaticity?
There’s no point spending time adding new features to Open Babel unless you describe how to use them and give
examples. The best place to do this is in the user documentation. . . which you’re reading right now.
This documentation is automatically generated from text files in a simple markup language (reStructuredText) using
the Sphinx documentation system. This allows us to generate web pages, PDF files, and even ePub eBooks all from
the same source (which is currently maintained at BitBucket).
If you notice any errors or feel like adding a section, please let us know at openbabel-devel.
Tests allow us to maintain code quality, ensure that code is working, prevent regressions, and facilitate refactoring.
Personally, I find that there is no better motivation for writing tests than knowing that that bug I fixed will stay fixed,
and that feature I implemented will not be broken by others. As an open source developer, I never have enough time;
tests ensure that what time I have is not wasted.
We can divide the existing tests into three classes, based on how they test the Open Babel codebase:
1. Tests written in C++ that test the public API
2. Tests written in Python that use the SWIG bindings to test the public API
3. Tests written in Python that use the command-line executables for testing
Which type of test should you write? It doesn’t really matter - it’s more important that you write some type of test.
Personally, I can more quickly test more if I write the test in Python, so generally I write and check-in tests of type (2)
above; when I need to run a testcase in a debugger, I write a short test of type (1) so that I can step through and see
what’s happening.
To begin with, we need to configure CMake to enable tests: -DENABLE_TESTS=ON. This adds the make test
target and builds the C++ tests. For tests of type 3 (above), you will also need to enable the Python bindings:
-DPYTHON_BINDINGS=ON -DRUN_SWIG=ON. Some tests are dependent on optional dependencies; if you don’t
build with support for these, then the corresponding tests will not be run.
To actually run the tests, you can run the entire test suite in one go or run individual tests. To run the entire suite, use
make test or ctest (note that you can use the -j option to speed up ctest). The ctest command also allows a
single test or a list of tests to be specified, and in combination with -VV (verbose) may be useful to run an individual
test. However, I find it more useful to run individual tests directly. Here is an example of how to run an individual test
for each of the three types discussed earlier:
1. test_runner regressionstest 1
This will run test number 1 in regressionstest.cpp. Nothing will happen. . . unless the test fails.
(test_runner is a testing harness generated by CMake.)
2. python test\testbindings.py TestSuite.testAsterisk
This will run the testAsterisk test in testbindings.py. This will write out a single dot, and some summary
information.
3. python test\testbabel.py testOBabel.testSMItoInChI
This will run the testSMItoInChI test in testbabel.py.
The next few sections describe adding a new test of types 1 to 3. The same test will be added, a test to ensure that the
molecular weight of ethanol is reported as 46.07.
The easiest place to add new tests is into test/regressionstest.cpp. Look at the switch statement at the end
of the file and pick a number for the test. Let’s say 260. Add the following:
case 260:
test_Ethanol_MolWt();
break;
Now add the value of 260 to test/CMakeLists.txt so that it will be run as part of the testsuite.:
set (regressions_parts 1 221 222 223 224 225 226 227 260)
Now let’s add the actual test somewhere near the top of the file:
void test_Ethanol_MolWt()
{
OBMol mol;
OBConversion conv;
OB_REQUIRE(conv.SetInFormat("smi"));
conv.ReadString(&mol, "CCO");
double molwt = mol.GetMolWt();
OB_ASSERT(molwt - 46.07 < 0.01);
}
The various assert methods are listed in obtest.h and are as follows:
• OB_REQUIRE(exp) - This must evaluate to true or else the test will be marked as failing and will terminate.
This is useful for conditions that must be true or else the remaining tests cannot be run (e.g. was the necessary
OBFormat found?).
• OB_ASSERT(exp) - This must evaluate to true or else the test will be marked as failing. In contrast to
OB_REQUIRE, the test does not terminate in this case, but continues to run. This feature can be useful because
it lets you know (based on the output) how many and which OB_ASSERT statements failed.
• OB_COMPARE(expA, expB) - Expressions A and B must be equal or else the test fails (but does not termi-
nate).
It is often useful to write a test that uses a checked-in testfile. Let’s do this for our example testcase. If you place
a file ethanol.smi into test/files, then the following will read it using a convenience function provided by
obtest.h.:
void test_Ethanol_MolWt()
{
OBMolPtr mol = OBTestUtil::ReadFile("ethanol.smi")
double molwt = mol.GetMolWt();
OB_ASSERT(molwt - 46.07 < 0.01);
}
As well as ReadFile (which is convenient for single molecules), the OBTestUtil struct provides GetFilename
which will return the full path to the testfile, if you wish to open it yourself.
At the command-line we can calculate the molecular weight of ethanol as shown below. We are going to do something
similar using the Python test framework:
Open test/testbabel.py in an editor. I have grouped tests related to the obabel executable into a class
testOBabel, so let’s add a new test there. Somewhere in that class (for example, at the end), add a function such as the
following (note: it must begin with the word “test”):
def testMolWtEthanol(self):
"""Check the molecular weight of ethanol"""
self.canFindExecutable("obabel")
answers = [
("CCO", 46.07),
("[H]", 1.01),
("[2H]", 2.01),
]
for smi, molwt in answers:
output, error = run_exec('obabel -:%s --append mw -otxt' % smi)
my_molwt = round(float(output), 2)
self.assertEqual(my_molwt, molwt)
We provide a few convenience functions to help write these tests. The most important of these is
run_exec(command) which runs the commandline executable returns a tuple of stdout and stderr. Behind the
scenes, it adds the full path to the named executable. In the example above, run_exec(stdin, command) took
a single argument; the next example will show its use with two arguments - the additional argument is a string which
is treated as stdin, and piped through the executable.
In the previous example, each SMILES string was passed in one-at-a-time. However, it is more efficient to do them all
in one go as in the following example:
def testMolWtEthanol(self):
"""Check the molecular weight of ethanol"""
self.canFindExecutable("obabel")
smifile = """CCO
[H]
[2H]
"""
answers = [46.07, 1.01, 2.01]
output, error = run_exec(smifile, 'obabel -ismi --append mw -otxt')
for ans, my_ans in zip(answers, output.split("\n")):
self.assertEqual(ans, round(float(my_ans), 2))
def testMolWtEthanol(self):
"""Check the molecular weight of ethanol"""
self.canFindExecutable("obabel")
answers = [46.07, 1.01, 2.01]
smifile = self.getTestFile("ethanol.smi")
output, error = run_exec('obabel %s --append mw -otxt' % smifile)
for ans, my_ans in zip(answers, output.split("\n")):
self.assertEqual(ans, round(float(my_ans), 2))
The easiest place to add new tests is into test/testbindings.py. Classes are used to organise the tests, but for
a single ‘miscellaneous’ test a good place is the TestSuite class. Somewhere in that class add the following function:
def testMolWtEthanol(self):
"""Check the molecular weight of ethanol"""
answers = [
("CCO", 46.07),
("[H]", 1.01),
("[2H]", 2.01),
]
for smi, molwt in answers:
my_molwt = round(pybel.readstring("smi", smi).molwt, 2)
self.assertEqual(my_molwt, molwt)
The variable here is defined in testbindings.py and may be used find the path to testfiles. For example, given
the test/ethanol.smi, the following may be used to read it:
def testMolWtEthanol(self):
"""Check the molecular weight of ethanol"""
answers = [46.07, 1.01, 2.01]
testfile = os.path.join(here, "test", "ethanol.smi")
for mol, answer in zip(pybel.readfile("smi", testfile), answers):
my_molwt = round(mol.molwt, 2)
self.assertEqual(my_molwt, molwt)
The tests use the standard unittest framework. One thing to note, which is not obvious, is how to test for exceptions. A
typical case is checking that a dodgy SMILES is rejected on reading; in this instance, Pybel.readstring() will
raise an IOError. To assert that this is the case, rather than use try/except, the following syntax is required:
If you have multiple tests to add on a single ‘topic’, you will probably want to add your own class either into
testbindings.py or a new Python file. Note that if you create a new Python file, it should start with the word
test and you will need to add the rest of the name to the pybindtest list in test/CMakeLists.txt.
Potential problems/gotchas:
• Why isn’t your Python test being run? Test functions name must begin with the word test.
• If your new test passes first time, check that it is actually running correctly, by changing your asserts so that they
should fail.
• The C++ tests will be marked as failing if the test writes any of the following to stdout: ERROR, FAIL, Test
failed. This is actually how the assert methods work.
• It’s best to avoid writing to disk, and instead write to a variable or stdout and capture it (as in the examples
above).
In any large software project, some parts of the code are revised and kept up-to-date more than others.
Conversely, some parts of the code begin to fall behind – the code may be poorly tested, poorly documented, and not
always up to best practices.
With that in mind, the following sections describe the important task of software archeology – diving in to older parts
of code and bringing them up to date. Whenever editing a file, please keep these in mind.
• Minimize #if/#endif conditional compilation. Some is required for portability, but these should be mini-
mized where possible. If there seems to be some magic #define which accesses parts of the file, it’s probably
dead code. As above, dead code makes it harder to maintain and read everything else.
• Removing calls to cout, cerr, STDOUT, perror etc. These should use the global error reporting code.
• Minimize warnings from compilers (e.g., GCC flags -Wextra -Wall). Sometimes these are innocuous, but
it’s usually better to fix the problems before they become bugs.
• Use static code analysis tools to find potential bugs in the code and remove them.
• Insure proper use of atom and bond iterators, e.g., FOR_ATOMS_OF_MOL rather than atom or bond index
access, which will break if indexing changes.
Patches and contributions towards any of these tasks will be greatly appreciated.
Open Babel uses a plugin architecture for file formats, ‘operations’, charge models, forcefields, fingerprints and de-
scriptors. The general idea behind plugins is described on Wikipedia. When you start an application that uses the
Open Babel library, it searches for available plugins and loads them. This means, for example, that plugins could be
distributed separately to the Open Babel distribution.
In fact, even the plugin types are themselves plugins; this makes it easy to add new categories of plugin. The different
types of plugins can be listed using:
C:\>babel -L
charges
descriptors
fingerprints
forcefields
formats
loaders
ops
To list the plugins of a particular type, for example, charge models, just specify the plugin type:
C:\>babel -L charges
gasteiger Assign Gasteiger-Marsili sigma partial charges
mmff94 Assign MMFF94 partial charges
qeq Assign QEq (charge equilibration) partial charges (Rappe and Goddard, 199
1)
qtpie Assign QTPIE (charge transfer, polarization and equilibration) partial
charges (Chen and Martinez, 2007)
To add a new plugin of any type, the general method is very simple:
1. Make a copy of an existing plugin .cpp file
2. Edit it so that it does what you want
3. Add the name of the .cpp file to the appropriate CMakeLists.txt.
The following sections describe in depth how to add support for a new file format or operation to Open Babel. Re-
member that if you do add a new plugin, please contribute the code back to the Open Babel project.
147
, Release 3.0.1
Adding support for a new file format is a relatively easy process, particularly with Open Babel 2.3 and later. Here are
several important steps to remember when developing a format translator:
1. Create a file for your format in src/formats/ or src/formats/xml/ (for XML-based formats). Ideally,
this file is self-contained although several formats modules are compiled across multiple source code files.
2. Add the name of the new .cpp file to an appropriate place in src/formats/CMakeLists.txt. It will now
be compiled as part of the build process.
3. Take a look at other file format code, particularly exampleformat.cpp, which contains a heavily-annotated
description of writing a new format. XML formats need to take a different approach; see the code in
xcmlformat.cpp or pubchemformat.cpp.
4. When reading in molecules (and thus performing a lot of molecular modifications) call
:obapi:‘OBMol::BeginModify() <OpenBabel::OBMol::BeginModify>‘ at the beginning and
:obapi:‘OBMol::EndModify() <OpenBabel::OBMol::EndModify>‘ at the end. This will ensure that
perception routines do not run while you read in a molecule and are reset after your code finishes (see Lazy
Evaluation).
5. Currently, lazy perception does not include connectivity and bond order assignment. If
your format does not include bonds, make sure to call :obapi:‘OBMol::ConnectTheDots()
<OpenBabel::OBMol::ConnectTheDots>‘ and :obapi:‘OBMol::PerceiveBondOrders() <Open-
Babel::OBMol::PerceiveBondOrders>‘ after :obapi:‘OBMol::EndModify() <OpenBa-
bel::OBMol::EndModify>‘ to ensure bonds are assigned.
6. Consider various input and output options that users can set from the command-line or GUI. For example, many
quantum mechanics formats (as well as other formats which do not recognize bonds) offer the following options:
-as Call only :obapi:‘OBMol::ConnectTheDots() <OpenBabel::OBMol::ConnectTheDots>‘ (single bonds
only)
-ab No bond perception
7. Make sure to use generic data classes like :obapi:‘OBUnitCell‘ and others as appropriate. If your format stores
any sort of common data types, consider adding a subclass of :obapi:‘OBGenericData‘ for use by other formats
and user code.
8. Please make sure to add several example files to the test set repository. Ideally, these should work several areas
of your import code – in the end, the more robust the test set, the more stable and useful Open Babel will be. The
test files should include at least one example of a correct file and one example of an invalid file (i.e., something
which will properly be ignored and not crash babel).
9. Make sure to document your format using the string returned by Description(). At the minimum this
should include a description of all options, along with examples. However, the more information you add (e.g.
unimplemented features, applications of the format, and so forth) the more confident users will be in using it.
10. That’s it! Contact the openbabel-discuss mailing list with any questions, comments, or to contribute your new
format code.
Options that control the conversion process For example -i, -o and -m
Options specific to particular input or output formats These are specified with the -a and -x prefixes
General options These usually operate on a molecule after it has been read by the input format and
before it has been written by the output format.
The ones of interest here are the general options. These can be single letter options like -c (which centers coordinates),
or multi-character options like --separate (which makes separate molecules from disconnected fragments). The
ones mentioned are hardwired into the code, but it is possible to define new options that work in a similar way. This is
done using the :obapi:‘OBOp‘ class.
The name :obapi:‘OBOp‘ is intended to imply an operation as well as an option. This is a plugin class, which means
that new ops are easily added without a need to alter any existing code.
The ops that are installed can be found using:
babel -L ops
or in the plugins menu item in the GUI. An example is the --gen3D option, which adds 3D coordinates to a molecule:
12 OpGen3D theOpGen3D("gen3D");
13
20 OBBuilder builder;
21 builder.Build(*pmol);
22 pmol->SetDimension(3);
23
24 return true;
25 }
The real work is done in the Do function, but there is a bit of boilerplate code that is necessary.
Line 4: The constructor calls the base class constructor, which registers the class with the system. There could be
additional parameters on the constructor if necessary, provided the base constructor is called in this way. (The false
parameter value is to do with setting a default instance which is not relevant here.)
Line 5: It is necessary to provide a description. The first line is used as a caption for the GUI checkbox. Subsequent
lines are shown when listed with the verbose option.
Line 7: WorksWith() identifies the type of object. Usually this is a molecule (OBMol) and the line is used as shown.
The function is used by the GUI to display the option only when it is relevant.
The OBOp base class doesn’t know about OBMol or OBConversion and so it can be used with any kind of
object derived from OBBase (essentially anything). Although this means that the dependencies between
one bit of the program and another are reduced, it does lead to some compromises, such as having to code
WorksWith() explicitly rather than as a base class default.
Line 12: This is a global instance which defines the Id of the class. This is the option name used on the command line,
preceded by --.
Line 14: The Do() function carries out the operation on the target object. It should normally return true. Returning
false prevents the molecule being sent to the output format. Although this means that it is possible to use an OBOp
class as a filter, it is better to do this using the --filter option.
Any other general options specified on the command line (or the GUI) can be accessed by calling find on the parameter
pmap. For example, to determine whether the -c option was also specified:
Group contribution descriptors are a common type of molecular descriptor whose value is a sum of contributions from
substructures of the molecule. Such a descriptor can easily be added to Open Babel without the need to recompile the
code. All you need is a set of SMARTS strings for each group, and their corresponding contributions to the descriptor
value.
The following example shows how to add a new descriptor, hellohalo, whose value increments by 1, 2, 3 or 4 for each
F, Cl, Br, and I (respectively) in the molecule.
1. Create a working directory, for example C:\Work.
2. Copy the plugin definition file, plugindefines.txt to the working directory. This file can be
found in the Open Babel data directory (typically in /usr/share/openbabel on Linux systems, or
C:\Users\username\AppDataRoaming\OpenBabel-2.3.2\data on Windows).
3. For the hellohalo descriptor, add the following to the end of plugindefines.txt (make sure to include a
blank line between it and other descriptor definitions):
OBGroupContrib
hellohalo # name of descriptor
hellohalo_smarts.txt # data file
Count up the number of halogens (sort of)\n # brief description
This descriptor is not correlated with any\n # longer description
known property, living or dead.
4. Now create a file hellohalo_smarts.txt, again in the working directory, containing the following
SMARTS definitions and contribution values:
That’s it!
Now let’s test it. Open a command prompt, and change directory to the working directory. We can find information
on the new descriptor using obabel’s -L option:
C:\Work>obabel -L descriptors
abonds Number of aromatic bonds
atoms Number of atoms
...
hellohalo Count up the number of halogens (sort of)
...
title For comparing a molecule's title
TPSA topological polar surface area
C:\Work>obabel -L hellohalo
One of the descriptors
hellohalo Count up the number of halogens (sort of)
This descriptor is not correlated with any
known property, living or dead.
Datafile: hellohalo_smarts.txt
OBGroupContrib is definable
An easy way to test the descriptor is to use the title output format, and append the descriptor value to the title:
;heavy
[*] 0.4 # All atoms
[#6] 1.0 # All carbon atoms
3. If you wish to take into account contributions from hydrogen atoms, you should precede the ;heavy section
by a ;hydrogen section. The values for the contributions in the latter section are multiplied by the number of
hydrogens attached to the matching atom. For example, consider the following set of patterns:
;hydrogen
[*] 0.2 # Hydrogens attached to all atoms
C 1.0 # Hydrogens attached to an aliphatic carbon
;heavy
C 10.0 # An aliphatic carbon
For ethanol, this gives a value of 25.2: two carbons (20.0), five hydrogens attached to a carbon (5.0), and one
other hydrogen (0.2).
For further inspiration, check out psa.txt, mr.txt and logp.txt in the data directory. These are the group
contribution descriptions for Polar Surface Area, Molar Refractivity and LogP.
Chemists are a very imaginative group. They keep thinking of new file formats.
Indeed, these are not just simple differences in how chemical data is stored, but often completely different views on
molecular representations. For example, some file formats ignore hydrogen atoms as “implicit,” while others do not
store bonding information. This is, in fact, a key reason for Open Babel’s existence.
OpenBabel has support for 146 formats in total. It can read 108 formats and can write 107 formats. These formats are
identified by a name (for example, ShelX format) and one or more short codes (in this case, ins or res). The
titles of each section provide this information (for example, ShelX format (ins, res)).
The short code is used when using obabel or babel to convert files from one format to another:
obabel -iins myfile.ins -ocml
converts from ShelX format to Chemical Markup Language (in this case, no output file is specified and the output will
be written to screen [stdout]). In fact, if the filename extension is the same as the file format code, then there is no
need to specify the code. In other words, the following command will behave identically:
babel myfile.ins -ocml
As well as the general conversion options described elsewhere (see Options), each format may have its own options
for either reading or writing. For example, the ShelX format has two options that affect reading of files, s and b. To
set a file format option:
• For Read Options, precede the option with -a at the command line
• For Write Options, precede the option with -x
Mnemonic
To remember the correct switch for read or write options, think of “raw eggs”: read is a, write is x (“eggs”).
For example, if we wanted to set all bonds to single bonds when reading a ShelX format file, we could specify the s
option:
babel -iins myfile.ins -ocml -as
More than one read (or write) option can be specified (e.g. -ax -ay -az). babel (but not obabel) also allows
you to specify several options together (e.g. as -axyz).
153
, Release 3.0.1
Developer Note To set the file formats for an OBConversion object, use SetInAndOutFormat(InCode,
OutCode). To set a Read Option s, use SetOptions("s", OBConversion::INOPTIONS).
Write Options
• Elements:
– molecule, atomArray, atom, bondArray, bond, atomParity, bondStereo
– name, formula, crystal, scalar (contains crystal data)
– string, stringArray, integer, integerArray, float floatArray, builtin
• Attributes:
– On <molecule>: id, title, ref(in CMLReact)
– On <atom>: id, atomId, atomID, elementType, x2, y2, x3, y3, z3, xy2, xyz3, xFract, yFract, zFract,
xyzFract, hydrogenCount, formalCharge, isotope, isotopeNumber, spinMultiplicity, radical(from Marvin),
atomRefs4 (for atomParity)
– On <bond>: atomRefs2, order, CML1: atomRef, atomRef1, atomRef2
Atom classes are also read and written. This is done using a specially formed atom id. When reading, if the atom id is
of the form aN_M (where N and M are positive integers), then M is interpreted as the atom class. Such atom ids are
automatically generated when writing an atom with an atom class.
Read Options
Write Options
Comments
In the absence of hydrogenCount and any explicit hydrogen on an atom, implicit hydrogen is assumed to be present
appropriate to the radical or spinMultiplicity attributes on the atom or its normal valency if they are not present.
The XML formats require the XML text to be well formed but generally interpret it fairly tolerantly. Unrecognised
elements and attributes are ignored and there are rather few error messages when any required structures are not found.
This laxity allows, for instance, the reactant and product molecules to be picked out of a CML React file using CML.
Each format has an element which is regarded as defining the object that OpenBabel will convert. For CML this is
<molecule>. Files can have multiple objects and these can be treated the same as with other multiple object formats
like SMILES and MDL Molfile. So conversion can start at the nth object using the -fn option and finish before the
end using the -ln option. Multiple object XML files also can be indexed and searched using FastSearch, although
this has not yet been extensively tested.
Read Options
Write Options
The following options are for convenience, e.g. -xF but produce non-standard
InChI.
-F include fixed hydrogen layer
-M include bonds to metal
Comments
This is the same as using -oinchi -xK and can take the same options as the InChI format (see InChI format (inchi)):
Note that while a molecule with a particular InChI will always give the same InChIKey, the reverse is not true; there
may exist more than one molecule which have different InChIs but yield the same InChIKey.
Read Options
Write Options
Read Options
Write Options
A linear text format which can describe the connectivity and chirality of a molecule
Open Babel implements the OpenSMILES specification.
It also implements an extension to this specification for radicals.
Note that the l <atomno> option, used to specify a “last” atom, is intended for the generation of SMILES strings
to which additional atoms will be concatenated. If the atom specified has an explicit H within a bracket (e.g. [nH] or
[C@@H]) the output will have the H removed along with any associated stereo symbols.
See also:
The Canonical SMILES format (can) produces a canonical representation of the molecule in SMILES format. This is
the same as the c option below but may be more convenient to use.
Read Options
Write Options
The Smiley parser presents an alternative to the standard SMILES parser (SMILES format (smi, smiles)). It was written
to be strictly compatible with the OpenSMILES standard (http://opensmiles.org). In comparison, the standard parser
is more forgiving to erroneous input, and also supports some extensions such as for radicals.
In addition, the Smiley parser returns detailed error messages when problems arise parsing or validating the SMILES,
whereas the standard parser seldom describes the specific problem. For a detailed description of the OpenSMILES
semantics, the specification should be consulted. In addition to syntactical and grammatical correctness, the Smiley
parser also verifies some basic semantics.
Here are some examples of the errors reported:
SyntaxError: Bracket atom expression contains invalid trailing characters.
F.FB(F)F.[NH2+251][C@@H](CP(c1ccccc1)c1ccccc1)C(C)(C)C 31586112
^^
SyntaxError: Unmatched branch opening.
(continues on next page)
Hydrogen atoms can not have a hydrogen count. Hydrogen bound to a hydrogen atom should be specified by two
bracket atom expressions.
Examples:
[HH] invalid
[HH1] invalid (same as [HH]
[HH3] invalid
[HH0] valid (same as [H])
[H][H] valid
C1CCC
When the bond type for ring bonds are explicitly specified at both ends, these should be the same.
Example:
C-1CCCCCC=1
There are two types of invalid ring bonds. The first is when two atoms both have the same two ring bonds. This would
mean adding a parallel edge in the graph which is not allowed. The second type is similar but results in a self-loop by
having a ring bond number twice.
Examples:
When an atom is specified as being chiral, it should have the correct number of neighboring atoms (possibly including
an implicit H inside the bracket.
The valid valences are:
Tetrahedral (TH) : 4
Allene (AL) : 4 (*)
Square Planar (SP) : 4
Trigonal Bypiramidal (TB) : 5
Octahedral(OH) : 6
(*) The chiral atom has only 2 bonds but the neighbor's neighbors are
counted: NC(Br)=[C@AL1]=C(F)I
Chiral atoms can only have one hydrogen in their bracket since multiple hydrogens would make them not chiral.
Example:
C[C@H2]F
Read Options
Write Options
A utility format that allows you to compare molecules using their InChIs
The first molecule is compared with the rest, e.g.:
This is the same as using -oinchi -xet and can take the same options as InChI format (see InChI format (inchi)).
Write Options
A utility format for exactly copying the text of a chemical file format
This format allows you to filter molecules from multimolecule files without the risk of losing any additional informa-
tion they contain, since no format conversion is carried out.
Warning: Currently not working correctly for files with Windows line endings.
Example:
Extract only structures that include at least one aromatic carbon (by matching the SMARTS pattern [c]):
Note: XML files may be missing non-object elements at the start or end and so may no longer be well formed.
Read Options
Read Options
[Molec_name]\t[atomtype];[layer]-[frequency]-[neighbour_type];
Write Options
Type Elements
H H
C C
N N
O O
F F
Si Si
P P
S S
Cl Cl
Ca Ca
As As
Se Se
Br Br
Li Li, Na
B B, Re
Mg Mg, Mn
Sn Sn, Pb
Te Te, Po
I I, At
Os Os, Ir
Sc Sc, Ti, Zr
Fe Fe, Hf, Ta
Co Co, Sb, W
Sr Sr, Ba, Ra
Pd Pd, Pt, Au
Continued on next page
Write Options
See also:
Open Babel report format (report)
FILENAME: benzene.report
FORMULA: C6H6
MASS: 78.1118
EXACT MASS: 78.0469502
INTERATOMIC DISTANCES
C 1 C 2 C 3 C 4 C 5 C 6
------------------------------------------------------------------
C 1 0.0000
C 2 1.3958 0.0000
C 3 2.4176 1.3958 0.0000
C 4 2.7916 2.4176 1.3958 0.0000
C 5 2.4176 2.7916 2.4176 1.3958 0.0000
C 6 1.3958 2.4176 2.7916 2.4176 1.3958 0.0000
H 7 1.0846 2.1537 3.4003 3.8761 3.4003 2.1537
H 8 2.1537 1.0846 2.1537 3.4003 3.8761 3.4003
H 9 3.4003 2.1537 1.0846 2.1537 3.4003 3.8761
(continues on next page)
H 7 H 8 H 9 H 10 H 11 H 12
------------------------------------------------------------------
H 7 0.0000
H 8 2.4803 0.0000
H 9 4.2961 2.4804 0.0000
H 10 4.9607 4.2961 2.4803 0.0000
H 11 4.2961 4.9607 4.2961 2.4803 0.0000
H 12 2.4803 4.2961 4.9607 4.2961 2.4804 0.0000
ATOMIC CHARGES
C 1 -0.1000000000
C 2 -0.1000000000
C 3 -0.1000000000
C 4 -0.1000000000
C 5 -0.1000000000
C 6 -0.1000000000
H 7 0.1000000000
H 8 0.1000000000
H 9 0.1000000000
H 10 0.1000000000
H 11 0.1000000000
H 12 0.1000000000
BOND ANGLES
7 1 2 HC Car Car 120.000
1 2 3 Car Car Car 120.000
1 2 8 Car Car HC 120.000
8 2 3 HC Car Car 120.000
2 3 4 Car Car Car 120.000
2 3 9 Car Car HC 120.000
9 3 4 HC Car Car 120.000
3 4 5 Car Car Car 120.000
3 4 10 Car Car HC 120.000
10 4 5 HC Car Car 120.000
4 5 6 Car Car Car 120.000
4 5 11 Car Car HC 120.000
11 5 6 HC Car Car 120.000
5 6 1 Car Car Car 120.000
5 6 12 Car Car HC 120.000
12 6 1 HC Car Car 120.000
6 1 2 Car Car Car 120.000
6 1 7 Car Car HC 120.000
2 1 7 Car Car HC 120.000
3 2 8 Car Car HC 120.000
4 3 9 Car Car HC 120.000
5 4 10 Car Car HC 120.000
6 5 11 Car Car HC 120.000
1 6 12 Car Car HC 120.000
TORSION ANGLES
6 1 2 3 0.026
6 1 2 8 -179.974
7 1 2 3 179.974
(continues on next page)
See also:
Open Babel molecule report (molreport)
• Line one of the file contains the number of atoms in the file.
• Line two of the file contains a title, comment, or filename.
Any remaining lines are parsed for atom information. Lines start with the element symbol, followed by X, Y, and Z
coordinates in angstroms separated by whitespace.
Multiple molecules / frames can be contained within one file.
On output, the first line written is the number of atoms in the molecule (warning - the number of digits is limited to
three for some programs, e.g. Maestro). Line two is the title of the molecule or the filename if no title is defined. Re-
maining lines define the atoms in the file. The first column is the atomic symbol (right-aligned on the third character),
followed by the XYZ coordinates in “10.5” format, in angstroms. This means that all coordinates are printed with five
decimal places.
Example:
12
benzene example
C 0.00000 1.40272 0.00000
H 0.00000 2.49029 0.00000
C -1.21479 0.70136 0.00000
H -2.15666 1.24515 0.00000
C -1.21479 -0.70136 0.00000
H -2.15666 -1.24515 0.00000
C 0.00000 -1.40272 0.00000
H 0.00000 -2.49029 0.00000
C 1.21479 -0.70136 0.00000
H 2.15666 -1.24515 0.00000
C 1.21479 0.70136 0.00000
H 2.15666 1.24515 0.00000
Read Options
Read Options
• G Chlorine atom
• H Hydrogen atom
• I Iodine atom
• Q Hydroxyl group, -OH
• R Benzene ring
• S Sulfur atom
• U Double bond
• UU Triple bond
• V Carbonyl, -C(=O)-
• C Unbranched carbon multiply bonded to non-carbon atom
• K Nitrogen atom bonded to more than three other atoms
• L First symbol of a carbocyclic ring notation
• M Imino or imido -NH-group
• N Nitrogen atom, hydrogen free, bonded to fewer than 4 atoms
• O Oxygen atom, hydrogen-free
• T First symbol of a heterocyclic ring notation
• W Non-linear dioxo group, as in -NO2 or -SO2-
• X Carbon attached to four atoms other than hydrogen
• Y Carbon attached to three atoms other then hydrogen
• Z Amino and amido NH2 group
• <digit> Digits ‘1’ to ‘9’ denote unbranched alkyl chains
• & Sidechain terminator or, after a space, a component separator
For a more complete description of the grammar see Smith’s book [1], which more accurately reflects the WLN
commonly encountered than Wiswesser’s book [2]. Additional WLN dialects include inorganic salts, and methyl
contractions.
Here are some examples of WLN strings along with a corresponding SMILES string:
• WN3 [O-][N+](=O)CCC
• G1UU1G ClC#CCl
• VH3 O=CCCC
• NCCN N#CC#N
• ZYZUM NC(=N)N
• QY CC(C)O
• OV1 &-NA- CC(=O)[O-].[Na+]
• RM1R c1ccccc1NCc2ccccc2
• T56 BMJ B D - DT6N CNJ BMR BO1 DN1 & 2N1 & 1 EMV1U1 (osimertinib)
Cn1cc(c2c1cccc2)c3ccnc(n3)Nc4cc(c(cc4OC)N(C)CCN(C)C)NC(=O)C=C
This reader was contributed by Roger Sayle (NextMove Software). The text of this description was taken from his
Bio-IT World poster [3]. Note that not all of WLN is currently supported; however, about 76% of the WLN strings
found in PubChem can be interpreted.
1. Elbert G. Smith, “The Wiswesser Line-Formula Chemical Notation”, McGraw-Hill Book Company publishers,
1968.
2. William J. Wiswesser, “A Line-Formula Chemical Notation”, Thomas Crowell Company publishers, 1954.
3. Roger Sayle, Noel O’Boyle, Greg Landrum, Roman Affentranger. “Open sourcing a Wiswesser Line Notation
(WLN) parser to facilitate electronic lab notebook (ELN) record transfer using the Pistoia Alliance’s UDM
(Unified Data Model) standard.” BioIT World. Apr 2019. https://www.nextmovesoftware.com/posters/Sayle_
WisswesserLineNotation_BioIT_201904.pdf
Read Options
Read Options
Read Options
Read Options
Read Options
Read Options
Culgi format
No options currently
Read Options
Write Options
Read Options
Read Options
4
%PBC
C 0.00000 1.40272 0.00000
H 0.00000 2.49029 0.00000
C -1.21479 0.70136 0.00000
H -2.15666 1.24515 0.00000
On output, the first line written is the number of atoms in the molecule. Line two is the title of the molecule or the
filename if no title is defined. Remaining lines define the atoms in the file. The first column is the atomic symbol
(right-aligned on the third character), followed by the XYZ coordinates in “15.5” format separated by an addition
whitespace, in angstroms. This means that all coordinates are printed with five decimal places.
The next block starts with a blank line to separate the coordinates from the unit cell vectors followed by the vectors of
the unit cell marked with the keywords Vector1/2/3. The vectors themselves are written in the same format as the atom
coordinates. The last line contains the keyword Offset and the offset of the unit cell. The unit is always angstrom.
Read Options
Read Options
Write Options
Read Options
Write Options
18.4.26 Gaussian Output (g03, g09, g16, g92, g94, g98, gal)
Read Options
Read Options
Write Options
Read Options
Read Options
Read Options
Read Options
Write Options
Write Options
Read Options
Read Options
Read Options
Read Options
Write Options
Read Options
Write Options
Read Options
Read Options
Write Options
-a Output Angstroms
Reads in data from POSCAR and CONTCAR to obtain information from VASP calculations.
Due to limitations in Open Babel’s file handling, reading in VASP files can be a bit tricky; the client that is using Open
Babel must use OBConversion::ReadFile() to begin the conversion. This change is usually trivial. Also, the complete
path to the CONTCAR/POSCAR file must be provided, otherwise the other files needed will not be found.
Both VASP 4.x and 5.x POSCAR formats are supported.
By default, atoms are written out in the order they are present in the input molecule. To sort by atomic number specify
-xw. To specify the sort order, use the -xz option.
Read Options
Write Options
Write Options
The FPS file format for fingerprints was developed by Andrew Dalke to define and promote common file formats for
storing and exchanging cheminformatics fingerprint data sets, and to develop tools which work with that format. For
more information, see http://chem-fingerprints.googlecode.com
Any molecule without a title is given its index in the file as title.
A list of available fingerprint types can be obtained by:
obabel -L fingerprints
Write Options
This prepares an index dataset.fs with default parameters, and is slow (~30 minutes for a 250,000 molecule file).
However, when reading from the fs format searches are much faster, a few seconds, and so can be done interactively.
The search target is the parameter of the -s option and can be slightly extended SMILES (with [#n] atoms and ~
bonds) or the name of a file containing a molecule.
Several types of searches are possible:
• Identical molecule:
• Substructure:
The datafile plus the -ifs option can be used instead of the index file.
NOTE on 32-bit systems the datafile MUST NOT be larger than 4GB.
Dative bonds like -[N+][O-](=O) are indexed as -N(=O)(=O), and when searching the target molecule should be in the
second form.
See also:
Molecular fingerprints and similarity searching
Read Options
Write Options
babel -L fingerprints
The current default type FP2 is is of the Daylight type, indexing a molecule based on the occurrence of linear fragment
up to 7 atoms in length. To use a fingerprint type other than the default, use the -xf option, for example:
For a single molecule the fingerprint is output in hexadecimal form (intended mainly for debugging).
With multiple molecules the hexadecimal form is output only if the -xh option is specified. But in addition the
Tanimoto coefficient between the first molecule and each of the subsequent ones is displayed. If the first molecule is
a substructure of the target molecule a note saying this is also displayed.
The Tanimoto coefficient is defined as:
For the path-based fingerprint FP2, the output from the -xs option is instead a list of the chemical fragments used to
set bits, e.g.:
where the first digit is 0 for linear fragments but is a bond order for cyclic fragments. The remaining digits indicate
the atomic number and bond order alternatively. Note that a bond order of 5 is used for aromatic bonds. For example,
bit 623 above is the linear fragment O=C (8 for oxygen, 2 for double bond and 6 for carbon).
Write Options
Read Options
The CIF file format is the standard interchange format for small-molecule crystal structures
Fractional coordinates are converted to cartesian ones using the following convention:
• The x axis is parallel to a
• The y axis is in the (a,b) plane
• The z axis is along c*
Ref: Int. Tables for Crystallography (2006), vol. B, sec 3.3.1.1.1 (the matrix used is the 2nd form listed)
Read Options
Write Options
When used as an output format, The first line written is the title of the molecule or the filename if no title is defined.
If a molecule has a defined unit cell, then the second line will be formatted as:
where a, b, c are the unit cell vector lengths, and alpha, beta, and gamma are the angles between them. These numbers
are formatted as “10.5”, which means that 5 decimal places will be output for all numbers. In the case where no unit
cell is defined for the molecule, the vector lengths will be defined as 1.0, and the angles to 90.0 degrees.
Remaining lines define the atoms in the file. The first column is the atomic symbol, followed by the XYZ coordinates
in 10.5 format (in angstroms).
Here is an example file:
Read Options
Read Options
Read Options
Read Options
Write Options
Comments
The implementation of this format which reads and writes to and from OBReaction objects is fairly minimal at present.
(Currently the only other reaction format in OpenBabel is RXN.) During reading, only the elements <reaction>, <re-
actant>, <product> and <molecule> are acted upon (the last through CML). The molecules can be collected together
in a list at the start of the file and referenced in the reactant and product via e.g. <molecule ref=”mol1”>.
On writing, the list format can be specified with the -xl option. The list containers are <moleculeList> and <reaction-
List> and the overall wrapper is <mechanism>. These are non-standard CMLReact element names and would have to
be changed (in the code) to <list>,<list> and <cml> if this was unacceptable.
Write Options
Write Options
__
__/__\_
_/__/ \__
_/_/ \__
| |
| | |
| | |
| | |
| | |
|___ _ Cl
\_\__ _/ \_ __
\_\_ __/ \__ __/
\__/ \__/
| |
| |
| |
| |
If the image appears elongated or squat, the aspect ratio should be changed from its default value of 1.5 using the -xa
<ratio> option. To help determine the correct value, use the -xs option to display a square.
Write Options
Chemical structure data can be embedded in the .png file (in a tEXt chunk):
The parameter of the -xO option specifies the format (“file”can be added). Note that if you intend to embed a 2D or
3D format, you may have to call --gen2d or --gen3d to generate the required coordinates if they are not present
in the input.
Molecules can also be embedded in an existing PNG file:
Reading from a PNG file will extract any embedded chemical structure data:
Read Options
Write Options
would add a aliases COOH and CHO to represent the carboxyl and aldehyde
groups and would display them as such in the svg diagram. The aliases which are
recognized are in data/superatom.txt, which can be edited.
-O <format ID> Format of embedded text
For example, molfile or smi. If there is no parameter, input format is used.
-y <additional chunk ID> Write to a chunk with specified ID
Comments
If Cairo was not found when Open Babel was compiled, then the 2D depiction will be unavailable. However, it will
still be possible to extract and embed chemical data in .png files.
See also:
PNG 2D depiction (png)
Generate an input file for the open source POV-Ray ray tracer.
The POV-Ray file generated by Open Babel should be considered a starting point for the user to create a rendered
image of a molecule. Although care is taken to center the camera on the molecule, the user will probably want to
adjust the viewpoint, change the lighting, textures, etc.
The file babel_povray3.inc is required to render the povray file generated by Open Babel. This file is included
in the Open Babel distribution, and it should be copied into the same directory as the .pov file before rendering. By
editing the settings in babel_povray3.inc it is possible to tune the appearance of the molecule.
For example, the image below was generated by rendering the output from the following command after setting the
reflection of non-metal atoms to 0 (line 121 in babel_povray3.inc):
obabel -:"CC(=O)Cl acid chloride" --gen3d -O chloride.pov -xc -xf -xs -m SPF
Write Options
Write Options
Write Options
would add a aliases COOH and CHO to represent the carboxyl and aldehyde
groups and would display them as such in the svg diagram. The aliases which are
recognized are in data/superatom.txt, which can be edited.
-S Ball and stick depiction of molecules
Depicts the molecules as balls and sticks instead of the normal line style.
Comments
If the input molecule(s) contain explicit hydrogen, you could consider improving the appearance of the diagram by
adding an option -d to make it implicit. Hydrogen on hetero atoms and on explicitly drawn C is always shown. For
example, if input.smi had 10 molecules:
would produce a svg file with a black background, with no explicit terminal carbon, and with an embedded cml
representation of each molecule. The structures would be in two rows of four and one row of two.
Read only
The whole file is read in one call. Note that a file may contain a mixture of reactions and molecules. With the -ad
option, a human-readable representation of the CDX tree structure is output as an OBText object. Use textformat to
view it:
Many reactions in CDX files are not fully specified with reaction data structures, and may not be completely interpreted
by this parser.
Read Options
Read Options
-b no bonds
-s no multiple bonds
Read Options
Read Options
Read Options
Read Options
Write Options
Read Options
-e Terminate on “END”
Read Options
Reads and writes AutoDock PDBQT (Protein Data Bank, Partial Charge (Q), & Atom Type (T)) format
Note that the torsion tree is by default. Use the r write option to prevent this.
Read Options
Write Options
Read Options
Write Options
Read Options
Write Options
The format used in the POSFF and CONTFF files used by MDFF
POSFF and CONTFF are read to obtain information from MDFF calculations. The program will try to read the
IONS.POT file if the name of the input file is POSFF or CONTFF.
Write Options
The format used by SIESTA (Spanish Initiative for Electronic Simulations with Thousands of Atoms).
LAMMPS is a classical molecular dynamics code, and an acronym for Large-scale Atomic/Molecular Massively
Parallel Simulator.
Write Options
The cartesian XYZ file format used by the molecular mechanics package TINKER.
By default, the MM2 atom types are used for writing files but MM3 atom types are provided as an option. Another
option provides the ability to take the atom type from the atom class (e.g. as used in SMILES, or set via the API).
Read Options
Write Options
Currently the ADF Tape41 support reads grids from TAPE41 text files. To generate an ASCII version from the default
binary, use the dmpkf program.
Read Options
Read Options
-b no bonds
-s no multiple bonds
Write Options
Write Options
Read Options
Write Options
Read Options
-s disable stereo perception and just read stereo information from input
Write Options
Generates input to the MSMS (Michael Sanner Molecular Surface) program to compute solvent surfaces.
Write Options
Read Options
Write Options
Read Options
Read Options
Add or remove hydrogens to count total or bonds between heavy atoms SMARTS: *~*
SMARTS: [!#6;!H0]
Identification of Biological Activity Profiles Using Substructural Analysis and Genetic Algorithms – Gillet, Wil-
lett and Bradshaw, U. of Sheffield and Glaxo Wellcome. Presented at Random & Rational: Drug Discovery via
Rational Design and Combinitorial Chemistry, Strategic Research Institute, Princeton NJ, Sept. 1995 SMARTS:
[$([!#6;+0]);!$([F,Cl,Br,I]);!$([o,s,nX3]);!$([Nv5,Pv5,Sv4,Sv6])]
SMARTS: [$([$([#8,#16]);!$(*=N~O);!$(*~N=O);X1,X2]),$([#7;v3;!$([nH]);!$(*(-a)-a)])]
SMARTS: F
209
, Release 3.0.1
Datafile: logp.txt
SMARTS: *#*
Datafile: mr.txt
SMARTS: *:*
SMARTS: *-*
SMARTS: *=*
Datafile: psa.txt
This is a melting point descriptor developed by Andy Lang. For details see: http://onschallenge.wikispaces.com/
MeltingPointModel011 Datafile: mpC.txt
InChIKey (InChIKey)
Assign QEq (charge equilibration) partial charges (Rappe and Goddard, 1991) (qeq)
Assign QTPIE (charge transfer, polarization and equilibration) partial charges (Chen and Martinez,
2007) (qtpie)
213
, Release 3.0.1
Released on 2019-10-10.
This is a major release. It fixes some long-standing issues affecting performance in terms of chemical accuracy and
speed, and all users are recommended to upgrade. It also removes deprecated components and breaks the API in a few
places. For information on migrating from the previous version, please see Updating to Open Babel 3.0 from 2.x.
• The babel program has been removed, and the replacement obabel should be used instead. The obabel program
fixes some flaws with the original babel (not least that the user could accidentally overwrite an input file) and so
has been preferred for many years.
• The Python bindings are now accessed via “from openbabel import pybel” or “from openbabel import openba-
bel”.
• Under the hood, the code for handling implicit hydrogens and kekulization has been entirely replaced in order
to address problems with the original approach that had resulted in multiple bug reports over the years. As well
as being accurate, the new approach is much faster.
• The speed of reading and writing SMILES has been improved by more than 50-fold.
• A faster and more accurate fragment-based 3D coordinate generation code has been added, part of Google Sum-
mer of Code 2018 and 2019, detailed in *J. Cheminf.* (2019) **11**, Art. 49.<https://doi.org/10.1186/s13321-
019-0372-5>
• New functionality in the API:
– A new class for managing reactions stored as OBMols (OBReactionFacade)
– A new method to copy part of an OBMol into a new OBMol (OBMol::CopySubstructure)
• Add basic support for RInChI (Reaction InChI) (by baoilleach, PR#1667)
• Added basic ADF Band and ADF DFTB readers (by psavery, PR#1793)
215
, Release 3.0.1
• Add support for COF format (Culgi object file) plus tests (by pbecherer, PR#1944)
• Add maeparser support to openbabel (by lorton, PR#1993)
• Include original when there are zero rotatable bonds in confab (by cowsandmilk, PR#370)
• Improve thread safety for global objects (by baoilleach, PR#381)
• Change the OBAromTyper from using SMARTS patterns to a switch statement (rebased) (by baoilleach,
PR#1545)
• Keep count of implicit hydrogens instead of inferring them (by baoilleach, PR#1576)
• Obthermo update patch (by mmghahremanpour, PR#1598)
• Improve performance of element handling (by baoilleach, PR#1601)
• Implement the Daylight aromaticity model as described by John Mayfield (by baoilleach, PR#1638)
• Allow multiple agents in OBReaction (by baoilleach, PR#1640)
• Clarify python examples (by theavey, PR#1657)
• Add support for wrapping GetRGB() call to return r, g, b params. (by ghutchis, PR#1670)
• Adding missing manpages (by merkys, PR#1678)
• Expose obfunctions api through python bindings (by cstein, PR#1697)
• Avoid logging messages that are taking time (by baoilleach, PR#1714)
• warning/error messages for fastindex when the structure file is compressed (by adalke, PR#1733)
• Refactor atom class to being data on an atom rather than on a molecule (by baoilleach, PR#1741)
• Add Molecule.make2D function (by eloyfelix, PR#1765)
• Change the behavior of OBMol.Separate so that it preserves atom order (by baoilleach, PR#1773)
• When calling OBMol.Separate, preserve whether aromaticity has been perceived (by baoilleach, PR#1800)
• Add OBMol::CopySubstructure (by baoilleach, PR#1811)
• Add OBMol::SetChainsPerceived(false) (by baoilleach, PR#1813)
• Add stereo + obfunctions + kekulize to ruby binding (by CamAnNguyen, PR#1824)
• Generate useful error messages if plugins can’t be found. (by dkoes, PR#1826)
• Allow public access to retrieve gradients (by ghutchis, PR#1833)
• Re-enable vector.clear() to allow wrapped std::vectors to be reused (by baoilleach, PR#1834)
• Implement reaction handling as part of OBMol (by baoilleach, PR#1836)
• Added rotors as a descriptor/filter. (by ghutchis, PR#1846)
• Keep aromaticity in EndModify() (by baoilleach, PR#1847)
• Fragment-based coordinate generation (by n-yoshikawa, PR#1850)
• Rebuild OBMM tool for interactive MM optimization (by ghutchis, PR#1873)
• Update fragment based builder (by n-yoshikawa, PR#1931)
• Refactor python bindings so that openbabel.py and pybel.py are within an openbabel folder (by baoilleach,
PR#1946)
• Change default build type to RELEASE and add -O3 switch (by baoilleach, PR#352)
• Add a default issue template for Open Babel - Suggestions welcome (by ghutchis, PR#383)
• Compile position independent code for shared libraries. (by susilehtola, PR#1575)
• Introduce std:isnan for older versions of MSVC (by mwojcikowski, PR#1586)
• Prepend to LD_LIBRARY_PATH instead of overwrite (by barrymoo, PR#1588)
• Changes needed to compile with C++17 (by arkose, PR#1619)
• Compiler version parsing and comparison from CMake 2.8 (by cowsandmilk, PR#1630)
• Create CODE_OF_CONDUCT.md (by ghutchis, PR#1671)
• Clarify option needed to generate SWIG bindings. (by jeffjanes, PR#1686)
• Correct spelling of file name for Perl bindings (by jeffjanes, PR#1687)
• In the Python bindings, avoid adding methods from the iterated object to the iterator itself (by baoilleach,
PR#1729)
• Ensure portability to ARM platforms (by baoilleach, PR#1744)
• Switch to rapidjson library for JSON parsing/writing (by mcs07, PR#1776)
• Fix linking of python bindings on Mac (by mcs07, PR#1807)
• Using pillow instead of PIL (by hille721, PR#1822)
• Ignore compile warnings on inchi directory. (by ghutchis, PR#1864)
• Fix some small misspellings in the csharp bindings (by cmanion, PR#1608)
• Tweak the handling of implicit Hs when reading SMILES (by baoilleach, PR#1609)
• Fix underflow causing a noticeable delay when e.g. writing a molfile (by baoilleach, PR#1610)
• Fix install regression with element data (by bbucior, PR#1617)
• Added some missing formats to the static build (by psavery, PR#1622)
• In SiestaFormat, print warnings to cerr (by psavery, PR#1623)
• For SIESTA format, use obErrorLog instead of cerr (by psavery, PR#1627)
• Correct the spelling of the Frerejacque number in a comment (by baoilleach, PR#1629)
• Lowercase second element letter in PDB and test (by cowsandmilk, PR#1631)
• Remove erroneous -1 in switch statement (by baoilleach, PR#1632)
• Make sure to handle molecular total charge by default for keywords (by ghutchis, PR#1634)
• Added fix for OBMolAtomBFSIter in Python3 (by oititov, PR#1637)
• space-groups.txt: correct Hall symbol for C -4 2 b (by wojdyr, PR#1645)
• Reset path to empty in kekulization code (potential segfault) (by baoilleach, PR#1650)
• Correct handling of stereo when writing InChIs (by baoilleach, PR#1652)
• ECFP Fixup (by johnmay, PR#1653)
• Fix “folding” for fingerprints to larger bit sizes - #1654. (by ghutchis, PR#1658)
• Fix reading atom symbols from XSF file (by sencer, PR#1663)
• Minor fixes in the nwchem format reader (by xomachine, PR#1666)
• use isinstance to test if filename is bytes (by cowsandmilk, PR#1673)
• Fix bug found due to MSVC warning (by baoilleach, PR#1674)
• Fix MSVC warning about unused variable (by baoilleach, PR#1675)
• Correct handling of atom maps (by baoilleach, PR#1698)
• Fix #1701 - a GCC compiler error (by baoilleach, PR#1704)
• Remove some audit messages (by baoilleach, PR#1707)
• Fix bug when copying stereo during obmol += obmolB (by baoilleach, PR#1719)
• Fix uninitialized read in kekulize.cpp found by Dr Memory. (by baoilleach, PR#1721)
• Fixes for ring closure parsing (by baoilleach, PR#1723)
• Make sure that OBAtom::IsInRing always triggers ring perception if not set as perceived (by baoilleach,
PR#1724)
• Fix code error found from @baoilleach compiler warnings (by ghutchis, PR#1736)
• Fix Python3 compatibility (by ghutchis, PR#1737)
• Fix ChemDraw CDX incremental value (by CamAnNguyen, PR#1743)
• Fix error in VASPformat found by static code analysis (by baoilleach, PR#1745)
• Fix for 1731. Store atom classes in CML atomids by appending _ATOMCLASS. (by baoilleach, PR#1746)
• Fix GCC warnings (by baoilleach, PR#1747)
• Simplify/fix behavior of OBAtom::GetResidue so that it behaves like other lazy properties (by baoilleach,
PR#1849)
• Fixes #1851: check some limits when converting smi to sdf using –gen2D (by serval2412, PR#1852)
• Modify cleaning blank line behaviors (by yishutu, PR#1855)
• Ring membership of atoms and bonds was not being reset during perception (by baoilleach, PR#1856)
• Update qeq.txt (by mkrykunov, PR#1882)
• Support lone pair stereo on nitrogen as well as sulfur (by baoilleach, PR#1885)
• Changed indexing of fragments, should fix #1889 (by fredrikw, PR#1890)
• Avoid out-of-range access in OBMolBondBFSIter (by baoilleach, PR#1892)
• Fix OBChemTsfm wrapping of implicit H counts (by baoilleach, PR#1896)
• Updated the coordinate generation from templates. (by fredrikw, PR#1902)
• Fix incorrect use of memcpy. (by sunoru, PR#1908)
• Add SetChainsPerceived() after EndModify() in formats that add residues (by baoilleach, PR#1914)
• define isfinite removed. (by orex, PR#1928)
• Teach the isomorphism mapper to respect atom identity (by johnmay, PR#1939)
• Fix memory leak in OBSmartsPattern::Init() (by n-yoshikawa, PR#1945)
• Address CMake build warning about policy CMP0005 being set to OLD (by baoilleach, PR#1948)
• Fix clang warning about in-class init of a non-static data member (by baoilleach, PR#1949)
• Update bindings for changes to headers (by baoilleach, PR#1963)
• Fix randomly failing Python gradient test (by baoilleach, PR#1966)
• Exit with non-zero if an error occurs (by e-kwsm, PR#1973)
• Avoid non-finite bond vectors (by dkoes, PR#1981)
• Include babelconfig in vector3.h (by dkoes, PR#1985)
• Fix #1987: CMake failing at FindRapidJSON (by RMeli, PR#1988)
• fpsformat.cpp: compile bugfix header added. (by orex, PR#1991)
• Address Ubuntu bug in defining python install dir (by dkoes, PR#1992)
• PDB and PDBQT Insertion Code Fixes (by RMeli, PR#1998)
• Make pybel compatible with #1975 (by yishutu, PR#2005)
• H vector fix (by dkoes, PR#2010)
• Change forcefield.cpp so that steepest descent and conjugate gradient update maxgrad (by PeaWagon, PR#2017)
• Update coordinates in the fast option of obabel (by n-yoshikawa, PR#2026)
• Update the CSharp bindings (by baoilleach, PR#2032)
• Don’t make kekule SMILES the default in the GUI (by baoilleach, PR#2039)
• Bumping the major version requires more changes throughout the library. (by baoilleach, PR#2036)
• Fix reading of uninitialized data. (by dkoes, PR#2038)
• Remove minor version from some names (by baoilleach, PR#2040)
• Fixed alias expansion for files with multiple aliases (by fredrikw, PR#2035)
• Update doc (by e-kwsm, PR#1979)
• Fix compilation with GCC 4.8 (standard compiler on CentOS 7.5) (by baoilleach, PR#2047)
• Some tests (by dkoes, PR#2008)
aandi, adalke (Andrew Dalke), adamjstewart (Adam J. Stewart), afonari (Alexandr Fonari), artoria2e5 (Mingye Wang),
baoilleach (Noel O’Boyle), barrymoo (Barry Moore), bbucior (Ben Bucior), boryszef (Borys Szefczyk), camannguyen
(An Nguyen), cmanion (Charles A. Manion), cowsandmilk (David Hall), cstein (Casper Steinmann), derekharmon
(Derek Harmon), djhogan (Daniel Hogan), dkoes (David Koes), e-kwsm (Eisuke Kawashima), eloyfelix (Eloy Felix),
fredrikw (Fredrik Wallner), ghutchis (Geoff Hutchison), hille721 (Christoph Hille), hseara (Hector Martinez-Seara),
jasonychuang (Jason Huang), jeffjanes (Jeff Janes), johnmay (John Mayfield), katrinleinweber (Katrin Leinweber),
keipertk (Kristopher Keipert), kyle-roberts-arzeda, langner (Karol M. Langner), lorton (Pat Lorton), mcs07 (Matt
Swain), merkys (Andrius Merkys), mkrykunov, mmghahremanpour (Mohammad Ghahremanpour), mwojcikowski
(Maciej Wójcikowski), n-yoshikawa (Naruki Yoshikawa), nakatamaho (Nakata Maho), nsoranzo (Nicola Soranzo),
oititov (Titov Oleg), orex (Kirill Okhotnikov), pbecherer (Paul Becherer), peawagon (Jen), philthiel (Philipp Thiel),
psavery (Patrick Avery), rmeli (Rocco Meli), serval2412 (Julien Nabet), sunoru, susilehtola (Susi Lehtola), tgaudin
(Théophile Gaudin), theavey (Thomas Heavey), timvdm (Tim Vandermeersch), torcolvin (Tor Colvin), wojdyr (Marcin
Wojdyr), xomachine (Dmitriy Fomichev), yishutu (Yi-Shu Tu)
Released on 2016-09-21.
Note that this release deprecates the babel executable in favor of obabel. A future release will remove babel entirely.
For information on the differences, please see http://openbabel.org/docs/current/Command-line_tools/babel.html.
• DALTON output files (read only) and DALTON input files (read/write) (Casper Steinmann)
• JSON format used by ChemDoodle (read/write) (Matt Swain)
• JSON format used by PubChem (read/write) (Matt Swain)
• LPMD’s atomic configuration file (read/write) (Joaquin Peralta)
• The format used by the CONTFF and POSFF files in MDFF (read/write) (Kirill Okhotnikov)
• ORCA output files (read only) and ORCA input files (write only) (Dagmar Lenk)
• ORCA-AICCM’s extended XYZ format (read/write) (Dagmar Lenk)
• Painter format for custom 2D depictions (write only) (Noel O’Boyle)
• Siesta output files (read only) (Patrick Avery)
• Smiley parser for parsing SMILES according to the OpenSMILES specification (read only) (Tim Vandermeer-
sch)
• STL 3D-printing format (write only) (Matt Harvey)
• Turbomole AOFORCE output (read only) (Mathias Laurin)
• A representation of the VDW surface as a point cloud (write only) (Matt Harvey)
• AutoDock PDBQT: Options to preserve hydrogens and/or atom names (Matt Harvey)
• CAR: Improved space group support in .car files (kartlee)
• CDXML: Read/write isotopes (Roger Sayle)
• CIF: Extract charges (Kirill Okhotnikov)
• CIF: Improved support for space-groups and symmetries (Alexandr Fonari)
• DL_Poly: Cell information is now read (Kirill Okhotnikov)
• Gaussian FCHK: Parse alpha and beta orbitals (Geoff Hutchison)
• Gaussian out: Extract true enthalpy of formation, quadrupole, polarizability tensor, electrostatic potential fitting
points and potential values, and more (David van der Spoel)
• MDL Mol: Read in atom class information by default and optionally write it out (Roger Sayle)
• MDL Mol: Support added for ZBO, ZCH and HYD extensions (Matt Swain)
• MDL Mol: Implement the MDL valence model on reading (Roger Sayle)
• MDL SDF: Option to write out an ASCII depiction as a property (Noel O’Boyle)
• mmCIF: Improved mmCIF reading (Patrick Fuller)
• mmCIF: Support for atom occupancy and atom_type (Kirill Okhotnikov)
• Mol2: Option to read UCSF Dock scores (Maciej Wójcikowski)
• MOPAC: Read z-matrix data and parse (and prefer) ESP charges (Geoff Hutchison)
• NWChem: Support sequential calculations by optionally overwriting earlier ones (Dmitriy Fomichev)
• NWChem: Extract info on MEP(IRC), NEB and quadrupole moments (Dmitriy Fomichev)
• PDB: Read/write PDB insertion codes (Steffen Möller)
• PNG: Options to crop the margin, and control the background and bond colors (Fredrik Wallner)
• PQR: Use a stored atom radius (if present) in preference to the generic element radius (Zhixiong Zhao)
• PWSCF: Extend parsing of lattice vectors (David Lonie)
• PWSCF: Support newer versions, and the ‘alat’ term (Patrick Avery)
• SVG: Option to avoid addition of hydrogens to fill valence (Lee-Ping)
• SVG: Option to draw as ball-and-stick (Jean-Noël Avila)
• VASP: Vibration intensities are calculated (Christian Neiss, Mathias Laurin)
• VASP: Custom atom element sorting on writing (Kirill Okhotnikov)
• 2D layout: Improved the choice of which bonds to designate as hash/wedge bonds around a stereo center (Craig
James)
• 3D builder: Use bond length corrections based on bond order from Pyykko and Atsumi (https://doi.org/10.1002/
chem.200901472) (Geoff Hutchison)
• 3D generation: “–gen3d”, allow user to specify the desired speed/quality (Geoff Hutchison)
• Bindings: Support compiling only the bindings against system libopenbabel (Reinis Danne)
• Java bindings: Add example Scala program using the Java bindings (Reinis Danne)
• New bindings: PHP (Maciej Wójcikowski)
• PHP bindings: BaPHPel, a simplified interface (Maciej Wójcikowski)
• Python bindings: Add 3D depiction support for Jupyter notebook (Patrick Fuller)
• Python bindings, Pybel: calccharges() and convertdbonds() added (Patrick Fuller, Björn Grüning)
• Python bindings, Pybel: compress output if filename ends with .gz (Maciej Wójcikowski)
• Python bindings, Pybel: Residue support (Maciej Wójcikowski)
• Version control: move to git and GitHub from subversion and SourceForge
• Continuous integration: Travis for Linux builds and Appveyor for Windows builds (David Lonie and Noel
O’Boyle)
• Python installer: Improvements to the Python setup.py installer and “pip install openbabel” (David Hall, Matt
Swain, Joshua Swamidass)
• Compilation speedup: Speed up compilation by combining the tests (Noel O’Boyle)
• MacOSX: Support compiling with libc++ on MacOSX (Matt Swain)
Alexandr Fonari, Anders Steen Christensen, Andreas Kempe, arkose, Benoit Leblanc, Björn Grüning, Casper Stein-
mann, Chris Morley, Christoph Willing, Craig James, Dagmar Lenk, David Hall, David Koes, David Lonie, David
van der Spoel, Dmitriy Fomichev, Fulvio Ciriaco, Fredrik Wallner, Geoff Hutchison, Heiko Becker, Itay Zandbank,
Jean-Noel Avila, Jeff Janes, Joaquin Peralta, Joshua Swamidass, Julien Nabet, Karol Langner, Karthik Rajagopalan,
Katsuhiko Nishimra, Kevin Horan, Kirill Okhotnikov, Lee-Ping, Matt Harvey, Maciej Wójcikowski, Marcus Han-
well, Mathias Laurin, Matt Swain, Mohamad Mohebifar, Mohammad Ghahremanpour, Noel O’Boyle, Patrick Avery,
Patrick Fuller, Paul van Maaren, Peng Bai, Philipp Thiel, Reinis Danne, Ronald Cohen, Scott McKechnie, Stefano
Forli, Steve Roughley, Steffen Moeller, Tim Vandermeersch, Tomas Racek, Tomáš Trnka, Tor Colvin, Torsten Sachse,
Yi-Shu Tu, Zhixiong Zhao
Released on 2011-10-14.
This release represents a major bug-fix release and is a stable upgrade, strongly recommended for all users of Open
Babel. Many bugs and enhancements have been added since the 2.3.0 release.
After 10 years, we finally published a paper discussing Open Babel. Please consider citing this work if you publish
work which used Open Babel: Noel M. O’Boyle , Michael Banck , Craig A. James , Chris Morley , Tim Vandermeersch
and Geoffrey R. Hutchison. “Open Babel: An open chemical toolbox.” Journal of Cheminformatics 2011, 3:33.
http://www.jcheminf.com/content/3/1/33
Released on 2010-10-23.
This release represents a major update and should be a stable upgrade, strongly recommended for all users of Open
Babel. Highlights include a completely rewritten stereochemistry engine, Spectrophore fingerprint generation, 2D
depiction, improved 3D coordinate generation, conformer searching, and more. Many formats are improved or added,
including CIF, PDBQT, SVG, and more. Improved developer API and scripting support and many, many bug fixes are
also included.
• Completely rewritten stereochemistry perception, including support for tetrahedral, square planar, and higher-
order stereochemistry.
• Dramatically improved canonicalization algorithm (Note that in general, canonical SMILES have changed since
the 2.2.x release.)
• 2D depiction, including SVG vector graphics generation using code from MCDL.
• New Spectrophore generation, contributed by Silicos NV.
• New ChargeMethod API including support for partial charge assignment from Gasteiger, MMFF94, QEq, QT-
PIE methods and plugin interface for adding more.
• Improved 3D coordinate generation.
• New conformer generation framework, including support for diverse conformer generation and genetic algo-
rithm lowest-energy searching.
• Improved user documentation.
• Improved aromaticity / Kekule bond assignment.
• Improved unit test suite using the CMake-based CTest program.
• Improved support for crystallographic unit cells (e.g., in CIF format).
• Improved UFF force field method, including hypervalent 5, 6, 7 and higher coordination numbers.
• Support for the GAFF (Generalized Amber Force Field) method.
• Support for reading geometry optimizations as multiple conformers from Gaussian, GAMESS-US, and other
quantum chemistry packages.
• Support for reading molecular orbital energies from quantum chemistry formats.
• Several memory leaks fixed.
• Fixed many compiler warnings.
• Fixed support for MinGW and Cygwin environments.
• Fixed bugs with Gaussian 09 output files.
• Latest released version of the InChI library (1.0.3) generating standard InChI.
• Many more bug fixes and small feature improvements.
• –canonical: Output atoms in canonical order for any file format (i.e., not just SMILES)
• –conformer: Run a conformer search on the input molecules (has many options)
• –gen2D: Generate a 2D depiction of the molecule
• –partialcharge <model>: Use the partial charge model supplied to generate charges (i.e., instead of default
Gasteiger sigma model)
• –sort <descriptor>: Sort molecules by a specified descriptor
• –unique: Only output unique molecules (as determined by InChI generation)
Released on 2009-07-31.
This release represents an important bug-fix upgrade, strongly recommended for all users of Open Babel.
• Fixed bug in fingerprints in 2.2.2, where the default fingerprint format and bit length was changed inadvertently.
• Fixed detection of shared_ptr in tr1/memory.
• Fixed additional aromaticity / Kekule assignment bugs.
• Fixed several bugs in the MMCIF format.
• Additional bug fixes.
Released on 2009-07-04.
This release represents a major bug-fix release and is a stable upgrade, strongly recommended for all users of Open
Babel. While there may not be many new features, many crashes and other bugs have been fixed since 2.2.1.
• Upgraded to the new InChI 1.02 release to produce standardized InChI and InChIKey output.
• Fixed many stereochemistry errors when reading/writing SMILES. This is part of a larger project which will be
finished in the 2.3 release.
• Fixed compilation and installation on Cygwin and MinGW platforms.
• Significantly improved aromaticity and Kekule bond assignment.
• Improved 2D -> 3D coordinate generation
• Improved coordinate generation using the –gen3d command-line operation
• Improved performance for coordinate generation.
• New –fillUC command-line operation for babel.
• Fixes to pH-dependent hydrogen addition.
• Added support for reading vibrational data from Molden, Molpro, and NWChem output files.
• Updated atomic radii from recent theoretical calculations.
• Fixed bug when reading gzip-compressed Mol2 or XML files.
• Close files after an error. Fixes a bug with Pybel where files would remain open.
• Many more bug fixes and small feature improvements.
Import & Export: - Molpro input and output. - VASP coordinate files (CONTCAR and POSCAR).
Released on 2009-03-01.
This release represents a major bug-fix release and is a stable upgrade, strongly recommended for all users of Open
Babel. While there may not be many new features, many crashes and other bugs have been fixed since 2.2.0.
• Improved scripting interfaces, including Python 3 support and improved Java and C# support.
• Added support for MACCS fingerprints. Thanks to the RDKit project.
• Many fixes and enhancements to the force field code. In particular, the UFF force field implementation should
handle many more molecules.
• Improved 3D coordinate generation, particularly with ring fragments. You can give this a try with the obgen
utility.
• Fixed a variety of PDB import errors with atom types.
• Added support for reading charges and radii from PQR file formats.
• Added support for reading and writing unit cells in PDB formats.
• New “output” file format for taking generic “.out”, “.log”, and “.dat” files and reading with appropriate file type
based on contents. Currently works extremely well for quantum chemistry packages.
• Added improved error handling and reporting when unable to load file formats.
• Improved CIF file format support.
• Many, many, many additional bug fixes and small enhancements.
Released on 2008-07-04.
• New support for 3D coordinate generation using the OBBuilder class. Note that this code directly supports
non-chiral compounds Stereochemistry may or may not be supported in this release
• Significantly faster force fields (up to 200x faster) and support for constrained optimization.
• New force fields, including complete UFF, MMFF94, and MMFF94s implementations.
• Monte Carlo conformer search support, including a new obconformer tool.
• Unified framework for plugin classes, including easy-to program file formats, descriptors, filters, force fields,
fingerprints, etc.
• A new “descriptor” plugin framework for QSAR descriptors, etc. Initial descriptors include hydrogen-bond
donors, acceptors, octanol/water partition, topological polar surface area, molar refractivity, molecular weight,
InChI, SMARTS, titles, Lipinski Rule of Five, etc.
• A new “filter” plugin framework for selecting molecules by title, molecular weight, etc.
• Facility to add new “ops”, commandline options or operations on the conversion process as plugin code. Initial
operations include 3D coordinate generation, tautomer standarization, and addition of polar hydrogens.
• Code for integrating Open Babel and the BOOST graph library.
• Improved scripting support, including new bindings for C# and improved Java, Ruby, Python, and Perl bindings.
• Space group support and thoroughly revised and improved CIF format.
• Initial support for 3D point group symmetry perception.
• Improved support for “grids” or “cubes” of molecular data, such as from quantum mechanics programs. (See
below for supported file formats.)
• Initial support for reading trajectories and animations.
• Improved support for reaction formats, including CML, RXN, and Reaction SMILES.
• Improved residue handling in PDB and Mol2 formats.
• Improved pH-dependent hydrogen addition.
• Latest released version of the InChI library, including use of the latest “preferred” options for InChI gener-
ation.
• Support for the cross-platform CMake build system.
• File format modules are now installed in a version-specific directory on unix, preventing problems between
2.2.x and 2.1.x (or older) plugin libraries.
• Framework to support “aliases” for group abbreviations, partially implemented for MDL formats.
• Many more bug fixes and small feature improvements.
Import & Export: Chemkin Gaussian Cube Gaussian Z-matrix GROMACS xtc trajectories MCDL mmCIF OpenDX
cube (e.g., from APBS) Reaction SMILES
Import only: Accelrys/MSI Cerius II MSI text format ADF output ADF Tape41 ASCII data GAMESS-UK input and
output Molden structure PNG (for embedded chemical data) PQR
Export only: MSMS input ADF input InChI Keys
Released on 2007-07-07.
• Improved scripting support, including dictionary-support for OBGenericData in pybel, casting from
OBUnitCell, etc. Improved access to OBRings from OBMol.GetSSSR().
• Added support for descriptors (e.g., PSA, logP) from scripting interfaces.
• Added support for reading all PDB records (beyond current atom and bond connections). Records not
handled directly by Open Babel are added as key/value pairs through OBPairData.
• Added a new configure flag –with-pkglibdir to allow Linux package distributors to define version-specific
directories for file format plugins.
• Fixed a bug which would not output chirality information for canonical SMILES with 3D files.
• Fixed problems with new line-ending code. Now correctly reads DOS and old Mac OS files with non-
UNIX line endings.
• Correctly rejects SMILES with incorrect ring closures. Thanks to Craig James for the report.
• Fixed a crash when output to canonical SMILES.
• Fixed a crash when converting from SMILES to InChI.
• Fixed a crash when reading some PDB files on Windows.
• Fixed a crash when reading invalid MDL/SDF files.
• Fixed a bug which made it impossible to read some GAMESS files.
• Fixed a problem when reading ChemDraw CDX files on Mac OS X.
• A large number of additional fixes, including some rare crashes.
Released on 2007-04-07.
• Now handles molecules with >65536 atoms or bonds. Some PDB entries, in particular have such large
molecular systems.
• New features for molecular mechanics force fields, including energy evaluation and geometry optimization.
Ultimately, this will enable coordinate generation and refinement for SMILES and other formats. (A
flexible force field framework is available for developers.)
• Implementation of the open source Ghemical all atom force field.
• Framework for canonical atom numbering, including a new canonical SMILES format.
• New support for Ruby and Java interfaces to the Open Babel library.
• Improved scripting interfaces through Perl and Python, including the new “pybel” module with a more Python-
like syntax.
• Automatically handles reading from text files with DOS or Mac OS 9 line endings.
• Many enhancements to the Open Babel API: See the Developers API Notes for more information.
• New obenergy tool - evaluate the energy of a molecule using molecular mechanics.
• New obminimize tool - optimize the geometry of structures using molecular mechanics.
• Improved obprop tool - outputs a variety of molecular properties including Topological Polar Surface
Area (TPSA), Molar Refractivity (MR), and logP.
• The babel tool can now setting program keywords for some quantum mechanics formats from the
command-line, including: GAMESS, Gaussian, Q-Chem, and MOPAC. (This feature can also be accessed
by developers and expanded to other formats.)
• New options for babel tool, including: -e for continuing after errors -k for translating computational keywords
(e.g., GAMESS, Gaussian, etc.) –join to join all input molecules into a single output –separate to separate
disconnected fragments into separate molecular records -C (combine mols in first file with others having
the same name) –property to add or replace a property (e.g., in an MDL SD file) –title to add or replace the
molecule title –addtotitle to append text to the current molecule title –addformula to append the molecular
formula to the current title
• Many more bug fixes and small feature improvements.
Import & Export: Carine’s ASCII Crystal (ACR) ChemDraw CDX & CDXML Crystallographic Inter-
change Format (CIF) Fasta Sequence Thermo Format
Import: Gaussian fchk InChI
Export: Open Babel MolReport Titles
Released on 2006-07-24.
• Substantial fixes to the SMILES and SMARTS parsing support, thanks to a variety of bug reports.
• A variety of fixes to aromaticity perception and Kekule form assignment.
• Fixed gzip support, broken in version 2.0.1 inadvertantly.
• Output a warning when a multi-molecule files is converted to a single-molecule format.
• Better support for command-line tools such as obgrep on Cygwin.
• Fixed a variety of crashes.
• Countless other bug fixes.
Released on 2006-04-17.
• Support for dynamic building on the Cygwin environment. This fixes a long-standing problem that made Open
Babel useless to Cygwin users.
• Fixed a variety of memory leaks and improved overall memory use. More work to reduce memory consumption
is underway for the 2.1 release.
Released on 2005-11-26.
This release represents Open Babel’s fourth “birthday” and a milestone for a stable, flexible interface for developers
and users alike.
• New conversion framework. The new framework allows dynamic loading/unloading of file translator mod-
ules (i.e., shared libraries, DLLs, DSO, etc.). More importantly, it facilitates adding new formats, since
each format is self-contained and no editing of other files is required.
• Improved support for XML chemistry formats, including CML, PubChem XML,
• Support for fingerprinting and calculation of Tanimoto coefficients for similarity consideration. (A flexi-
ble fingerprint framework is available for developers.)
• New support for Perl and Python “wrappers” of the Open Babel library.
• Many enhancements to the Open Babel API: See the Developers API Notes for more information. Some
code will require updating, see the Developer’s Migration Guide for details.
• Support for automatically reading .gz compressed files. (e.g., 1abc.pdb.gz is uncompressed and treated as a
PDB file) Use of the -z flag creates gzip-compressed output files.
• Support for the new IUPAC InChI identifiers.
• Improved bond order typing, including flexible SMARTS matching in bondtyp.txt.
• New Kekulization routine – improves aromaticity detection in aromatic amines like pyrroles, porphyrins,
etc.
• Improved support for radicals and spin multiplicity, including assignment of hydrogens to radicals.
• Improved support for 2D vs. 3D file formats.
• New error logging framework keeps an “audit log” of changes to files (hydrogen addition, bond order as-
signment) and different levels of error reporting / debugging. Use the “—errorlevel 4” flag to access this
information.
• Improved atom typing and hydrogen addition rules.
• Improved obfit utility will output RMSD and find matches with the best RMSD.
• Updated isotope data from 2003 IUPAC standard.
• Updated elemental data from the Blue Obelisk Data Repository. (project started, in part, to validate the old
Open Babel data)
• Improved z-matrix code (CartesianToInternal / InternalToCartesian).
• Countless bug fixes.
• Import & Export: ChemDraw CT (Connection Table) CML Reaction files MDL Molfile V3000 MDL Rxn
files Open Babel free-form fractional (crystallographic coordinates) Open Babel fastsearch database format
Open Babel fingerprint formats PCModel format YASARA.org YOB format Turbomole Improved CML
support Improved Gaussian 98/03 support Improved SMILES import / export
• Import-Only: PubChem XML
• Export-Only: MPQC input Open Babel “copy” format (i.e., copy the raw input file) Sybyl MPD descriptor
format IUPAC InChI descriptor
• Changed formats:
– MMADS - eliminated
– bin - OpenEye binary v 1, eliminated
– GROMOS96 - changed from separate g96a & g96nm types to a unified g96 type. Defaults to output
Angstroms, Use -xn to output nm.
– Titles - eliminated – can be produced with SMILES -xt
Released on 2004-02-22.
• Shared library (version 0:0:0) built by default on POSIX systems (e.g. Linux, BSD, Mac OS X. . . )
• Fixed installation of header files. The headers in the math/ subdirectory were not installed alongside the other
headers.
• Added tools/ directory with small examples of using libopenbabel: * obgrep: Use SMARTS patterns to grep
through multi-molecule files. * obfit: Use SMARTS patterns to align molecules on substructures. * obrotate:
Rotate a torsional bond matching a SMARTS pattern.
• Improved PDB support: uses HETATM records more appropriately, attempts to determine chain/residue infor-
mation if not available.
• Fixed a variety of bugs in ShelX support.
• Added support for handling atom and molecule spin multiplicity.
• Updated documentation – not yet complete, but significantly improved.
• Fixed major omissions in CML readers and writers. All versions of CML are now supported (CML1/2 and
array/nonArray). Also added *.bat file for roundtripping between these formats for both 2- and 3-D data. Fixed
bugs in test/cmltest/cs2a.mol.cml.
• Building and running the test-suite in a build-directory other than the source-directory is now fully supported.
• Support for the Intel C++ Compiler on GNU/Linux.
• Miscellaneous fixes to make it easier to compile on non-POSIX machines.
-Export: Chemtool Chemical Resource Kit (CRK) 2D and 3D Parallel Quantum Solutions (PQS)
-Import: CRK 2D and 3D PQS
Released on 2003-6-24.
• Much better bond typing overall for files converted from formats without bond information (e.g. XYZ, QM
codes). Fixed some bugs in 1.100.1 and added additional improvments.
• Support for the command-line “babel” program to convert some or all structures in a file with multiple molecules.
By default this version will convert all molecules in a file. To change this, use the -f and -l command-line options
as documented in the man page.
• Isotope support, including exact masses in the “report” file format and SMILES data.
• Updated API documentation.
• Support for the Borland C++ compiler.
• Fixed a variety of bugs in the PDB file format support, including better bond typing.
• Support for output of residue information in the Sybyl Mol2 file format.
• Some support for conversion of unit cell information, both in the library and in some file formats (i.e. DMol3,
Cacao).
• Coordinates now use double-precision floating point libraries for greater accuracy in conversions.
• Fixed a variety of bugs uncovered in roundtrip testing.
• Fixed a bug when attempting to perceive bond information on 2D structures.
• Fixed several rare bugs that could cause segmentation faults.
Released on 2002-12-12.
• Bond order typing is performed when importing from formats with no notion of bonds (quantum chemistry
programs, XYZ, etc.). -Now better conforms to the ISO C++ standard, should compile on most modern C++
compilers.
• Improved test suite, including “roundtrip” testing, ensuring more accurate translations.
• Support for the Chemical Markup Language (CML) and other file formats. (see below)
• Improved PDB support – should read PDB files more accurately and hew closer to the current PDB standard for
export.
• Improved Gaussian input generation.
• Added support for the Chemical MIME standards, including command-line switches.
• Added support for using the babel program as a pipe for a “translation filter” for other programs.
• Can add hydrogen atoms based on pH.
• Fixed a variety of memory leaks, sometimes causing other bugs.
• Fixed a wide variety of bugs in various file formats.
• Faster SMARTS matching and some overall speedups across the program.
• API documentation using the Doxygen system.
• Of course there are many other bug-fixes and improvements.
-Import: NWChem Output -Export: POV-Ray, NWChem Input -Both: CML, ViewMol, Chem3D
Released on 2002-1-29.
The Open Babel team is pleased to announce the release of Open Babel 1.99, a first beta release for the 2.0 version of
the free, open-source replacement for the Babel chemistry file translation program.
At the moment, the beta release is not a drop-in replacement for babel as some file formats are not implemented and
bond orders are not calculated for QM file formats.
Open Babel includes two components, a command-line utility and a C++ library. The command-line utility is intended
to be used as a replacement for the original babel program, to translate between various chemical file formats. The
C++ library includes all of the file-translation code as well as a wide variety of utilities to foster development of other
open source chemistry software.
[obj2011] Noel M. O’Boyle, Michael Banck, Craig A. James, Chris Morley, Tim Vandermeersch, Geoffrey R. Hutchi-
son Open Babel: An open chemical toolbox. J. Cheminf. 2011, 3, 33. [Link]
[bll2002] P. Bultinck, W. Langenaeker, P. Lahorte, F. De Proft, P. Geerlings, C. Van Alsenoy, and J. P. Tollenaere.
The Electronegativity Equalization Method II: Applicability of Different Atomic Charge Schemes. J.
Phys. Chem. A 2002, 106, 7895-7901. [Link]
[blc2003] Patrick Bultinck, Wilfried Langenaeker, Ramon Carbó-Dorca, and Jan P. Tollenaere. Fast Calculation of
Quantum Chemical Molecular Descriptors from the Electronegativity Equalization Method. J. Chem.
Inf. Comput. Sci. 2003, 43, 422-428. [Link]
[omh2008] N.M. O’Boyle, C. Morley and G.R. Hutchison. Pybel: a Python wrapper for the OpenBabel chemin-
formatics toolkit. Chem. Cent. J. 2008, 2, 5. [Link]
[bmg2004] Andreas Bender, Hamse Y. Mussa, and Robert C. Glen. Molecular Similarity Searching Using Atom
Environments, Information-Based Feature Selection, and a Naive Bayesian Classifier. J. Chem. Inf.
Comput. Sci. 2004, 44, 170-178. [Link]
[fpbg99] Dmitrii Filimonov, Vladimir Poroikov, Yulia Borodina, and Tatyana Gloriozova. Chemical Similarity
Assessment through Multilevel Neighborhoods of Atoms: Definition and Comparison with the Other
Descriptors. J. Chem. Inf. Comput. Sci. 1999, 39, 666-670. [Link]
[gb2001] A.A. Gakh and M.N. Burnett. Modular Chemical Descriptor Language (MCDL): Composition, Con-
nectivity and Supplementary Modules. J. Chem. Inf. Comput. Sci., 2004, 41, 1491-1499. [Link]
239