# rubabel 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). ## 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' # 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] # 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 #### From a file Reading multiple entries from a file: 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 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 # explicit format for uninformative/wrong extensions: mol = Rubabel::Molecule.from_file("file", :sdf) ### Writing/Drawing #### create string output mol = Rubabel["OCC"] # ethanol mol.to_s # canonical smiles -> "CCO" mol.csmiles # 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" Other formats in the same manner: 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") Write multiple molecules to a file: 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") # 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 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 ### Add & Delete 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 # add an ethyl group specifically to second 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) #### Deleting # delete an atom: mol = Rubabel["NCO"] mol.delete(mol[0]) # -> #<Mol CO> # delete a bond: bond = mol[0].get_bond(mol[1]) mol.delete(bond) # -> #<Mol C.O> ## 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 Then install the gem (which should install the openbabel gem, too): 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 [[Still need directions to install the gem on top of a build from source]] ## Copyright MIT License. See LICENSE for further details.