<?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 rubidium</title>
    <link>http://depth-first.com/articles/tag/rubidium</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Walking the Web of Chemical Informatics</description>
    <item>
      <title>Simple Installation of Rubidium</title>
      <description>&lt;p&gt;&lt;a href="http://rbtk.rubyforge.org/"&gt;&lt;img src="http://depth-first.com/demo/20071015/rubidium.png" align="right"&gt;&lt;/img&gt;&lt;/a&gt;&lt;a href="http://rbtk.rubyforge.org/"&gt;Rubidium&lt;/a&gt; is a Ruby cheminformatics scripting environment. Previously, &lt;a href="http://depth-first.com/articles/2007/11/12/parsing-sd-files-with-ruby-and-rubidium"&gt;a problem&lt;/a&gt; was reported with the RubyForge gem repository that prevented the simple installation of the Rubidium gem. After filing a &lt;a href="http://rubyforge.org/tracker/index.php?func=detail&amp;amp;aid=15665&amp;amp;group_id=5&amp;amp;atid=101"&gt;bug report&lt;/a&gt;, the problem was resolved.&lt;/p&gt;

&lt;p&gt;The problem, which led to a 404 being issued when trying to install the gem from the remote RubyGems repository, was a variant of a &lt;a href="http://rubyforge.org/tracker/index.php?func=detail&amp;amp;aid=15417&amp;amp;group_id=5&amp;amp;atid=102"&gt;known RubyForge issue&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can now install Rubidium like this:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ jruby -S gem install rbtk
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Installation takes a few minutes due to the large size of the included &lt;a href="http://cdk.sf.net"&gt;Chemistry Development Kit&lt;/a&gt; jarfile.&lt;/p&gt;</description>
      <pubDate>Wed, 21 Nov 2007 09:26:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:f0a52354-e6aa-4a02-b329-4b5271486940</guid>
      <author>Rich Apodaca</author>
      <link>http://depth-first.com/articles/2007/11/21/simple-installation-of-rubidium</link>
      <category>Tools</category>
      <category>rubidium</category>
      <category>ruby</category>
      <category>jruby</category>
      <category>cdk</category>
    </item>
    <item>
      <title>Parsing SD Files with Ruby and Rubidium</title>
      <description>&lt;p&gt;&lt;a href="http://rbtk.rubyforge.org"&gt;&lt;img src="http://depth-first.com/demo/20071015/rubidium.png" align="right"&gt;&lt;/img&gt;&lt;/a&gt;Reading SD files is a bread-and-butter cheminformatics operation. At a minimum, a cheminformatics toolkit needs to parse the individual entries of an SD file, and provide access to the embedded molfile and data hash for each.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://depth-first.com/articles/tag/rubidium"&gt;Recent articles&lt;/a&gt; have introduced &lt;a href="http://rbtk.rubyforge.org"&gt;Rubidium&lt;/a&gt;, a Ruby cheminformatics scripting environment. The Rubidium team now announces the release of &lt;a href="http://rubyforge.org/frs/?group_id=4671"&gt;Rubidium-0.1.1&lt;/a&gt;, which, among other features, introduces the ability to parse SD files.&lt;/p&gt;

&lt;h4&gt;Prerequisites&lt;/h4&gt;

&lt;p&gt;Rubidium is designed to run on &lt;a href="http://jruby.codehaus.org/"&gt;JRuby&lt;/a&gt;. Installing JRuby is straightforward on unix-like systems. First, download the &lt;a href="http://dist.codehaus.org/jruby/jruby-bin-1.1b1.tar.gz"&gt;JRuby-1.1b1 binary release&lt;/a&gt;. Then, unpack the archive to your directory of choice. Set &lt;tt&gt;$JRUBY_HOME&lt;/tt&gt; and &lt;tt&gt;$JAVA_HOME&lt;/tt&gt;. Finally, add &lt;tt&gt;$JRUBY_HOME/bin&lt;/tt&gt; to your path.&lt;/p&gt;

&lt;h4&gt;Installing Rubidium-0.1.1&lt;/h4&gt;

&lt;p&gt;Generally speaking, it should be possible to install Rubidium with a one-line command to RubyGems:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ jruby -S gem install rbtk
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Unfortunately at the time of this writing, I was receiving the mysterious &lt;a href="http://www.google.com/search?q=rubygems+%22ERROR:++While+executing+gem+...+OpenURI::HTTPError%22&amp;amp;hl=en&amp;amp;pwst=1&amp;amp;start=0&amp;amp;sa=N"&gt;RubyGems 404 error&lt;/a&gt; with the RubyForge remote repository:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ jruby -S gem install rbtk
Select which gem to install for your platform (java)
 1. rbtk 0.1.1 (java)
 2. rbtk 0.1.0 (java)
 3. Skip this gem
 4. Cancel installation
&gt; 1
ERROR:  While executing gem ... (OpenURI::HTTPError)
    404 Not Found
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This appears to affect only certain RubyGems on RubyForge - possibly only those with multiple versions. It seems to be an error on the RubyForge server that occasionally appears and then disappears.&lt;/p&gt;

&lt;p&gt;As a workaround, you can &lt;a href="http://rubyforge.org/frs/download.php/27819/rbtk-0.1.1-jruby.gem"&gt;download the Rubidium gem&lt;/a&gt; and install it manually:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ jruby -S gem install tmp/rbtk-0.1.1-jruby.gem
&lt;/div&gt;

&lt;p&gt;&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;Because Rubidium-0.1.1 introduces an &lt;a href="http://rubyforge.org/projects/activesupport/"&gt;Active Support&lt;/a&gt; dependency, you will need to install that library before installing Rubidium:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ jruby -S gem install tmp/rbtk-0.1.1-jruby.gem
ERROR:  While executing gem ... (RuntimeError)
    Error instaling tmp/rbtk-0.1.1-jruby.gem:
        rbtk requires activesupport &gt;= 1.4.2
$ jruby -S gem install activesupport
Successfully installed activesupport-1.4.4
Installing ri documentation for activesupport-1.4.4...
Installing RDoc documentation for activesupport-1.4.4...
$ jruby -S gem install tmp/rbtk-0.1.1-jruby.gem
Successfully installed rbtk, version 0.1.1
Installing ri documentation for rbtk-0.1.1-jruby...
Installing RDoc documentation for rbtk-0.1.1-jruby...
&lt;/div&gt;

&lt;p&gt;&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;It's possible that the RubyForge 404 issue will be resolved by the time you read this article, so &lt;tt&gt;jruby -S gem install rbtk&lt;/tt&gt; should be tried first.&lt;/p&gt;

&lt;h4&gt;Parsing an SD File&lt;/h4&gt;

