<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Depth-First: Tag cheminformatics</title>
    <link>http://depth-first.com/articles/tag/cheminformatics</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Walking the Web of Chemical Informatics</description>
    <item>
      <title>Flexible Depth-First Search With MX</title>
      <description>&lt;p&gt;&lt;a href="http://code.google.com/p/mx-java/"&gt;&lt;img src="http://depth-first.com/demo/20081121/mx.png" align="right"&gt;&lt;/img&gt;&lt;/a&gt;Graph theory is an essential component of cheminformatics, if you dig deeply enough. &lt;a href="http://code.google.com/p/mx-java/"&gt;MX&lt;/a&gt; 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 &lt;a href="http://depth-first.com/articles/2008/11/17/substructure-search-from-scratch-in-java-part-1-the-atom-mapping-problem"&gt;subgraph monomorphism&lt;/a&gt; functionality for use in substructure search. The new MX release, &lt;a href="http://code.google.com/p/mx-java/downloads/list"&gt;0.104.0&lt;/a&gt;, introduces support for depth-first traversal. This article will give a simple example using this feature.&lt;/p&gt;

&lt;h4&gt;Downloading MX&lt;/h4&gt;

&lt;p&gt;MX can be downloaded in source or binary form:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://code.google.com/p/mx-java/downloads/detail?name=mx-0.104.0.jar&amp;amp;can=2&amp;amp;q="&gt;mx-0.104.0.jar&lt;/a&gt; Platform-independent bytecode.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://code.google.com/p/mx-java/downloads/detail?name=mx-0.104.0-src.tar.gz&amp;amp;can=2&amp;amp;q="&gt;mx-0.104.0-src.tar.gz&lt;/a&gt; Source code and regression tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Scripting MX with JRuby&lt;/h4&gt;

&lt;p&gt;A &lt;a href="http://depth-first.com/articles/2008/11/24/getting-started-with-mx"&gt;previous article&lt;/a&gt; outlined the simple steps needed to install JRuby on unix-based systems for scripting MX.&lt;/p&gt;

&lt;h4&gt;Finding All Paths From a Given Atom&lt;/h4&gt;

&lt;p&gt;A fundamental graph operation in cheminformatics is finding all paths through a molecule from a starting atom. MX makes this easy with the &lt;tt&gt;com.metamolecular.mx.path.PathFinder&lt;/tt&gt; class. Depth-first traversal is used in creating &lt;a href="http://depth-first.com/articles/2008/10/02/fast-substructure-search-using-open-source-tools-part-1-fingerprints-and-databases"&gt;molecular fingerprints&lt;/a&gt;. Another use is in creating &lt;a href="http://www.daylight.com/dayhtml/doc/theory/theory.smiles.html"&gt;SMILES strings&lt;/a&gt;, although a limited form of depth-first traversal is used in which each atom in a molecule is traversed only once.&lt;/p&gt;

&lt;p&gt;We can create a short library to print out all of the paths through a molecule in JRuby:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;mx-0.104.0.jar&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;com.metamolecular.mx.path.PathFinder&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;PathPrinter&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;
    &lt;span class="attribute"&gt;@finder&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;PathFinder&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;print_paths&lt;/span&gt; &lt;span class="ident"&gt;atom&lt;/span&gt;
    &lt;span class="ident"&gt;paths&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="attribute"&gt;@finder&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;find_all_paths&lt;/span&gt; &lt;span class="ident"&gt;atom&lt;/span&gt;

    &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;printing all paths through the molecule&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;

    &lt;span class="ident"&gt;paths&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;path&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
      &lt;span class="ident"&gt;print_path&lt;/span&gt; &lt;span class="ident"&gt;path&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="ident"&gt;private&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;print_path&lt;/span&gt; &lt;span class="ident"&gt;path&lt;/span&gt;
    &lt;span class="ident"&gt;path&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;atom&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
      &lt;span class="ident"&gt;print&lt;/span&gt; &lt;span class="ident"&gt;atom&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;get_index&lt;/span&gt;
      &lt;span class="ident"&gt;print&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;-&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;unless&lt;/span&gt; &lt;span class="ident"&gt;path&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;get&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;path&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;length&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;equals&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;atom&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="ident"&gt;puts&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Saving the above code in a file called &lt;strong&gt;pathprinter.rb&lt;/strong&gt;, we can test it from interactive JRuby:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ jirb
