JavaScript for Cheminformatics: Atom Typing with Prototype and Iterators
The previous article in this series discussed the use of Prototype to build a simple cheminformatics model. But there's much more to Prototype than an improved class-like syntax. This article discusses one specific way that Prototype enhances JavaScript collections through iterators.
The Problem
Let's say we have an instance of Molecule, as defined in the previous article, and we'd like to group the carbon atoms separately from the heteroatoms. In many languages, including Java, we'd have to write a for-loop complete with logic for comparing atoms and then placing them into bins. Prototype makes possible a more modular approach with iterators.
Functional Programming and Iterators
JavaScript is a multi-paradigm programming language that offers tools for both object-oriented and functional programming approaches. In practical terms, this simply means that even functions in JavaScript behave as objects: they can be created dynamically and passed as parameters. Prototype takes advantage of this to extend collections instances such as Arrays with built-in iterators that are analogous to iterators found in languages such as Ruby.
A Simple Test
The JavaScript below builds a pyridine molecule:
function createPyridine(){
var pyridine = new Molecule();
var c1 = pyridine.addAtom("C");
var c2 = pyridine.addAtom("C");
var c3 = pyridine.addAtom("C");
var c4 = pyridine.addAtom("C");
var c5 = pyridine.addAtom("C");
var n6 = pyridine.addAtom("N");
pyridine.connect(c1, c2, 1);
pyridine.connect(c2, c3, 2);
pyridine.connect(c3, c4, 1);
pyridine.connect(c4, c5, 2);
pyridine.connect(c5, n6, 1);
pyridine.connect(n6, c1, 2);
return pyridine;
}Saving this code in a file called molecules.js, we can use Firefox with Firebug to test it with the following HTML:
<html>
<head>
<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript" src="chem.js"></script>
<script type="text/javascript" src="molecules.js"></script>
</head>
<body></body>
</html>>>> m = createPyridine();
To separate carbons from heteroatoms, we use the Prototype partition iterator:
>>> m=createPyridine();
Object atoms=[6] bonds=[6]
>>> m.atoms.partition(function(atom){return atom.label == "C"});
[[Object label=C neighbors=[2] bonds=[2], Object label=C neighbors=[2] bonds=[2], Object label=C neighbors=[2] bonds=[2], 2 more...], [Object label=N neighbors=[2] bonds=[2]]]
The partition iterator accepts a function as a parameter and returns an array containing two sub-arrays: the first contains the elements for which the function evaluated to true (carbons) and the second contains the elements for which the function evaluated to false (heteroatoms).
Conclusions
Although the example shown here is rather simple, it's possible to extend the general principle to more complex atom typing systems. By creating a single function that evaluated atom type, we could pass it as a parameter to any number of collection iterator functions.
JavaScript for Cheminformatics: Using the Prototype Framework 1
If you want to do the kind of cheminformatics that involves manipulating atoms, bonds, and molecules, object-oriented programming works well as a development paradigm. Although perhaps not readily apparent, JavaScript offers everything needed to create object-oriented models just as intricate at those written in languages like C++ and Java. This article discusses one approach that makes use of the Prototype Framework.
About Prototype
Prototype is a set of extensions to the JavaScript language that make developing in it less painful. Some of the extensions relate to DOM manipulation. Other have to do with the way Strings and Arrays behave. For the purposes of this article, we'll be using Prototype's syntax support for classes and inheritance.
Atoms, Bonds, and Molecules
To start, we'll need classes that define the basic behavior of atoms, bonds, and molecules. Although we may ultimately need to consider issues such as multicentered bonding, for now, we'll stick to a simplified view of chemistry that has bonds connecting two and only two atoms.
Creating the Classes
We could use JavaScript's built-in method for creating objects from class-like structures, but Prototype's approach is cleaner.
In the following library, we define a Molecule as a collection of Atoms and Bonds with useful relationships:
var Molecule = Class.create({
initialize: function(){
this.atoms = [];
this.bonds = [];
},
addAtom: function(label){
var atom = new Atom(label);
this.atoms.push(atom);
return atom;
},
connect: function(sourceAtom, targetAtom, bondType){
var bond = new Bond(sourceAtom, targetAtom, bondType);
sourceAtom.neighbors.push(targetAtom);
sourceAtom.bonds.push(bond);
targetAtom.neighbors.push(sourceAtom);
targetAtom.bonds.push(bond);
this.bonds.push(bond);
return bond;
}
});
var Atom = Class.create({
initialize: function(label){
this.label = label;
this.neighbors = [];
this.bonds = [];
}
});
var Bond= Class.create({
initialize: function(source, target, type){
this.source = source;
this.target = target;
this.type = type;
},
getMate: function(atom){
if (atom == this.source) return this.target;
if (atom == this.target) return this.source;
return null;
},
contains: function(atom){
return (atom == this.source || atom == this.target);
}
});Testing the Library
We can test the library interactively by saving it in a file called chem.js and creating some simple HTML:
<html>
<head>
<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript" src="chem.js"></script>
</head>
<body></body>
</html>We can then use the Firebug console to test the library interactively:
>>> m = new Molecule();
Object atoms=[0] bonds=[0]
>>> c = m.addAtom("C");
Object label=C neighbors=[0] bonds=[0]
>>>n = m.addAtom("N");
Object label=N neighbors=[0] bonds=[0]
>>> m.connect(c, n, 3);
>>> c.neighbors.size()
1
Conclusions
Although the cheminformatics library discussed here is far from being useful, it's not difficult to see how to extend it. Prototype offers a several possibilities for doing so.
Adobe Flash for Cheminformatics: Chemul, a 3D Structure Viewer 4
Previous articles have discussed the use of Adobe Flash for cheminformatics. Tetsuya Hoshi has created a 3D structure viewer (embedded above) called Chemul that can be used with the Flash Player and which is written in ActionScript 3.0. Although the documentation is written in Japanese, it appears that Chemul supports multiple display options, as evidenced here.
Encapsulated PostScript for Cheminformatics 5
Previous articles have discussed ways to display chemical structures in a variety of vector graphics formats, including Scalable Vector Graphics (SVG), Vector Markup Language (VML), and Shockwave Flash (SWF, or "Flash"). There is one other vector graphics format still in common use that has so far not been discussed: Encapsulated PostScript (EPS).
EPS is a vector graphics format developed by Adobe Systems specifically for desktop publishing. Apparently, the last revision to the EPS Specification, Version 3.0, was published in 1992. Although ancient as technologies go, EPS can still be found in use today. Like the other vector graphics formats discussed here, EPS has all of the features necessary to create high-quality 2D images of chemical structures.
To demonstrate, a development version of ChemWriter was used to convert a molfile representing rosuvastatin (Crestor) into the corresponding color EPS file. The result can be downloaded here.
An open source library, jlibeps, can be used to encode EPS in Java. The business end of the library is an EPS encoding class that extends Graphics2D, enabling most Java2D rendering to be converted into EPS. If you've worked with the Batik SVG toolkit, the concept is similar.
Although jlibeps is a good solution, EPS shares enough similarities to other vector graphics languages that directly encoding EPS output is also a viable option, and the one that was used in the rosuvastatin example above.
Image Credit: Kelly Smith