&lt;p&gt;Let's say we'd like to extract all InChIs from a PubChem dataset. If you don't have one handy, a compilation of about 2000 PubChem benzodiazepines has been &lt;a href="http://rubyforge.org/frs/download.php/27768/pubchem_benzodiazepine_20071110.sdf.gz"&gt;deposited on RubyForge&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With our unzipped datafile in our working directory, we can now test the SD File parser by saving the following library to a file called &lt;strong&gt;parse.rb&lt;/strong&gt;:&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;rubygems&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;gem&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;rbtk&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;rubidium/sdf&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;parse_sd&lt;/span&gt; &lt;span class="ident"&gt;filename&lt;/span&gt;
  &lt;span class="ident"&gt;p&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Rubidium&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;SDF&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Parser&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt; &lt;span class="constant"&gt;File&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;filename&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;

  &lt;span class="ident"&gt;p&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;entry&lt;/span&gt;&lt;span class="punct"&gt;|&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;InChI: &lt;span class="expr"&gt;#{entry['PUBCHEM_NIST_INCHI']}&lt;/span&gt;&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;

which can be tested with &lt;tt&gt;jirb&lt;/tt&gt;:

&lt;div class="console"&gt;
&lt;pre&gt;
$ jirb
irb(main):001:0&gt; require 'parse'
=&gt; true
irb(main):002:0&gt; parse_sd 'pubchem_benzodiazepine_20071110.sdf'
InChI: InChI=1/C16H12Cl2N2O/c1-20-14-7-6-12(18)8-13(14)16(19-9-15(20)21)10-2-4-11(17)5-3-10/h2-8H,9H2,1H3

[truncated]
&lt;/pre&gt;
&lt;/div&gt;

&lt;h4&gt;RSpec and Behavior-Driven Development&lt;/h4&gt;

&lt;p&gt;If you &lt;a href="http://rubyforge.org/frs/download.php/27820/rbtk-0.1.1.tar.gz"&gt;check out the Rubidium source distribution&lt;/a&gt;, you'll notice that the SD parser library is tested with &lt;a href="http://rspec.rubyforge.org/"&gt;RSpec&lt;/a&gt;, the &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development"&gt;BDD&lt;/a&gt; framework for Ruby. Ultimately, all components of Rubidium will be tested and documented this way.&lt;/p&gt;

&lt;h4&gt;Acknowledgments&lt;/h4&gt;

&lt;p&gt;Rubidium's new SD file parser was written by &lt;a href="http://www.moseshohman.com/"&gt;Moses Hohman&lt;/a&gt;. It was kindly donated by &lt;a href="http://www.collaborativedrug.com/"&gt;Collaborative Drug Discovery&lt;/a&gt;, who have built their drug discovery application using &lt;a href="http://rubyonrails.com"&gt;Ruby on Rails&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;Future Directions&lt;/h4&gt;

&lt;p&gt;One problem in working with SD files is pinpointing encoding errors. A parser should not only raise an exception, but point to a line number and identify offending text to aid debugging. Rubidium's SD parser will eventually incorporate these enhancements.&lt;/p&gt;

&lt;p&gt;Because Rubidium runs on JRuby, performance gains may be achievable by re-writing select portions in Java.&lt;/p&gt;

&lt;p&gt;Parsing SD files is only the beginning of the story. Many cheminformatics applications need a convenient, fast, and robust method for &lt;em&gt;writing&lt;/em&gt; molfiles. This is also something Rubidium will attempt to provide.&lt;/p&gt;

&lt;p&gt;If your company or organization is curious about Ruby and cheminforamatics, give Rubidium a try. Rubidium is licensed under the permissive &lt;a href="http://www.opensource.org/licenses/mit-license.php"&gt;MIT License&lt;/a&gt; to make collaboration as simple as possible.&lt;/p&gt;</description>
      <pubDate>Mon, 12 Nov 2007 11:27:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:8e195fb8-22d0-4ea3-a2bd-40f44281fc8f</guid>
      <author>Rich Apodaca</author>
      <link>http://depth-first.com/articles/2007/11/12/parsing-sd-files-with-ruby-and-rubidium</link>
      <category>Tools</category>
      <category>rubidium</category>
      <category>ruby</category>
      <category>cdd</category>
      <category>sdfile</category>
      <category>sdf</category>
      <category>bdd</category>
      <category>rspec</category>
      <category>jruby</category>
    </item>
    <item>
      <title>Cheminformatics for Ruby: Getting Started with Rubidium</title>
      <description>&lt;p&gt;&lt;a href="http://rbtk.rubyforge.org"&gt;&lt;img src="http://depth-first.com/demo/20071015/rubidium.png" align="right"  border="0"&gt;&lt;/img&gt;&lt;/a&gt;
Cheminformatics has seen the introduction of a diverse array of new open source software over the last few years. Using it all to its fullest potential is not always easy; differing languages, dependencies, interfaces, and varying levels of documentation make the job especially difficult. &lt;a href="http://rbtk.rubyforge.org"&gt;Rubidium&lt;/a&gt; is a new open source project aimed at changing that.&lt;/p&gt;

&lt;p&gt;Rubidium is a full-featured cheminformatics scripting environment for Ruby. When complete, Rubidium will offer a single well-tested and well-documented Ruby interface to the best open source cheminformatics software. Rubidium-0.1.0 is now available for download.&lt;/p&gt;

&lt;h4&gt;Downloading and Installing Rubidium&lt;/h4&gt;

&lt;p&gt;Rubidium runs on &lt;a href="http://jruby.codehaus.org"&gt;JRuby&lt;/a&gt;, a pure Java implementation of the Ruby language. After &lt;a href="http://jruby.codehaus.org/The+JRuby+Tutorial+Part+1+-+Getting+Started"&gt;installing JRuby on your system&lt;/a&gt;, you should be ready to install Rubidium.&lt;/p&gt;

&lt;p&gt;Installation is most conveniently done with the Ruby package manager &lt;a href="http://rubygems.org/"&gt;RubyGems&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Rubidium RubyGem can be &lt;a href="http://rubyforge.org/frs/download.php/27580/rbtk-0.1.0-jruby.gem"&gt;downloaded from RubyForge&lt;/a&gt; (large file). The &lt;tt&gt;gem&lt;/tt&gt; command is all we need:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ ll rbtk-0.1.0-jruby.gem
-rw-r--r-- 1 rich rich 12955136 Nov  6 07:56 rbtk-0.1.0-jruby.gem
$ jruby -S gem install rbtk-0.1.0.gem
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Note: at the time of this writing, my installation of JRuby 1.0.1 was reporting an out of memory error when attempting to use the RubyForge RubyGems repository directly. Downloading Gems separately and then installing the local copy is a workaround.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;Testing the Installation&lt;/h4&gt;

&lt;p&gt;Rubidium can be tested with the following code run in interactive JRuby (jirb):&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ jirb
irb(main):001:0&gt; require 'rubygems'
=&gt; true
irb(main):002:0&gt; gem 'rbtk'
=&gt; true
irb(main):003:0&gt; require 'rubidium/lang'
=&gt; true
irb(main):004:0&gt; c=Rubidium::Converter.new
=&gt; #&amp;lt;Rubidium::Converter:0xbd4e3c ... &amp;gt;
irb(main):005:0&gt; c.set_formats 'smi', 'mol'
=&gt; true
irb(main):006:0&gt; c.convert 'c1ccccc1'
=&gt; "\n  CDK    11/6/07,8:41\n\n  6  6  0  0  0  0  0  0  0  0999 V2000\n    0.0000    0.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n    0.0000    0.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n    0.0000    0.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n    0.0000    0.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n    0.0000    0.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n    0.0000    0.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n  2  1  2  0  0  0  0 \n  3  2  1  0  0  0  0 \n  4  3  2  0  0  0  0 \n  5  4  1  0  0  0  0 \n  6  5  2  0  0  0  0 \n  6  1  1  0  0  0  0 \nM  END\n"
&lt;/pre&gt;
&lt;/div&gt;