irb(main):001:0&amp;gt; require 'pathprinter'                   
=&amp;gt; true
irb(main):002:0&amp;gt; import com.metamolecular.mx.io.Molecules
=&amp;gt; Java::ComMetamolecularMxIo::Molecules
irb(main):003:0&amp;gt; benzene=Molecules.create_benzene        
=&amp;gt; #&amp;lt;Java::ComMetamolecularMxModel::DefaultMolecule:0x43da1b @java_object=com.metamolecular.mx.model.DefaultMolecule@8a2023&amp;gt;
irb(main):004:0&amp;gt; p=PathPrinter.new                       
=&amp;gt; #&amp;lt;PathPrinter:0x19ed7e @finder=#&amp;lt;Java::ComMetamolecularMxPath::PathFinder:0x3727c5 @java_object=com.metamolecular.mx.path.PathFinder@1140709&amp;gt;&amp;gt;
irb(main):005:0&amp;gt; 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
=&amp;gt; nil
&lt;/pre&gt;
&lt;/div&gt;

&lt;h4&gt;How It Works&lt;/h4&gt;

&lt;p&gt;Two classes collaborate in this traversal: &lt;a href="http://github.com/rapodaca/mx/tree/master/src%2Fcom%2Fmetamolecular%2Fmx%2Fpath%2FPathFinder.java"&gt;&lt;tt&gt;com.metamolecular.mx.path.PathFinder&lt;/tt&gt;&lt;/a&gt; and &lt;a href="http://github.com/rapodaca/mx/tree/master/src%2Fcom%2Fmetamolecular%2Fmx%2Fpath%2FDefaultStep.java"&gt;&lt;tt&gt;com.metamolecular.mx.path.DefaultStep&lt;/tt&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Creating a depth-first traversal of your own is as simple as creating a &lt;tt&gt;DefaultStep&lt;/tt&gt; from an &lt;tt&gt;Atom&lt;/tt&gt; and implementing a &lt;tt&gt;walk&lt;/tt&gt; method similar to the one shown below:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_java "&gt;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();
    }
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4&gt;Conclusions&lt;/h4&gt;

&lt;p&gt;Depth-first traversal is an important tool in any cheminformatics library. MX offers an implementation of this traversal strategy that can be easily customized.&lt;/p&gt;</description>
      <pubDate>Wed, 26 Nov 2008 16:13:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:63a41f58-823a-4d0b-ad7d-da537fa4d99c</guid>
      <author>Rich Apodaca</author>
      <link>http://depth-first.com/articles/2008/11/26/flexible-depth-first-search-with-mx</link>
      <category>Tools</category>
      <category>mx</category>
      <category>java</category>
      <category>cheminformatics</category>
      <category>ruby</category>
      <category>jruby</category>
      <category>depthfirst</category>
      <category>graphtheory</category>
    </item>
    <item>
      <title>Substructure Search From Scratch in Java Part 1: The Atom Mapping Problem</title>
      <description>&lt;p&gt;&lt;a href="http://flickr.com/photos/dollar_bin/2086969723/"&gt;&lt;img src="http://depth-first.com/demo/20081117/map.jpg" align="right"&gt;&lt;/img&gt;&lt;/a&gt;One of the most important capabilities in cheminformatics is mapping the atoms of a &lt;em&gt;query structure&lt;/em&gt; onto the atoms of a &lt;em&gt;target structure&lt;/em&gt;. Although useful in itself, the main value of atom mapping comes from the software that gets built on top of it: exact structure comparators, &lt;a href="http://depth-first.com/articles/2008/10/02/fast-substructure-search-using-open-source-tools-part-1-fingerprints-and-databases"&gt;substructure search systems&lt;/a&gt;, and query atom/bond search systems such as &lt;a href="http://www.daylight.com/dayhtml/doc/theory/theory.smarts.html"&gt;SMARTS&lt;/a&gt;. The fundamental nature of atom mapping means that correctness, efficiency and adaptability are essential features of a good mapping implementation. Recently, a D-F article made the case that atom mapping software written in Java &lt;a href="http://depth-first.com/articles/2008/11/13/one-of-these-things-is-not-like-the-other"&gt;needs to be Java-centric&lt;/a&gt; to achieve these goals. This article, the first in a series that describes a complete substructure search system written in Java, takes the first step by offering some simple interface definitions and code for the atom mapping problem.&lt;/p&gt;

&lt;h4&gt;The Problem&lt;/h4&gt;

