Class: Rubabel::Molecule

Inherits:
Object show all
Includes:
Enumerable, Fragmentable
Defined in:
lib/rubabel/molecule/fragmentable.rb,
lib/rubabel/molecule.rb

Defined Under Namespace

Modules: Fragmentable

Constant Summary collapse

DEFAULT_FINGERPRINT =
"FP2"
DEFAULT_OUT_TYPE =
:can
DEFAULT_IN_TYPE =
:smi

Constants included from Fragmentable

Fragmentable::DEFAULT_OPTIONS, Fragmentable::RULES

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Enumerable

#index_by, #uniq_by

Methods included from Fragmentable

#allowable_fragmentation?, #break_with_double_bond, #carbon_oxygen_esteal, #carbonyl_oxygen_dump, #dup_molecule, #fragment

Constructor Details

#initialize(obmol = nil) ⇒ Molecule

Returns a new instance of Molecule.



177
178
179
# File 'lib/rubabel/molecule.rb', line 177

def initialize(obmol=nil)
  @ob = obmol.nil? ? OpenBabel::OBMol.new  : obmol
end

Instance Attribute Details

#obObject

the OpenBabel::OBmol object



82
83
84
# File 'lib/rubabel/molecule.rb', line 82

def ob
  @ob
end

Class Method Details

.from_atoms_and_bonds(atoms = [], bonds = []) ⇒ Object



103
104
105
106
107
108
# File 'lib/rubabel/molecule.rb', line 103

def from_atoms_and_bonds(atoms=[], bonds=[])
  obj = self.new( OpenBabel::OBMol.new )
  atoms.each {|atom| obj.add_atom(atom) }
  bonds.each {|bond| obj.add_bond(bond) }
  obj
end

.from_file(file, type = nil) ⇒ Object



90
91
92
93
# File 'lib/rubabel/molecule.rb', line 90

def from_file(file, type=nil)
  (obmol, obconv, not_at_end) = Rubabel.read_first_obmol(file, type).first
  Rubabel::Molecule.new(obmol)
end

.from_string(string, type = DEFAULT_IN_TYPE) ⇒ Object



95
96
97
98
99
100
101
# File 'lib/rubabel/molecule.rb', line 95

def from_string(string, type=DEFAULT_IN_TYPE)
  obmol = OpenBabel::OBMol.new
  obconv = OpenBabel::OBConversion.new
  obconv.set_in_format(type.to_s) || raise(ArgumentError, "invalid format #{type}")
  obconv.read_string(obmol, string) || raise(ArgumentError, "invalid string" )
  self.new(obmol)
end

.tanimoto(mol1, mol2, type = DEFAULT_FINGERPRINT) ⇒ Object



86
87
88
# File 'lib/rubabel/molecule.rb', line 86

def tanimoto(mol1, mol2, type=DEFAULT_FINGERPRINT)
  OpenBabel::OBFingerprint.tanimoto(mol1.ob_fingerprint(type), mol2.ob_fingerprint(type))
end

Instance Method Details

#==(other) ⇒ Object

defined as whether the csmiles strings are identical. This incorporates more information than the FP2 fingerprint, for instance (try changing the charge and see how it does not influence the fingerprint). Obviously, things like title or data will not be evaluated with ==. See equal? if you are looking for identity. More stringent comparisons will have to be done by hand!



326
327
328
# File 'lib/rubabel/molecule.rb', line 326

def ==(other)
  other.respond_to?(:csmiles) && (csmiles == other.csmiles)
end

#[](*args) ⇒ Object

retrieves the atom by index (accepts everything an array would)



146
147
148
# File 'lib/rubabel/molecule.rb', line 146

def [](*args)
  atoms[*args]
end

#add_atom!(arg = 6, bond_order = 1, attach_to = nil) ⇒ Object Also known as: <<

returns the atom passed in or that was created. arg is a pre-existing atom, an atomic number or an element symbol (e.g. :c). default is to add carbon.



136
137
138
139
140
141
# File 'lib/rubabel/molecule.rb', line 136

def add_atom!(arg=6, bond_order=1, attach_to=nil)
  attach_to ||= atoms.last
  atom = associate_atom!(arg)
  add_bond!(attach_to, atom, bond_order) if attach_to
  atom
end

#add_bond!(atom1, atom2, order = 1) ⇒ Object

takes a pair of Rubabel::Atom objects and adds a bond to the molecule returns whether the bond creation was successful.



452
453
454
# File 'lib/rubabel/molecule.rb', line 452

