<?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 ruby</title>
    <link>http://depth-first.com/articles/tag/ruby</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Walking the Web of Chemical Informatics</description>
    <item>
      <title>The Daily Molecule: The Wonders of Chemistry - One Molecule at a Time</title>
      <description>&lt;p&gt;&lt;a href="http://blog.chempedia.com"&gt;&lt;img src="http://depth-first.com/demo/20080513/chempedia.png" align="right"&gt;&lt;/img&gt;&lt;/a&gt;Chemistry is a big field judged by any standard, including the &lt;a href="http://depth-first.com/articles/2008/05/07/1908-and-all-that-the-long-tail-and-chemistry"&gt;proliferation of American Chemical Society (ACS) divisions&lt;/a&gt;. Each subdiscipline in chemistry is in turn so big, that once a chemist becomes 'differentiated' it's easy to lose touch even with neighboring subdisciplines. It doesn't have to be that way. This article introduces a new service, &lt;a href="http://blog.chempedia.com"&gt;&lt;em&gt;The Daily Molecule&lt;/em&gt;&lt;/a&gt; designed to make it just a little bit easier (and hopefully fun) to stay in the chemical loop.&lt;/p&gt;

&lt;h4&gt;What Is It?&lt;/h4&gt;

&lt;p&gt;The idea is simple: every weekday, a new molecule will be featured on &lt;em&gt;The Daily Molecule&lt;/em&gt; with a short write-up and some leading references. Although molecules in the news will get first priority, any molecule is fair game.&lt;/p&gt;

&lt;p&gt;The material for &lt;em&gt;The Daily Molecule&lt;/em&gt; will be drawn from &lt;a href="http://chempedia.com"&gt;Chempedia&lt;/a&gt;, which in turn gets some of its content from &lt;a href="http://wikipedia.org"&gt;Wikipedia&lt;/a&gt;. In other words, the entries on the Daily Molecule will be largeley written by my fellow chemists.&lt;/p&gt;

&lt;p&gt;The process of creating a &lt;em&gt;Daily Molecule&lt;/em&gt; entry is not time-consuming, but much of what is being done manually now could be automated in the future. The technology platform lends itself well to many forms of chemistry-specific modification (see below).&lt;/p&gt;

&lt;p&gt;I hesitate to use the term 'blog' to describe &lt;em&gt;The Daily Molecule&lt;/em&gt;, but the description may be helpful to an extent.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Daily Molecule&lt;/em&gt; is unlike a blog in that most content will be generated by others, selected by some criteria, reformatted for consistency, and published. In that sense, &lt;em&gt;The Daily Molecule&lt;/em&gt; is a something like a mini scientific journal, but it turns the process of acquiring content on its head.&lt;/p&gt;

&lt;p&gt;If chemistry ever evolves beyond the &lt;a href="http://depth-first.com/articles/2007/07/16/go-west-young-man-does-open-access-really-matter-in-the-long-run"&gt;current model of publication&lt;/a&gt;, which seems inevitable at this point, the journals of the future may resemble &lt;em&gt;The Daily Molecule&lt;/em&gt; in one or more ways.&lt;/p&gt;

&lt;h4&gt;Technology&lt;/h4&gt;

&lt;p&gt;The software running &lt;em&gt;The Daily Molecule&lt;/em&gt; is a modified version of &lt;a href="http://simplelog.net/"&gt;SimpleLog&lt;/a&gt;, a Web application based on &lt;a href="http://www.rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt;. Unlike most blogging engines, SimpleLog focuses on implementing only the most basic publication features, and doing them to perfection. If you know a little Ruby and can work with Rails, you can do a lot with SimpleLog.&lt;/p&gt;

&lt;p&gt;One of the first items of business will be to implement &lt;a href="http://depth-first.com/articles/2007/09/18/six-reasons-i-like-recaptcha-or-how-to-build-a-web-service-worth-talking-about"&gt;reCAPTCHA&lt;/a&gt; support and activate comments on articles.&lt;/p&gt;

&lt;p&gt;Some ideas for chemically-enabling &lt;em&gt;The Daily Molecule&lt;/em&gt; include a graphical abstract sidebar and (sub)structure search. Currently, the 2D chemical structure images posted to &lt;em&gt;The Daily Molecule&lt;/em&gt; &lt;a href="http://depth-first.com/articles/2007/08/08/never-draw-the-same-molecule-twice-viewing-image-metadata"&gt;have complete connection tables embedded as metadata&lt;/a&gt;, a feature with some interesting possibilities.&lt;/p&gt;

