lib/rubabel/atom.rb in rubabel-0.1.6 vs lib/rubabel/atom.rb in rubabel-0.2.0

- old
+ new

@@ -77,11 +77,10 @@ block.call _bond.upcast _bond = @ob.next_bond(iter) end end - alias_method :each, :each_bond # retrieves the bond def get_bond(atom) @ob.get_bond(atom.ob).andand.upcast end @@ -99,10 +98,11 @@ while _atom block.call _atom.upcast _atom = @ob.next_nbr_atom(iter) end end + alias_method :each, :each_atom # returns the neighboring atoms. Consider using each_atom. def atoms each_atom.map.to_a end @@ -151,10 +151,83 @@ def partial_charge @ob.get_partial_charge end + # permanently removes a hydrogen by properly incrementing the + # spin_multiplicity (and deleting a hydrogen if one is explicitly attached + # to the atom). If called with cnt=2 a carbene or nitrene can be made + # (giving a spin_multiplicity of 3). Makes no effort to ensure that the + # proper number of hydrogens already exist to be deleted, just alters the + # spin_multiplicity and deletes the right number of hydrogens if they are + # available to be deleted. Adds one charge to the atom. + def remove_an_h!(add_charge=true) + new_spin = + case @ob.get_spin_multiplicity + when 0 then 2 + when 2 then 3 + end + @ob.set_spin_multiplicity(new_spin) + atoms.each do |atom| + if atom.atomic_num == 1 + self.mol.delete_atom(atom) + break + end + end + # add the charge + (self.charge = charge + 1) if add_charge + self + end + + # philosophy on equality: there are *so* many ways for two atoms to be + # different that we can never really ensure that "equivalence" is met + # without calling ~20 methods. We narrowly define equivalence so it is + # useful for that case and let the user make more complicated + # equivalency/equality definitions themselves. + + # the exact same atom in the same molecule. The equivalency test for + # molecules is a little pricey, so better to use something like atom.id == + # other.id if you know you are working within the same molecule. + def equal?(other) + other.respond_to?(:mol) && mol.equal?(other.mol) && id == other.id + end + + alias_method :==, :equal? + alias_method :eql?, :equal? + + ## opposite of remove_an_h! + ## THIS IS STILL BROKEN!!! + # maybe need to change the type?? C+ -> C2 or C3, but this gets really + # invasive... Why is this so flippin hard to do!! + #def add_an_h!(remove_charge=true) + #new_spin = + #case @ob.get_spin_multiplicity + #when 2 then 0 + #when [1,3] then 2 + #end + #@ob.set_spin_multiplicity(new_spin) + + #puts self.inspect_internals + #puts "EXAMIN B:" + #p self + #p self.charge + #(self.charge = self.charge - 1) if remove_charge + #puts "EXAMIN A:" + #puts self.inspect_internals + #p self + #p self.charge + #puts "BEFORE:" + #p mol.formula + #p mol.atoms + #mol.add_bond!(self, mol.add_atom!(1)) + #puts "AFTER:" + #p mol.formula + #p mol.atoms + #abort 'here' + #self + #end + def spin @ob.get_spin_multiplicity end def type @@ -201,14 +274,31 @@ def chiral_volume?() @ob.has_chiral_volume end def hbond_acceptor?() @ob.is_hbond_acceptor end def hbond_donor?() @ob.is_hbond_donor end def hbond_donor_h?() @ob.is_hbond_donor_h end + def double_bond? + each_bond.any? {|bond| bond.bond_order == 2 } + end + + def single_bond? + each_bond.any? {|bond| bond.bond_order == 1 } + end + def carboxyl_carbon? - atoms.any?(&:carboxyl_oxygen?) + each_atom.any?(&:carboxyl_oxygen?) end + def carbonyl_oxygen? + ats = atoms + ats.size == 1 && ats.first.el == :c && double_bond? + end + + def carbonyl_carbon? + each_atom.any?(&:carbonyl_oxygen?) + end + # # does this carbon hold a primary alcohol # def primary_alcohol_carbon? # end def coords @@ -216,7 +306,19 @@ end def inspect "<#{type} id:#{id}>" end + + def inspect_internals + "<" << @ob.methods.grep(/get_/).map do |mthd| + begin + "#{mthd.to_s.sub(/get_/,'')}=#{@ob.send(mthd)}" + rescue ArgumentError + nil + end + end.compact.join(" ") << ">" + end + + end end