def add_bond!(atom1, atom2, order=1)
  @ob.add_bond(atom1.idx, atom2.idx, order)
end

#add_h!(ph = nil, polaronly = false) ⇒ Object

returns self. Corrects for ph if ph is not nil. NOTE: the reversal of arguments from the OpenBabel api.



232
233
234
235
236
237
238
239
# File 'lib/rubabel/molecule.rb', line 232

def add_h!(ph=nil, polaronly=false)
  if ph.nil?
    @ob.add_hydrogens(polaronly)
  else
    @ob.add_hydrogens(polaronly, true, ph)
  end
  self
end

#add_hydrogen_to_formula!Object

adds 1 hydrogen to the formula and returns self



676
677
678
679
680
681
682
683
684
685
686
687
688
# File 'lib/rubabel/molecule.rb', line 676

def add_hydrogen_to_formula!
  string = @ob.get_formula
  substituted = false
  new_string = string.sub(/H(\d*)/) { substituted=true; "H#{$1.to_i+1}" }
  unless substituted
    new_string = string.sub("^(C?\d*)") { $1 + 'H' }
  end
  puts 'HERE'
  p string
  p new_string
  #@ob.set_formula(new_string)
  self
end

#add_polar_h!Object

only adds polar hydrogens. returns self



242
243
244
245
# File 'lib/rubabel/molecule.rb', line 242

def add_polar_h!
  @ob.add_polar_hydrogens
  self
end

#associate_atom!(arg) ⇒ Object

arg may be a Fixnum, a Symbol (Elemental symbol that is a Symbol), or a Rubabel::Atom. Returns the newly associated/created atom.



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/rubabel/molecule.rb', line 113

def associate_atom!(arg)
  if arg.is_a?(Rubabel::Atom)
    @ob.add_atom(arg.ob)
    arg
  else
    (num, is_aromatic) = 
      if arg.is_a?(Symbol)
        [Rubabel::ELEMENT_TO_NUM[arg], (arg.to_s.capitalize != arg.to_s)]
      else
        [arg, false]
      end

    new_obatom = @ob.new_atom
    new_obatom.set_atomic_num(num)
    new_obatom.set_aromatic if is_aromatic
    Rubabel::Atom.new(new_obatom)
  end
end

#atom(id) ⇒ Object

gets the atom by id



374
375
376
# File 'lib/rubabel/molecule.rb', line 374

def atom(id)
  @ob.get_atom_by_id(id).upcast
end

#atomsObject

returns the array of atoms. Consider using #each



379
380
381
# File 'lib/rubabel/molecule.rb', line 379

def atoms
  each_atom.map.to_a
end

#bond(id) ⇒ Object

gets the bond by id



364
365
366
# File 'lib/rubabel/molecule.rb', line 364

def bond(id)
  @ob.get_bond_by_id(id).upcast
end

#bondsObject

returns the array of bonds. Consider using #each_bond



369
370
371
# File 'lib/rubabel/molecule.rb', line 369

def bonds
  each_bond.map.to_a
end

#center!Object

centers the molecule (deals with the atomic coordinate systems for 2D or 3D molecules). returns self.



626
627
628
629
# File 'lib/rubabel/molecule.rb', line 626

def center!
  @ob.center
  self
end

#chargeObject



158
# File 'lib/rubabel/molecule.rb', line 158

def charge() @ob.get_total_charge end

#charge=(v) ⇒ Object



159
# File 'lib/rubabel/molecule.rb', line 159

def charge=(v) @ob.set_total_charge(v) end

#convert_dative_bonds!Object

returns self



619
620
621
622
# File 'lib/rubabel/molecule.rb', line 619

def convert_dative_bonds!
  @ob.convert_dative_bonds
  self
end

#correct_for_ph!(ph = 7.4) ⇒ Object

returns self. If ph is nil, then #neutral! is called



248
249
250
251
# File 'lib/rubabel/molecule.rb', line 248

def correct_for_ph!(ph=7.4)
  ph.nil? ? neutral! : @ob.correct_for_ph(ph)
  self
end

#csmilesObject

returns just the smiles string (not the id)



292
293
294
# File 'lib/rubabel/molecule.rb', line 292

def csmiles
  to_s(:can)
end

#dataObject

returns a Rubabel::MoleculeData hash



504
505
506
# File 'lib/rubabel/molecule.rb', line 504

def data
  Rubabel::MoleculeData.new(@ob)
end

#delete(obj) ⇒ Object

obj is an atom or bond