&lt;h4&gt;Low-Level Interface&lt;/h4&gt;

&lt;p&gt;There's not much yet to Rubidium itself beyond molecular language interconversions offered by the &lt;a href="http://cdk.sf.net"&gt;Chemistry Development Kit&lt;/a&gt; (CDK). But the CDK offers a wide range of cheminformatics functionality that is immediately accessible in raw form via JRuby itself. For example, we can calculate the TPSA of oxazepam:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ jirb
irb(main):001:0&gt; require 'rubygems'
=&gt; true
irb(main):002:0&gt; gem 'rbtk'
=&gt; true
irb(main):003:0&gt; require 'cdk/lang'
=&gt; true
irb(main):004:0&gt; import 'org.openscience.cdk.qsar.descriptors.molecular.TPSADescriptor'
=&gt; ["org.openscience.cdk.qsar.descriptors.molecular.TPSADescriptor"]
irb(main):005:0&gt; reader=CDK::SmilesReader.new
=&gt; #&amp;lt;CDK::SmilesReader:0x1088a1b ... &amp;gt; 
irb(main):006:0&gt; mol=reader.read 'O=C3Nc1ccc(Cl)cc1C(c2ccccc2)=NC3O'
=&gt; #&amp;lt;Java::OrgOpenscienceCdk::Molecule:0x174f02c ... &amp;gt;
irb(main):007:0&gt; tpsa = TPSADescriptor.new
=&gt; #&amp;lt;Java::OrgOpenscienceCdkQsarDescriptorsMolecular::TPSADescriptor:0x14596d5 ...&amp;gt;
irb(main):008:0&gt; result = tpsa.calculate mol
=&gt; #&amp;lt;Java::OrgOpenscienceCdkQsar::DescriptorValue:0x171120a ..&amp;gt;
irb(main):009:0&gt; result.value.double_value
=&gt; 61.69
&lt;/pre&gt;
&lt;/div&gt;

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

&lt;p&gt;There's much more to be done with Rubidium. As more software packages and their Ruby interfaces are added, a major challenge will be to maintain a simple yet powerful interface to the underlying capabilities.&lt;/p&gt;</description>
      <pubDate>Tue, 06 Nov 2007 11:17:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:049b9b9c-456d-4d7e-992b-5e4776d183c8</guid>
      <author>Rich Apodaca</author>
      <link>http://depth-first.com/articles/2007/11/06/cheminformatics-for-ruby-getting-started-with-rubidium</link>
      <category>Tools</category>
      <category>rubidium</category>
      <category>ruby</category>
      <category>java</category>
    </item>
    <item>
      <title>Building Rubidium: Creating a RubyForge Project Space</title>
      <description>&lt;p&gt;&lt;img src="http://depth-first.com/demo/20071015/rubidium.png" align="right" border="0"&gt;&lt;/img&gt;Recent articles have discussed &lt;a href="http://depth-first.com/articles/tag/rubidium"&gt;Rubidium&lt;/a&gt;, the cheminformatics toolkit for Ruby. In this article, the first in a series, I'll go beyond the Ruby code to discuss the technical aspects of taking an Open Source idea from concept to release.&lt;/p&gt;

&lt;h4&gt;Finding a Home&lt;/h4&gt;

&lt;p&gt;Before setting up your Open Source project, you'll need to decide on how to host it. Project hosting can be as simple or elaborate as you wish, but the basic services include: a website; a mailing list; a discussion forum; a source code repository (typically CVS or Subversion); a bug tracking system; and a file release system.&lt;/p&gt;

&lt;p&gt;The multitude of choices can be broken down into two basic options: host the project yourself or use a free hosting service. Fortunately, Ruby-based projects enjoy two excellent free hosting options: &lt;a href="http://sourceforge.net"&gt;SourceForge&lt;/a&gt; and &lt;a href="http://rubyforge.org"&gt;RubyForge&lt;/a&gt;. Although SourceForge could certainly be used for a Ruby project, RubyForge is a more popular option. One of the reasons is that any RubyGem your project releases automatically becomes installable through the &lt;a href="http://rubygems.org/"&gt;RubyGems&lt;/a&gt; package management system with a simple one-line incantation:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ sudo gem install &amp;lt;yourprojectname&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Another reason to use RubyForge is discoverability. RubyForge only hosts projects related in some way to Ruby. So, your project will stand out a lot more in its category than with a much larger site like SourceForge.&lt;/p&gt;

&lt;p&gt;Given RubyForge's advantages, and my own interest in minimizing the work needed to maintain an Open Source project, Rubidium will be hosted on RubyForge.&lt;/p&gt;

&lt;h4&gt;Requesting a Project Space&lt;/h4&gt;

&lt;p&gt;Having decided on RubyForge as Rubidium's host, all that's left is to ask for free services. You'll need to &lt;a href="http://rubyforge.org/account/register.php"&gt;register for a user account&lt;/a&gt; if you haven't done so already. Then, simply &lt;a href="http://rubyforge.org/register/projectinfo.php"&gt;apply for project space&lt;/a&gt;. After about three business days, you should be notified whether your project was accepted.&lt;/p&gt;

&lt;p&gt;Several days ago, I completed this process for Rubidium. Its new home on RubyForge will be:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://rubyforge.org/projects/rbtk"&gt;http://rubyforge.org/projects/rbtk&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Rubidium home page can be found at:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://rbtk.rubyforge.org"&gt;http://rbtk.rubyforge.org&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There's nothing useful there yet, a situation that will hopefully be fixed in a few weeks.&lt;/p&gt;

&lt;h4&gt;Next Steps&lt;/h4&gt;

&lt;p&gt;With powerful free services now available for the Rubidium project, we'll want to start taking advantage of them. The next articles in this series will discuss some ways of doing so.&lt;/p&gt;</description>
      <pubDate>Fri, 26 Oct 2007 10:21:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:cc895dbc-1a02-4b7a-9fd9-11431a3e9cc3</guid>
      <author>Rich Apodaca</author>
      <link>http://depth-first.com/articles/2007/10/26/building-rubidium-creating-a-rubyforge-project-space</link>
      <category>Tools</category>
      <category>rubidium</category>
      <category>rubyforge</category>
      <category>ruby</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Easily Convert IUPAC Nomenclature to SMILES, InChI, or Molfile with Rubidium</title>
      <description>&lt;p&gt;&lt;img src="http://depth-first.com/demo/20071015/rubidium.png" align="right"&gt;&lt;/img&gt;A recent article &lt;a href="http://depth-first.com/articles/2007/10/15/an-introduction-to-the-rubidium-cheminforamtics-toolkit-interconvert-smiles-inchi-and-molfile-with-an-open-babel-like-interface"&gt;introduced Rubidium&lt;/a&gt;, a cheminformatics toolkit written in Ruby. One of Ruby's strengths is the speed with which it enables disparate pieces of code to be glued together - even if they're written in different programming languages. In this article, we'll see how Rubidium can be extended to provide support for converting IUPAC nomenclature into SMILES, InChI, or Molfile formats.&lt;/p&gt;

