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