412
413
414
415
416
417
418
419
420
421
# File 'lib/rubabel/molecule.rb', line 412

def delete(obj)
  case obj
  when Rubabel::Bond
    delete_bond(obj)
  when Rubabel::Atom
    delete_atom(obj)
  else 
    raise(ArgumentError, "don't know how to delete objects of type: #{obj.class}")
  end
end

#delete_and_restore_bonds(*bonds, &block) ⇒ Object

yields self after deleting the specified bonds. When the block is closed the bonds are restored. Returns whatever is returned from the block.



459
460
461
462
463
464
465
466
467
468
# File 'lib/rubabel/molecule.rb', line 459

def delete_and_restore_bonds(*bonds, &block)
  bonds.each do |bond|
    unless @ob.delete_bond(bond.ob, false)
      raise "#{bond.inspect} not deleted!" 
    end
  end
  reply = block.call(self)
  bonds.each {|bond| @ob.add_bond(bond.ob) }
  reply
end

#delete_atom(atom) ⇒ Object



150
151
152
# File 'lib/rubabel/molecule.rb', line 150

def delete_atom(atom)
  @ob.delete_atom(atom.ob, false)
end

#delete_bond(*args) ⇒ Object

if given a bond, deletes it (doesn’t garbage collect). If given two atoms, deletes the bond between them.



425
426
427
428
429
430
431
432
# File 'lib/rubabel/molecule.rb', line 425

def delete_bond(*args)
  case args.size
  when 1
    @ob.delete_bond(args[0].ob, false)
  when 2
    @ob.delete_bond(args[0].get_bond(args[1]).ob, false)
  end
end

#dimObject



383
384
385
# File 'lib/rubabel/molecule.rb', line 383

def dim
  @ob.get_dimension
end

#each_atom(&block) ⇒ Object Also known as: each

iterates over the molecule’s Rubabel::Atom objects



331
332
333
334
335
336
337
338
339
340
# File 'lib/rubabel/molecule.rb', line 331

def each_atom(&block)
  # could use the C++ iterator in the future
  block or return enum_for(__method__)
  iter = @ob.begin_atoms
  atom = @ob.begin_atom(iter)
  while atom
    block.call atom.upcast
    atom = @ob.next_atom(iter)
  end
end

#each_bond(&block) ⇒ Object

iterates over the molecule’s Rubabel::Bond objects



344
345
346
347
348
349
350
351
352
353
354
# File 'lib/rubabel/molecule.rb', line 344

def each_bond(&block)
  # could use the C++ iterator in the future
  block or return enum_for(__method__)
  iter = @ob.begin_bonds
  obbond = @ob.begin_bond(iter)
  while obbond
    block.call obbond.upcast
    obbond = @ob.next_bond(iter)
  end
  self
end

#each_fragment(&block) ⇒ Object



483
484
485
486
487
488
# File 'lib/rubabel/molecule.rb', line 483

def each_fragment(&block)
  block or return enum_for(__method__)
  @ob.separate.each do |ob_mol|
    block.call( ob_mol.upcast )
  end
end

#each_match(smarts_or_string, uniq = true, &block) ⇒ Object

yields atom arrays matching the pattern. returns an enumerator if no block is given



195
196
197
198
199
200
201
# File 'lib/rubabel/molecule.rb', line 195

def each_match(smarts_or_string, uniq=true, &block)
  block or return enum_for(__method__, smarts_or_string, uniq)
  _atoms = self.atoms
  smarts_indices(smarts_or_string, uniq).each do |ar|
    block.call(_atoms.values_at(*ar))
  end
end

#equal?(other) ⇒ Boolean Also known as: eql?

checks to see if the molecules are the same OBMol object underneath by modifying one and seeing if the other changes. This is because openbabel routinely creates new objects that point to the same underlying data store, so even checking for OBMol equivalency is not enough.

Returns:

  • (Boolean)


301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
# File 'lib/rubabel/molecule.rb', line 301