&lt;h4&gt;About Rubidium&lt;/h4&gt;

&lt;p&gt;Rubidium is a cheminformatics toolkit written in Ruby. Rubidium is currently configured to run on &lt;a href="http://jruby.codehaus.org/"&gt;JRuby&lt;/a&gt;, although future versions may also work with &lt;a href="http://en.wikipedia.org/wiki/Ruby_(programming_language"&gt;Matz' Ruby Implementation&lt;/a&gt;) (MRI) via &lt;a href="http://rjb.rubyforge.org/"&gt;Ruby Java Bridge&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Rubidium will eventually be packaged as a &lt;a href="http://www.rubygems.org/"&gt;RubyGem&lt;/a&gt; and hosted on &lt;a href="http://rubyforge.org"&gt;RubyForge&lt;/a&gt;. For now, the toolkit consists of a running library that will updated and documented on this blog.&lt;/p&gt;

&lt;h4&gt;The Library&lt;/h4&gt;

&lt;p&gt;The library extends the CDK module presented in the &lt;a href="http://depth-first.com/articles/2007/10/15/an-introduction-to-the-rubidium-cheminforamtics-toolkit-interconvert-smiles-inchi-and-molfile-with-an-open-babel-like-interface"&gt;previous article in this series&lt;/a&gt;. The main change is the addition of an &lt;tt&gt;IUPACReader&lt;/tt&gt; class, based on Peter Corbett's excellent &lt;a href="http://depth-first.com/articles/2007/10/12/jruby-for-cheminformatics-parsing-iupac-nomenclature-with-opsin"&gt;OPSIN library&lt;/a&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;IUPACReader&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;java.io.StringReader&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;uk.ac.cam.ch.wwmm.opsin.NameToStructure&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;org.openscience.cdk.io.CMLReader&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;org.openscience.cdk.ChemFile&lt;/span&gt;&lt;span class="punct"&gt;'&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;@iupac_reader&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;NameToStructure&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;
    &lt;span class="attribute"&gt;@cml_reader&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;CMLReader&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;read&lt;/span&gt; &lt;span class="ident"&gt;name&lt;/span&gt;
    &lt;span class="ident"&gt;cml&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="attribute"&gt;@iupac_reader&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;parse_to_cml&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;name&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;

    &lt;span class="keyword"&gt;raise&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Could not parse '&lt;span class="expr"&gt;#{name}&lt;/span&gt;'.&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="keyword"&gt;unless&lt;/span&gt; &lt;span class="ident"&gt;cml&lt;/span&gt;

    &lt;span class="attribute"&gt;@cml_reader&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;set_reader&lt;/span&gt; &lt;span class="constant"&gt;StringReader&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;cml&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_xml&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;

    &lt;span class="ident"&gt;chem_file&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="attribute"&gt;@cml_reader&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;read&lt;/span&gt; &lt;span class="constant"&gt;ChemFile&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;

    &lt;span class="ident"&gt;chem_file&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;chem_sequence&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;chem_model&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;molecule_set&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;molecule&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;0&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;Using this additional functionality requires nothing more than copying the &lt;a href="http://prdownloads.sourceforge.net/oscar3-chem/opsin-big-0.1.0.jar?download"&gt;OPSIN jarfile&lt;/a&gt; into the &lt;strong&gt;lib&lt;/strong&gt; directory of your JRuby installation. You'll also need to place the &lt;a href="http://downloads.sourceforge.net/cdk/cdk-1.0.1.jar?modtime=1182877138&amp;big_mirror=0"&gt;CDK jarfile&lt;/a&gt; in this directory if you haven't done so already.&lt;/p&gt;

&lt;p&gt;The complete Rubidium library can be &lt;a href="http://depth-first.com/demo/20071019/cdk.rb"&gt;downloaded here&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;A Test&lt;/h4&gt;

&lt;p&gt;We can test Rubidium's IUPAC nomenclature parsing abilities with &lt;tt&gt;jirb&lt;/tt&gt;. For example, to convert from name to SMILES:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ jirb
irb(main):001:0&gt; require 'cdk'
=&gt; true
irb(main):002:0&gt; c=CDK::Conversion.new
=&gt; #&amp;lt;CDK::Conversion:0x46ca65 ... &amp;gt;
irb(main):003:0&gt; c.set_formats 'iupac', 'smi'
=&gt; "smi"
irb(main):004:0&gt; c.convert '1,4-dichlorobenzene'
=&gt; "C=1C=C(C=CC=1Cl)Cl"
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;To convert from name to InChI (in the same &lt;tt&gt;jirb&lt;/tt&gt; session):&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
irb(main):005:0&gt; c.set_out_format 'inchi'
=&gt; "inchi"
irb(main):006:0&gt; c.convert '1,4-dichlorobenzene'
=&gt; "InChI=1/C6H4Cl2/c7-5-1-2-6(8)4-3-5/h1-4H"
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;And to convert from name to Molfile (also in the same &lt;tt&gt;jirb&lt;/tt&gt; session):&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
irb(main):007:0&gt; c.set_out_format 'mol'
=&gt; "mol"
irb(main):008:0&gt; c.convert '1,4-dichlorobenzene'
=&gt; "\n  CDK    10/19/07,7:59\n\n  8  8  0  0  0  0  0  0  0  0999 V2000\n    0.0000    0.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n    0.0000    0.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n    0.0000    0.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n    0.0000    0.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n    0.0000    0.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n    0.0000    0.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n    0.0000    0.0000    0.0000 Cl  0  0  0  0  0  0  0  0  0  0  0  0\n    0.0000    0.0000    0.0000 Cl  0  0  0  0  0  0  0  0  0  0  0  0\n  1  2  2  0  0  0  0 \n  2  3  1  0  0  0  0 \n  3  4  2  0  0  0  0 \n  4  5  1  0  0  0  0 \n  5  6  2  0  0  0  0 \n  6  1  1  0  0  0  0 \n  7  1  1  0  0  0  0 \n  8  4  1  0  0  0  0 \nM  END\n"
&lt;/pre&gt;
&lt;/div&gt;

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

