Flexible Depth-First Search With MX 2
Graph theory is an essential component of cheminformatics, if you dig deeply enough. MX is a lightweight cheminformatics toolkit written in Java with a major goal of exposing the most important cheminformatics graph manipulations in a flexible, Java-centric way. Previous releases have focused on implementing subgraph monomorphism functionality for use in substructure search. The new MX release, 0.104.0, introduces support for depth-first traversal. This article will give a simple example using this feature.
Downloading MX
MX can be downloaded in source or binary form:
mx-0.104.0.jar Platform-independent bytecode.
mx-0.104.0-src.tar.gz Source code and regression tests.
Scripting MX with JRuby
A previous article outlined the simple steps needed to install JRuby on unix-based systems for scripting MX.
Finding All Paths From a Given Atom
A fundamental graph operation in cheminformatics is finding all paths through a molecule from a starting atom. MX makes this easy with the com.metamolecular.mx.path.PathFinder class. Depth-first traversal is used in creating molecular fingerprints. Another use is in creating SMILES strings, although a limited form of depth-first traversal is used in which each atom in a molecule is traversed only once.
We can create a short library to print out all of the paths through a molecule in JRuby:
require 'mx-0.104.0.jar'
import 'com.metamolecular.mx.path.PathFinder'
class PathPrinter
def initialize
@finder = PathFinder.new
end
def print_paths atom
paths = @finder.find_all_paths atom
puts "printing all paths through the molecule"
paths.each do |path|
print_path path
end
end
private
def print_path path
path.each do |atom|
print atom.get_index
print '-' unless path.get(path.length - 1).equals(atom)
end
puts
end
endSaving the above code in a file called pathprinter.rb, we can test it from interactive JRuby:
$ jirb irb(main):001:0> require 'pathprinter' => true irb(main):002:0> import com.metamolecular.mx.io.Molecules => Java::ComMetamolecularMxIo::Molecules irb(main):003:0> benzene=Molecules.create_benzene => #<Java::ComMetamolecularMxModel::DefaultMolecule:0x43da1b @java_object=com.metamolecular.mx.model.DefaultMolecule@8a2023> irb(main):004:0> p=PathPrinter.new => #<PathPrinter:0x19ed7e @finder=#<Java::ComMetamolecularMxPath::PathFinder:0x3727c5 @java_object=com.metamolecular.mx.path.PathFinder@1140709>> irb(main):005:0> p.print_paths benzene.get_atom(0) printing all paths through the molecule 0-5-4-3-2-1 0-1-2-3-4-5 => nil
How It Works
Two classes collaborate in this traversal: com.metamolecular.mx.path.PathFinder and com.metamolecular.mx.path.DefaultStep.
Creating a depth-first traversal of your own is as simple as creating a DefaultStep from an Atom and implementing a walk method similar to the one shown below:
public void walk(Step step)
{
if (!step.hasNextBranch())
{
// do something with the completed branch
return;
}
while(step.hasNextBranch())
{
Atom next = step.nextBranch();
if (step.isBranchFeasible(next))
{
walk(step.nextStep(next));
step.backTrack();
}
}
}Conclusions
Depth-first traversal is an important tool in any cheminformatics library. MX offers an implementation of this traversal strategy that can be easily customized.