def equal?(other)
  return false unless other.is_a?(self.class)
  are_identical = false
  if self.title == other.title
    begin
      obj_id = self.object_id.to_s
      self.title += obj_id
      are_identical = (self.title == other.title)
    ensure
      self.title.sub(/#{obj_id}$/,'')
    end
    are_identical
  else
    false
  end
end

#exact_massObject



166
# File 'lib/rubabel/molecule.rb', line 166

def exact_mass() @ob.get_exact_mass end

#formulaObject

returns a string representation of the molecular formula. Not sensitive to add_h!



175
# File 'lib/rubabel/molecule.rb', line 175

def formula() @ob.get_formula end

#graph_diameterObject

obconv.add_option(“u”,OpenBabel::OBConversion::OUTOPTIONS)

self

end



664
665
666
667
668
669
670
671
672
673
# File 'lib/rubabel/molecule.rb', line 664

def graph_diameter
  distance_matrix = Array.new
  self.atoms.each do |a|
    iter = OpenBabel::OBMolAtomBFSIter.new(self.ob, a.idx)
    while iter.inc.deref do
      distance_matrix << iter.current_depth - 1
    end
  end
  distance_matrix.max
end

#highlight_substructure!(substructure, color = 'red') ⇒ Object

returns self



644
645
646
647
648
649
# File 'lib/rubabel/molecule.rb', line 644

def highlight_substructure!(substructure, color='red')
  tmpconv = OpenBabel::OBConversion.new
  tmpconv.add_option("s",OpenBabel::OBConversion::GENOPTIONS, "#{substructure} #{color}")
  self.ob.do_transformations(tmpconv.get_options(OpenBabel::OBConversion::GENOPTIONS), tmpconv)
  self
end

#hydrogens_added?Boolean Also known as: h_added?

are there hydrogens added yet

Returns:

  • (Boolean)


225
226
227
# File 'lib/rubabel/molecule.rb', line 225

def hydrogens_added?
  @ob.has_hydrogens_added
end

#initialize_copy(source) ⇒ Object

creates a deep copy of the molecule (even the atoms are duplicated)



357
358
359
360
361
# File 'lib/rubabel/molecule.rb', line 357

def initialize_copy(source)
  super
  @ob = OpenBabel::OBMol.new(source.ob)
  self
end

#inspectObject



614
615
616
# File 'lib/rubabel/molecule.rb', line 614

def inspect
  "#<Mol #{to_s}>"
end

#kekulize!Object

returns self



632
633
634
635
# File 'lib/rubabel/molecule.rb', line 632

def kekulize!
  @ob.kekulize
  self
end

#local_optimize!(forcefield = DEFAULT_FORCEFIELD, steps = 500) ⇒ Object

adds hydrogens if necessary. Performs only steepest descent optimization (no rotors optimized) returns self



535
536
537
538
539
540
541
542
543
544
545
546
# File 'lib/rubabel/molecule.rb', line 535

def local_optimize!(forcefield=DEFAULT_FORCEFIELD, steps=500)
  add_h! unless hydrogens_added?
  if dim == 3
    ff = Rubabel.force_field(forcefield.to_s)
    ff.setup(@ob) || raise(OpenBabelUnableToSetupForceFieldError)
    ff.steepest_descent(steps)  # is the default termination count 1.0e-4 (used in obgen?)
    ff.update_coordinates(@ob)
  else
    make_3d!(forcefield, steps) 
  end
  self
end

#make_3d!(forcefield = DEFAULT_FORCEFIELD, steps = 50) ⇒ Object Also known as: make3d!

does a bit of basic local optimization unless steps is set to nil returns self



557
558
559
560
561
562
# File 'lib/rubabel/molecule.rb', line 557

def make_3d!(forcefield=DEFAULT_FORCEFIELD, steps=50)
  BUILDER.build(@ob)
  @ob.add_hydrogens(false, true) unless hydrogens_added?
  local_optimize!(forcefield, steps) if steps
  self
end

#massObject

returns the exact_mass corrected for charge gain/loss



169
170
171
# File 'lib/rubabel/molecule.rb', line 169

def mass
  @ob.get_exact_mass - (@ob.get_total_charge * Rubabel::MASS_E)
end

#matches(smarts_or_string, uniq = true) ⇒ Object

returns an array of matching atom sets. Consider using each_match.



204
205
206
# File 'lib/rubabel/molecule.rb', line 204

def matches(smarts_or_string, uniq=true)
  each_match(smarts_or_string, uniq).map.to_a
end

#matches?(smarts_or_string) ⇒ Boolean

Returns:

  • (Boolean)


208
209
210
211
# File 'lib/rubabel/molecule.rb', line 208

def matches?(smarts_or_string)
  # TODO: probably a more efficient way to do this using API
  smarts_indices(smarts_or_string).size > 0
end

#mol_wtObject Also known as: avg_mass



163
# File 'lib/rubabel/molecule.rb', line 163

def mol_wt() @ob.get_mol_wt end

#neutral!Object

simple method to coerce the molecule into a neutral charge state. It does this by removing any charge from each atom and then removing the hydrogens (which will then can be added back by the user and will be added back with proper valence). If the molecule had hydrogens added it will return the molecule with hydrogens added returns self.



259
260
261
262
263
264
265
# File 'lib/rubabel/molecule.rb', line 259

def neutral!
  had_hydrogens = h_added?
  atoms.each {|atom| atom.charge = 0 if (atom.charge != 0) }
  remove_h!
  add_h! if had_hydrogens 
  self
end

#new_bondObject

creates a new (as yet unspecified) bond associated with the molecule and gives it a unique id



446
447
448
# File 'lib/rubabel/molecule.rb', line 446

def new_bond
  @ob.new_bond.upcast
end

#num_atoms(count_implied_hydrogens = false) ⇒ Object

sensitive to add_h!



509
510
511
512
513
514
515
# File 'lib/rubabel/molecule.rb', line 509

def num_atoms(count_implied_hydrogens=false) 
  if !count_implied_hydrogens
    @ob.num_atoms  
  else
    @ob.num_atoms + reduce(0) {|cnt, atom| cnt + atom.ob.implicit_hydrogen_count }
  end
end

#num_bondsObject



516
# File 'lib/rubabel/molecule.rb', line 516

def num_bonds() @ob.num_bonds  end

#num_hvy_atomsObject



517
# File 'lib/rubabel/molecule.rb', line 517

def num_hvy_atoms() @ob.num_hvy_atoms  end

#num_residuesObject



518
# File 'lib/rubabel/molecule.rb', line 518

def num_residues() @ob.num_residues  end

#num_rotorsObject



519
# File 'lib/rubabel/molecule.rb', line 519

def num_rotors() @ob.num_rotors  end

#ob_fingerprint(type = DEFAULT_FINGERPRINT) ⇒ Object

returns a std::vector<unsigned int> that can be passed directly into the OBFingerprint.tanimoto method



404
405
406
407
408
409
# File 'lib/rubabel/molecule.rb', line 404

def ob_fingerprint(type=DEFAULT_FINGERPRINT)
  fprinter = OpenBabel::OBFingerprint.find_fingerprint(type) || raise(ArgumentError, "fingerprint type not found")
  fp = OpenBabel::VectorUnsignedInt.new
  fprinter.get_fingerprint(@ob, fp) || raise("failed to get fingerprint for #{mol}")
  fp
end

#ob_sssrObject

returns an array of OpenBabel::OBRing objects.



214
215
216
# File 'lib/rubabel/molecule.rb', line 214

def ob_sssr
  @ob.get_sssr.to_a
end

#png_transformer(type_s, out_options = {}, &block) ⇒ Object

yields the type of object. Expects the block to yield the image string.



566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
# File 'lib/rubabel/molecule.rb', line 566

def png_transformer(type_s, out_options={}, &block)
  orig_out_options = out_options[:size]
  if type_s == 'png'
    png_output = true
    type_s = 'svg'
    if out_options[:size]
      unless out_options[:size].to_s =~ /x/i
        out_options[:size] = out_options[:size].to_s + 'x' + out_options[:size].to_s
      end
    end
  else
    if out_options[:size].is_a?(String) && (out_options[:size] =~ /x/i)
      warn 'can only use the width dimension for this format'
      out_options[:size] = out_options[:size].split(/x/i).first
    end
  end
  image_blob = block.call(type_s, out_options)
  if png_output
    st = StringIO.new
    image = MiniMagick::Image.read(image_blob, 'svg')
    image.format('png')
    # would like to resize as an svg, then output the png of proper
    # granularity...
    image.resize(out_options[:size]) if out_options[:size]
    image_blob = image.write(st).string
  end
  out_options[:size] = orig_out_options
  image_blob
end

#remove_h!Object

returns self



281
282
283
284
# File 'lib/rubabel/molecule.rb', line 281

def remove_h!
  @ob.delete_hydrogens
  self
end

#smarts_indices(smarts_or_string, uniq = true) ⇒ Object

returns a list of atom indices matching the patterns (corresponds to the OBSmartsPattern::GetUMapList() method if uniq==true and GetMapList method if uniq==false). Note that the original GetUMapList returns atom numbers (i.e., the index + 1). This method returns the zero indexed indices.



186
187
188
189
190
191
# File 'lib/rubabel/molecule.rb', line 186

def smarts_indices(smarts_or_string, uniq=true)
  mthd = uniq ? :get_umap_list : :get_map_list
  pattern = smarts_or_string.is_a?(Rubabel::Smarts) ? smarts_or_string : Rubabel::Smarts.new(smarts_or_string)
  pattern.ob.match(@ob)
  pattern.ob.send(mthd).map {|atm_indices| atm_indices.map {|i| i - 1 } }
end

#smilesObject

returns just the smiles string :smi (not the id)



287
288
289
# File 'lib/rubabel/molecule.rb', line 287

def smiles
  to_s(:smi)
end

#spinObject



161
# File 'lib/rubabel/molecule.rb', line 161

def spin() @ob.get_total_spin_multiplicity end

#split(*bonds) ⇒ Object

splits the molecules at the given bonds and returns the fragments. Does not alter the caller. If the molecule is already fragmented, then returns the separate fragments.



473
474
475
476
477
478
479
480
481
# File 'lib/rubabel/molecule.rb', line 473

def split(*bonds)
  if bonds.size > 0
    delete_and_restore_bonds(*bonds) do |mol|
      mol.ob.separate.map(&:upcast)
    end
  else
    self.ob.separate.map(&:upcast)
  end
end

#strip_salts!Object

returns self



638
639
640
641
# File 'lib/rubabel/molecule.rb', line 638

def strip_salts!
  @ob.strip_salts!
  self
end

#swap!(anchor1, to_move1, anchor2, to_move2) ⇒ Object

swaps to_move1 for to_move2 on the respective anchors returns self



440
441
442
443
# File 'lib/rubabel/molecule.rb', line 440

def swap!(anchor1, to_move1, anchor2, to_move2)
  OpenBabel::OBBuilder.swap(@ob, *[anchor1, to_move1, anchor2, to_move2].map {|at| at.ob.get_idx } )
  self
end

#tanimoto(other, type = DEFAULT_FINGERPRINT) ⇒ Object

TODO: implement list of supported descriptors. (Not Yet Implemented!) def descs end



398
399
400
# File 'lib/rubabel/molecule.rb', line 398

def tanimoto(other, type=DEFAULT_FINGERPRINT)
  other.nil? ? 0 : Rubabel::Molecule.tanimoto(self, other, type)
end

#titleObject

attributes



155
# File 'lib/rubabel/molecule.rb', line 155

def title() @ob.get_title end

#title=(val) ⇒ Object



156
# File 'lib/rubabel/molecule.rb', line 156

def title=(val) @ob.set_title(val) end

#to_s(type = DEFAULT_OUT_TYPE) ⇒ Object

emits smiles without the trailing tab, newline, or id. Use write_string to get the default OpenBabel behavior (ie., tabs and newlines).



492
493
494
495
496
497
498
499
500
501
# File 'lib/rubabel/molecule.rb', line 492

def to_s(type=DEFAULT_OUT_TYPE)
  string = write_string(type)
  case type
  when :smi, :smiles, :can
    # remove name with openbabel options in the future
    string.split(/\s+/).first
  else
    string
  end
end

#write(filename_or_type = :can, out_options = {}) ⇒ Object

If filename_or_type is a symbol, then it will return a string of that type. If filename_or_type is a string, will write to the filename given no args, returns a DEFAULT_OUT_TYPE string



524
525
526
527
528
529
530
# File 'lib/rubabel/molecule.rb', line 524

def write(filename_or_type=:can, out_options={})
  if filename_or_type.is_a?(Symbol)
    write_string(filename_or_type, out_options)
  else
    write_file(filename_or_type, out_options)
  end
end

#write_file(filename, out_options = {}) ⇒ Object

writes to the file based on the extension given (must be recognized by OpenBabel). If png is the extension or format, the png is generated from an svg.



609
610
611
612
# File 'lib/rubabel/molecule.rb', line 609

def write_file(filename, out_options={})
  type = Rubabel.filetype(filename)
  File.write(filename, write_string(type, out_options))
end

#write_string(type = DEFAULT_OUT_TYPE, out_options = {}) ⇒ Object

out_options include any of those defined



597
598
599
600
601
602
603
604
# File 'lib/rubabel/molecule.rb', line 597

def write_string(type=DEFAULT_OUT_TYPE, out_options={})
  png_transformer(type.to_s, out_options) do |type_s, _out_opts|
    obconv = out_options[:obconv] || OpenBabel::OBConversion.new
    obconv.set_out_format(type_s)
    obconv.add_opts!(:out, _out_opts)
    obconv.write_string(@ob)
  end
end