rubabel 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2012 Brigham Young University
2
+ authored by: John T. Prince
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,52 @@
1
+ = rubabel
2
+
3
+ Ruby interface to the openbabel ruby bindings (or the openbabel gem). The
4
+ interface attempts to be a ruby-ish analogue of
5
+ {pybel}[http://openbabel.org/docs/current/UseTheLibrary/Python_PybelAPI.html].
6
+
7
+ == Examples
8
+
9
+ Rubabel.foreach("file.sdf") do |mol|
10
+ print mol.write # -> canonical smiles: "smiles_string\tname\n"
11
+ puts mol # .to_s -> canonical smiles string with no name or newline
12
+ puts mol.exact_mass
13
+ end
14
+
15
+ uniq_atom_types = Rubabel.foreach("file.mol").map(&:type).uniq
16
+
17
+ == Installing
18
+
19
+ === Install openbabel
20
+
21
+ First, make sure you have the ruby openbabel bindings properly installed. You can do this by {properly installing the gem][https://github.com/amaunz/openbabel-gem]. Alternatively, you can following these instructions to build from source:
22
+
23
+ 1. download openbabel
24
+ 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.
25
+ 3. make sure you have the right {dependencies to compile}(http://openbabel.org/docs/2.3.1/Installation/install.html#compiling-open-babel)
26
+
27
+ 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':
28
+
29
+ # install the dependencies:
30
+ sudo apt-get install libeigen2-dev cmake libwxgtk2.8-dev libxml2-dev libcairo2-dev
31
+ # unpack it:
32
+ tar -xzvf openbabel-2.3.1.tar.gz
33
+ # swap out buggy lines in ruby bindings:
34
+ sed -i 's/Init_OpenBabel/Init_openbabel/g' openbabel-2.3.1/scripts/ruby/openbabel-ruby.cpp
35
+ # make a separate build directory for building in:
36
+ mkdir build-rvmruby1.9.3
37
+ cd build-rvmruby1.9.3
38
+ mkdir ~/tools
39
+ cmake ../openbabel-2.3.1 -DRUBY_BINDINGS=ON -DCMAKE_INSTALL_PREFIX=~/tools/openbabel-rvmruby1.9.3
40
+ make && make install
41
+
42
+ === Install the gem
43
+
44
+ gem install rubabel
45
+
46
+ Assuming you have the {dependencies for the openbabel gem}[https://github.com/amaunz/openbabel-gem], you could install in one go like this:
47
+
48
+ gem install openbabel rubabel
49
+
50
+ == Copyright
51
+
52
+ MIT License. See LICENSE for further details.
data/Rakefile ADDED
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'rake'
5
+
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |gem|
8
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
9
+ gem.name = "rubabel"
10
+ gem.homepage = "http://github.com/princelab/rubabel"
11
+ gem.license = "MIT"
12
+ gem.summary = %Q{Ruby interface to the OpenBabel ruby bindings similar to pybel}
13
+ gem.description = %Q{Ruby interface to the openbabel ruby bindings (or the openbabel gem). The
14
+ interface attempts to be a ruby-ish analogue of pybel.}
15
+ gem.email = "jtprince@gmail.com"
16
+ gem.authors = ["John T. Prince"]
17
+ [
18
+ ["rspec", "~> 2.8.0"],
19
+ ["rdoc", "~> 3.12"],
20
+ ["jeweler", "~> 1.8.3"]
21
+ ].each do |name, version_string|
22
+ gem.add_development_dependency(name, version_string)
23
+ end
24
+ end
25
+ Jeweler::RubygemsDotOrgTasks.new
26
+
27
+ require 'rspec/core'
28
+ require 'rspec/core/rake_task'
29
+ RSpec::Core::RakeTask.new(:spec) do |spec|
30
+ spec.pattern = FileList['spec/**/*_spec.rb']
31
+ end
32
+
33
+ task :default => :spec
34
+
35
+ require 'rdoc/task'
36
+ Rake::RDocTask.new do |rdoc|
37
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
38
+
39
+ rdoc.rdoc_dir = 'rdoc'
40
+ rdoc.title = "rubabel #{version}"
41
+ rdoc.rdoc_files.include('README*')
42
+ rdoc.rdoc_files.include('lib/**/*.rb')
43
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/lib/rubabel.rb ADDED
@@ -0,0 +1,116 @@
1
+ require 'openbabel'
2
+
3
+ %w(atom molecule fingerprint smarts molecule_data).each do |klass|
4
+ require "rubabel/#{klass}"
5
+ end
6
+
7
+ module Rubabel
8
+ # the command to execute the utility. They are initialized to be eponymous.
9
+ CMD = {
10
+ babel: 'babel',
11
+ obabel: 'obabel',
12
+ }
13
+
14
+ class << self
15
+
16
+ # returns a hash keyed by type (Symbol) pointing to a description of the
17
+ # format
18
+ def in_formats
19
+ @in_formats ||= formats_to_hash(OpenBabel::OBConversion.new.get_supported_input_format)
20
+ end
21
+
22
+ # returns a hash keyed by type (Symbol) pointing to a description of the
23
+ # format
24
+ def out_formats
25
+ @out_formats ||= formats_to_hash(OpenBabel::OBConversion.new.get_supported_output_format)
26
+ end
27
+
28
+ # determines the extension from filename if type is nil
29
+ def foreach(filename, type=nil, &block)
30
+ block or return enum_for(__method__, filename, type)
31
+ (obmol, obconv, not_at_end) = read_first_obmol(filename, type)
32
+ # the obmol is not valid if we are already at the end!
33
+ while not_at_end
34
+ block.call Rubabel::Molecule.new(obmol)
35
+ obmol = OpenBabel::OBMol.new
36
+ not_at_end = obconv.read(obmol)
37
+ end
38
+ end
39
+
40
+ # returns a Rubabel::Molecule (the first in the file if there are
41
+ # multiples). See ::foreach for accessing all molecules in a file
42
+ # determines the type from the extension if type is nil.
43
+ def read_file(filename, type=nil)
44
+ obmol = read_first_obmol(filename, type).first
45
+ Rubabel::Molecule.new(obmol)
46
+ end
47
+
48
+ # reads one molecule from the string
49
+ def read_string(string, type=:smi)
50
+ obmol = OpenBabel::OBMol.new
51
+ obconv = OpenBabel::OBConversion.new
52
+ obconv.set_in_format(type.to_s) || raise(ArgumentError, "invalid format #{type}")
53
+ success = obconv.read_string(obmol, string)
54
+ Rubabel::Molecule.new(obmol)
55
+ end
56
+
57
+ # returns a filetype symbol based on the extension
58
+ def filetype(filename)
59
+ # should use the openbabel method in the future
60
+ File.extname(filename)[1..-1].to_sym
61
+ end
62
+
63
+ private
64
+ # reads the first entry and returns the OBMol object, the OBConversion object,
65
+ # and the boolean not_at_end. This method is not intended for public usage
66
+ # but is necessary based on discrepancies between accessing the first
67
+ # molecule and subsequent molecules.
68
+ def read_first_obmol(filename, type=nil)
69
+ type ||= filetype(filename)
70
+ obconv = OpenBabel::OBConversion.new
71
+ obconv.set_in_format(type.to_s) || raise(ArgumentError, "invalid format #{type}")
72
+ obmol = OpenBabel::OBMol.new
73
+ not_at_end = obconv.read_file(obmol, filename)
74
+ [obmol, obconv, not_at_end]
75
+ end
76
+
77
+ def formats_to_hash(format_strings)
78
+ Hash[
79
+ format_strings.map do |str|
80
+ pair = str.split(/\s+--\s+/)
81
+ [pair[0].to_sym, pair[1]]
82
+ end
83
+ ]
84
+ end
85
+ end
86
+
87
+ #protected_class_method :read_first_obmol
88
+
89
+ end
90
+
91
+ module Rubabel
92
+ # capitalized strings
93
+ ELEMENTS = %w(H He Li Be B C N O F Ne Na Mg Al Si P S Cl Ar K Ca Sc Ti V Cr Mn Fe Co Ni Cu Zn Ga Ge As Se Br Kr Rb Sr Y Zr Nb Mo Tc Ru Rh Pd Ag Cd In Sn Sb Te I Xe Cs Ba La Ce Pr Nd Pm Sm Eu Gd Tb Dy Ho Er Tm Yb Lu Hf Ta W Re Os Ir Pt Au Hg Tl Pb Bi Po At Rn Fr Ra Ac Th Pa U Np Pu Am Cm Bk Cf Es Fm Md No Lr Rf Db Sg Bh Hs Mt Ds Rg Cn Uut Fl Uup Lv Uus Uuo)
94
+
95
+ # atomic number to properly capitalized element abbreviation
96
+ NUM_TO_ELEMENT = Hash[ ELEMENTS.each_with_index.map {|el,i| [i+1,el] } ]
97
+
98
+ # atomic number to lowercase symbol abbreviation
99
+ NUM_TO_EL = Hash[ ELEMENTS.each_with_index.map {|el,i| [i+1,el.downcase.to_sym] } ]
100
+ end
101
+
102
+ =begin
103
+ OBConversion conv;
104
+ OBMol mol;
105
+ bool success = conv.SetInFormat("sdf");
106
+ if(success)
107
+ {
108
+ bool notatend = conv.ReadFile(&mol, "myfile.sdf");
109
+ // Do something with mol
110
+ while(notatend)
111
+ {
112
+ notatend = conv.Read(&mol);
113
+ // Do something with mol
114
+ }
115
+ }
116
+ =end
@@ -0,0 +1,143 @@
1
+ require 'matrix'
2
+
3
+ require 'rubabel/bond'
4
+
5
+ class OpenBabel::OBAtom
6
+ def upcast
7
+ Rubabel::Atom.new(self)
8
+ end
9
+ end
10
+
11
+ module Rubabel
12
+ class Atom
13
+ include Enumerable
14
+
15
+ # the OpenBabel::OBAtom object
16
+ attr_accessor :ob
17
+
18
+ def initialize(obatom)
19
+ @ob = obatom
20
+ end
21
+
22
+ def id
23
+ @ob.get_id
24
+ end
25
+
26
+ def id=(val)
27
+ @ob.set_id(val)
28
+ end
29
+
30
+ # index of the atom (begins with 1)
31
+ def idx
32
+ @ob.get_idx
33
+ end
34
+
35
+ # abbreviated name, all lowercase as a Symbol
36
+ def el
37
+ NUM_TO_EL[atomic_num]
38
+ end
39
+
40
+ # abbreviated name, properly capitalized and as a String
41
+ def element
42
+ NUM_TO_ELEMENT[atomic_num]
43
+ end
44
+
45
+ def each_bond(&block)
46
+ block or return enum_for(__method__)
47
+ iter = @ob.begin_bonds
48
+ _bond = @ob.begin_bond(iter)
49
+ while _bond
50
+ block.call _bond.upcast
51
+ _bond = @ob.next_bond(iter)
52
+ end
53
+ end
54
+
55
+ alias_method :each, :each_bond
56
+
57
+ # returns the bonds. Consider using each_bond.
58
+ def bonds
59
+ each_bond.map.to_a
60
+ end
61
+
62
+ # iterates through each neighboring atom
63
+ def each_atom(&block)
64
+ block or return enum_for(__method__)
65
+ iter = @ob.begin_bonds
66
+ _atom = @ob.begin_nbr_atom(iter)
67
+ while _atom
68
+ block.call _atom.upcast
69
+ _atom = @ob.next_nbr_atom(iter)
70
+ end
71
+ end
72
+
73
+ # returns the neighboring atoms. Consider using each_atom.
74
+ def atoms
75
+ each_atom.map.to_a
76
+ end
77
+
78
+ def atomic_mass
79
+ @ob.get_atomic_mass
80
+ end
81
+
82
+ def atomic_num
83
+ @ob.get_atomic_num
84
+ end
85
+
86
+ def exact_mass
87
+ @ob.get_exact_mass
88
+ end
89
+
90
+ def formal_charge
91
+ @ob.get_formal_charge
92
+ end
93
+ alias_method :charge, :formal_charge
94
+
95
+ def heavy_valence
96
+ @ob.get_heavy_valence
97
+ end
98
+
99
+ def hetero_valence
100
+ @ob.get_hetero_valence
101
+ end
102
+
103
+ def hyb
104
+ @ob.get_hybridization
105
+ end
106
+
107
+ def implicit_valence
108
+ @ob.get_implicit_valence
109
+ end
110
+
111
+ def isotope
112
+ @ob.get_isotope
113
+ end
114
+
115
+ def partial_charge
116
+ @ob.get_partial_charge
117
+ end
118
+
119
+ def spin
120
+ @ob.get_spin_multiplicity
121
+ end
122
+
123
+ def type
124
+ @ob.get_type
125
+ end
126
+
127
+ def valence
128
+ @ob.get_valence
129
+ end
130
+
131
+ def vector
132
+ @ob.get_vector
133
+ end
134
+
135
+ def coords
136
+ Vector[@ob.x, @ob.y, @ob.z]
137
+ end
138
+
139
+ def inspect
140
+ "<#{type} id:#{id}>"
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,47 @@
1
+ require 'rubabel/atom'
2
+
3
+ class OpenBabel::OBBond
4
+ def upcast
5
+ Rubabel::Bond.new(self)
6
+ end
7
+ end
8
+
9
+
10
+ module Rubabel
11
+
12
+ # delegates to obbond object if the method is missing
13
+ class Bond
14
+ include Enumerable
15
+
16
+ attr_accessor :ob
17
+
18
+ def initialize(obbond)
19
+ @ob = obbond
20
+ end
21
+
22
+ # considered included if the atom ids match
23
+ def include?(atom)
24
+ # atoms.any? {|atm| atom.id == atm.id }
25
+ (@ob.get_begin_atom.get_id == atom.id) || (@ob.get_end_atom.get_id == atom.id)
26
+ end
27
+
28
+ def each_atom(&block)
29
+ block or return enum_for(__method__)
30
+ block.call @ob.get_begin_atom.upcast
31
+ block.call @ob.get_end_atom.upcast
32
+ self
33
+ end
34
+
35
+ alias_method :each, :each_atom
36
+
37
+ # returns an array of Rubabel::Atoms
38
+ def atoms
39
+ [@ob.get_begin_atom.upcast, @ob.get_end_atom.upcast]
40
+ end
41
+
42
+ def inspect
43
+ "[#{atoms.map(&:inspect).join('-')}]"
44
+ end
45
+
46
+ end
47
+ end
File without changes
@@ -0,0 +1,23 @@
1
+
2
+ module Rubabel
3
+ class Fragmentation
4
+
5
+ ADDUCTS = [:lioh, :nh4cl, :nh4oh]
6
+
7
+ DEFAULTS = {
8
+ ph: 7.4,
9
+ adducts: [],
10
+ }
11
+
12
+ def initialize(mol, options)
13
+ @mol = mol
14
+ @options = options
15
+ end
16
+
17
+ def fragment(rules=[:co])
18
+ end
19
+
20
+
21
+
22
+ end
23
+ end