Module: Rubabel::Molecule::Fragmentable
- Included in:
- Rubabel::Molecule
- Defined in:
- lib/rubabel/molecule/fragmentable.rb
Constant Summary collapse
- RULES =
:sp3c_oxygen_asymmetric_far_sp3, :sp3c_nitrogen_asymmetric_far_sp3, RULES = Set[ :alcohol_to_aldehyde, :peroxy_to_carboxy, :co2_loss,
:sp3c_oxygen_double_bond_far_side_sp3, :sp3c_oxygen_double_bond_far_side_sp2, :sp3c_oxygen_double_bond_water_loss, :sp3c_nitrogen_double_bond,
] ADDUCTS = [:lioh, :nh4cl, :nh4oh] CO_RULES = Set[:alcohol_to_aldehyde, :peroxy_to_carboxy, :co2_loss,
:sp3c_oxygen_double_bond_water_loss, :sp3c_oxygen_double_bond_far_side_sp2, :sp3c_oxygen_double_bond_far_side_sp3, :sp3c_oxygen_asymmetric_far_sp3
]
Set[:cad_o, :cad_oo, :oxed_ether]
- DEFAULT_OPTIONS =
{ rules: RULES, #adduct: nil, #ph: 7.4, # return only the set of unique fragments uniq: false, }
Instance Method Summary collapse
- #alcohol_to_aldehyde(carbon, oxygen, carbon_nbrs) ⇒ Object
-
#allowable_fragment_sets!(fragment_sets) ⇒ Object
add_h! to self, then selects allowable fragments.
-
#allowable_fragmentation?(frags) ⇒ Boolean
molecules and fragments should all have hydrogens added (add_h!) before calling this method.
-
#carbon_oxygen_esteal(carbon, oxygen) ⇒ Object
breaks the bond and gives the electrons to the oxygen.
-
#carbonyl_oxygen_dump(carbon, oxygen, carbon_nbr) ⇒ Object
splits the molecule between the carbon and carbon_nbr, adds a double bond between the carbon and oxygen, and moves whatever was on the oxygen (e.g., an OH or a charge) to the carbon_nbr.
- #co2_loss(carbon, oxygen, c3_nbr) ⇒ Object
-
#electrophile_snatches_electrons(carbon, electrophile) ⇒ Object
warning, this method adds_h! to the calling molecule.
-
#feint_double_bond(bond, give_e_pair = nil, get_e_pair = nil, &block) ⇒ Object
will turn bond into a double bond, yield the changed molecule, then return the bond to the original state when the block is closed returns whatever the block returned.
- #feint_e_transfer(give_e_pair = nil, get_e_pair = nil, &block) ⇒ Object
-
#fragment(opts = {}) ⇒ Object
an empty array is returned if there are no fragments generated.
- #near_side_double_bond_break(carbon, electrophile) ⇒ Object
- #peroxy_to_carboxy(carbon, oxygen, carbon_nbrs, oxygen_nbr) ⇒ Object
Instance Method Details
#alcohol_to_aldehyde(carbon, oxygen, carbon_nbrs) ⇒ Object
103 104 105 106 107 108 109 110 111 112 |
# File 'lib/rubabel/molecule/fragmentable.rb', line 103 def alcohol_to_aldehyde(carbon, oxygen, carbon_nbrs) # alcohol becomes a ketone and one R group is released frag_sets = carbon_nbrs.select {|atom| atom.type == 'C3' }.map do |_atom| frags = feint_double_bond(carbon.get_bond(oxygen)) do |_mol| frags = _mol.split(carbon.get_bond(_atom)) frags.map(&:add_h!) end end allowable_fragment_sets!(frag_sets) end |
#allowable_fragment_sets!(fragment_sets) ⇒ Object
add_h! to self, then selects allowable fragments
40 41 42 43 44 45 46 47 48 |
# File 'lib/rubabel/molecule/fragmentable.rb', line 40 def allowable_fragment_sets!(fragment_sets) self.add_h! fragment_sets.select do |_frags| putsv "ExMAIN:" putsv _frags.inspect putsv self.allowable_fragmentation?(_frags) self.allowable_fragmentation?(_frags) end end |
#allowable_fragmentation?(frags) ⇒ Boolean
molecules and fragments should all have hydrogens added (add_h!) before calling this method
For instance, water loss with double bond formation is not allowable for NCC(O)CC => CCC=C, presumably because of the lone pair and double bond resonance.
35 36 37 |
# File 'lib/rubabel/molecule/fragmentable.rb', line 35 def allowable_fragmentation?(frags) self.num_atoms == frags.map(&:num_atoms).reduce(:+) end |
#carbon_oxygen_esteal(carbon, oxygen) ⇒ Object
breaks the bond and gives the electrons to the oxygen
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/rubabel/molecule/fragmentable.rb', line 175 def carbon_oxygen_esteal(carbon, oxygen) nmol = self.dup nmol.ob.add_hydrogens ncarbon = nmol.atom(carbon.id) noxygen = nmol.atom(oxygen.id) nmol.delete_bond(ncarbon, noxygen) ncarbon.charge += 1 noxygen.charge -= 1 ncarbon.remove_an_h! #p ncarbon.ob.implicit_hydrogen_count #p ncarbon #ncarbon.ob.decrement_implicit_valence #p ncarbon.ob.implicit_hydrogen_count #p ncarbon #ncarbon.ob.increment_implicit_valence nmol.title = nmol.to_s p nmol.write("tmp.svg") parts = nmol.split p z=parts.first p z.formula p z.mass p z.exact_mass puts "HIAY" end |
#carbonyl_oxygen_dump(carbon, oxygen, carbon_nbr) ⇒ Object
splits the molecule between the carbon and carbon_nbr, adds a double bond between the carbon and oxygen, and moves whatever was on the oxygen (e.g., an OH or a charge) to the carbon_nbr. Returns two new molecules.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/rubabel/molecule/fragmentable.rb', line 151 def carbonyl_oxygen_dump(carbon, oxygen, carbon_nbr) appendage = oxygen.atoms.find {|a| a.el != :c } if oxygen.charge != 0 ocharge = oxygen.charge end nmol = self.dup new_oxygen = nmol.atom(oxygen.id) new_carbon = nmol.atom(carbon.id) new_carbon_nbr = nmol.atom(carbon_nbr.id) new_appendage = nmol.atom(appendage.id) if appendage nmol.delete_bond(new_carbon.get_bond(new_carbon_nbr)) if new_appendage nmol.delete_bond(new_oxygen.get_bond(new_appendage)) nmol.add_bond!(new_carbon_nbr, new_appendage) end if ocharge new_carbon_nbr.charge += ocharge new_oxygen.charge -= ocharge end new_carbon.get_bond(new_oxygen).bond_order = 2 nmol.split end |
#co2_loss(carbon, oxygen, c3_nbr) ⇒ Object
114 115 116 117 118 119 120 121 122 123 |
# File 'lib/rubabel/molecule/fragmentable.rb', line 114 def co2_loss(carbon, oxygen, c3_nbr) # carboxyl rules ... # neutral carbon dioxide loss with anion gain on attaching group # (if carbon) frags = feint_double_bond(carbon.get_bond(oxygen), oxygen, c3_nbr) do |_mol| frags = _mol.split(c3_nbr.get_bond(carbon)) frags.map(&:add_h!) end allowable_fragment_sets!([frags]) end |
#electrophile_snatches_electrons(carbon, electrophile) ⇒ Object
warning, this method adds_h! to the calling molecule
67 68 69 70 71 72 73 |
# File 'lib/rubabel/molecule/fragmentable.rb', line 67 def electrophile_snatches_electrons(carbon, electrophile) self.add_h! frags = self.split(carbon.get_bond(electrophile)) raise NotImplementedError # don't check for allowable fragments because it #allowable_fragment_sets!([frag_set]) end |
#feint_double_bond(bond, give_e_pair = nil, get_e_pair = nil, &block) ⇒ Object
will turn bond into a double bond, yield the changed molecule, then return the bond to the original state when the block is closed returns whatever the block returned
53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/rubabel/molecule/fragmentable.rb', line 53 def feint_double_bond(bond, give_e_pair=nil, get_e_pair=nil, &block) orig = bond.bond_order bond.bond_order = 2 reply = if give_e_pair || get_e_pair feint_e_transfer(give_e_pair, get_e_pair, &block) else block.call(self) end bond.bond_order = orig reply end |
#feint_e_transfer(give_e_pair = nil, get_e_pair = nil, &block) ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/rubabel/molecule/fragmentable.rb', line 75 def feint_e_transfer(give_e_pair=nil, get_e_pair=nil, &block) if give_e_pair gc_orig = give_e_pair.charge give_e_pair.charge = gc_orig + 1 end if get_e_pair rc_orig = get_e_pair.charge get_e_pair.charge = rc_orig - 1 end reply = block.call(self) give_e_pair.charge = gc_orig if give_e_pair get_e_pair.charge = rc_orig if get_e_pair reply end |
#fragment(opts = {}) ⇒ Object
an empty array is returned if there are no fragments generated. Hydrogens are added at a pH of 7.4, unless they have already been added.
:rules => queryable by :include? set of rules
:uniq => false
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/rubabel/molecule/fragmentable.rb', line 208 def fragment(opts={}) only_uniqs = true opts = DEFAULT_OPTIONS.merge(opts) opts[:rules].each do |rule| raise ArgumentError, "bad rule: #{rule}" unless RULES.include?(rule) end had_hydrogens = self.h_added? self.correct_for_ph!(7.4) unless had_hydrogens self.remove_h! fragment_sets = [] if opts[:rules].any? {|r| [:cad_o, :cad_oo].include?(r) } self.each_match("C[O;h1,O]", only_uniqs) do |carbon, oxygen| carbon.atoms.select {|a| a.el == :c }.each do |carbon_nbr| fragment_sets << carbonyl_oxygen_dump(carbon, oxygen, carbon_nbr) end end end if opts[:rules].any? {|r| [:oxed_ether].include?(r) } self.each_match("C[O&X2]", only_uniqs) do |carbon, oxygen| fragment_sets << carbon_oxygen_esteal(carbon, oxygen) end end unless had_hydrogens fragment_sets.each {|set| set.each(&:remove_h!) } self.remove_h! end if opts[:uniq] # TODO: impelent properly raise NotImplementedError #fragment_sets = fragment_sets.uniq_by(&:csmiles) end fragment_sets end |
#near_side_double_bond_break(carbon, electrophile) ⇒ Object
93 94 95 96 97 98 99 100 101 |
# File 'lib/rubabel/molecule/fragmentable.rb', line 93 def near_side_double_bond_break(carbon, electrophile) frag_sets = carbon.atoms.select {|atom| atom.type == "C3" }.map do |near_c3| frags = feint_double_bond(carbon.get_bond(near_c3)) do |_mol| frags = _mol.split(electrophile.get_bond(carbon)) frags.map(&:add_h!) end end allowable_fragment_sets!(frag_sets) end |
#peroxy_to_carboxy(carbon, oxygen, carbon_nbrs, oxygen_nbr) ⇒ Object
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/rubabel/molecule/fragmentable.rb', line 125 def peroxy_to_carboxy(carbon, oxygen, carbon_nbrs, oxygen_nbr) if oxygen_nbr.el == :o # has a neighbor oxygen distal_o = oxygen_nbr if distal_o.bonds.size == 1 # this is a peroxy frag_sets = carbon_nbrs.select {|atom| atom.type == 'C3' }.map do |_atom| self.swap!(carbon, _atom, oxygen, distal_o) frags = feint_double_bond(carbon.get_bond(oxygen)) do |_mol| # we swapped the atoms so the bond to split off is now # attached to the oxygen frags = _mol.split(oxygen.get_bond(_atom)) frags.map(&:add_h!) end self.swap!(carbon, distal_o, oxygen, _atom) frags end allowable_fragment_sets!(frag_sets) end end end |