&lt;p&gt;By re-using a simple conversion API together with another Java library, we've given Rubidium the ability to translate IUPAC nomenclature into other molecular languages. The additional code was both easy to write and easy to test. Future articles will discuss the packaging, distribution, and further elaboration of Rubidium.&lt;/p&gt;</description>
      <pubDate>Fri, 19 Oct 2007 10:05:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:1b7e76b3-93a7-4372-982f-cd60c9ed40d0</guid>
      <author>Rich Apodaca</author>
      <link>http://depth-first.com/articles/2007/10/19/easily-convert-iupac-nomenclature-to-smiles-inchi-or-molfile-with-rubidium</link>
      <category>Tools</category>
      <category>rubidium</category>
      <category>iupac</category>
      <category>smiles</category>
      <category>inchi</category>
      <category>moflile</category>
    </item>
    <item>
      <title>An Introduction to the Rubidium Cheminforamtics Toolkit: Interconvert SMILES, InChI, and Molfile with an Open Babel-Like Interface</title>
      <description>&lt;p&gt;&lt;img src="http://depth-first.com/demo/20071015/rubidium.png" align="right"&gt;&lt;/img&gt;Interconverting molecular languages is a very common operation in cheminformatics, so convenient conversion tools are desirable. Recent articles have discussed JRuby as a &lt;a href="http://depth-first.com/articles/tag/ruby"&gt;functional cheminformatics scripting environement&lt;/a&gt;. In this article, we'll see how this functionality can be combined with convenience for molecular language conversions.&lt;/p&gt;

&lt;p&gt;In addition to illustrating a technique, this article is the first in a series aimed at documenting a new cheminformatics toolkit for Ruby called "Rubidium". Rubidium will provide a unified set of Ruby APIs for working with diverse Open Source cheminformatics tools.&lt;/p&gt;

&lt;p&gt;Rubidium will be distributed under the highly permissive &lt;a href="http://www.opensource.org/licenses/mit-license.php"&gt;MIT License&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;Prerequisites&lt;/h4&gt;

&lt;p&gt;This Rubidium library requires &lt;a href="http://jruby.codehaus.org/"&gt;JRuby&lt;/a&gt; and the &lt;a href="http://cdk.sf.net"&gt;Chemistry Development Kit&lt;/a&gt; (CDK). Copying the &lt;a href="http://downloads.sourceforge.net/cdk/cdk-1.0.1.jar?modtime=1182877138&amp;amp;big_mirror=0"&gt;CDK jarfile&lt;/a&gt; into your JRuby &lt;tt&gt;lib&lt;/tt&gt; directory is all that's needed.&lt;/p&gt;

&lt;h4&gt;The Library&lt;/h4&gt;

&lt;p&gt;The goal of this library is to provide a simple, yet flexible way to interconvert SMILES, InChI, and molfile formats. It was inspired the &lt;a href="http://openbabel.sf.net"&gt;Open Babel&lt;/a&gt; library, in which an &lt;tt&gt;OBConversion&lt;/tt&gt; object is configured with input and output formats prior to performing one or more conversions. In today's library, a similar Ruby interface is created for the CDK. Because of it's length, it won't be presented in its entirety. Instead, it can be &lt;a href="http://depth-first.com/demo/20071015/cdk.rb"&gt;downloaded here&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;Testing the Library&lt;/h4&gt;

&lt;p&gt;The library can be tested by saving it as a file called &lt;strong&gt;cdk.rb&lt;/strong&gt; and invoking &lt;tt&gt;jirb&lt;/tt&gt;. We can then convert a SMILES for benzene into the InChI for benzene:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ jirb
irb(main):001:0&gt; require 'cdk'
=&gt; true
irb(main):002:0&gt; c=CDK::Conversion.new
=&gt; #&amp;lt;CDK::Conversion:0x4c6320 ... &amp;gt;
irb(main):003:0&gt; c.set_formats 'smi', 'inchi'
=&gt; "inchi"
irb(main):004:0&gt; c.convert 'c1ccccc1'
=&gt; "InChI=1/C6H6/c1-2-4-6-5-3-1/h1-6H"
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Upcoming articles will show more examples of interconversions using this library, and discuss some of its limitations.&lt;/p&gt;

&lt;h4&gt;An Aside&lt;/h4&gt;

&lt;p&gt;It might be useful for Rubidium to support multiple &lt;tt&gt;Conversions&lt;/tt&gt;, each using its own cheminformatics toolkit. For example, a recent article discussed &lt;a href="http://depth-first.com/articles/2007/06/25/interconvert-almost-any-smiles-and-inchi-with-ruby-open-babel"&gt;SMILES and InChI interconversion with Ruby Open Babel&lt;/a&gt;. With a little tweaking, the Ruby Open Babel &lt;tt&gt;OBConversion&lt;/tt&gt; interface could be make identical to the Ruby interface used in today's tutorial. We could also configure &lt;a href="http://joelib.sf.net"&gt;JOELib&lt;/a&gt; and &lt;a href="http://sf.net/projects/rosetta"&gt;Rosetta&lt;/a&gt; &lt;tt&gt;Conversions&lt;/tt&gt; in an analogous fashion.&lt;/p&gt;

&lt;p&gt;Rubidium would then offer a family of molecular language converters, each of which used exactly the same API. We could then pick the best converter based on the situation at hand.&lt;/p&gt;

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

&lt;p&gt;With just a little Ruby code, we've created a convenient Ruby interface for interconverting SMILES, InChI, and molfile formats. JRuby supports even more interconversions through the CDK as well as other Java and Java Native Interface libraries. Future articles will discuss some of the possibilities.&lt;/p&gt;</description>
      <pubDate>Mon, 15 Oct 2007 10:59:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:fbde8b22-25ba-498c-8ade-b9a74738d560</guid>
      <author>Rich Apodaca</author>
      <link>http://depth-first.com/articles/2007/10/15/an-introduction-to-the-rubidium-cheminforamtics-toolkit-interconvert-smiles-inchi-and-molfile-with-an-open-babel-like-interface</link>
      <category>Tools</category>
      <category>rubidium</category>
      <category>jruby</category>
      <category>java</category>
      <category>cdk</category>
    </item>
    <item>
      <title>JRuby for Cheminformatics: Parsing IUPAC Nomenclature with OPSIN</title>
      <description>&lt;p&gt;&lt;a href="http://ruby-lang.org"&gt;&lt;img src="http://depth-first.com/files/ruby_logo_new.gif" align="right"&gt;&lt;/img&gt;&lt;/a&gt;Recent articles have discussed the use of &lt;a href="http://depth-first.com/articles/tag/rubidium"&gt;JRuby for cheminformatics&lt;/a&gt;. We've seen how to &lt;a href="http://depth-first.com/articles/2007/10/09/jruby-for-cheminformatics-parsing-smiles-simply"&gt;parse SMILES strings&lt;/a&gt;, and &lt;a href="http://depth-first.com/articles/2007/10/10/jruby-for-cheminformatics-reading-and-writing-inchis-via-the-java-native-interface"&gt;read or write InChIs&lt;/a&gt;. In this article, we'll see how easy it is to parse IUPAC nomenclature from JRuby using Peter Corbett's &lt;a href="http://depth-first.com/articles/2006/10/14/decoding-iupac-names-with-opsin"&gt;OPSIN library&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;Installation&lt;/h4&gt;