&lt;h4&gt;The Molecule of the Day/Week/Month&lt;/h4&gt;

&lt;p&gt;The basic idea behind &lt;em&gt;The Daily Molecule&lt;/em&gt; is not new. Many other services have sprung up over the last ten years that operate, at least on the surface, similarly. Some examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.moleculeoftheday.com/"&gt;Molecule of the Day&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://portal.acs.org/portal/acs/corg/content?_nfpb=true&amp;amp;_pageLabel=PP_TRANSITIONMAIN&amp;amp;node_id=677&amp;amp;use_sec=false&amp;amp;sec_url_var=region1"&gt;ACS Molecule of the Week&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.drugsandpoisons.com/"&gt;Drugs and Poisons&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://the-half-decent-pharmaceutical-chemistry-blog.chemblogs.org/category/saturday-night-synthesis"&gt;Saturday Night Synthesis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.chm.bris.ac.uk/motm/motm.htm"&gt;The Molecule of the Month&lt;/a&gt; (may be the oldest continuously-operated MOTM site in existence)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.3dchem.com/motm.asp"&gt;3dchem.com Molecule of the Month&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.expasy.org/spotlight/"&gt;Protein Spotlight&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://mgl.scripps.edu/people/goodsell/illustration/pdb"&gt;PDB Molecule of the Month&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.prous.com/molecules/default.asp"&gt;Prous Molecule of the Month&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Quite a few others don't appear on this list.&lt;/p&gt;

&lt;p&gt;The different idea behind the &lt;em&gt;The Daily Molecule&lt;/em&gt; is that chemical content already exists in on the Web in machine-readable format with licenses that permit its re-use; all that's needed is a way to aggregate, format, and package that information in a form suitable for once-daily scanning and cheminformatics manipulation.&lt;/p&gt;

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

&lt;p&gt;Like no other medium, the Web blurs artificial distinctions: between work and play; between private and public; between on-topic and off-topic; between fame and obscurity; between mine and yours; between big and small; and between profit and non-profit. Chemistry may be late to the party, but is not immune to its call.&lt;/p&gt;</description>
      <pubDate>Wed, 14 May 2008 11:58:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:804a7467-98a1-47ae-975a-b1fdd172f1c0</guid>
      <author>Rich Apodaca</author>
      <link>http://depth-first.com/articles/2008/05/14/the-daily-molecule-the-wonders-of-chemistry-one-molecule-at-a-time</link>
      <category>Meta</category>
      <category>dailymolecule</category>
      <category>scientificpublication</category>
      <category>chempedia</category>
      <category>wikipedia</category>
      <category>journal</category>
      <category>web</category>
      <category>rails</category>
      <category>ruby</category>
      <category>simplelog</category>
    </item>
    <item>
      <title>Hacking DOI: Interconvert Bibliographic References and DOIs with CrossRef and OpenURL</title>
      <description>&lt;p&gt;&lt;a href="http://flickr.com/photos/ecstaticist/1340787730/"&gt;&lt;img src="http://depth-first.com/demo/20080506/web.jpg" align="right"&gt;&lt;/img&gt;&lt;/a&gt;Science is in the middle of a transition from print to the internet as the primary medium of communication. This transition, although a boon for many scientists, creates a host of problems for those dealing with scientific information. For example, how would you interconvert a &lt;a href="http://www.doi.org/"&gt;DOI&lt;/a&gt; and its corresponding bibliographic reference?&lt;/p&gt;

&lt;p&gt;A previous Depth-First article discussed &lt;a href="http://depth-first.com/articles/2007/06/27/easily-convert-publisher-urls-and-dois-to-bibliographical-citations-synthesis-synlett-ruby-and-mechanize"&gt;a screen-scraping method&lt;/a&gt; as one solution. Unfortunately, this system relies on an intimate understanding of how individual publishers' Websites work, requires a different implementation for each publisher, and can break at any time without warning.&lt;/p&gt;

&lt;p&gt;This article discusses a far more robust solution to the problem of interconverting bibliographic references and DOIs.&lt;/p&gt;