&lt;p&gt;Given a query molecule (&lt;tt&gt;query&lt;/tt&gt;) and a target molecule (&lt;tt&gt;target&lt;/tt&gt;), our atom mapping software needs to find ways to match the atoms of &lt;tt&gt;query&lt;/tt&gt; onto &lt;tt&gt;target&lt;/tt&gt; such that the mapping describes a substructure embedded in &lt;tt&gt;target&lt;/tt&gt;. The software might stop at one mapping, continue on to find all of them, or stop at some point in the middle. It all depends on the specific cheminformatics problem we're trying to solve.&lt;/p&gt;

&lt;h4&gt;The Recursive Function&lt;/h4&gt;

&lt;p&gt;Our implementation will gradually build up an atom mapping by traversing the atoms of &lt;tt&gt;query&lt;/tt&gt; in depth-first order and trying to map each found atom onto an atom in &lt;tt&gt;target&lt;/tt&gt;. At each step in the process, we will have a partial atom map that maps some of the atoms in &lt;tt&gt;query&lt;/tt&gt; onto &lt;tt&gt;target&lt;/tt&gt;. That map, and any other information needed to complete the analysis will be kept in an instance of a class implementing the &lt;tt&gt;State&lt;/tt&gt; interface.&lt;/p&gt;

&lt;p&gt;A &lt;tt&gt;State&lt;/tt&gt; will be manipulated by a recursive method, &lt;tt&gt;mapFirst&lt;/tt&gt; that returns when the first atom map is found:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_java "&gt;// create a list to hold atom maps
List&amp;lt;Map&amp;lt;Atom, Atom&amp;gt;&amp;gt; maps = new ArrayList&amp;lt;Map&amp;lt;Atom, Atom&amp;gt;&amp;gt;();

// create initial state
State state = ...; 