&lt;p&gt;After &lt;a href="http://depth-first.com/articles/2007/10/09/jruby-for-cheminformatics-parsing-smiles-simply"&gt;installing JRuby&lt;/a&gt;, simply &lt;a href="http://prdownloads.sourceforge.net/oscar3-chem/opsin-big-0.1.0.jar?download"&gt;download the OPSIN jarfile&lt;/a&gt; and copy it to your JRuby &lt;tt&gt;lib&lt;/tt&gt; directory. You're done.&lt;/p&gt;

&lt;h4&gt;A Simple Library&lt;/h4&gt;

&lt;p&gt;We can write a simple library to convert an IUPAC name into a CML document:&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;jruby&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;uk.ac.cam.ch.wwmm.opsin.NameToStructure&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="keyword"&gt;module &lt;/span&gt;&lt;span class="module"&gt;IUPAC&lt;/span&gt;
  &lt;span class="attribute"&gt;@@nts&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;NameToStructure&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;def &lt;/span&gt;&lt;span class="method"&gt;read_name&lt;/span&gt; &lt;span class="ident"&gt;name&lt;/span&gt;
    &lt;span class="ident"&gt;cml&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="attribute"&gt;@@nts&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;parse_to_cml&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;name&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;

    &lt;span class="keyword"&gt;raise&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Could not parse '&lt;span class="expr"&gt;#{name}&lt;/span&gt;'.&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="keyword"&gt;unless&lt;/span&gt; &lt;span class="ident"&gt;cml&lt;/span&gt;

    &lt;span class="ident"&gt;cml&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_xml&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;The &lt;tt&gt;read_name&lt;/tt&gt; method accepts an iupac name as a string and returns a CML document as a string. If the input can't be parsed, an exception is raised.&lt;/p&gt;

&lt;h4&gt;Testing the Library&lt;/h4&gt;

&lt;p&gt;We can test the library by saving it as a file called &lt;strong&gt;iupac.rb&lt;/strong&gt; and invoking &lt;tt&gt;jirb&lt;/tt&gt;:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ jirb
irb(main):001:0&gt; require 'iupac'
=&gt; true
irb(main):002:0&gt; include IUPAC
=&gt; Object
irb(main):003:0&gt; read_name('4-iodobenzoic acid')
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This returns the XML shown below, which has been re-formatted for clarity:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_xml "&gt;&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;cml&lt;/span&gt; &lt;span class="attribute"&gt;xmlns&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;http://www.xml-cml.org/schema&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;molecule&lt;/span&gt; &lt;span class="attribute"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;m1&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&amp;gt;&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;atomArray&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;atom&lt;/span&gt; &lt;span class="attribute"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;a1&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;elementType&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;C&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&amp;gt;&lt;/span&gt;
        &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;label&lt;/span&gt; &lt;span class="attribute"&gt;value&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;atom&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;atom&lt;/span&gt; &lt;span class="attribute"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;a2&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;elementType&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;C&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&amp;gt;&lt;/span&gt;
        &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;label&lt;/span&gt; &lt;span class="attribute"&gt;value&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;atom&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;atom&lt;/span&gt; &lt;span class="attribute"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;a3&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;elementType&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;C&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&amp;gt;&lt;/span&gt;
        &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;label&lt;/span&gt; &lt;span class="attribute"&gt;value&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;3&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;atom&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;atom&lt;/span&gt; &lt;span class="attribute"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;a4&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;elementType&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;C&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&amp;gt;&lt;/span&gt;
        &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;label&lt;/span&gt; &lt;span class="attribute"&gt;value&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;4&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;atom&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;atom&lt;/span&gt; &lt;span class="attribute"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;a5&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;elementType&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;C&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&amp;gt;&lt;/span&gt;
        &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;label&lt;/span&gt; &lt;span class="attribute"&gt;value&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;5&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;atom&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;atom&lt;/span&gt; &lt;span class="attribute"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;a6&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;elementType&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;C&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&amp;gt;&lt;/span&gt;
        &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;label&lt;/span&gt; &lt;span class="attribute"&gt;value&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;6&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;atom&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;atom&lt;/span&gt; &lt;span class="attribute"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;a7&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;elementType&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;C&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;atom&lt;/span&gt; &lt;span class="attribute"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;a8&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;elementType&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;O&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;atom&lt;/span&gt; &lt;span class="attribute"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;a9&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;elementType&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;O&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;atom&lt;/span&gt; &lt;span class="attribute"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;a10&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;elementType&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;I&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&amp;gt;&lt;/span&gt;
        &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;label&lt;/span&gt; &lt;span class="attribute"&gt;value&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;atom&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;atomArray&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;bondArray&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;bond&lt;/span&gt; &lt;span class="attribute"&gt;atomRefs2&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;a1 a2&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;order&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;bond&lt;/span&gt; &lt;span class="attribute"&gt;atomRefs2&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;a2 a3&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;order&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;bond&lt;/span&gt; &lt;span class="attribute"&gt;atomRefs2&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;a3 a4&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;order&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;bond&lt;/span&gt; &lt;span class="attribute"&gt;atomRefs2&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;a4 a5&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;order&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;bond&lt;/span&gt; &lt;span class="attribute"&gt;atomRefs2&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;a5 a6&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;order&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;bond&lt;/span&gt; &lt;span class="attribute"&gt;atomRefs2&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;a6 a1&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;order&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;bond&lt;/span&gt; &lt;span class="attribute"&gt;atomRefs2&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;a7 a1&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;order&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;bond&lt;/span&gt; &lt;span class="attribute"&gt;atomRefs2&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;a7 a8&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;order&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;bond&lt;/span&gt; &lt;span class="attribute"&gt;atomRefs2&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;a7 a9&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;order&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;bond&lt;/span&gt; &lt;span class="attribute"&gt;atomRefs2&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;a10 a4&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="attribute"&gt;order&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;bondArray&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;molecule&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;cml&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This simple Ruby library has parsed the name '4-iodobenzoic acid' and has returned a string containing the CML representation for the molecule. If we had wanted the &lt;tt&gt;read_name&lt;/tt&gt; method to return a traversable XML object model, we could have enabled that as well.&lt;/p&gt;

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

