rubabel 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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