boolean mapFirst(State state)
{
  if (state.isDead())
  {
    return false;
  }

  if (state.isGoal())
  {
    maps.add(state.getMap());

    return true;
  }

  boolean found = false;

  while (!found &amp;amp;&amp;amp; state.hasNextCandidate())
  {
    Match candidate = state.nextCandidate();

    if (state.isMatchFeasible(candidate))
    {
      State nextState = state.nextState(candidate);
      found = mapFirst(nextState);

      nextState.backTrack();
    }
  }

  return found;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Comparison of the &lt;tt&gt;mapFirst&lt;/tt&gt; method to the pseudocode &lt;a href="http://depth-first.com/articles/2008/11/13/one-of-these-things-is-not-like-the-other"&gt;VF algorithm &lt;tt&gt;Match&lt;/tt&gt; procedure given in the previous article&lt;/a&gt; shows some similarities. In fact, something similar to the &lt;tt&gt;mapFirst&lt;/tt&gt; method forms the basis of many atom mappers in use today.&lt;/p&gt;

&lt;p&gt;Although it may be clear from the code, it's worth re-iterating that each time &lt;tt&gt;mapFirst&lt;/tt&gt; is recursively called, an attempt is made to branch off a new &lt;tt&gt;State&lt;/tt&gt; that maps an additional pair of atoms from &lt;tt&gt;query&lt;/tt&gt; to &lt;tt&gt;target&lt;/tt&gt;. If that branch leads to a possible solution, it's followed. Otherwise the next possible mapping is explored.&lt;/p&gt;

&lt;h4&gt;The &lt;tt&gt;State&lt;/tt&gt; Interface&lt;/h4&gt;

&lt;p&gt;The recursive &lt;tt&gt;mapFirst&lt;/tt&gt; method determines all of the methods the &lt;tt&gt;State&lt;/tt&gt; interface needs to define:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_java "&gt;public interface State
{
  /**
   * Returns the current mapping of query atoms onto target atoms.
   * This map is shared among all states obtained through nextState.
   */
  public Map&amp;lt;Atom, Atom&amp;gt; getMap();

  /**
   * Returns true if another candidate match can be found or
   * false otherwise.
   */
  public boolean hasNextCandidate();

  /**
   * Returns the next candidate match.
   */
  public Match nextCandidate();

  /**
   * Returns true if the given match will work with the current
   * map, or false otherwise.
   */
  public boolean isMatchFeasible(Match match);

  /**
   * Returns true if all atoms in the query molecule have been
   * mapped.
   */
  public boolean isGoal();

  /**
   * Returns true if no match will come from this State.
   */
  public boolean isDead();

  /**
   * Returns a state in which the atoms in match have been
   * added to the current mapping.
   */
  public State nextState(Match match);

  /**
   * Returns this State's atom map to its original condition.
   */
  public void backTrack();
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Finally, &lt;tt&gt;State&lt;/tt&gt; uses an instance of the &lt;tt&gt;Match&lt;/tt&gt; class:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_java "&gt;public class Match
{
  private Atom query;
  private Atom target;

  public Match(Atom query, Atom target)
  {
    this.query = query;
    this.target = target;
  }

  public Atom getQueryAtom()
  {
    return query;
  }

  public Atom getTargetAtom()
  {
    return target;
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4&gt;Conclusions&lt;/h4&gt;

&lt;p&gt;With just a few lines of Java, we've managed to reduce the fundamental cheminformatics problem of atom mapping to the far simpler problem of implementing the &lt;tt&gt;State&lt;/tt&gt; interface.&lt;/p&gt;

&lt;p&gt;How many ways are there to implement the &lt;tt&gt;State&lt;/tt&gt; interface? Probably as many as there are subgraph isomorphism algorithms. Notice that the way we've set up the problem lets us use the same recursive method to test all &lt;tt&gt;State&lt;/tt&gt; implementations, an essential prerequisite for benchmarking and optimization.&lt;/p&gt;

&lt;p&gt;Future articles in this series will describe one way to implement the &lt;tt&gt;State&lt;/tt&gt; interface.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image Credit: &lt;a href="http://flickr.com/photos/dollar_bin/"&gt;Dollar Bin&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</description>
      <pubDate>Mon, 17 Nov 2008 19:17:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:a8551af2-31ff-48b0-8b1b-dbd0382d21a9</guid>
      <author>Rich Apodaca</author>
      <link>http://depth-first.com/articles/2008/11/17/substructure-search-from-scratch-in-java-part-1-the-atom-mapping-problem</link>
      <category>Tools</category>
      <category>vf</category>
      <category>cheminformatics</category>
      <category>java</category>
      <category>mapping</category>
      <category>substructuresearch</category>
      <category>substructure</category>
    </item>
    <item>
      <title>What's Broken in Cheminformatics?</title>
      <description>&lt;p&gt;&lt;img src="http://depth-first.com/demo/20070214/soccer.png" align="right"&gt;&lt;/img&gt;A while back, &lt;a href="http://sethgodin.typepad.com/"&gt;Seth Godin&lt;/a&gt; gave &lt;a href="http://sethgodin.typepad.com/seths_blog/2006/08/this_is_broken_.html"&gt;a talk&lt;/a&gt; on things that are broken, why they are broken, and why they stay broken (&lt;a href="http://video.google.com/videoplay?docid=-4101280286098310645&amp;amp;hl=en"&gt;video&lt;/a&gt;). Seth is one of those rare speakers who can entertain and inform at the same time. I especially liked how his talk identifies seven (maybe more) reasons for brokenness:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not My Job&lt;/li&gt;
&lt;li&gt;Selfish Jerks&lt;/li&gt;
&lt;li&gt;The World Changed&lt;/li&gt;
&lt;li&gt;I Didn't Know&lt;/li&gt;
&lt;li&gt;I'm not a Fish&lt;/li&gt;
&lt;li&gt;Contradictions&lt;/li&gt;
&lt;li&gt;Broken on Purpose&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As I watched Seth's talk, it wasn't hard to think of many examples in which chem(o|i)informatics is broken. Of course, the way you feel about something being broken depends on your perspective. It's far too easy to become cynical when dealing with the frustration of broken things. But for anyone wanting to do research that matters or build useful products, things that are broken are like manna from heaven.&lt;/p&gt;</description>
      <pubDate>Wed, 14 Feb 2007 10:17:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:3262ece9-2d45-4927-ac01-d2f9b4bec9b8</guid>
      <author>Rich Apodaca</author>
      <link>http://depth-first.com/articles/2007/02/14/whats-broken-in-cheminformatics</link>
      <category>Meta</category>
      <category>broken</category>
      <category>sethgodin</category>
      <category>cheminformatics</category>
    </item>
    <item>
      <title>Mongrel and Rails: It's Just not Fair</title>
      <description>&lt;p&gt;&lt;img src="http://depth-first.com/demo/20070205/mongrel.png" align="right"&gt;&lt;/img&gt;&lt;a href="http://www.rubyonrails.org/"&gt;Rails&lt;/a&gt; excels as a rapid Web development platform. Deployment of Rails applications, on the other hand, has until recently been a lot less rapid and a lot more complicated. A new Rails technology called &lt;a href="http://mongrel.rubyforge.org/index.html"&gt;Mongrel&lt;/a&gt; is now set to change all of that.&lt;/p&gt;

&lt;p&gt;Mongrel is a fast Rails application container. It can be used in standalone mode - exactly like &lt;a href="http://www.webrick.org/"&gt;WEBrick&lt;/a&gt;. For hassle-free scaling, your Rails application can also be run on multiple Mongrel instances (either located on the same server or on multiple servers) behind a load balancer such as &lt;a href="http://siag.nu/pen/"&gt;Pen&lt;/a&gt;, &lt;a href="http://www.inlab.de/balance.html"&gt;Balance&lt;/a&gt;, or &lt;a href="http://httpd.apache.org/"&gt;Apache 2.1+&lt;/a&gt;. Using Mongrel is very simple: it's packaged as a Ruby Gem and requires minimal configuration. Mongrel is also stable (Version 1.0 was just released), actively maintained (unlike &lt;a href="http://www.lighttpd.net/"&gt;lighttpd&lt;/a&gt;), and apparently quite secure.&lt;/p&gt;

&lt;p&gt;What does this have to do with cheminformatics? Quite a lot if you, like me, see the Web as the &lt;a href="http://depth-first.com/articles/2006/11/20/unchaining-chemistry-from-the-desktop"&gt;ideal platform&lt;/a&gt; for developing cheminformatics applications. Sure, a lot of technologies will need to be created first. But this is just another way of underscoring the big opportunities ahead. Future articles will discuss some of them.&lt;/p&gt;</description>
      <pubDate>Mon, 05 Feb 2007 14:51:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:ff3dcc1f-15b8-427d-8ed8-dae594ce78ec</guid>
      <author>Rich Apodaca</author>
      <link>http://depth-first.com/articles/2007/02/05/mongrel-and-rails-its-just-not-fair</link>
      <category>Tools</category>
      <category>mongrel</category>
      <category>rails</category>
      <category>ruby</category>
      <category>cheminformatics</category>
      <category>loadbalance</category>
    </item>
    <item>
      <title>Anatomy of a Cheminformatics Web Application: Ajaxifying Depict</title>
      <description>&lt;p&gt;&lt;a href="http://rubyonrails.org"&gt;&lt;img src="http://depth-first.com/files/rails_logo.png" align="right" border="0"&gt;&lt;/img&gt;&lt;/a&gt;The &lt;a href="http://depth-first.com/articles/2006/11/27/anatomy-of-a-cheminformatics-web-application-beautifying-depict"&gt;previous tutorial in this series&lt;/a&gt; showed some techniques for improving the appearance and usability of a simple cheminformatics Web application. That application, Depict, rendered color images of 2-D molecular structures when given a SMILES string. Still, something is missing. Wouldn't it be better if the application responded to individual keystrokes in the input field, rather than waiting for the user to hit the return key? In this tutorial, we'll see how to quickly accomplish this effect with a technology called "Ajax."&lt;/p&gt;

&lt;h4&gt;Downloads and Prerequisites&lt;/h4&gt;

&lt;p&gt;For this tutorial, you'll need &lt;a href="http://depth-first.com/articles/2006/10/30/agile-chemical-informatics-development-with-cdk-and-ruby-rcdk-0-3-0"&gt;Ruby CDK&lt;/a&gt; (RCDK). A recent article described the small amount of system configuration required for &lt;a href="http://depth-first.com/articles/2006/09/25/cdk-the-ruby-way-rcdk-0-2-0"&gt;RCDK on Linux&lt;/a&gt;. Another article showed how to install &lt;a href="http://depth-first.com/articles/2006/10/12/running-ruby-java-bridge-on-windows"&gt;RCDK on Windows&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In addition, you'll need to install &lt;a href="http://www.rubyonrails.org/down"&gt;Ruby on Rails&lt;/a&gt; - something that can be done through &lt;a href="http://docs.rubygems.org/"&gt;RubyGems&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Rails application that this tutorial starts with can be downloaded from &lt;a href="http://depth-first.com/demo/20061127/depict-20061127.tar.gz"&gt;this link&lt;/a&gt;. If you'd rather start working directly with the version of Depict produced by applying the changes outlined in this tutorial, the full source code can be downloaded from &lt;a href="http://depth-first.com/demo/20061204/depict-20061204.tar.gz"&gt;this link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you'll be running Depict on an AMD64 Linux system, you'll need to prepend your invocation of &lt;tt&gt;script/server&lt;/tt&gt; with &lt;tt&gt;LD_PRELOAD&lt;/tt&gt;. For example, on my system running Sun's JVM, the full command looks like:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ LD_PRELOAD=/usr/java/jdk1.5.0_09/jre/lib/amd64/libzip.so ruby script/server
&lt;/pre&gt;
&lt;/div&gt;

&lt;h4&gt;A Brief Introduction to Ajax&lt;/h4&gt;

&lt;p&gt;When stripped down to its essentials, &lt;a href="http://ajaxian.com/"&gt;Ajax&lt;/a&gt; is nothing more than an asynchronous communication channel between Web browsers and Web servers. In the pre-Ajax model of client-server Web interactions, a browser would make a request to a server and then wait until getting a server response, which would take the form of a complete Web page. In the Ajax model, a browser makes a request to a server, continuing to function while the server generates a response, which takes the form of a small section of the page that gets replaced. For this reason, Ajax-enabled Web sites are far more application-like than the document-centric sites that preceded them.&lt;/p&gt;

&lt;h4&gt;Ajax Support in Rails&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://www.amazon.com/gp/product/0977616630?ie=UTF8&amp;amp;tag=depthfirst-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0977616630"&gt;&lt;img border="0" src="http://depth-first.com/demo/20061127/0977616630.01._AA_SCMZZZZZZZ_V36350687_.jpg" align="right"&gt;&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=depthfirst-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0977616630" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;Ajax is implemented in JavaScript using the &lt;tt&gt;HTMLHttpRequest&lt;/tt&gt; object, although working at this level can require a lot of code to do anything meaningful. Fortunately, Rails and other Web application frameworks provide high-level interfaces to Ajax. In Rails, Ajax support takes the form of a variety of helper methods, one of which we'll use in this tutorial: &lt;tt&gt;observe_field&lt;/tt&gt;. This method, an instance of the &lt;a href="http://en.wikipedia.org/wiki/Observer_pattern"&gt;Observer Pattern&lt;/a&gt;, assigns an Observer to monitor input activity in a text field.&lt;/p&gt;

&lt;h4&gt;The Problem at Hand&lt;/h4&gt;

&lt;p&gt;We'd like Depict to provide immediate feedback by rendering a SMILES string as it is keyed into the input field. If the partial SMILES string is valid, it will be rendered, otherwise, an error image will be rendered. At no point will the user need to press the return key to see an image of the SMILES string they are typing.&lt;/p&gt;

&lt;h4&gt;Step 1: Ajaxify the View&lt;/h4&gt;

&lt;p&gt;Let's start by adding an observer to Depict's input field. These changes will occur to the SMILES View, contained in &lt;strong&gt;depict/app/views/smiles/depict.rhtml&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Depict&amp;lt;/title&amp;gt;
    &amp;lt;%= stylesheet_link_tag &amp;quot;default&amp;quot;, :media =&amp;gt; &amp;quot;all&amp;quot; %&amp;gt;

    &amp;lt;!-- Nothing works without this line. --&amp;gt;
    &amp;lt;%= javascript_include_tag :defaults %&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Depict a SMILES String&amp;lt;/h1&amp;gt;

    &amp;lt;!-- New id attribute needed by Ajax --&amp;gt;
    &amp;lt;div class=&amp;quot;image&amp;quot; id=&amp;quot;results&amp;quot; &amp;gt;
      &amp;lt;img src=&amp;quot;&amp;lt;%= image_for_smiles :smiles =&amp;gt; @smiles %&amp;gt;&amp;quot;&amp;gt;&amp;lt;/img&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;
      &amp;lt;div class=&amp;quot;smiles&amp;quot;&amp;gt;
      &amp;lt;%= form_tag :action=&amp;gt;'depict' %&amp;gt;
        &amp;lt;label&amp;gt;SMILES: &amp;lt;/label&amp;gt;

        &amp;lt;!-- Ajaxified text field. --&amp;gt;
        &amp;lt;!-- We turn off autocomplete to simplfify the interface. --&amp;gt;
        &amp;lt;%= text_field_tag :smiles, @smiles, {:autocomplete =&amp;gt; &amp;quot;off&amp;quot;} %&amp;gt;
        &amp;lt;%= observe_field( :smiles,
                           :frequency =&amp;gt; 0.5,
                           :update    =&amp;gt; :results,
                           :url       =&amp;gt; { :action =&amp;gt; :ajax_depict } ) %&amp;gt;
      &amp;lt;%= end_form_tag %&amp;gt;
      &amp;lt;/div&amp;gt;
  &amp;lt;/body&amp;gt;

  &amp;lt;div class=&amp;quot;about&amp;quot;&amp;gt;
    &amp;lt;!-- Update the URL to point to the new Depth-First article --&amp;gt;
    &amp;lt;a href=&amp;quot;http://depth-first.com/articles/2006/12/04/anatomy-of-a-cheminformatics-web-application-ajaxifying-depict&amp;quot;&amp;gt;About this Application&amp;lt;/a&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The above code introduces three key elements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The &lt;tt&gt;javascript_include_tag&lt;/tt&gt; method is called, which is surprisingly easy to forget to do.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The original &lt;tt&gt;text_field&lt;/tt&gt; method call is replaced by &lt;tt&gt;text_field_tag&lt;/tt&gt; to simplify coding. We disable browser-based autocompletion by setting the &lt;tt&gt;autocomplete&lt;/tt&gt; attribute to &lt;tt&gt;off&lt;/tt&gt;. This removes a feature unlikely to ever be used, and leads to a more streamlined interface.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;tt&gt;observe_field&lt;/tt&gt; method is called, linking activity in the text field to an Ajax action, &lt;tt&gt;ajax_depict&lt;/tt&gt;, that will update the image area. To accomplish this, we assign the &lt;tt&gt;div&lt;/tt&gt; containing our image the id "results."&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Making these changes and refreshing the browser window gives a screen like the one below:&lt;/p&gt;

&lt;p&gt;&lt;center&gt;&lt;img src="http://depth-first.com/demo/20061204/step_1_1.png"&gt;&lt;/img&gt;&lt;/center&gt;&lt;/p&gt;

&lt;p&gt;Although the client side of the Ajax communication channel is working, the server side is not. Let's fix that.&lt;/p&gt;

&lt;h4&gt;Step 2: Ajaxify the Server&lt;/h4&gt;

&lt;p&gt;Depict needs an Action and View that will be invoked in response to keyboard events in the SMILES input box. To do this, first add a new &lt;tt&gt;ajax_depict&lt;/tt&gt; method to &lt;tt&gt;SmilesController&lt;/tt&gt;, the source for which is found in &lt;strong&gt;depict/app/controllers/smiles_controller.rb&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;SmilesController&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ApplicationController&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;depict&lt;/span&gt;
    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;params&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:smiles&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;
      &lt;span class="attribute"&gt;@smiles&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;params&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:smiles&lt;/span&gt;&lt;span class="punct"&gt;][&lt;/span&gt;&lt;span class="symbol"&gt;:value&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;
    &lt;span class="keyword"&gt;else&lt;/span&gt;
      &lt;span class="attribute"&gt;@smiles&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;image_for&lt;/span&gt;
    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;flash&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:bytes&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;
      &lt;span class="ident"&gt;send_data&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;flash&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:bytes&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="symbol"&gt;:type&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;image/png&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:disposition&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;inline&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:filename&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{flash[:smiles]}&lt;/span&gt;.png&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="comment"&gt;# The new ajax_depict method.&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;ajax_depict&lt;/span&gt;
    &lt;span class="attribute"&gt;@smiles&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="ident"&gt;request&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;raw_post&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Making the above changes and refreshing your browser should give an error message:&lt;/p&gt;

&lt;p&gt;&lt;center&gt;&lt;img src="http://depth-first.com/demo/20061204/step_2_1.png"&gt;&lt;/img&gt;&lt;/center&gt;&lt;/p&gt;

&lt;p&gt;The new &lt;tt&gt;ajax_depict&lt;/tt&gt; method is being called, but no associated template exits. This template contains the HTML that will be inserted into the &lt;tt&gt;div&lt;/tt&gt; with the &lt;tt&gt;results&lt;/tt&gt; id attribute that we set up in Step 1. We can resolve the error we're getting by simply creating a new file (&lt;strong&gt;depict/app/views/smiles/ajax_depict.rhtml&lt;/strong&gt;) containing the following partial template:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;lt;img src=&amp;quot;&amp;lt;%= image_for_smiles :smiles =&amp;gt; @smiles %&amp;gt;&amp;quot;&amp;gt;&amp;lt;/img&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, refreshing your browser should produce a screen like that shown below. We have now Ajaxified Depict, but we're not quite done yet.&lt;/p&gt;

&lt;p&gt;&lt;center&gt;&lt;img src="http://depth-first.com/demo/20061204/step_2_2.png"&gt;&lt;/img&gt;&lt;/center&gt;&lt;/p&gt;

&lt;h4&gt;Step 3: Update the Cascading Style Sheet&lt;/h4&gt;

&lt;p&gt;As you type a SMILES string into the input window, you may have noticed the input box being repositioned toward the top of the application window just prior to the display of a new image. This is due to the image area being resized to zero height as the new image is generated.&lt;/p&gt;

&lt;p&gt;Fortunately, the fix is simple; we'll just specify that the image area must be 400 pixels high, whether an image is being displayed or not. This is done by editing the &lt;tt&gt;image&lt;/tt&gt; selector in the CSS file at &lt;strong&gt;depict/public/stylesheets/default.css&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;.image {
    margin-left: auto;
    margin-right: auto;
    width: 400px;
    /* Keeps the input box from moving during image refresh.*/
    height: 400px;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Refreshing the Depict window should now give a statically-positioned SMILES input field.&lt;/p&gt;

&lt;h4&gt;Step 4: Backward Compatibility&lt;/h4&gt;

&lt;p&gt;As it stands, if the user presses the return key, they will see the "Enter SMILES Below" message. This is due to the change in the way SMILES strings are transmitted into the application. To fix this problem, we simply change the way that &lt;tt&gt;SmilesController&lt;/tt&gt; assigns the &lt;tt&gt;smiles&lt;/tt&gt; instance variable (&lt;strong&gt;depict/app/controllers/smiles_controller.rb&lt;/strong&gt;):&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;depict&lt;/span&gt;
  &lt;span class="comment"&gt;# Uses new input method.&lt;/span&gt;
  &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;params&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:smiles&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;
    &lt;span class="attribute"&gt;@smiles&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;params&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:smiles&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;
  &lt;span class="keyword"&gt;else&lt;/span&gt;
    &lt;span class="attribute"&gt;@smiles&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Making this change produces an interface that will render the correct image whether the return key is typed or not. If JavaScript is disabled, Depict will work exactly the same way as it did in the non-Ajax version.&lt;/p&gt;

&lt;h4&gt;Conclusions&lt;/h4&gt;

&lt;p&gt;Ajax makes the Web more attractive than ever as an application development platform. In this tutorial, we've seen how using Rails made it very easy to give Depict the feel of an interactive SMILES depiction tool using Ajax. But a few details remain before we're ready to deploy this application on a Web server for the public to use. For example, we need to take server load and network latency into account, and we need to make sure Depict works well on all major browsers. The next articles in this series will address these issues.&lt;/p&gt;</description>
      <pubDate>Mon, 04 Dec 2006 15:06:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:04460726-dd5b-40ce-aeb8-1b8f055932a8</guid>
      <author>Rich Apodaca</author>
      <link>http://depth-first.com/articles/2006/12/04/anatomy-of-a-cheminformatics-web-application-ajaxifying-depict</link>
      <category>Tools</category>
      <category>depict</category>
      <category>rails</category>
      <category>cheminformatics</category>
      <category>2d</category>
      <category>integration</category>
      <category>ajax</category>
    </item>
    <item>
      <title>Making the Case: Milestones in Bio- and Chem(o)informatics</title>
      <description>&lt;p&gt;&lt;img src="http://depth-first.com/demo/20061023/cdk_is_launched.png" align="right"&gt;&lt;/img&gt;&lt;a href="http://dx.doi.org/10.1021/ci600240w"&gt;An article by Thomas Engel honoring Johann Gasteiger&lt;/a&gt; has recently appeared in &lt;em&gt;J. Chem. Inf. Model.&lt;/em&gt; Tucked between two pages of text is a fascinating full-color, full-page timeline of Bio- and Chem(o)informatics. It starts with the abacus in 3000 B.C. and Libavius' &lt;em&gt;Alchemia&lt;/em&gt; in 1500 A.D. Near the end, it records the advent of virtual screening in 1998. Then, the very next event on this very large timeline happens in 2000 - it's the founding of the &lt;a href="http://cdk.sf.net"&gt;CDK project&lt;/a&gt;!&lt;/p&gt;</description>
      <pubDate>Tue, 24 Oct 2006 05:56:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:160be571-99dd-4e11-aae2-d5fd599e0d97</guid>
      <author>Rich Apodaca</author>
      <link>http://depth-first.com/articles/2006/10/24/making-the-case-milestones-in-bio-and-chem-o-informatics</link>
      <category>Open X</category>
      <category>timeline</category>
      <category>cheminformatics</category>
      <category>chemoinformatics</category>
      <category>cdk</category>
    </item>
  </channel>
</rss>
