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