&lt;h4&gt;Background: OpenURL and CrossRef&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://www.crossref.org/"&gt;CrossRef&lt;/a&gt; is the official &lt;a href="http://www.doi.org/"&gt;DOI&lt;/a&gt; link registration agency for scholarly and professional publications. One of the less well-known services offered by CrossRef is a free, Web-based &lt;a href="http://www.crossref.org/openurl_info.html"&gt;bidirectional DOI/bibliographic reference converter&lt;/a&gt; based on &lt;a href="http://en.wikipedia.org/wiki/OpenURL"&gt;OpenURL&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;The following Ruby library is all we need to begin using CrossRef and OpenURL:&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;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;hpricot&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;open-uri&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;DOI&lt;/span&gt;
  &lt;span class="comment"&gt;# Convert a doi into a bibliographic reference.&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;biblio_for&lt;/span&gt; &lt;span class="ident"&gt;doi&lt;/span&gt;
    &lt;span class="ident"&gt;doc&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Hpricot&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;open&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;http://www.crossref.org/openurl/?id=doi:&lt;span class="expr"&gt;#{doi}&lt;/span&gt;&amp;amp;noredirect=true&amp;amp;pid=ourl_sample:sample&amp;amp;format=unixref&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;))&lt;/span&gt;

    &lt;span class="ident"&gt;journal&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;doc&lt;/span&gt;&lt;span class="punct"&gt;/&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;abbrev_title&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;).&lt;/span&gt;&lt;span class="ident"&gt;inner_html&lt;/span&gt;
    &lt;span class="ident"&gt;year&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;doc&lt;/span&gt;&lt;span class="punct"&gt;/&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;journal_issue/publication_date/year&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;).&lt;/span&gt;&lt;span class="ident"&gt;inner_html&lt;/span&gt;
    &lt;span class="ident"&gt;volume&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;doc&lt;/span&gt;&lt;span class="punct"&gt;/&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;journal_issue/journal_volume/volume&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;).&lt;/span&gt;&lt;span class="ident"&gt;inner_html&lt;/span&gt;
    &lt;span class="ident"&gt;number&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;doc&lt;/span&gt;&lt;span class="punct"&gt;/&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;journal_issue/issue&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;).&lt;/span&gt;&lt;span class="ident"&gt;inner_html&lt;/span&gt;
    &lt;span class="ident"&gt;first_page&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;doc&lt;/span&gt;&lt;span class="punct"&gt;/&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;pages/first_page&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;).&lt;/span&gt;&lt;span class="ident"&gt;inner_html&lt;/span&gt;
    &lt;span class="ident"&gt;last_page&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;doc&lt;/span&gt;&lt;span class="punct"&gt;/&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;pages/last_page&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;).&lt;/span&gt;&lt;span class="ident"&gt;inner_html&lt;/span&gt;

    &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{journal}&lt;/span&gt; &lt;span class="expr"&gt;#{year}&lt;/span&gt;, &lt;span class="expr"&gt;#{volume}&lt;/span&gt;(&lt;span class="expr"&gt;#{number}&lt;/span&gt;) &lt;span class="expr"&gt;#{first_page}&lt;/span&gt;-&lt;span class="expr"&gt;#{last_page}&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="comment"&gt;# Convert a bibliographic reference into a DOI.&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;doi_for&lt;/span&gt; &lt;span class="ident"&gt;journal&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;year&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;volume&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;issue&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;page&lt;/span&gt;
    &lt;span class="ident"&gt;doc&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Hpricot&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;open&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;http://www.crossref.org/openurl/?title=&lt;span class="expr"&gt;#{journal.gsub(/ /, '%20')}&lt;/span&gt;&amp;amp;volume=&lt;span class="expr"&gt;#{volume}&lt;/span&gt;&amp;amp;issue=&lt;span class="expr"&gt;#{issue}&lt;/span&gt;&amp;amp;spage=&lt;span class="expr"&gt;#{page}&lt;/span&gt;&amp;amp;date=&lt;span class="expr"&gt;#{year}&lt;/span&gt;&amp;amp;pid=ourl_sample:sample&amp;amp;redirect=false&amp;amp;format=unixref&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;))&lt;/span&gt;

   &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;doc&lt;/span&gt;&lt;span class="punct"&gt;/&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;doi&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;).&lt;/span&gt;&lt;span class="ident"&gt;inner_html&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;This code makes use of the excellent Ruby HTML parser library &lt;a href="http://code.whytheluckystiff.net/hpricot"&gt;Hpricot&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;Saving the Ruby code to a file named &lt;strong&gt;doi.rb&lt;/strong&gt;, we can test it using the interactive Ruby shell:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ irb