&lt;p&gt;One of the objections raised whenever the issue of "new" programming languages comes up, regardless of their merit, is the age-old refrain "Yeah, but where's the software?" With JRuby, we bypass this question altogether. We can leverage the full scope of the massive Java development effort over the last ten years, which includes several excellent cheminformatics libraries. With virtually no effort, we have a working cheminformatics platform based on a widely-used, versatile and dynamic object-oriented scripting language. Future articles will discuss extensions to this platform and some applications.&lt;/p&gt;</description>
      <pubDate>Fri, 12 Oct 2007 10:37:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:873940fd-7b22-4013-a61b-ef928eee1c8e</guid>
      <author>Rich Apodaca</author>
      <link>http://depth-first.com/articles/2007/10/12/jruby-for-cheminformatics-parsing-iupac-nomenclature-with-opsin</link>
      <category>Tools</category>
      <category>opsin</category>
      <category>iupac</category>
      <category>nametostruct</category>
      <category>rubidium</category>
      <category>jruby</category>
      <category>ruby</category>
      <category>java</category>
    </item>
    <item>
      <title>JRuby for Cheminformatics: Reading and Writing InChIs Via the Java Native Interface</title>
      <description>&lt;p&gt;&lt;a href="http://ruby-lang.org"&gt;&lt;img src="http://depth-first.com/files/ruby_logo_new.gif" align="right"&gt;&lt;/img&gt;&lt;/a&gt;The increased use of the &lt;a href="http://depth-first.com/articles/2007/09/27/inchi-for-newbies"&gt;InChI identifier&lt;/a&gt; is making the reading and writing of InChIs a standard cheminformatics capability. Recent articles have discussed the &lt;a href="http://depth-first.com/articles/tag/jruby"&gt;advantages of JRuby for cheminformatics&lt;/a&gt;. One disadvantage of JRuby is that code written in C can't be directly used. The presents a potential problem for libraries, such as the InChI toolkit, that are written in C. Fortunately, the solution is simple. Today's tutorial will demonstrate how InChIs can be both read and written using the C-InChI toolkit via JRuby and the excellent &lt;a href="http://jni-inchi.sourceforge.net/"&gt;JNI-InChI library&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;About JNI-InChI&lt;/h4&gt;

&lt;p&gt;The &lt;a href="http://jni-inchi.sourceforge.net/"&gt;JNI-InChI&lt;/a&gt; library, written by Jim Downing and Sam Adams, wraps the &lt;a href="http://www.iupac.org/inchi/"&gt;C InChI toolkit&lt;/a&gt; in a Java Native Interface. This low-level toolkit is suitable for building more complex software, but lacks many features present in the C InChI toolkit. For example, JNI-InChI doesn't directly interconvert SMILES or molfile with InChI. For that you'd need to build a support library. If you're building a toolkit from scratch, this lightweight approach can be a significant advantage.&lt;/p&gt;

&lt;p&gt;The JNI-InChI binary distribution jarfile includes the compiled native InChI library. In this sense it's virtually indistinguishable from any other Java library. This simplified packaging makes it exceptionally easy to use JNI-InChI from JRuby, as we'll see below.&lt;/p&gt;

&lt;h4&gt;Installation&lt;/h4&gt;

&lt;p&gt;JRuby &lt;a href="http://depth-first.com/articles/2007/10/09/jruby-for-cheminformatics-parsing-smiles-simply"&gt;can be installed&lt;/a&gt; as described previously. To install the JNI-InChI library for JRuby, simply copy the &lt;a href="http://sourceforge.net/project/showfiles.php?group_id=173262"&gt;current release jarfile&lt;/a&gt; into the &lt;tt&gt;lib&lt;/tt&gt; directory of your JRuby installation. That's all there is to it.&lt;/p&gt;

&lt;h4&gt;A Simple Library&lt;/h4&gt;

&lt;p&gt;We can now write a simple library to read InChIs via 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;java&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="ident"&gt;include_class&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;net.sf.jniinchi.JniInchiInput&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;include_class&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;net.sf.jniinchi.JniInchiInputInchi&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;include_class&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;net.sf.jniinchi.JniInchiWrapper&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="keyword"&gt;module &lt;/span&gt;&lt;span class="module"&gt;IUPAC&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;read_inchi&lt;/span&gt; &lt;span class="ident"&gt;inchi&lt;/span&gt;
    &lt;span class="ident"&gt;input&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;JniInchiInputInchi&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt; &lt;span class="ident"&gt;inchi&lt;/span&gt;

    &lt;span class="constant"&gt;JniInchiWrapper&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;getStructureFromInchi&lt;/span&gt; &lt;span class="ident"&gt;input&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;h4&gt;Testing the Library&lt;/h4&gt;

&lt;p&gt;By saving the above library to a file called &lt;strong&gt;iupac.rb&lt;/strong&gt;, we can parse InChIs via JRuby:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ jirb
irb(main):001:0&gt; require 'iupac'
=&gt; true
irb(main):002:0&gt; include IUPAC
=&gt; Object
irb(main):003:0&gt; output = read_inchi 'InChI=1/C14H10/c1-3-7-13-11(5-1)9-10-12-6-2-4-8-14(12)13/h1-10H'
=&gt; #&lt;Java::NetSfJniinchi::JniInchiOutputStructure:0x1ed5459 @java_object=net.sf.jniinchi.JniInchiOutputStructure@313170&gt;
irb(main):004:0&gt; output.num_atoms
=&gt; 14
irb(main):005:0&gt; output.num_bonds
=&gt; 16
&lt;/pre&gt;
&lt;/div&gt;

&lt;h4&gt;Writing InChIs&lt;/h4&gt;

&lt;p&gt;Because JNI-InChI is a low-level toolkit, writing InChIs is feasible, but not trivial. We must first construct a representation, and then get the InChI for it. For example, we could get the InChI for methane as follows:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ jirb
irb(main):001:0&gt; require 'java'
=&gt; true
irb(main):002:0&gt; include_class 'net.sf.jniinchi.JniInchiInput'
=&gt; ["net.sf.jniinchi.JniInchiInput"]
irb(main):003:0&gt; include_class 'net.sf.jniinchi.JniInchiAtom'
=&gt; ["net.sf.jniinchi.JniInchiAtom"]
irb(main):004:0&gt; include_class 'net.sf.jniinchi.JniInchiWrapper'
=&gt; ["net.sf.jniinchi.JniInchiWrapper"]
irb(main):005:0&gt; input = JniInchiInput.new
=&gt; #&lt;Java::NetSfJniinchi::JniInchiInput:0x2f2295 @java_object=net.sf.jniinchi.JniInchiInput@15b0333&gt;
irb(main):006:0&gt; a1 = input.add_atom JniInchiAtom.new(0,0,0, "C")
=&gt; #&lt;Java::NetSfJniinchi::JniInchiAtom:0x1b22920 @java_object=net.sf.jniinchi.JniInchiAtom@2f356f&gt;
irb(main):007:0&gt; a1.set_implicit_h(4)
=&gt; nil
irb(main):008:0&gt; output = JniInchiWrapper.get_inchi input
=&gt; #&lt;Java::NetSfJniinchi::JniInchiOutput:0xf894ce @java_object=net.sf.jniinchi.JniInchiOutput@132ae7&gt;
irb(main):009:0&gt; output.get_inchi
=&gt; "InChI=1/CH4/h1H4"
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Fortunately, we don't have to work that hard. The &lt;a href="http://cdk.sf.net"&gt;Chemistry Development Kit&lt;/a&gt;, through JNI-InChI, supports reading and writing of InChIs via a variety of molecular languages, including SMILES and molfile. More on that later, though.&lt;/p&gt;

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

