Cheminfo-to-web Project

Open Babel Demo

Overview

To use the OpenBabel JS compilation, you need to deploy openbabel.js, openbabel.wasm and openbabel.data all togather in the same directory. The JavaScript file should be included in the HTML file:

<script src="openbabel.js"></script>

The openbabel.js will then load openbabel.wasm, the web assembly compiled from OpenBabel lib, and openbabel.data, the external data file need by Open Babel. This is a asynchronous process and a custom event callback should be used to acknowledge the ready of OpenBabel module:

var OpenBabel = OpenBabelModule();
OpenBabel.onRuntimeInitialized = function()
{
  // Now the OpenBabel routines can be called 
}

After initialization, all useful classes can be accessed from that OpenBabel module. In native OpenBabel, the core class to do data format conversion is OBConversion. For some reason, in JavaScript compiliation, a wrapper class ObConversionWrapper is created to wrap functions of OBConversion. Most of I/O job can be done with this wrapper class.

Enumeration Supported Formats

OpenBabel supports a lot of different chemical formats (note that not all of them are ported to JavaScript currently). To list all of them, the following JavaScript code can be used:

var conv = new OpenBabel.ObConversionWrapper();  // create ObConversionWrapper instance
try
{
	// list all supported input/output formats, use '\n' to separate between each format string
	var sInputFormats = conv.getSupportedInputFormatsStr('\n');
	var sOutputFormats = conv.getSupportedInputFormatsStr('\n');
	console.log(sInputFormats);
	console.log(sOutputFormats);
}
finally
{
	conv.delete();  // free ObConversionWrapper instance
}

Live demo:


 

It can be seen from the demo above that the each item of returned format string of getSupportedInputFormatsStr / getSupportedOutputFormatsStr contains two parts: format id and format description with a delimiter of "--". You can then extract the id and get more informations from it:

var conv = new OpenBabel.ObConversionWrapper();  // create ObConversionWrapper instance
try
{
	var formatId = "mol";
	var formatInfo = conv.getFormatInfoById(formatId);  // returns detailed format info
	console.log(formatInfo.id, formatInfo.mimeType, formatInfo.specificationURL, formatInfo.description);
}
finally
{
	conv.delete();  // free ObConversionWrapper instance
}

Live demo:


Convert between Data Formats

The dominate use of class ObConversionWrapper is to do conversion between different data formats:

var conv = new OpenBabel.ObConversionWrapper();  // create ObConversionWrapper instance
try
{
	var inData = '...';   // set input data
	conv.setInFormat('', 'mol');  // set input format by file extension
		// the input format can also be set by MIME type:
		// conv.setInFormat('chemical/x-mdl-molfile');
	var mol = new OpenBabel.OBMol();  // create a new molecule object...
	conv.readString(mol, inData);  // ... and load it with input data
	conv.setOutFormat('', 'pdb');  // set out format by file extension
	var outData = conv.writeString(mol, false);  // get output data, do not trim white spaces
	console.log(outData);
}
finally
{
	conv.delete();  // free ObConversionWrapper instance
}

It is noticeable that during the conversion, an OBMol object is created. This object holds the structure of a molecule, and you can even manipulate it with OpenBabel API before saving it. For example, the following code will change mass number of all C atoms in molecule to 13:

// ...
var mol = new OpenBabel.OBMol();
conv.readString(mol, inData);
var atomCount = mol.NumAtoms();  // get atom number of molecule
for (var i = 0; i < atomCount; ++i)
{
	var atom = mol.GetAtom(i + 1);  // note: OpenBabel atom starts with index 1, not 0
	var atomicNum = atom.GetAtomicNum();
	if (atomicNum === 6)  // is C atom
	{
		atom.SetIsotope(13)  // change mass number to 13
	}
}
// ...

Live demo:





Force Field Calculation

Aside from molecule I/O, Open Babel supports molecular modeling to some degree. The core class OBForceField is also exported in current JavaScript compilation. It can be called in a similar way to native C++ code. For example, the following codes calculate the energy of a molecule (the JavaScript codes are actaully borrowed from C++ code from obenergy program of OpenBabel):

var FF = new OpenBabel.OBForceField.FindForceField("ghemical");
FF.SetLogLevel(3); // OBFF_LOGLVL_HIGH
if (!FF.Setup(mol))
	console.log('Error set force field');
var sUnit = FF.GetUnit();
var msg = 'Molecule total energy: ' + FF.Energy(true) + sUnit + '\n'
	+ '  Bond stretching energy: ' + FF.E_Bond(true) + sUnit + '\n'
	+ '  Angle bending energy: ' + FF.E_Angle(true) + sUnit + '\n'
	+ '  Stretch bending energy: ' + FF.E_StrBnd(true) + sUnit + '\n'
	+ '  Torsional energy: ' + FF.E_Torsion(true) + sUnit + '\n'
	+ '  Out-Of-Plane bending energy: ' + FF.E_OOP(true) + sUnit + '\n'
	+ '  Van der Waals energy: ' + FF.E_VDW(true) + sUnit + '\n'
	+ '  Electrostatic energy: ' + FF.E_Electrostatic(true) + sUnit + '\n';
console.log(msg);
			

Live demo:




OpenBabel Operation

The OpenBabel library provides a series of instances of OBOp to perform some useful operations on molecule (e.g., 2D diagram and 3D structure generation). In the JavaScript code, you can call those operations similarly to the C++ code. For example, the following codes can be used to generate 3D coordinates of atoms from a 2D molecule structure:

var molData = '....';  // MOL format molecule data
var conv = new OpenBabel.ObConversionWrapper();
conv.setInFormat('', 'mol');
var mol = new OpenBabel.OBMol();
conv.readString(mol, molData);
var gen3d = OpenBabel.OBOp.FindType("Gen3D");
if (!gen3d.Do(mol, ''))
  console.error('Generate 3D failed');
else
{
  conv.setOutFormat('', 'mol');
  var outputData = conv.writeString(mol, false);
  console.log(outputData);
}
conv.delete();
			

Live demo: