README.md in rubabel-0.2.2 vs README.md in rubabel-0.3.0
- old
+ new
@@ -1,199 +1,243 @@
# rubabel
-Ruby interface to the openbabel ruby bindings (or the openbabel gem). The
+Ruby interface to the OpenBabel ruby bindings (or the openbabel gem). The
interface attempts to be a ruby-ish analogue of
-[pybel](http://openbabel.org/docs/current/UseTheLibrary/Python_PybelAPI.html).
+[pybel](http://openbabel.org/docs/current/UseTheLibrary/Python_PybelAPI.html). Works with ruby 1.9 and 2.0.
## Examples
The [Chemistry Toolkit Rosetta Wiki](http://ctr.wikia.com/wiki/Chemistry_Toolkit_Rosetta_Wiki) has a lot of examples you can check out.
### Creating a molecule
#### From a string
- require 'rubabel'
+```ruby
+require 'rubabel'
- # by default, reads in smiles strings
- serine = Rubabel["C(C(C(=O)O)N)O"]
- # more formally:
- serine = Rubabel::Molecule.from_string("C(C(C(=O)O)N)O")
+# by default, reads in smiles strings
+serine = Rubabel["C(C(C(=O)O)N)O"]
+# more formally:
+serine = Rubabel::Molecule.from_string("C(C(C(=O)O)N)O")
- # also any other format openbabel supports, for example inchi
- serine = Rubabel["InChI=1S/C3H7NO3/c4-2(1-5)3(6)7/h2,5H,1,4H2,(H,6,7)", :inchi]
+# also any other format openbabel supports, for example inchi
+serine = Rubabel["InChI=1S/C3H7NO3/c4-2(1-5)3(6)7/h2,5H,1,4H2,(H,6,7)", :inchi]
- # from the internet:
- mol = Rubabel[some_molecule, Rubabel.format_from_mime(some_mime_type)]
+# from the internet:
+mol = Rubabel[some_molecule, Rubabel.format_from_mime(some_mime_type)]
Find out all the formats Rubabel supports (hash is format key pointing to the description):
- hash = Rubabel.in_formats
- hash = Rubabel.out_formats
+hash = Rubabel.in_formats
+hash = Rubabel.out_formats
+```
#### From a file
Reading multiple entries from a file:
- Rubabel.foreach("file.sdf") do |mol|
- puts mol.exact_mass
- end
+```ruby
+Rubabel.foreach("file.sdf") do |mol|
+ puts mol.exact_mass
+end
+```
Foreach returns an enumerator that can be chained:
- # return an array of every unique atom type in the file
- uniq_atom_types = Rubabel.foreach("file.mol").flat_map {|mol| mol.map(&:type) }.uniq
+```ruby
+# return an array of every unique atom type in the file
+uniq_atom_types = Rubabel.foreach("file.mol").flat_map {|mol| mol.map(&:type) }.uniq
+```
Read a single molecule from a file (reads only the first molecule)
- mol = Rubabel::Molecule.from_file("file.sdf")
- # handles gzipped files seamlessly:
- mol = Rubabel::Molecule.from_file("file.sdf.gz")
- mol = Rubabel.molecule_from_file("file.sdf") # alternative
+```ruby
+mol = Rubabel::Molecule.from_file("file.sdf")
+# handles gzipped files seamlessly:
+mol = Rubabel::Molecule.from_file("file.sdf.gz")
+mol = Rubabel.molecule_from_file("file.sdf") # alternative
- # explicit format for uninformative/wrong extensions:
- mol = Rubabel::Molecule.from_file("file", :sdf)
+# explicit format for uninformative/wrong extensions:
+mol = Rubabel::Molecule.from_file("file", :sdf)
+```
### Writing/Drawing
#### create string output
- mol = Rubabel["OCC"] # ethanol
+```ruby
+mol = Rubabel["OCC"] # ethanol
- mol.to_s # canonical smiles -> "CCO"
- mol.csmiles # same thing
+mol.to_s # canonical smiles -> "CCO"
+mol.csmiles # same thing
- mol.to_s(:smi) # smiles -> "OCC"
- mol.smiles # same thing
+mol.to_s(:smi) # smiles -> "OCC"
+mol.smiles # same thing
+```
For inclusion in a file with standard smiles formatting (SMILES\tID\n):
- can_smiles_string = mol.write_string # -> "CCO\t\n"
- mol.title = "ethanol"
- can_smiles_string = mol.write(:can) # -> "CCO\tethanol\n"
+```ruby
+can_smiles_string = mol.write_string # -> "CCO\t\n"
+mol.title = "ethanol"
+can_smiles_string = mol.write(:can) # -> "CCO\tethanol\n"
+```
Other formats in the same manner:
- pdb_string = mol.write(:pdb)
+```ruby
+pdb_string = mol.write(:pdb)
+```
Write to a file directly (single molecule only; depends on file extension for type):
- # write to a smiles file
- mol.write("file.smi")
- mol.write_file("file.smi")
+```ruby
+# write to a smiles file
+mol.write("file.smi")
+mol.write_file("file.smi")
+```
Write multiple molecules to a file:
- File.open("somefile.pdb", 'w') do |out|
- molecules.each {|mol| out.print mol.write(:pdb) }
- end
+```ruby
+File.open("somefile.pdb", 'w') do |out|
+ molecules.each {|mol| out.print mol.write(:pdb) }
+end
+```
#### Drawing
If you write to svg or png (png uses mini_magick to convert from svg) then the
molecule is automatically drawn in 2D:
- mol = Rubabel["NCC(O)C(=O)O"]
- mol.write("file.svg")
+```ruby
+mol = Rubabel["NCC(O)C(=O)O"]
+mol.write("file.svg")
- # must have imagemagick ('convert' command) and mini_magick gem installed
- mol.write("file.png")
+# must have imagemagick ('convert' command) and mini_magick gem installed
+mol.write("file.png")
+```
### Searching and Splitting
*each_match*, *matches*, *matches?*, *smarts_indices* all take the same input (SMARTS
string or object and optional boolean specifying uniqueness of results):
- mol = Rubabel["NCC(O)C(=O)O"]
- mol.each_match("CO") do |match|
- # match is just an array of atoms that matched
- match.first.el # => :c
- match.last.el # => :o
- end
-
- # matches returns all the matches in an array
- all_matches = mol.matches("CO")
- # all the match routines take a boolean to alter uniqueness
- all_matches = mol.matches("CO", false) # some matches may not be uniq
+```ruby
+mol = Rubabel["NCC(O)C(=O)O"]
+mol.each_match("CO") do |match|
+ # match is just an array of atoms that matched
+ match.first.el # => :C
+ match.last.el # => :O
+end
+# matches returns all the matches in an array
+all_matches = mol.matches("CO")
+# all the match routines take a boolean to alter uniqueness
+all_matches = mol.matches("CO", false) # some matches may not be uniq
+```
+
Have some bonds to break?, split makes new molecules split from that bond(s)
-
- bonds = mol.matches("CO").map {|c, o| c.get_bond(o) }
- mol.split(*bonds) # splits between every carbon single bonded to oxygen
+```ruby
+bonds = mol.matches("CO").map {|c, o| c.get_bond(o) }
+mol.split(*bonds) # splits between every carbon single bonded to oxygen
+```
+
### Add, delete, modify atoms/bonds
#### Adding
- mol = Rubabel["OCC"]
- # adds a carbon, then an oxygen to last indexed atom by atomic number
- mol << 6 << 8 # #<Mol "OCCCO">
- mol << :c << :o # same thing
+```ruby
+mol = Rubabel["OCC"]
+# adds a carbon, then an oxygen to the previous carbon
+mol << 6 << 8 # #<Mol "OCCCO">
+mol << :C << :O # same thing
- # add an ethyl group specifically to second carbon
- mol = Rubabel["OCC"]
- mol[1] << :c << :c
+# add an ethyl group specifically to second atom (the first carbon)
+mol = Rubabel["OCC"]
+mol[1] << :C << :C
- # add a vinyl group to second carbon (use method notation and parenthesis
- # because we are going to specify 2 arguments (the bond order):
- ( mol[1] << :c).<<(:c, 2)
+# add a vinyl group to second carbon (use method notation and parenthesis
+# because we are going to specify 2 arguments (the bond order):
+( mol[1] << :C).<<(:C, 2)
+```
#### Deleting
- # delete an atom:
- mol = Rubabel["NCO"]
- mol.delete(mol[0]) # -> #<Mol CO>
+```ruby
+# delete an atom:
+mol = Rubabel["NCO"]
+mol.delete(mol[0])
+# mol.to_s -> #<Mol CO>
- # delete a bond:
- bond = mol[0].get_bond(mol[1])
- mol.delete(bond) # -> #<Mol C.O>
+# delete a bond:
+bond = mol[0].get_bond(mol[1])
+mol.delete(bond)
+# mol.to_s -> #<Mol C.O>
+```
#### Modifying
-Can add or subtract from bonds to change bond order:
+Can easily change the bond order:
- mol = Rubabel["CC"]
- mol[0].get_bond(mol[1]) + 1 # now it is a double bond
- bond = mol[0].bonds.first
- bond - 1
- bond.bond_order # => 1
+```ruby
+mol = Rubabel["CC"]
+bond = mol[0].get_bond(mol[1]) # get the bond you want
+bond = mol[0].bonds.first # alternate way to get at bonds
+bond += 2 # now it is a triple bond
+bond.dec! # now a double bond
+bond -= 1 # now a single bond
+bond.inc!(2) # back to a triple bond
+```
+
## Installing
First, many thanks to Andreas Maunz for packaging openbabel as a gem which makes this install quite painless.
### Quick Install
On a POSIX system, make sure you have openbabel (including header files), cmake, curl, tar, sed and make {see openbabel instructions}[https://github.com/amaunz/openbabel-gem]. On ubuntu/debian:
- sudo apt-get install openbabel libopenbabel-dev cmake make curl
+```bash
+sudo apt-get install openbabel libopenbabel-dev cmake make curl
+```
Then install the gem (which should install the openbabel gem, too):
- gem install rubabel
+```bash
+gem install rubabel
+```
### Building from Source
1. download openbabel
2. swap out Init_OpenBabel for Init_openbabel in scripts/ruby/openbabel-ruby.cpp (see [here](http://forums.openbabel.org/Ruby-Open-Babel-in-2-1-1-td957640.html)). Some versions have this fixed already, apparently.
3. make sure you have the right [dependencies to compile](http://openbabel.org/docs/2.3.1/Installation/install.html#compiling-open-babel)
Here's a complete example of compiling for a single user on Ubuntu 11.10 and probably will be generally forward compatible for some time. This will compile bindings on whichever ruby comes up with '/usr/bin/env ruby':
- # install the dependencies:
- sudo apt-get install libeigen2-dev cmake libwxgtk2.8-dev libxml2-dev libcairo2-dev
- # unpack it:
- tar -xzvf openbabel-2.3.1.tar.gz
- # swap out buggy lines in ruby bindings:
- sed -i 's/Init_OpenBabel/Init_openbabel/g' openbabel-2.3.1/scripts/ruby/openbabel-ruby.cpp
- # make a separate build directory for building in:
- mkdir build-rvmruby1.9.3
- cd build-rvmruby1.9.3
- mkdir ~/tools
- cmake ../openbabel-2.3.1 -DRUBY_BINDINGS=ON -DCMAKE_INSTALL_PREFIX=~/tools/openbabel-rvmruby1.9.3
- make && make install
+```bash
+# install the dependencies:
+sudo apt-get install libeigen2-dev cmake libwxgtk2.8-dev libxml2-dev libcairo2-dev
+# unpack it:
+tar -xzvf openbabel-2.3.1.tar.gz
+# swap out buggy lines in ruby bindings:
+sed -i 's/Init_OpenBabel/Init_openbabel/g' openbabel-2.3.1/scripts/ruby/openbabel-ruby.cpp
+# make a separate build directory for building in:
+mkdir build-rvmruby1.9.3
+cd build-rvmruby1.9.3
+mkdir ~/tools
+cmake ../openbabel-2.3.1 -DRUBY_BINDINGS=ON -DCMAKE_INSTALL_PREFIX=~/tools/openbabel-rvmruby1.9.3
+make && make install
+```
+## See also
-[[Still need directions to install the gem on top of a build from source]]
-
+* [Rubidium](http://rbtk.rubyforge.org/) (based on the Chemistry Development Kit [jruby])
+* [ChemRuby](https://github.com/ank/chemruby) [standalone using MRI extensions]
+* [Chemcaster Ruby API](https://github.com/metamolecular/chemcaster-ruby)
+
## Copyright
MIT License. See LICENSE for further details.