irb(main):001:0&gt; require 'doi'
=&gt; true
irb(main):002:0&gt; include DOI
=&gt; Object
irb(main):003:0&gt; biblio_for "10.1021/cr00032a009"
=&gt; "Chem. Rev. 1994, 94(8) 2483-2547"
irb(main):004:0&gt; doi_for "Chem. Rev.", 1994, 94, 8, 2483
=&gt; "10.1021/cr00032a009"
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Notice how the journal abbreviation &lt;em&gt;Chem. Rev.&lt;/em&gt; was used; we'd get the same result if we used &lt;em&gt;Chemical Reviews&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Of course, the implementation described here could be refined a lot. With a DOI, it's trivial to &lt;a href="http://dx.doi.org/10.1021/cr00032a009"&gt;construct a URL to the example paper&lt;/a&gt;. But we could take it further than that. With some carefully crafted regular expressions, our &lt;tt&gt;doi_for&lt;/tt&gt; method could accept a freeform bibliographical citation rather than separately identified fragments. From there we might start to think about creating living HTML and/or Wikis from old PDFs and Word documents.&lt;/p&gt;

&lt;p&gt;With a little creative thought, other possibilities are well within reach.&lt;/p&gt;

&lt;h4&gt;Caveat&lt;/h4&gt;

&lt;p&gt;Before extensively experimenting with CrossRef's OpenURL system, you might want to &lt;a href="http://www.crossref.org/requestaccount/"&gt;sign up for a free account&lt;/a&gt;. CrossRef is understandably interested in tracking usage and this is their way to do it.&lt;/p&gt;

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

&lt;p&gt;DOIs and traditional bibliographical citations now coexist in a variety of settings, from literature citation managers to journals themselves. Using CrossRef, OpenURL and a little bit of code, it's now possible to make a great deal more sense of it all.&lt;/p&gt;

&lt;p&gt;Harvesting bibliographical citations must be one of the least sexy topics in cheminformatics. But as Google demonstrated (building on the approach taken by &lt;a href="http://scientific.thomson.com/products/sci/"&gt;&lt;em&gt;Science Citation Index&lt;/em&gt;&lt;/a&gt;), cataloging citation behavior leads to a unique and highly productive way to view many tough problems. Future articles will discuss how this might apply to cheminformatics.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image Credit: &lt;a href="http://flickr.com/photos/ecstaticist/"&gt;ecstaticist&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 06 May 2008 15:50:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:8eafadd6-bf10-4e65-ac43-2a3bf37de457</guid>
      <author>Rich Apodaca</author>
      <link>http://depth-first.com/articles/2008/05/06/hacking-doi-interconvert-bibliographic-references-and-dois-with-crossref-and-openurl</link>
      <category>Tools</category>
      <category>openurl</category>
      <category>crossref</category>
      <category>ruby</category>
      <category>hpricot</category>
      <category>sciencecitationindex</category>
      <category>citations</category>
    </item>
    <item>
      <title>CampDepict: Building a Simple SMILES Depict Web Application With JRuby, Structure CDK, and Camping</title>
      <description>&lt;p&gt;&lt;a href="http://redhanded.hobix.com/bits/campingAMicroframework.html"&gt;&lt;img src="http://depth-first.com/demo/20080423/camping.png" align="right"&gt;&lt;/img&gt;&lt;/a&gt;Today's tribute to the power of simplicity comes by way of &lt;a href="http://goeslightly.blogspot.com/"&gt;John Jaeger&lt;/a&gt;, who has built one of the simplest cheminformatics Web applications ever written. His creation, &lt;a href="http://goeslightly.blogspot.com/2008/04/campdepict-jruby-cdk-and-camping.html"&gt;CampDepict&lt;/a&gt;, interactively produces a raster image of a 2D chemical structure given a SMILES string, not unlike &lt;a href="http://www.daylight.com/daycgi/depict"&gt;Daylight's Depict application&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;CampDepict uses the Ruby Web microframework &lt;a href="http://redhanded.hobix.com/bits/campingAMicroframework.html"&gt;Camping&lt;/a&gt;. From the &lt;a href="http://camping.rubyforge.org/files/README.html"&gt;README&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;Camping is a web framework which consistently stays at less than 4kb of code. You can probably view the complete source code on a single page. But, you know, it&#8216;s so small that, if you think about it, what can it really do?&lt;/p&gt;
    
    &lt;p&gt;The idea here is to store a complete fledgling web application in a single file like many small CGIs. But to organize it as a Model-View-Controller application like Rails does. You can then easily move it to Rails once you&#8216;ve got it going.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;John's application is loosely-based on the &lt;a href="http://depth-first.com/articles/2006/12/04/anatomy-of-a-cheminformatics-web-application-ajaxifying-depict"&gt;Rails Depict&lt;/a&gt; application first described in 2006 here on Depth-First. His code makes use of &lt;a href="http://cdk.sf.net"&gt;CDK&lt;/a&gt; and &lt;a href="http://sf.net/projects/structure"&gt;Structure CDK&lt;/a&gt;, and it runs on &lt;a href="http://jruby.codehaus.org/"&gt;JRuby&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you've ever been curious about what Ruby has to offer cheminformatics, CampDepict could be just the application to get your feet wet.&lt;/p&gt;</description>
      <pubDate>Wed, 23 Apr 2008 11:16:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:b831ffb0-cb0a-46ed-aaa1-a5cddc2acfcf</guid>
      <author>Rich Apodaca</author>
      <link>http://depth-first.com/articles/2008/04/23/campdepict-building-a-simple-smiles-depict-web-application-with-jruby-structure-cdk-and-camping</link>
      <category>Tools</category>
      <category>camping</category>
      <category>ruby</category>
      <category>jruby</category>
      <category>campdepict</category>
      <category>structurecdk</category>
      <category>cdk</category>
      <category>webapplication</category>
    </item>
    <item>
      <title>Chempedia.net: Mashing Up PubChem and Wikipedia</title>
      <description>&lt;p&gt;&lt;a href="http://chempedia.com"&gt;&lt;img src="http://chempedia.net/images/global/logo.png" align="right"&gt;&lt;/img&gt;&lt;/a&gt;&lt;a href="http://pubchem.ncbi.nlm.nih.gov/"&gt;PubChem&lt;/a&gt; and &lt;a href="http://wikipedia.net"&gt;Wikipedia&lt;/a&gt; represent two of the largest open repositories of chemical information in the world. And they complement each other very nicely. PubChem contains mainly low-level chemical structure information whereas Wikipedia contains free-text descriptions of chemical compounds in the form of &lt;a href="http://depth-first.com/articles/2008/04/02/wikipedia-for-cheminformatics-a-simple-web-api-for-finding-cas-numbers-in-compound-monographs"&gt;compound monographs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Both services offer permission and access to copy and reuse their contents. But neither service is, by itself, nearly as useful as it could be.&lt;/p&gt;

&lt;p&gt;Why not mash them up?&lt;/p&gt;

&lt;p&gt;To explore that question my company, &lt;a href="http://metamolecular.com"&gt;Metamolecular, LLC&lt;/a&gt; has launched &lt;a href="http://chempedia.com"&gt;Chempedia&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To my knowledge, Chempedia represents the first publicly-facing database of compounds to incorporate Wikipedia's collection of organic compound monographs. And it's one of the few cheminformatics services to make use of free-text descriptions generated by individual chemists.&lt;/p&gt;

&lt;p&gt;Chempedia has been somewhat selective about the compounds it includes. To date, it has spidered over 2,500 monographs, combining them with over 300,000 of the most interesting compounds from PubChem. Not every Chempedia.net molecule has a monograph, but now there's a tool that can actually make that absence apparent.&lt;/p&gt;

&lt;p&gt;Chempedia is both an experiment and a service. It's immediately useful for anyone in the business of making or doing things with organic molecules. It's created several unexpected moments of "Oh, that's actually a useful molecule!" It also will serve as a platform to test some of the ideas discussed in Depth-First over the last year or so on the advantages of the Web for collaboration in chemistry.&lt;/p&gt;

&lt;p&gt;Stay tuned for more details about how Chempedia was created and some of its applications in chemistry.&lt;/p&gt;</description>
      <pubDate>Fri, 04 Apr 2008 10:06:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:168432fb-c064-43c2-a60d-728c7c29c406</guid>
      <author>Rich Apodaca</author>
      <link>http://depth-first.com/articles/2008/04/04/chempedia-net-mashing-up-pubchem-and-wikipedia</link>
      <category>Tools</category>
      <category>chempedia</category>
      <category>wikipedia</category>
      <category>pubchem</category>
      <category>rails</category>
      <category>ruby</category>
      <category>chemwriter</category>
      <category>applet</category>
      <category>java</category>
      <category>jruby</category>
    </item>
    <item>
      <title>Wikipedia for Cheminformatics: A Simple Web API for Finding CAS Numbers in Compound Monographs</title>
      <description>&lt;p&gt;&lt;a href="http://wikipedia.org"&gt;&lt;img src="http://depth-first.com/demo/20070123/wikipedia.jpg" align="right"&gt;&lt;/img&gt;&lt;/a&gt;Good news for cheminformatics: Chemical Abstracts Service (CAS) &lt;a href="http://en.wikipedia.org/wiki/Wikipedia_talk:WikiProject_Chemistry/CAS_validation"&gt;has agreed&lt;/a&gt; to help Wikipedia users curate its collection of CAS numbers. As a result of the diligence of some hard-working volunteers, chemistry's most universal system for referring to chemicals can now be used far more effectively by the worlds biggest open repository of knowledge.&lt;/p&gt;

