rubabel 0.1.5 → 0.1.6
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/Rakefile +2 -1
- data/VERSION +1 -1
- data/lib/rubabel.rb +4 -9
- data/lib/rubabel/atom.rb +5 -4
- data/lib/rubabel/molecule.rb +293 -52
- data/spec/chemistry_toolkit_rosetta/chemistry_toolkit_rosetta_spec.rb +152 -22
- data/spec/chemistry_toolkit_rosetta/key/3016_highlighted.rubabel.frozen.png +0 -0
- data/spec/chemistry_toolkit_rosetta/key/caffeine.frozen.png +0 -0
- data/spec/chemistry_toolkit_rosetta/tpsa.tab +44 -0
- data/spec/rubabel/atom_spec.rb +0 -2
- data/spec/rubabel/molecule_spec.rb +36 -0
- metadata +21 -3
- data/rubabel.gemspec +0 -100
data/Rakefile
CHANGED
@@ -16,7 +16,8 @@ interface attempts to be a ruby-ish analogue of pybel.}
|
|
16
16
|
gem.authors = ["John T. Prince"]
|
17
17
|
[
|
18
18
|
["openbabel", "~> 2.3.1.2"],
|
19
|
-
["andand", "~> 1.3.3"]
|
19
|
+
["andand", "~> 1.3.3"],
|
20
|
+
["mini_magick", "~> 3.4"]
|
20
21
|
].each do |args|
|
21
22
|
gem.add_dependency(*args)
|
22
23
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.6
|
data/lib/rubabel.rb
CHANGED
@@ -66,7 +66,7 @@ module Rubabel
|
|
66
66
|
(obmol, obconv, not_at_end) = read_first_obmol(filename, type)
|
67
67
|
# the obmol is not valid if we are already at the end!
|
68
68
|
while not_at_end
|
69
|
-
block.call Rubabel::Molecule.new(obmol
|
69
|
+
block.call Rubabel::Molecule.new(obmol)
|
70
70
|
obmol = OpenBabel::OBMol.new
|
71
71
|
not_at_end = obconv.read(obmol)
|
72
72
|
end
|
@@ -77,19 +77,14 @@ module Rubabel
|
|
77
77
|
# determines the type from the extension if type is nil.
|
78
78
|
def molecule_from_file(filename, type=nil)
|
79
79
|
(obmol, obconv, not_at_end) = read_first_obmol(filename, type).first
|
80
|
-
Rubabel::Molecule.new(obmol
|
80
|
+
Rubabel::Molecule.new(obmol)
|
81
81
|
end
|
82
82
|
|
83
83
|
# reads one molecule from the string
|
84
|
-
def molecule_from_string(string, type
|
85
|
-
|
86
|
-
obconv = OpenBabel::OBConversion.new
|
87
|
-
obconv.set_in_format(type.to_s) || raise(ArgumentError, "invalid format #{type}")
|
88
|
-
obconv.read_string(obmol, string) || raise(ArgumentError, "invalid string" )
|
89
|
-
Rubabel::Molecule.new(obmol, obconv)
|
84
|
+
def molecule_from_string(string, type=Rubabel::Molecule::DEFAULT_IN_TYPE)
|
85
|
+
Rubabel::Molecule.from_string(string, type)
|
90
86
|
end
|
91
87
|
|
92
|
-
private
|
93
88
|
# reads the first entry and returns the OBMol object, the OBConversion object,
|
94
89
|
# and the boolean not_at_end. This method is not intended for public usage
|
95
90
|
# but is necessary based on discrepancies between accessing the first
|
data/lib/rubabel/atom.rb
CHANGED
@@ -14,11 +14,12 @@ module Rubabel
|
|
14
14
|
include Enumerable
|
15
15
|
|
16
16
|
class << self
|
17
|
-
# takes an element symbol and creates that atom
|
18
|
-
|
17
|
+
# takes an element symbol and creates that atom. If el_sym is set to
|
18
|
+
# nil or 0, then an atom of atomic number 0 is used
|
19
|
+
def [](el_sym=:h, id=nil)
|
19
20
|
ob_atom = OpenBabel::OBAtom.new
|
20
|
-
ob_atom.set_id(id)
|
21
|
-
ob_atom.set_atomic_num(Rubabel::EL_TO_NUM[el_sym])
|
21
|
+
ob_atom.set_id(id) if id
|
22
|
+
ob_atom.set_atomic_num(Rubabel::EL_TO_NUM[el_sym] || 0)
|
22
23
|
self.new(ob_atom)
|
23
24
|
end
|
24
25
|
end
|
data/lib/rubabel/molecule.rb
CHANGED
@@ -3,6 +3,8 @@ require 'rubabel'
|
|
3
3
|
require 'rubabel/atom'
|
4
4
|
require 'rubabel/bond'
|
5
5
|
require 'rubabel/molecule/fragmentable'
|
6
|
+
require 'stringio'
|
7
|
+
require 'mini_magick'
|
6
8
|
|
7
9
|
class OpenBabel::OBMol
|
8
10
|
def upcast
|
@@ -10,11 +12,65 @@ class OpenBabel::OBMol
|
|
10
12
|
end
|
11
13
|
end
|
12
14
|
|
15
|
+
class OpenBabel::OBConversion
|
16
|
+
OUT_OPTS_SHORT = {
|
17
|
+
no_element_coloring: :u,
|
18
|
+
no_internal_specified_color: :U,
|
19
|
+
black_bkg: :b,
|
20
|
+
no_terminal_c: :C,
|
21
|
+
draw_all_carbon: :a,
|
22
|
+
no_molecule_name: :d,
|
23
|
+
embed_mol_as_cml: :e,
|
24
|
+
scale_to_bondlength_pixels: :p,
|
25
|
+
size: :P, # single number of pixels (e.g., 300, but will take dims for png: ('300x250'))
|
26
|
+
add_atom_index: :i,
|
27
|
+
no_javascript: :j,
|
28
|
+
wedge_hash_bonds: :w,
|
29
|
+
no_xml_declaration: :x,
|
30
|
+
aliases: :A,
|
31
|
+
}
|
32
|
+
|
33
|
+
# adds the opts to the type, where type is :gen, :out, or :in.
|
34
|
+
# takes opts as either a hash or a list:
|
35
|
+
#
|
36
|
+
# # hash
|
37
|
+
# obconv.add_opts!(:out, d: true, u: true, p: 10 )
|
38
|
+
#
|
39
|
+
# # list
|
40
|
+
# obconv.add_opts!(:out, :d, :u, [:p, 10] )
|
41
|
+
#
|
42
|
+
# returns self
|
43
|
+
def add_opts!(type=:gen, *opts)
|
44
|
+
opt_type = OpenBabel::OBConversion.const_get(type.to_s.upcase.<<("OPTIONS"))
|
45
|
+
hash =
|
46
|
+
if opts.first.is_a?(Hash)
|
47
|
+
opts.first
|
48
|
+
else
|
49
|
+
opts.inject({}) do |hsh,v|
|
50
|
+
if v.is_a?(Array)
|
51
|
+
hsh[v[0]] = v[1]
|
52
|
+
else
|
53
|
+
hsh[v] = true
|
54
|
+
end
|
55
|
+
hsh
|
56
|
+
end
|
57
|
+
end
|
58
|
+
hash.each do |k,v|
|
59
|
+
next if v == false
|
60
|
+
args = [ (OUT_OPTS_SHORT[k] || k).to_s, opt_type ]
|
61
|
+
if v && (v != true)
|
62
|
+
args << v
|
63
|
+
end
|
64
|
+
self.add_option(*args)
|
65
|
+
end
|
66
|
+
self
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
13
70
|
class OpenBabelUnableToSetupForceFieldError < RuntimeError
|
14
71
|
end
|
15
72
|
|
16
73
|
module Rubabel
|
17
|
-
# yet to implement:
|
18
74
|
class Molecule
|
19
75
|
include Enumerable
|
20
76
|
|
@@ -25,9 +81,6 @@ module Rubabel
|
|
25
81
|
# the OpenBabel::OBmol object
|
26
82
|
attr_accessor :ob
|
27
83
|
|
28
|
-
# the OpenBabel::OBConversion object
|
29
|
-
attr_accessor :obconv
|
30
|
-
|
31
84
|
class << self
|
32
85
|
|
33
86
|
def tanimoto(mol1, mol2, type=DEFAULT_FINGERPRINT)
|
@@ -35,11 +88,16 @@ module Rubabel
|
|
35
88
|
end
|
36
89
|
|
37
90
|
def from_file(file, type=nil)
|
38
|
-
Rubabel.
|
91
|
+
(obmol, obconv, not_at_end) = Rubabel.read_first_obmol(file, type).first
|
92
|
+
Rubabel::Molecule.new(obmol)
|
39
93
|
end
|
40
94
|
|
41
95
|
def from_string(string, type=DEFAULT_IN_TYPE)
|
42
|
-
|
96
|
+
obmol = OpenBabel::OBMol.new
|
97
|
+
obconv = OpenBabel::OBConversion.new
|
98
|
+
obconv.set_in_format(type.to_s) || raise(ArgumentError, "invalid format #{type}")
|
99
|
+
obconv.read_string(obmol, string) || raise(ArgumentError, "invalid string" )
|
100
|
+
self.new(obmol)
|
43
101
|
end
|
44
102
|
|
45
103
|
def from_atoms_and_bonds(atoms=[], bonds=[])
|
@@ -50,8 +108,13 @@ module Rubabel
|
|
50
108
|
end
|
51
109
|
end
|
52
110
|
|
53
|
-
|
54
|
-
|
111
|
+
# arg is an atomic number. returns the newly created atom
|
112
|
+
def add_atom!(atomic_num=1)
|
113
|
+
# jtp implementation:
|
114
|
+
# @ob.add_atom(atom.ob)
|
115
|
+
new_a = @ob.new_atom
|
116
|
+
new_a.set_atomic_num(atomic_num)
|
117
|
+
Rubabel::Atom.new(new_a)
|
55
118
|
end
|
56
119
|
|
57
120
|
def delete_atom(atom)
|
@@ -82,34 +145,35 @@ module Rubabel
|
|
82
145
|
def formula() @ob.get_formula end
|
83
146
|
|
84
147
|
|
85
|
-
def initialize(obmol
|
148
|
+
def initialize(obmol)
|
86
149
|
@ob = obmol
|
87
|
-
@obconv = obconv
|
88
150
|
end
|
89
151
|
|
90
|
-
# returns a list of atom indices matching the patterns (corresponds to
|
91
|
-
#
|
92
|
-
#
|
93
|
-
# returns the zero indexed
|
94
|
-
|
152
|
+
# returns a list of atom indices matching the patterns (corresponds to the
|
153
|
+
# OBSmartsPattern::GetUMapList() method if uniq==true and GetMapList
|
154
|
+
# method if uniq==false). Note that the original GetUMapList returns atom
|
155
|
+
# *numbers* (i.e., the index + 1). This method returns the zero indexed
|
156
|
+
# indices.
|
157
|
+
def smarts_indices(smarts_or_string, uniq=true)
|
158
|
+
mthd = uniq ? :get_umap_list : :get_map_list
|
95
159
|
pattern = smarts_or_string.is_a?(Rubabel::Smarts) ? smarts_or_string : Rubabel::Smarts.new(smarts_or_string)
|
96
160
|
pattern.ob.match(@ob)
|
97
|
-
pattern.ob.
|
161
|
+
pattern.ob.send(mthd).map {|atm_indices| atm_indices.map {|i| i - 1 } }
|
98
162
|
end
|
99
163
|
|
100
164
|
# yields atom arrays matching the pattern. returns an enumerator if no
|
101
165
|
# block is given
|
102
|
-
def each_match(smarts_or_string, &block)
|
103
|
-
block or return enum_for(__method__, smarts_or_string)
|
166
|
+
def each_match(smarts_or_string, uniq=true, &block)
|
167
|
+
block or return enum_for(__method__, smarts_or_string, uniq)
|
104
168
|
_atoms = self.atoms
|
105
|
-
smarts_indices(smarts_or_string).each do |ar|
|
169
|
+
smarts_indices(smarts_or_string, uniq).each do |ar|
|
106
170
|
block.call(_atoms.values_at(*ar))
|
107
171
|
end
|
108
172
|
end
|
109
173
|
|
110
174
|
# returns an array of matching atom sets. Consider using each_match.
|
111
|
-
def matches(smarts_or_string)
|
112
|
-
each_match(smarts_or_string).map.to_a
|
175
|
+
def matches(smarts_or_string, uniq=true)
|
176
|
+
each_match(smarts_or_string, uniq).map.to_a
|
113
177
|
end
|
114
178
|
|
115
179
|
def matches?(smarts_or_string)
|
@@ -123,11 +187,11 @@ module Rubabel
|
|
123
187
|
end
|
124
188
|
|
125
189
|
#def conformers
|
126
|
-
|
127
|
-
|
128
|
-
|
190
|
+
# Currently returns an object of type
|
191
|
+
# SWIG::TYPE_p_std__vectorT_double_p_std__allocatorT_double_p_t_t
|
192
|
+
#vec = @ob.get_conformers
|
129
193
|
#end
|
130
|
-
|
194
|
+
|
131
195
|
# are there hydrogens added yet
|
132
196
|
def hydrogens_added?
|
133
197
|
@ob.has_hydrogens_added
|
@@ -145,6 +209,12 @@ module Rubabel
|
|
145
209
|
self
|
146
210
|
end
|
147
211
|
|
212
|
+
# only adds polar hydrogens. returns self
|
213
|
+
def add_polar_h!
|
214
|
+
@ob.add_polar_hydrogens
|
215
|
+
self
|
216
|
+
end
|
217
|
+
|
148
218
|
# returns self. If ph is nil, then #neutral! is called
|
149
219
|
def correct_for_ph!(ph=7.4)
|
150
220
|
ph.nil? ? neutral! : @ob.correct_for_ph(ph)
|
@@ -170,13 +240,13 @@ module Rubabel
|
|
170
240
|
# # creates a new molecule (currently writes to smiles and uses babel
|
171
241
|
# # commandline to get hydrogens at a given pH; this is because no pH model
|
172
242
|
# # in ruby bindings currently).
|
173
|
-
#
|
174
|
-
# ## write the file with the molecule
|
175
|
-
# #self.write_file("tmp.smi")
|
176
|
-
# #system "#{Rubabel::CMD[:babel]} -i smi tmp.smi -p #{ph} -o can tmp.can"
|
177
|
-
# #Molecule.from_file("tmp.can")
|
178
|
-
# end
|
179
|
-
# #alias_method :add_h!, :add_hydrogens!
|
243
|
+
#
|
244
|
+
# ## write the file with the molecule
|
245
|
+
# #self.write_file("tmp.smi")
|
246
|
+
# #system "#{Rubabel::CMD[:babel]} -i smi tmp.smi -p #{ph} -o can tmp.can"
|
247
|
+
# #Molecule.from_file("tmp.can")
|
248
|
+
# end
|
249
|
+
# #alias_method :add_h!, :add_hydrogens!
|
180
250
|
|
181
251
|
# returns self
|
182
252
|
def remove_h!
|
@@ -235,7 +305,6 @@ module Rubabel
|
|
235
305
|
def initialize_copy(source)
|
236
306
|
super
|
237
307
|
@ob = OpenBabel::OBMol.new(source.ob)
|
238
|
-
@obconv = OpenBabel::OBConversion.new(source.obconv)
|
239
308
|
self
|
240
309
|
end
|
241
310
|
|
@@ -265,7 +334,7 @@ module Rubabel
|
|
265
334
|
#end
|
266
335
|
|
267
336
|
def tanimoto(other, type=DEFAULT_FINGERPRINT)
|
268
|
-
Rubabel::Molecule.tanimoto(self, other, type)
|
337
|
+
other.nil? ? 0 : Rubabel::Molecule.tanimoto(self, other, type)
|
269
338
|
end
|
270
339
|
|
271
340
|
# returns a std::vector<unsigned int> that can be passed directly into
|
@@ -281,9 +350,9 @@ module Rubabel
|
|
281
350
|
def delete(obj)
|
282
351
|
case obj
|
283
352
|
when Rubabel::Bond
|
284
|
-
delete_bond(obj
|
353
|
+
delete_bond(obj)
|
285
354
|
when Rubabel::Atom
|
286
|
-
delete_atom(obj
|
355
|
+
delete_atom(obj)
|
287
356
|
else
|
288
357
|
raise(ArgumentError, "don't know how to delete objects of type: #{obj.class}")
|
289
358
|
end
|
@@ -305,7 +374,7 @@ module Rubabel
|
|
305
374
|
end
|
306
375
|
|
307
376
|
# takes a Rubabel::Bond object or a pair of Rubabel::Atom objects
|
308
|
-
def add_bond(*args)
|
377
|
+
def add_bond!(*args)
|
309
378
|
case args.size
|
310
379
|
when 1
|
311
380
|
ob_bond = args.first.ob
|
@@ -313,10 +382,11 @@ module Rubabel
|
|
313
382
|
ob_bond.get_begin_atom.add_bond(ob_bond)
|
314
383
|
ob_bond.get_end_atom.add_bond(ob_bond)
|
315
384
|
when 2
|
316
|
-
|
317
|
-
ob_bond.
|
318
|
-
ob_bond.
|
319
|
-
|
385
|
+
@ob.add_bond(args[0].idx, args[1].idx, args[2] || 1)
|
386
|
+
#ob_bond = Rubabel::Bond[ *args ].ob
|
387
|
+
#ob_bond.get_begin_atom.add_bond(ob_bond)
|
388
|
+
#ob_bond.get_end_atom.add_bond(ob_bond)
|
389
|
+
#@ob.add_bond(ob_bond)
|
320
390
|
end
|
321
391
|
end
|
322
392
|
|
@@ -372,11 +442,11 @@ module Rubabel
|
|
372
442
|
# If filename_or_type is a symbol, then it will return a string of that type.
|
373
443
|
# If filename_or_type is a string, will write to the filename
|
374
444
|
# given no args, returns a DEFAULT_OUT_TYPE string
|
375
|
-
def write(filename_or_type=:can)
|
445
|
+
def write(filename_or_type=:can, out_options={})
|
376
446
|
if filename_or_type.is_a?(Symbol)
|
377
|
-
write_string(filename_or_type)
|
447
|
+
write_string(filename_or_type, out_options)
|
378
448
|
else
|
379
|
-
write_file(filename_or_type)
|
449
|
+
write_file(filename_or_type, out_options)
|
380
450
|
end
|
381
451
|
end
|
382
452
|
|
@@ -413,23 +483,116 @@ module Rubabel
|
|
413
483
|
end
|
414
484
|
alias_method :make3d!, :make_3d!
|
415
485
|
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
486
|
+
# yields the type of object. Expects the block to yield the image string.
|
487
|
+
def png_transformer(type_s, out_options={}, &block)
|
488
|
+
orig_out_options = out_options[:size]
|
489
|
+
if type_s == 'png'
|
490
|
+
png_output = true
|
491
|
+
type_s = 'svg'
|
492
|
+
if out_options[:size]
|
493
|
+
unless out_options[:size].to_s =~ /x/i
|
494
|
+
out_options[:size] = out_options[:size].to_s + 'x' + out_options[:size].to_s
|
495
|
+
end
|
496
|
+
end
|
497
|
+
else
|
498
|
+
if out_options[:size].is_a?(String) && (out_options[:size] =~ /x/i)
|
499
|
+
warn 'can only use the width dimension for this format'
|
500
|
+
out_options[:size] = out_options[:size].split(/x/i).first
|
501
|
+
end
|
502
|
+
end
|
503
|
+
image_blob = block.call(type_s, out_options)
|
504
|
+
if png_output
|
505
|
+
st = StringIO.new
|
506
|
+
image = MiniMagick::Image.read(image_blob, 'svg')
|
507
|
+
image.format('png')
|
508
|
+
# would like to resize as an svg, then output the png of proper
|
509
|
+
# granularity...
|
510
|
+
image.resize(out_options[:size]) if out_options[:size]
|
511
|
+
image_blob = image.write(st).string
|
512
|
+
end
|
513
|
+
out_options[:size] = orig_out_options
|
514
|
+
image_blob
|
515
|
+
end
|
516
|
+
|
517
|
+
# out_options include any of those defined
|
518
|
+
def write_string(type=DEFAULT_OUT_TYPE, out_options={})
|
519
|
+
png_transformer(type.to_s, out_options) do |type_s, _out_opts|
|
520
|
+
obconv = out_options[:obconv] || OpenBabel::OBConversion.new
|
521
|
+
obconv.set_out_format(type_s)
|
522
|
+
obconv.add_opts!(:out, _out_opts)
|
523
|
+
obconv.write_string(@ob)
|
524
|
+
end
|
420
525
|
end
|
421
526
|
|
422
527
|
# writes to the file based on the extension given. If type is given
|
423
|
-
# explicitly, then it is used.
|
424
|
-
|
425
|
-
|
426
|
-
|
528
|
+
# explicitly, then it is used. If png is the extension or format, the
|
529
|
+
# png is generated from an svg.
|
530
|
+
def write_file(filename, out_options={})
|
531
|
+
type = Rubabel.filetype(filename)
|
532
|
+
File.write(filename, write_string(type, out_options))
|
427
533
|
end
|
428
534
|
|
429
535
|
def inspect
|
430
536
|
"#<Mol #{to_s}>"
|
431
537
|
end
|
432
538
|
|
539
|
+
# returns self
|
540
|
+
def convert_dative_bonds!
|
541
|
+
@ob.convert_dative_bonds
|
542
|
+
self
|
543
|
+
end
|
544
|
+
|
545
|
+
# centers the molecule (deals with the atomic coordinate systems for 2D or
|
546
|
+
# 3D molecules). returns self.
|
547
|
+
def center!
|
548
|
+
@ob.center
|
549
|
+
self
|
550
|
+
end
|
551
|
+
|
552
|
+
# returns self
|
553
|
+
def kekulize!
|
554
|
+
@ob.kekulize
|
555
|
+
self
|
556
|
+
end
|
557
|
+
|
558
|
+
# returns self
|
559
|
+
def strip_salts!
|
560
|
+
@ob.strip_salts!
|
561
|
+
self
|
562
|
+
end
|
563
|
+
|
564
|
+
# returns self
|
565
|
+
def highlight_substructure!(substructure, color='red')
|
566
|
+
tmpconv = OpenBabel::OBConversion.new
|
567
|
+
tmpconv.add_option("s",OpenBabel::OBConversion::GENOPTIONS, "#{substructure} #{color}")
|
568
|
+
self.ob.do_transformations(tmpconv.get_options(OpenBabel::OBConversion::GENOPTIONS), tmpconv)
|
569
|
+
self
|
570
|
+
end
|
571
|
+
|
572
|
+
## returns self
|
573
|
+
#def highlight_substructure!(substructure)
|
574
|
+
# #obabel benzodiazepine.sdf.gz -O out.svg --filter "title=3016" -s "c1ccc2c(c1)C(=NCCN2)c3ccccc3 red" -xu -d
|
575
|
+
# obconv.set_out_format('svg')
|
576
|
+
|
577
|
+
# obconv.add_option("s",OpenBabel::OBConversion::GENOPTIONS, "#{substructure} red")
|
578
|
+
# obconv.add_option("d",OpenBabel::OBConversion::GENOPTIONS)
|
579
|
+
# self.ob.do_transformations(obconv.get_options(OpenBabel::OBConversion::GENOPTIONS), obconv)
|
580
|
+
|
581
|
+
# obconv.add_option("u",OpenBabel::OBConversion::OUTOPTIONS)
|
582
|
+
# self
|
583
|
+
#end
|
584
|
+
|
585
|
+
def graph_diameter
|
586
|
+
distance_matrix = Array.new
|
587
|
+
self.atoms.each do |a|
|
588
|
+
iter = OpenBabel::OBMolAtomBFSIter.new(self.ob, a.idx)
|
589
|
+
while iter.inc.deref do
|
590
|
+
distance_matrix << iter.current_depth - 1
|
591
|
+
end
|
592
|
+
end
|
593
|
+
distance_matrix.max
|
594
|
+
end
|
595
|
+
|
433
596
|
end
|
434
597
|
end
|
435
598
|
|
@@ -470,3 +633,81 @@ TPSA topological polar surface area
|
|
470
633
|
|
471
634
|
=end
|
472
635
|
|
636
|
+
|
637
|
+
=begin
|
638
|
+
e.g., -xu
|
639
|
+
u no element-specific atom coloring
|
640
|
+
Use this option to produce a black and white diagram
|
641
|
+
U do not use internally-specified color
|
642
|
+
e.g. atom color read from cml or generated by internal code
|
643
|
+
b black background
|
644
|
+
The default is white. The atom colors work with both.
|
645
|
+
C do not draw terminal C (and attached H) explicitly
|
646
|
+
The default is to draw all hetero atoms and terminal C explicitly,
|
647
|
+
together with their attched hydrogens.
|
648
|
+
a draw all carbon atoms
|
649
|
+
So propane would display as H3C-CH2-CH3
|
650
|
+
d do not display molecule name
|
651
|
+
e embed molecule as CML
|
652
|
+
OpenBabel can read the resulting svg file as a cml file.
|
653
|
+
p# scale to bondlength in pixels(single mol only)
|
654
|
+
i add index to each atom
|
655
|
+
These indices are those in sd or mol files and correspond to the
|
656
|
+
order of atoms in a SMILES string.
|
657
|
+
j do not embed javascript
|
658
|
+
Javascript is not usually embedded if there is one one molecule,
|
659
|
+
but it is if the rows and columns have been specified as 1: ``-xr1 -xc1``
|
660
|
+
w generate wedge/hash bonds(experimental)
|
661
|
+
x omit XML declaration (not displayed in GUI)
|
662
|
+
Useful if the output is to be embedded in another xml file.
|
663
|
+
A display aliases, if present
|
664
|
+
This applies to structures which have an alternative, usually
|
665
|
+
shorter, representation already present. This might have been input
|
666
|
+
from an A or S superatom entry in an sd or mol file, or can be
|
667
|
+
generated using the --genalias option. For example::
|
668
|
+
|
669
|
+
echo "c1cc(C=O)ccc1C(=O)O" | babel -ismi out.svg --genalias -xA
|
670
|
+
|
671
|
+
would add a aliases COOH and CHO to represent the carboxyl and
|
672
|
+
aldehyde groups and would display them as such in the svg diagram.
|
673
|
+
The aliases which are recognized are in data/superatom.txt, which
|
674
|
+
can be edited.
|
675
|
+
|
676
|
+
## SPECIFIC TO JUST MULTIPLE MOLS:
|
677
|
+
|
678
|
+
c# number of columns in table
|
679
|
+
r# number of rows in table
|
680
|
+
N# max number objects to be output
|
681
|
+
l draw grid lines
|
682
|
+
|
683
|
+
=end
|
684
|
+
|
685
|
+
# things JTP is playing with:
|
686
|
+
=begin
|
687
|
+
opts = DEFAULT_DRAW_OPTS.merge( opts )
|
688
|
+
self.title = opts[:title] if opts[:title]
|
689
|
+
self.obconv.set_out_format(opts[:format].to_s)
|
690
|
+
p OpenBabel::OBConversion::OUTOPTIONS
|
691
|
+
p OpenBabel::OBConversion::OUTOPTIONS.class
|
692
|
+
p self.obconv.get_options(OpenBabel::OBConversion::OUTOPTIONS).methods - Object.new.methods
|
693
|
+
abort 'here'
|
694
|
+
p self.obconv.get_options(OpenBabel::OBConversion::GENOPTIONS)
|
695
|
+
self.obconv.add_option("P", OpenBabel::OBConversion::OUTOPTIONS, opts[:size].to_s) #sets image size to 300X300
|
696
|
+
p self.obconv.get_options(OpenBabel::OBConversion::OUTOPTIONS)
|
697
|
+
p self.obconv.get_options(OpenBabel::OBConversion::GENOPTIONS)
|
698
|
+
p OpenBabel::OBConversion::OUTOPTIONS
|
699
|
+
p OpenBabel::OBConversion::OUTOPTIONS.class
|
700
|
+
#self.obconv.add_option("gen2D",OpenBabel::OBConversion::GENOPTIONS)
|
701
|
+
#self.obconv.add_option("h",OpenBabel::OBConversion::GENOPTIONS)
|
702
|
+
#self.ob.do_transformations(self.obconv.get_options(OpenBabel::OBConversion::GENOPTIONS), self.obconv)
|
703
|
+
self.obconv.write_file(self.ob, opts[:filename])
|
704
|
+
=end
|
705
|
+
|
706
|
+
#opts = DEFAULT_DRAW_OPTS.merge( opts )
|
707
|
+
#self.title = opts[:title] if opts[:title]
|
708
|
+
##self.title = (opts[:title]==nil ? "" : opts[:title])
|
709
|
+
#self.obconv.set_in_and_out_formats('smi',opts[:format])
|
710
|
+
#self.obconv.add_option("P",OpenBabel::OBConversion::OUTOPTIONS, opts[:size].to_s) #sets image size to 300X300
|
711
|
+
#self.obconv.do_transformations(self.obconv
|
712
|
+
#self.obconv.write_file(self.ob, opts[:filename])
|
713
|
+
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'fileutils'
|
2
3
|
|
3
4
|
# http://ctr.wikia.com/wiki/Chemistry_Toolkit_Rosetta_Wiki
|
4
5
|
|
@@ -23,6 +24,10 @@ end
|
|
23
24
|
|
24
25
|
describe 'Chemistry Toolkit Rosetta Wiki' do
|
25
26
|
|
27
|
+
def equivalent_pngs(png1, png2)
|
28
|
+
(png1.size - png2.size < 50) && (png1[0..100] == png2[0..100])
|
29
|
+
end
|
30
|
+
|
26
31
|
before(:each) do
|
27
32
|
@orig_dir = Dir.pwd
|
28
33
|
@wiki_spec_dir = File.dirname(__FILE__)
|
@@ -34,7 +39,7 @@ describe 'Chemistry Toolkit Rosetta Wiki' do
|
|
34
39
|
Dir.chdir(@orig_dir)
|
35
40
|
end
|
36
41
|
|
37
|
-
|
42
|
+
specify 'Heavy atom counts from an SD file' do
|
38
43
|
#http://ctr.wikia.com/wiki/Heavy_atom_counts_from_an_SD_file
|
39
44
|
output = wiki_code_capture_stdout do
|
40
45
|
require 'rubabel'
|
@@ -43,7 +48,7 @@ describe 'Chemistry Toolkit Rosetta Wiki' do
|
|
43
48
|
output.should == IO.read( @keydir + "/" + "benzodiazepine_heavy_atom_counts.output.10.txt" )
|
44
49
|
end
|
45
50
|
|
46
|
-
|
51
|
+
specify 'Ring counts in a SMILES file' do
|
47
52
|
# http://ctr.wikia.com/wiki/Ring_counts_in_a_SMILES_file
|
48
53
|
output = wiki_code_capture_stdout do
|
49
54
|
require 'rubabel'
|
@@ -52,7 +57,7 @@ describe 'Chemistry Toolkit Rosetta Wiki' do
|
|
52
57
|
output.should == IO.read( @keydir + '/' + "benzodiazepine_ring_counts.output.10.txt" )
|
53
58
|
end
|
54
59
|
|
55
|
-
|
60
|
+
specify 'Convert a SMILES string to canonical SMILES' do
|
56
61
|
# http://ctr.wikia.com/wiki/Convert_a_SMILES_string_to_canonical_SMILES
|
57
62
|
wiki_code do
|
58
63
|
require 'rubabel'
|
@@ -62,7 +67,7 @@ describe 'Chemistry Toolkit Rosetta Wiki' do
|
|
62
67
|
end
|
63
68
|
end
|
64
69
|
|
65
|
-
|
70
|
+
specify 'Working with SD tag data' do
|
66
71
|
# http://ctr.wikia.com/wiki/Working_with_SD_tag_data
|
67
72
|
wiki_code do
|
68
73
|
require 'rubabel'
|
@@ -94,7 +99,7 @@ describe 'Chemistry Toolkit Rosetta Wiki' do
|
|
94
99
|
unlink "RULE5.sdf"
|
95
100
|
end
|
96
101
|
|
97
|
-
|
102
|
+
specify 'Detect and report SMILES and SDF parsing errors' do
|
98
103
|
# http://ctr.wikia.com/wiki/Detect_and_report_SMILES_and_SDF_parsing_errors
|
99
104
|
wiki_code do
|
100
105
|
require 'rubabel'
|
@@ -114,7 +119,7 @@ describe 'Chemistry Toolkit Rosetta Wiki' do
|
|
114
119
|
unlink("log.txt")
|
115
120
|
end
|
116
121
|
|
117
|
-
|
122
|
+
specify 'Report how many SD file records are within a certain molecular weight range' do
|
118
123
|
# http://ctr.wikia.com/wiki/Report_how_many_SD_file_records_are_within_a_certain_molecular_weight_range
|
119
124
|
output = wiki_code_capture_stdout do
|
120
125
|
require 'rubabel'
|
@@ -124,7 +129,7 @@ describe 'Chemistry Toolkit Rosetta Wiki' do
|
|
124
129
|
# checked with large file and it came out to 3916, which is correct
|
125
130
|
end
|
126
131
|
|
127
|
-
|
132
|
+
specify 'Convert SMILES file to SD file' do
|
128
133
|
# http://ctr.wikia.com/wiki/Convert_SMILES_file_to_SD_file
|
129
134
|
wiki_code do
|
130
135
|
require 'rubabel'
|
@@ -143,21 +148,48 @@ describe 'Chemistry Toolkit Rosetta Wiki' do
|
|
143
148
|
unlink "benzodiazepine.smi.sdf"
|
144
149
|
end
|
145
150
|
|
146
|
-
|
151
|
+
specify 'Report the similarity between two structures' do
|
147
152
|
# http://ctr.wikia.com/wiki/Report_the_similarity_between_two_structures
|
148
153
|
output = wiki_code_capture_stdout do
|
149
154
|
require 'rubabel'
|
150
|
-
(mol1, mol2) = %w{CC(C)C=CCCCCC(=O)NCc1ccc(c(c1)OC)O COC1=C(C=CC(=C1)C=O)O}.map
|
151
|
-
Rubabel[smile]
|
152
|
-
end
|
155
|
+
(mol1, mol2) = %w{CC(C)C=CCCCCC(=O)NCc1ccc(c(c1)OC)O COC1=C(C=CC(=C1)C=O)O}.map{|smile| Rubabel[smile]}
|
153
156
|
puts mol1.tanimoto(mol2)
|
154
157
|
end
|
155
158
|
output.should == "0.36046511627906974\n"
|
156
159
|
# notes: reports similarity of 0.36046511627906974
|
157
160
|
end
|
158
161
|
|
159
|
-
|
162
|
+
specify 'Find the 10 nearest neighbors in a data set' do
|
160
163
|
# http://ctr.wikia.com/wiki/Find_the_10_nearest_neighbors_in_a_data_set
|
164
|
+
|
165
|
+
output = wiki_code_capture_stdout do
|
166
|
+
require 'rubabel'
|
167
|
+
|
168
|
+
prev = nil
|
169
|
+
comp = []
|
170
|
+
Rubabel.foreach("benzodiazepine.sdf.gz").map do |mol|
|
171
|
+
prev = mol if prev.nil?
|
172
|
+
comp << [prev.tanimoto(mol), mol.title]
|
173
|
+
end
|
174
|
+
puts comp.sort.reverse[1,11].map {|v| "#{v[0].round(3)} #{v[1]}" }
|
175
|
+
end
|
176
|
+
output.should == "0.979 3016\n0.979 2997\n0.909 3369\n0.874 2809\n0.769 3299\n0.74 2802\n0.379 3261\n0.377 2118\n0.368 1963\n"
|
177
|
+
# output when run on entire benzodiazepine.sdf.gz:
|
178
|
+
#1.0 450820
|
179
|
+
#1.0 1688
|
180
|
+
#0.993 20351792
|
181
|
+
#0.986 9862446
|
182
|
+
#0.979 398658
|
183
|
+
#0.979 398657
|
184
|
+
#0.979 6452650
|
185
|
+
#0.979 450830
|
186
|
+
#0.979 44353759
|
187
|
+
#0.979 3016
|
188
|
+
#0.979 2997
|
189
|
+
end
|
190
|
+
|
191
|
+
# jtp original implementation
|
192
|
+
=begin
|
161
193
|
output = wiki_code_capture_stdout do
|
162
194
|
require 'rubabel'
|
163
195
|
fp1 = nil
|
@@ -194,24 +226,122 @@ describe 'Chemistry Toolkit Rosetta Wiki' do
|
|
194
226
|
#end
|
195
227
|
#puts comparisons.sort.reverse.map {|pair| pair.join(" ") }
|
196
228
|
end
|
229
|
+
=end
|
197
230
|
|
198
|
-
|
231
|
+
specify 'Depict a compound as an image' do
|
199
232
|
# http://ctr.wikia.com/wiki/Depict_a_compound_as_an_image
|
200
233
|
wiki_code do
|
201
|
-
|
202
|
-
|
203
|
-
|
234
|
+
require 'rubabel'
|
235
|
+
mol = Rubabel["CN1C=NC2=C1C(=O)N(C(=O)N2C)C"]
|
236
|
+
mol.title = 'Caffeine'
|
237
|
+
mol.write('caffeine.png')
|
238
|
+
# NOTE: use svg and convert to png to change image size
|
239
|
+
end
|
240
|
+
png_out = IO.read(@wiki_spec_dir + "/caffeine.png")
|
241
|
+
key_out = IO.read(@keydir + "/caffeine.frozen.png")
|
242
|
+
equivalent_pngs(png_out, key_out).should be_true
|
243
|
+
File.unlink('caffeine.png')
|
244
|
+
end
|
245
|
+
#OR, using commandline
|
246
|
+
#%x{obabel -:"CN1C=NC2=C1C(=O)N(C(=O)N2C)C" -O "mol.png" -xP 300}
|
247
|
+
|
248
|
+
specify 'Highlight a substructure in the depiction' do
|
249
|
+
# http://ctr.wikia.com/wiki/Highlight_a_substructure_in_the_depiction
|
250
|
+
|
251
|
+
# when we fix the draw function, this should work like a charm!
|
252
|
+
wiki_code do
|
253
|
+
require 'rubabel'
|
254
|
+
mol = Rubabel.foreach("benzodiazepine.sdf.gz").find {|mol| mol.title == "3016" }
|
255
|
+
mol.highlight_substructure!("c1ccc2c(c1)C(=NCCN2)c3ccccc3").remove_h!
|
256
|
+
mol.write("3016_highlighted.rubabel.png", u: true)
|
257
|
+
# NOTE: use svg and convert to png to change image size
|
258
|
+
end
|
259
|
+
png_out = IO.read(@wiki_spec_dir + "/3016_highlighted.rubabel.png")
|
260
|
+
key_out = IO.read(@keydir + "/3016_highlighted.rubabel.frozen.png")
|
261
|
+
equivalent_pngs(png_out, key_out)
|
262
|
+
File.unlink('3016_highlighted.rubabel.png')
|
263
|
+
end
|
264
|
+
|
265
|
+
xspecify 'Align the depiction using a fixed substructure' do
|
266
|
+
# http://ctr.wikia.com/wiki/Align_the_depiction_using_a_fixed_substructure
|
267
|
+
#TODO
|
268
|
+
end
|
269
|
+
|
270
|
+
specify 'Unique SMARTS matches against a SMILES string' do
|
271
|
+
# http://ctr.wikia.com/wiki/Unique_SMARTS_matches_against_a_SMILES_string
|
272
|
+
output = wiki_code_capture_stdout do
|
273
|
+
require 'rubabel'
|
274
|
+
mol = Rubabel["C1CC12C3(C24CC4)CC3"]
|
275
|
+
[false, true].map {|uniq| puts mol.matches("*1**1", uniq).size }
|
204
276
|
end
|
277
|
+
output.should == "24\n4\n"
|
205
278
|
end
|
206
279
|
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
280
|
+
specify 'Calculate TPSA' do
|
281
|
+
output = wiki_code_capture_stdout do
|
282
|
+
require 'rubabel'
|
283
|
+
lines = IO.readlines("tpsa.tab")
|
284
|
+
header = lines.shift
|
285
|
+
@patterns = lines.map {|line| line.chomp.split("\t") }
|
286
|
+
|
287
|
+
def TPSA(mol)
|
288
|
+
@patterns.inject(0.0) {|s,p| s + p[0].to_f * mol.matches(p[1], false).size }
|
289
|
+
end
|
290
|
+
puts TPSA( Rubabel["CN2C(=O)N(C)C(=O)C1=C2N=CN1C"] )
|
291
|
+
end
|
292
|
+
output.should == "61.82\n"
|
293
|
+
end
|
294
|
+
|
295
|
+
specify 'Find the graph diameter' do
|
296
|
+
output = wiki_code_capture_stdout do
|
297
|
+
require 'rubabel'
|
298
|
+
puts Rubabel["CC(C)C(C(=O)NC(=O)C1CCCN1C(=O)C(C)NC(=O)C(C)NC(=O)CCC(=O)OC)NC2=CC=C(C=C2)[N+](=O)[O-]"].graph_diameter
|
299
|
+
end
|
300
|
+
output.should == "24\n"
|
301
|
+
end
|
302
|
+
|
303
|
+
specify 'Break rotatable bonds and report the fragments' do
|
304
|
+
output = wiki_code_capture_stdout do
|
305
|
+
smarts = "[!$([NH]!@C(=O))&!D1&!$(*#*)]-&!@[!$([NH]!@C(=O))&!D1&!$(*#*)]"
|
306
|
+
mol = Rubabel["c1ccc2c(c1)C(=NC(C(=O)N2CC(=O)O)Cc3ccc(cc3)O)c4cccc(c4)O"]
|
307
|
+
mol.matches(smarts).each do |atom1, atom2|
|
308
|
+
mol.delete(atom1.get_bond(atom2))
|
309
|
+
[atom1, atom2].each do |old_a|
|
310
|
+
mol.add_bond!(old_a, mol.add_atom!(0))
|
311
|
+
end
|
312
|
+
end
|
313
|
+
puts "#{mol.to_s.gsub('.',"\n")}"
|
314
|
+
end
|
315
|
+
output.should == "*C*\n*C*\n*C(=O)O\nO=C1C(*)N=C(c2c(N1*)cccc2)*\n*c1cccc(c1)O\n*c1ccc(cc1)O\n"
|
316
|
+
end
|
317
|
+
|
318
|
+
xit 'Perform a substructure search on SDF file and report the number of false positives' do
|
319
|
+
output = wiki_code_capture_stdout do
|
320
|
+
require 'rubabel'
|
321
|
+
smart = Rubabel::Smarts.new("C1C=C(NC=O)C=CC=1")
|
322
|
+
sm_mol = Rubabel[smart.to_s]
|
323
|
+
count = 0
|
324
|
+
Rubabel.foreach("benzodiazepine.sdf.gz").map do |mol|
|
325
|
+
count += 1 if sm_mol.to_s == mol.ob_fingerprint.to_s
|
326
|
+
end
|
327
|
+
#aromatize should be automatic for converstion from smarts??
|
328
|
+
#fingerprint search
|
329
|
+
#bitTest/full substructure match
|
330
|
+
puts count
|
331
|
+
# puts "#{mols.size} total\n#{num_true_matches} matches\n#{num_matches - num_true_matches}"
|
332
|
+
end
|
333
|
+
|
334
|
+
|
335
|
+
# output.should == "12386 total\n8836 matches\n1 false positives\n"
|
336
|
+
output.should == ""
|
213
337
|
end
|
214
338
|
|
339
|
+
xit 'Change stereochemistry of certain atoms in SMILES file' do
|
340
|
+
#TODO
|
341
|
+
end
|
342
|
+
|
343
|
+
|
344
|
+
|
215
345
|
|
216
346
|
end
|
217
347
|
|
Binary file
|
@@ -0,0 +1,44 @@
|
|
1
|
+
psa SMARTS description
|
2
|
+
23.79 [N+0;H0;D1;v3] N#
|
3
|
+
23.85 [N+0;H1;D1;v3] [NH]=
|
4
|
+
26.02 [N+0;H2;D1;v3] [NH2]-
|
5
|
+
25.59 [N+1;H2;D1;v4] [NH2+]=
|
6
|
+
27.64 [N+1;H3;D1;v4] [NH3+]-
|
7
|
+
12.36 [N+0;H0;D2;v3] =N-
|
8
|
+
13.6 [N+0;H0;D2;v5] =N#
|
9
|
+
12.03 [N+0;H1;D2;v3;!r3] -[NH]- not in 3-ring
|
10
|
+
21.94 [N+0;H1;D2;v3;r3] -[NH]- in 3-ring
|
11
|
+
4.36 [N+1;H0;D2;v4] -[N+]#
|
12
|
+
13.97 [N+1;H1;D2;v4] -[NH+]=
|
13
|
+
16.61 [N+1;H2;D2;v4] -[NH2+]-
|
14
|
+
12.89 [n+0;H0;D2;v3] :[n]:
|
15
|
+
15.79 [n+0;H1;D2;v3] :[nH]:
|
16
|
+
3.24 [N+0;H0;D3;v3;!r3] -N(-)-
|
17
|
+
3.01 [N+0;H0;D3;v3;r3] -N(-)- in 3-ring
|
18
|
+
11.68 [N+0;H0;D3;v5] -N(=)=
|
19
|
+
3.01 [N+1;H0;D3;v4] =[N+](-)-
|
20
|
+
4.44 [N+1;H1;D3;v4] -[NH+](-)-
|
21
|
+
0 [N+1;H0;D4;v4] -[N+](-)(-)-
|
22
|
+
17.07 [O+0;H0;D1;v2] O=
|
23
|
+
23.06 [O-1;H0;D1;v1] [O-]-
|
24
|
+
9.23 [O+0;H0;D2;!r3;v2] -O- not in 3-ring
|
25
|
+
12.53 [O+0;H0;D2;r3;v2] -O- in 3-ring
|
26
|
+
13.14 [o+0;H0;D2;v2] :o:
|
27
|
+
14.14 [n+1;H1;D2;v4] :[nH+]:
|
28
|
+
20.23 [O+0;H1;D1] [OH]-
|
29
|
+
4.93 [n+0;H0;D3;$(n-*)] -[n](:):
|
30
|
+
4.41 [n+0;H0;D3;$(n(:*)(:*):*)] :[n](:):
|
31
|
+
4.10 [n+1;H0;D3;v4;$(n(:*)(:*):*)] :[n+](:):
|
32
|
+
3.88 [n+1;H0;D3;v4;$(n-*)] -[n+](:):
|
33
|
+
8.39 [n+0;H0;D3;v5;$(n=*)] =[n](:):
|
34
|
+
11.3 [#8+1;H0;D2] 28.5 - 2*8.6; non-standard valency
|
35
|
+
12.8 [#8+1;H1;D2] 28.5 - 2*8.6 + 1.5; non-standard valency
|
36
|
+
11.3 [#8;H0;D2;v4] 28.5 - 2*8.6; non-standard valency
|
37
|
+
2.7 [#8;H0;D3;v4] 28.5 - 3 *8.6; non-standard valency
|
38
|
+
2.7 [#8+1;H0;D3;v3] 28.5 - 3*8.6; non-standard valency
|
39
|
+
7.4 [NH+0;v5;D3] =N(-)-; 30.5 - 8.2*3 + 1.5; non-standard valency
|
40
|
+
14.10 [#7;v2;D2] 30.5 - 2*8.2; -[N]-; non-standard valency
|
41
|
+
15.6 [NH+0;v5;D2] 30.5 - 2*8.2 + 1.5; -N#, =N=; non-standard valency
|
42
|
+
35.00 [NH3] 30.5 + 3*1.5 non-standard valency?
|
43
|
+
2.68 O=[N+][O-] 17.07 - 23.06 - 3.01 + 11.68; (O=) - ([O-])- - (-N(-)-) + (N(=)=) ; fix to make charge-separated spelling work
|
44
|
+
33.03 N=[N+]=[N-] 23.79 + 13.6 - 4.36; (N#) + (=N#) - (-[N+]#); fix to make charged-separated spelling work
|
data/spec/rubabel/atom_spec.rb
CHANGED
@@ -8,11 +8,9 @@ describe Rubabel::Atom do
|
|
8
8
|
it 'can be created given an element symbol' do
|
9
9
|
hydrogen = Rubabel::Atom[:h]
|
10
10
|
hydrogen.el.should == :h
|
11
|
-
hydrogen.id.should == 0
|
12
11
|
|
13
12
|
carbon = Rubabel::Atom[:c]
|
14
13
|
carbon.el.should == :c
|
15
|
-
carbon.id.should == 0
|
16
14
|
|
17
15
|
chlorine = Rubabel::Atom[:cl, 3]
|
18
16
|
chlorine.el.should == :cl
|
@@ -10,6 +10,20 @@ describe Rubabel::Molecule do
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
+
describe 'png output' do
|
14
|
+
it 'creates a png image (corresponds to the svg)' do
|
15
|
+
mol = Rubabel["NCC(=O)O"]
|
16
|
+
#mol.write("mol1.svg", size: '300x200')
|
17
|
+
#mol.write("mol1.png", size: '300x280')
|
18
|
+
mol.write("mol1.svg")
|
19
|
+
mol.write("mol1.png")
|
20
|
+
%w(mol1.svg mol1.png).each do |file|
|
21
|
+
File.exist?(file).should be_true
|
22
|
+
File.unlink(file)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
13
27
|
before(:each) do
|
14
28
|
@mol = Rubabel::Molecule.from_file( TESTFILES + '/cholesterol.sdf' )
|
15
29
|
end
|
@@ -25,6 +39,24 @@ describe Rubabel::Molecule do
|
|
25
39
|
end
|
26
40
|
end
|
27
41
|
|
42
|
+
specify '#add_atom! adds an atom given an atomic number and returns it' do
|
43
|
+
mol = Rubabel["CCO"]
|
44
|
+
before_size = mol.atoms.size
|
45
|
+
atom = mol.add_atom!(6)
|
46
|
+
atom.el.should == :c
|
47
|
+
(mol.atoms.size - before_size).should == 1
|
48
|
+
mol.csmiles.should == "CCO.C"
|
49
|
+
end
|
50
|
+
|
51
|
+
specify '#add_atom! with a Rubabel::Atom'
|
52
|
+
|
53
|
+
specify '#add_bond! adds a bond (and updates atoms)' do
|
54
|
+
mol = Rubabel["CCO"]
|
55
|
+
atom = mol.add_atom!(0)
|
56
|
+
mol.add_bond!(mol.atoms[1], atom)
|
57
|
+
mol.csmiles.should == '*C(O)C'
|
58
|
+
end
|
59
|
+
|
28
60
|
# specify '#add_bond adds a bond (and updates atoms)' do
|
29
61
|
# c = Rubabel::Atom[:c]
|
30
62
|
# o = Rubabel::Atom[:o]
|
@@ -244,4 +276,8 @@ describe Rubabel::Molecule do
|
|
244
276
|
end
|
245
277
|
|
246
278
|
end
|
279
|
+
|
280
|
+
describe 'using output format options' do
|
281
|
+
|
282
|
+
end
|
247
283
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubabel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-09-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: openbabel
|
@@ -43,6 +43,22 @@ dependencies:
|
|
43
43
|
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: 1.3.3
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: mini_magick
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '3.4'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.4'
|
46
62
|
- !ruby/object:Gem::Dependency
|
47
63
|
name: rspec
|
48
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -128,14 +144,16 @@ files:
|
|
128
144
|
- reference/fragmentation_rules_.pdf
|
129
145
|
- reference/get_methods.rb
|
130
146
|
- reference/mol_methods.txt
|
131
|
-
- rubabel.gemspec
|
132
147
|
- spec/chemistry_toolkit_rosetta/README.txt
|
133
148
|
- spec/chemistry_toolkit_rosetta/benzodiazepine.sdf.gz
|
134
149
|
- spec/chemistry_toolkit_rosetta/benzodiazepine.smi.gz
|
135
150
|
- spec/chemistry_toolkit_rosetta/chemistry_toolkit_rosetta_spec.rb
|
151
|
+
- spec/chemistry_toolkit_rosetta/key/3016_highlighted.rubabel.frozen.png
|
136
152
|
- spec/chemistry_toolkit_rosetta/key/benzodiazepine_heavy_atom_counts.output.10.txt
|
137
153
|
- spec/chemistry_toolkit_rosetta/key/benzodiazepine_ring_counts.output.10.txt
|
154
|
+
- spec/chemistry_toolkit_rosetta/key/caffeine.frozen.png
|
138
155
|
- spec/chemistry_toolkit_rosetta/key/rule5.10.sdf
|
156
|
+
- spec/chemistry_toolkit_rosetta/tpsa.tab
|
139
157
|
- spec/rubabel/atom_spec.rb
|
140
158
|
- spec/rubabel/bond_spec.rb
|
141
159
|
- spec/rubabel/molecule/fragmentable_spec.rb
|
data/rubabel.gemspec
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
-
# -*- encoding: utf-8 -*-
|
5
|
-
|
6
|
-
Gem::Specification.new do |s|
|
7
|
-
s.name = "rubabel"
|
8
|
-
s.version = "0.1.5"
|
9
|
-
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = ["John T. Prince"]
|
12
|
-
s.date = "2012-08-08"
|
13
|
-
s.description = "Ruby interface to the openbabel ruby bindings (or the openbabel gem). The\ninterface attempts to be a ruby-ish analogue of pybel."
|
14
|
-
s.email = "jtprince@gmail.com"
|
15
|
-
s.executables = ["fragmenter.rb"]
|
16
|
-
s.extra_rdoc_files = [
|
17
|
-
"LICENSE",
|
18
|
-
"README.rdoc"
|
19
|
-
]
|
20
|
-
s.files = [
|
21
|
-
".document",
|
22
|
-
".rspec",
|
23
|
-
"LICENSE",
|
24
|
-
"README.rdoc",
|
25
|
-
"Rakefile",
|
26
|
-
"VERSION",
|
27
|
-
"bin/fragmenter.rb",
|
28
|
-
"lib/rubabel.rb",
|
29
|
-
"lib/rubabel/atom.rb",
|
30
|
-
"lib/rubabel/bond.rb",
|
31
|
-
"lib/rubabel/core_ext/enumerable.rb",
|
32
|
-
"lib/rubabel/core_ext/putsv.rb",
|
33
|
-
"lib/rubabel/fingerprint.rb",
|
34
|
-
"lib/rubabel/molecule.rb",
|
35
|
-
"lib/rubabel/molecule/fragmentable.rb",
|
36
|
-
"lib/rubabel/molecule_data.rb",
|
37
|
-
"lib/rubabel/pm.rb",
|
38
|
-
"lib/rubabel/smarts.rb",
|
39
|
-
"reference/OBConversion_methods.txt",
|
40
|
-
"reference/arity_method_list.txt",
|
41
|
-
"reference/arity_method_list_CLASS.txt",
|
42
|
-
"reference/atom_methods.txt",
|
43
|
-
"reference/bond_methods.txt",
|
44
|
-
"reference/fragmentation_rules_.pdf",
|
45
|
-
"reference/get_methods.rb",
|
46
|
-
"reference/mol_methods.txt",
|
47
|
-
"rubabel.gemspec",
|
48
|
-
"spec/chemistry_toolkit_rosetta/README.txt",
|
49
|
-
"spec/chemistry_toolkit_rosetta/benzodiazepine.sdf.gz",
|
50
|
-
"spec/chemistry_toolkit_rosetta/benzodiazepine.smi.gz",
|
51
|
-
"spec/chemistry_toolkit_rosetta/chemistry_toolkit_rosetta_spec.rb",
|
52
|
-
"spec/chemistry_toolkit_rosetta/key/benzodiazepine_heavy_atom_counts.output.10.txt",
|
53
|
-
"spec/chemistry_toolkit_rosetta/key/benzodiazepine_ring_counts.output.10.txt",
|
54
|
-
"spec/chemistry_toolkit_rosetta/key/rule5.10.sdf",
|
55
|
-
"spec/rubabel/atom_spec.rb",
|
56
|
-
"spec/rubabel/bond_spec.rb",
|
57
|
-
"spec/rubabel/molecule/fragmentable_spec.rb",
|
58
|
-
"spec/rubabel/molecule_data_spec.rb",
|
59
|
-
"spec/rubabel/molecule_spec.rb",
|
60
|
-
"spec/rubabel_spec.rb",
|
61
|
-
"spec/spec_helper.rb",
|
62
|
-
"spec/testfiles/7-oxocholesterol-d7.mol",
|
63
|
-
"spec/testfiles/7-oxocholesterol-d7.sdf",
|
64
|
-
"spec/testfiles/Samples.sdf",
|
65
|
-
"spec/testfiles/Samples.sdf.gz",
|
66
|
-
"spec/testfiles/cholesterol.mol",
|
67
|
-
"spec/testfiles/cholesterol.sdf",
|
68
|
-
"spec/testfiles/two.sdf"
|
69
|
-
]
|
70
|
-
s.homepage = "http://github.com/princelab/rubabel"
|
71
|
-
s.licenses = ["MIT"]
|
72
|
-
s.require_paths = ["lib"]
|
73
|
-
s.rubygems_version = "1.8.23"
|
74
|
-
s.summary = "Ruby interface to the OpenBabel ruby bindings similar to pybel"
|
75
|
-
|
76
|
-
if s.respond_to? :specification_version then
|
77
|
-
s.specification_version = 3
|
78
|
-
|
79
|
-
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
80
|
-
s.add_runtime_dependency(%q<openbabel>, ["~> 2.3.1.2"])
|
81
|
-
s.add_runtime_dependency(%q<andand>, ["~> 1.3.3"])
|
82
|
-
s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
|
83
|
-
s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
|
84
|
-
s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
|
85
|
-
else
|
86
|
-
s.add_dependency(%q<openbabel>, ["~> 2.3.1.2"])
|
87
|
-
s.add_dependency(%q<andand>, ["~> 1.3.3"])
|
88
|
-
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
89
|
-
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
90
|
-
s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
|
91
|
-
end
|
92
|
-
else
|
93
|
-
s.add_dependency(%q<openbabel>, ["~> 2.3.1.2"])
|
94
|
-
s.add_dependency(%q<andand>, ["~> 1.3.3"])
|
95
|
-
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
96
|
-
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
97
|
-
s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|