&lt;p&gt;Provided that a Java Native Interface exists for a C library, it can be used from JRuby. Future articles will discuss the use of other cheminformatics libraries written in either C or C++ from JRuby, and their integration with pure Java and Ruby libraries.&lt;/p&gt;</description>
      <pubDate>Wed, 10 Oct 2007 08:21:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:0348fa93-7376-488d-9afc-789590ac9fcb</guid>
      <author>Rich Apodaca</author>
      <link>http://depth-first.com/articles/2007/10/10/jruby-for-cheminformatics-reading-and-writing-inchis-via-the-java-native-interface</link>
      <category>Tools</category>
      <category>rubidium</category>
      <category>jruby</category>
      <category>ruby</category>
      <category>java</category>
      <category>jni</category>
      <category>inchi</category>
      <category>cdk</category>
    </item>
    <item>
      <title>JRuby for Cheminformatics: Parsing SMILES Simply</title>
      <description>&lt;p&gt;&lt;a href="http://cdk.sf.net"&gt;&lt;img src="http://depth-first.com/files/cdk_logo.png" align="right"&gt;&lt;/img&gt;&lt;/a&gt;&lt;a href="http://ruby-lang.org"&gt;&lt;img src="http://depth-first.com/files/ruby_logo_new.gif" align="right"&gt;&lt;/img&gt;&lt;/a&gt;The previous article in this series outlined some &lt;a href="http://depth-first.com/articles/2007/10/08/five-reasons-to-start-using-jruby-now"&gt;reasons to consider JRuby for cheminformatics&lt;/a&gt;. Now I'll show how easy it is to get started by describing how to parse SMILES strings with the help of the &lt;a href="http://cdk.sf.net"&gt;Chemistry Development Kit&lt;/a&gt; (CDK).&lt;/p&gt;

&lt;h4&gt;What About Ruby CDK?&lt;/h4&gt;

&lt;p&gt;A number of Depth-First articles have discussed &lt;a href="http://depth-first.com/articles/2007/10/04/ruby-cdk-for-newbies"&gt;Ruby CDK&lt;/a&gt;. This library runs on top of C-Ruby, otherwise known as Matz' Ruby Implementation (MRI). &lt;a href="http://rjb.rubyforge.org/"&gt;Ruby Java Bridge&lt;/a&gt; connects MRI to a Java Virtual Machine under Ruby CDK.&lt;/p&gt;

&lt;p&gt;This article, and the others to follow, will instead discuss the use of the CDK and other Java libraries from JRuby. In contrast to MRI, JRuby is a pure Java implementation of the Ruby language. This approach offers some important advantages which will be highlighted along the way.&lt;/p&gt;

&lt;h4&gt;Installing JRuby&lt;/h4&gt;

&lt;p&gt;JRuby is not difficult to install. On Linux, the steps are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Install &lt;a href="http://java.sun.com"&gt;JDK Version 1.4 or higher&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download and unpack the most recent JRuby release - at the time of this writing, &lt;a href="http://dist.codehaus.org/jruby"&gt;version 1.0.1&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the JRuby &lt;tt&gt;bin&lt;/tt&gt; directory to your path.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There is no Step 4. ;-)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;Installing CDK for JRuby&lt;/h4&gt;

&lt;p&gt;Installing CDK so that it works on JRuby is similarly quite simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Download the most recent CDK jarfile - at the time of this writing, &lt;a href="http://downloads.sourceforge.net/cdk/cdk-1.0.1.jar?modtime=1182877138&amp;amp;big_mirror=0"&gt;version 1.0.1&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Move the CDK jarfile to your JRuby &lt;tt&gt;lib&lt;/tt&gt; directory.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;Testing CDK for JRuby&lt;/h4&gt;

&lt;p&gt;You can verify that your new CDK for JRuby installation works with &lt;tt&gt;jirb&lt;/tt&gt;:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ jirb
irb(main):001:0&gt; require 'java'
=&gt; true
irb(main):002:0&gt; include_class 'org.openscience.cdk.smiles.SmilesParser'
=&gt; ["org.openscience.cdk.smiles.SmilesParser"]
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;You should notice that &lt;tt&gt;jirb&lt;/tt&gt; takes a few seconds to initialize the JVM, whereas &lt;tt&gt;irb&lt;/tt&gt; starts almost instantly.&lt;/p&gt;

&lt;h4&gt;A Library to Read SMILES&lt;/h4&gt;

&lt;p&gt;We can write a short library to read SMILES strings using the CDK:&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;java&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;include_class&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;org.openscience.cdk.smiles.SmilesParser&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="keyword"&gt;module &lt;/span&gt;&lt;span class="module"&gt;Daylight&lt;/span&gt;
  &lt;span class="attribute"&gt;@@smiles_parser&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;SmilesParser&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;def &lt;/span&gt;&lt;span class="method"&gt;read_smiles&lt;/span&gt; &lt;span class="ident"&gt;smiles&lt;/span&gt;
    &lt;span class="attribute"&gt;@@smiles_parser&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;parse_smiles&lt;/span&gt; &lt;span class="ident"&gt;smiles&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;Notice the use of the Rubyesque method name &lt;tt&gt;parse_smiles&lt;/tt&gt; rather than &lt;tt&gt;parseSmiles&lt;/tt&gt;. This is just one of the built-in conveniences offered by JRuby.&lt;/p&gt;

&lt;h4&gt;Testing the Library&lt;/h4&gt;

Saving the library as a file called &lt;strong&gt;daylight.rb&lt;/strong&gt; lets us test it using interactive JRuby:

&lt;div class="console"&gt;
&lt;pre&gt;
$ jirb
irb(main):001:0&gt; require 'daylight'
=&gt; true
irb(main):002:0&gt; include Daylight
=&gt; Object
irb(main):003:0&gt; mol = read_smiles 'c1ccccc1'
=&gt; #&lt;Java::OrgOpenscienceCdk:: [truncated] ...&gt;
irb(main):004:0&gt; mol.atom_count
=&gt; 6
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;As you can see, the benzene SMILES has been parsed correctly. Again, notice the use of the Rubyesque method name &lt;tt&gt;atom_count&lt;/tt&gt;, rather than the CDK Java bean convention method name &lt;tt&gt;getAtomCount&lt;/tt&gt;. This feature makes it easy to ignore the fact you're using a Java library and get on with writing your Ruby code. Brilliant!&lt;/p&gt;

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

&lt;p&gt;This article has shown how to install JRuby and begin to write some simple cheminformatics programs with a distinctive Ruby flavor. Although the focus was on SMILES parsing, there's much more functionality to be found within the CDK and other cheminformatics libraries written in Java. Future articles will outline some of the possibilities.&lt;/p&gt;</description>
      <pubDate>Tue, 09 Oct 2007 08:40:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:9007f034-5aa0-458c-b4e1-f9dc182d19be</guid>
      <author>Rich Apodaca</author>
      <link>http://depth-first.com/articles/2007/10/09/jruby-for-cheminformatics-parsing-smiles-simply</link>
      <category>Tools</category>
      <category>jruby</category>
      <category>java</category>
      <category>ruby</category>
      <category>rubidium</category>
      <category>cdk</category>
      <category>smiles</category>
    </item>
  </channel>
</rss>