&lt;p&gt;Wouldn't it be great to be able to pull these CAS numbers from Wikipedia programmatically?&lt;/p&gt;

&lt;h4&gt;Perspective&lt;/h4&gt;

&lt;p&gt;Estimates place the number of Wikipedia pages dealing with individual &lt;a href="http://en.wikipedia.org/wiki/Wikipedia:WikiProject_Chemicals/Inorganics"&gt;inorganic&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/List_of_organic_compounds"&gt;organic&lt;/a&gt; substances in the thousands. (I'll use the term "compound monographs" to describe them.) One factor acting to keep this number low is poor visibility of these entries. Unlike most &lt;a href="http://depth-first.com/articles/2007/01/24/thirty-two-free-chemistry-databases"&gt;chemical databases&lt;/a&gt;, Wikipedia can't, by itself, be easily searched by structure. As chemically-aware tools for indexing Wikipedia begin to emerge, look for six things to happen:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The number of Wikipedia compound monographs will increase significantly.&lt;/li&gt;
&lt;li&gt;The quality of monographs for intermediate- to well-known compounds will increase substantially.&lt;/li&gt;
&lt;li&gt;Demand for user-friendly interfaces to Wikipedia's chemical content will increase.&lt;/li&gt;
&lt;li&gt;Wikipedia users will become interested in storing and finding ever more diverse kinds of information about each compound.&lt;/li&gt;
&lt;li&gt;Bench chemists will start to include Wikipedia as one of their preferred literature search techniques, leading to...&lt;/li&gt;
&lt;li&gt;More creative tools for using the chemical content of Wikipedia.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As noted previously, it wasn't too long ago that indexing of the chemical literature &lt;a href="http://depth-first.com/articles/2006/08/19/history-of-abstracting-at-chemical-abstracts-service"&gt;was done solely by volunteers&lt;/a&gt;. Wikipedia offers an intriguing way to channel the innate drive for chemists to combine their own work and experience with that of others to build useful information tools for the community.&lt;/p&gt;

&lt;p&gt;But for now we are left with the question of how to index the chemical content of Wikipedia. Although a few systems have been proposed, the only practical method is through the use of CAS numbers. Which brings us to the subject of today's tutorial.&lt;/p&gt;

&lt;h4&gt;A Quick CAS Number API for Wikipedia&lt;/h4&gt;

&lt;p&gt;The Ruby program below will accept the title of any Wikipedia compound monograph title and return the CAS number for the compound being discussed, or an error message if none was found:&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;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;hpricot&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;open-uri&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;cgi&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;Wikikemi&lt;/span&gt;
  &lt;span class="attribute"&gt;@cas&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;nil&lt;/span&gt;

  &lt;span class="ident"&gt;attr_reader&lt;/span&gt; &lt;span class="symbol"&gt;:cas&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt; &lt;span class="ident"&gt;title&lt;/span&gt;
    &lt;span class="ident"&gt;uri&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;URI&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;escape&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;http://en.wikipedia.org/wiki/&lt;span class="expr"&gt;#{title}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&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;loading... &lt;span class="expr"&gt;#{uri}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="ident"&gt;doc&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Hpricot&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;open&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;uri&lt;/span&gt;&lt;span class="punct"&gt;))&lt;/span&gt;
    &lt;span class="ident"&gt;table&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;doc&lt;/span&gt;&lt;span class="punct"&gt;/&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;table&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)[&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;table&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;inner_html&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;match&lt;/span&gt;&lt;span class="punct"&gt;(/&lt;/span&gt;&lt;span class="regex"&gt;([0-9]{2,7}?&lt;span class="escape"&gt;\-&lt;/span&gt;[0-9]{2}&lt;span class="escape"&gt;\-&lt;/span&gt;[0-9])&lt;/span&gt;&lt;span class="punct"&gt;/)&lt;/span&gt; &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;table&lt;/span&gt;

    &lt;span class="attribute"&gt;@cas&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="global"&gt;$1&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;# Returns the CAS number present in the Wikipedia monograph with&lt;/span&gt;
&lt;span class="comment"&gt;# the indicated title, or an error message if none is found. Try, for example,&lt;/span&gt;
&lt;span class="comment"&gt;# &amp;quot;benzene.&amp;quot;.&lt;/span&gt;
&lt;span class="keyword"&gt;while&lt;/span&gt; &lt;span class="constant"&gt;true&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;Enter the title of the Wikipedia page, for example: 'benzene'&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="ident"&gt;monograph_title&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;gets&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;chomp&lt;/span&gt;
  &lt;span class="ident"&gt;w&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Wikikemi&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;monograph_title&lt;/span&gt;
  &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="ident"&gt;w&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;cas&lt;/span&gt; &lt;span class="punct"&gt;?&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;[&lt;span class="expr"&gt;#{w.cas}&lt;/span&gt;]&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;:&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;CAS number not found&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This program makes use of the excellent Ruby HTML parser, &lt;a href="http://code.whytheluckystiff.net/hpricot/"&gt;Hpricot&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Saving the above code to a file called &lt;strong&gt;wikikemi.rb&lt;/strong&gt;, we can run it with:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ ruby wikikemi.rb
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;For example, we can look up the CAS numbers for Ferrocene, Lipitor, or 1,2,3,4,4a,5,6,7,8,8a-Decahydronaphthalene:&lt;/p&gt;

&lt;div class="console"&gt;
&lt;pre&gt;
$ ruby wikikemi.rb
Enter the title of the Wikipedia page, for example: 'benzene'
ferrocene
loading... http://en.wikipedia.org/wiki/ferrocene
[102-54-5]
Enter the title of the Wikipedia page, for example: 'benzene'
lipitor
loading... http://en.wikipedia.org/wiki/lipitor
[134523-00-5]
Enter the title of the Wikipedia page, for example: 'benzene'
1,2,3,4,4a,5,6,7,8,8a-Decahydronaphthalene
loading... http://en.wikipedia.org/wiki/1,2,3,4,4a,5,6,7,8,8a-Decahydronaphthalene
[91-17-8]
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;All this method requires is that the Wikipedia page lists the correct CAS number in its &lt;a href="http://en.wikipedia.org/wiki/Template:Drugbox"&gt;Drugbox&lt;/a&gt; or &lt;a href="http://en.wikipedia.org/wiki/Template:Chembox_new"&gt;Chembox&lt;/a&gt; template. Fortunately, CAS has agreed to help make this happen.&lt;/p&gt;

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

&lt;p&gt;A little Ruby code is all it takes to build a working CAS number lookup system using Wikipedia. Although this may be useful as a standalone tool, it becomes much more powerful when made part of &lt;a href="http://depth-first.com/articles/2007/05/21/simple-cas-number-lookup-with-pubchem"&gt;a larger cheminformatics system&lt;/a&gt;. But that's a story for another time.&lt;/p&gt;

&lt;p&gt;See also &lt;a href="http://www.chemspider.com/blog/a-message-of-support-and-public-service-from-the-chemical-abstracts-service.html"&gt;Antony Williams' announcement on CAS and Wikipedia&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Wed, 02 Apr 2008 17:29:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:c11402b2-406a-4ec9-8b65-fc34da179c1a</guid>
      <author>Rich Apodaca</author>
      <link>http://depth-first.com/articles/2008/04/02/wikipedia-for-cheminformatics-a-simple-web-api-for-finding-cas-numbers-in-compound-monographs</link>
      <category>Tools</category>
      <category>cas</category>
      <category>acs</category>
      <category>casnumber</category>
      <category>lookup</category>
      <category>wikipedia</category>
      <category>ruby</category>
    </item>
    <item>
      <title>NetBeans 6, Ruby, and Rails: A Surprisingly Effective Combination</title>
      <description>&lt;p&gt;For far too long Ruby has lacked a development environment that supported important features developers in other languages now take for granted: code completion; refactoring; platform-independence; and speed. Although &lt;a href="http://www.netbeans.org/"&gt;NetBeans&lt;/a&gt; may not spring to mind when thinking of Rails IDEs, it should be at the top of the list for anyone interested in the subject.&lt;/p&gt;

&lt;p&gt;Getting started with Ruby, Rails and NetBeans is as easy as &lt;a href="http://download.netbeans.org/netbeans/6.0/final/"&gt;downloading the installer&lt;/a&gt; and running it. If you later decide to add Java support to your installation (which is also excellent), that can be done by downloading and running the &lt;a href="http://download.netbeans.org/netbeans/6.0/final/"&gt;Java installer&lt;/a&gt;. You'll end up with a single IDE that supports both languages.&lt;/p&gt;

&lt;h4&gt;Code Completion&lt;/h4&gt;

&lt;p&gt;Although other IDEs support some form of Ruby code completion, NetBeans takes it to another level. Can't remember the exact name of the method you're looking for? Type the period and let NetBeans look up both the name and documentation for you:&lt;/p&gt;

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

&lt;p&gt;Hitting return enters the method and creates a template for parameters and any needed blocks.&lt;/p&gt;

&lt;h4&gt;Refactoring&lt;/h4&gt;

&lt;p&gt;One of the things that makes Java such a powerful language for large projects is the refactoring support offered by most IDEs. NetBeans brings this power to Ruby. Need to rename a class, method, or variable? Let NetBeans do it for you:&lt;/p&gt;

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

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

&lt;p&gt;There's much more to NetBeans 6 and Ruby/Rails than what's been shown here, including formatting/highlighting for JavaScript and CSS, user-definable Ruby/JRuby interpreter, and menu-based script execution. Whether you're looking for a way to get started with using Ruby and Rails or a way to become more efficient at it, NetBeans 6 is well worth the time.&lt;/p&gt;</description>
      <pubDate>Thu, 27 Mar 2008 13:46:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:b1fbcff2-4f5b-496f-9eeb-35f96e8d0b5d</guid>
      <author>Rich Apodaca</author>
      <link>http://depth-first.com/articles/2008/03/27/netbeans-6-ruby-and-rails-a-surprisingly-effective-combination</link>
      <category>Tools</category>
      <category>ruby</category>
      <category>rails</category>
      <category>netbeans</category>
      <category>ide</category>
      <category>refactoring</category>
      <category>codecompletion</category>
    </item>
    <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 -0500</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 -0500</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>Paginated Archives in Radiant CMS: The Power of Minimal But Extendable Systems</title>
      <description>&lt;p&gt;&lt;a href="http://radiantcms.org"&gt;&lt;img src="http://depth-first.com/demo/20071107/radiant.png" align="right"&gt;&lt;/a&gt;&lt;/a&gt;If you've ever needed to build a Website hosting mostly static content, you've probably tried out a few Content Management Systems. The problem is not finding them - there must be hundreds. The problem is finding one that successfully walks the fine line between being minimal (so that you can do things your way) and powerful (so that it can grow with your needs).&lt;/p&gt;

&lt;p&gt;&lt;a href="http://radiantcms.org"&gt;Radiant CMS&lt;/a&gt; is one of those systems. As an added bonus, it's written in Ruby and built on &lt;a href="http://rubyonrails.org"&gt;Rails&lt;/a&gt;. Radiant succeeds by focusing on the management of pages while providing a powerful extension mechanism.&lt;/p&gt;

&lt;p&gt;The Website for my company, &lt;a href="http://metamolecular.com"&gt;Metamolecular&lt;/a&gt;, will consist of content produced infrequently (product descriptions and documentation) intermingled with more frequently created blog-like content (updates, tutorials, responses to user questions). Traditionally, the CMS has handled the former, with blogging software handling the latter. But we needed a system that handled both well.&lt;/p&gt;

&lt;p&gt;One of the distinguishing characteristics of blogs, as opposed to other kinds of websites, is the unusually large number of similar pages. Handling this kind of content requires pagination - the ability to break an archive up into a series of pages containing a smaller subset of the archive.&lt;/p&gt;

&lt;p&gt;Although Radiant doesn't have the ability to paginate its content, it does have a wonderful system for creating extensions. I thought I'd give it a try.&lt;/p&gt;

&lt;p&gt;The result is the Paginated Archive extension. It works as a drop-in replacement for Radiant's existing Archive Page. After placing the extension into your PROJECT_HOME/vendor/extensions directory, you'll be able to create and configure Paginated Archives for use with blogs and other kinds of sites generating large numbers of pages. The extension requires Bruce Williams' excellent &lt;a href="http://rubyforge.org/projects/paginator"&gt;Paginator&lt;/a&gt; gem.&lt;/p&gt;

&lt;p&gt;You can get started by downloading the extension &lt;a href="http://depth-first.com/demo/20071107/paginated_archive.tar.gz"&gt;here&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Wed, 07 Nov 2007 09:40:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:3f1bf0a2-bd23-4a3a-9c7b-6b7d0e3c695f</guid>
      <author>Rich Apodaca</author>
      <link>http://depth-first.com/articles/2007/11/07/paginated-archives-in-radiant-cms-the-power-of-minimal-but-extendable-systems</link>
      <category>Tools</category>
      <category>radiantcms</category>
      <category>ruby</category>
      <category>rails</category>
      <category>blog</category>
      <category>cms</category>
      <category>paginated_archive</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 -0500</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>
  </channel>
</rss>
