rubabel 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/rubabel/molecule.rb +0 -1
- data/lib/rubabel/version.rb +1 -1
- metadata +3 -8
- data/bin/fragmenter.rb +0 -67
- data/lib/rubabel/molecule/fragmentable.rb +0 -162
- data/spec/rubabel/molecule/fragmentable_spec.rb +0 -199
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c407acb50267d5d801e3b17c7ca6c9090f09935
|
4
|
+
data.tar.gz: dc4f917d5688fd3be0b593bb34d3f25edce5b362
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 618fb4a2d529cdbf7c3ec1ae1fc85088a92cd4b554d43f95bfa527bb15c1cae946a45474c1553db0a4ab456cf70a7cd5c6566a47856a0a4f4656c251378ff067
|
7
|
+
data.tar.gz: eeb366cb6d73da968fd54dae44e6f64d3edc485a0913742713846ed7b28dabdb89708533d145dfc6ad6bf6b164a6584f8288120e45dc19e82c7af9e9410fa8a2
|
data/lib/rubabel/molecule.rb
CHANGED
data/lib/rubabel/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubabel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John T. Prince
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-06-
|
11
|
+
date: 2013-06-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: openbabel
|
@@ -139,8 +139,7 @@ dependencies:
|
|
139
139
|
description: Ruby interface to the OpenBabel ruby bindings similar to pybel
|
140
140
|
email:
|
141
141
|
- jtprince@gmail.com
|
142
|
-
executables:
|
143
|
-
- fragmenter.rb
|
142
|
+
executables: []
|
144
143
|
extensions: []
|
145
144
|
extra_rdoc_files: []
|
146
145
|
files:
|
@@ -152,7 +151,6 @@ files:
|
|
152
151
|
- README.md
|
153
152
|
- Rakefile
|
154
153
|
- VERSION
|
155
|
-
- bin/fragmenter.rb
|
156
154
|
- lib/rubabel.rb
|
157
155
|
- lib/rubabel/atom.rb
|
158
156
|
- lib/rubabel/bond.rb
|
@@ -160,7 +158,6 @@ files:
|
|
160
158
|
- lib/rubabel/core_ext/putsv.rb
|
161
159
|
- lib/rubabel/fingerprint.rb
|
162
160
|
- lib/rubabel/molecule.rb
|
163
|
-
- lib/rubabel/molecule/fragmentable.rb
|
164
161
|
- lib/rubabel/molecule_data.rb
|
165
162
|
- lib/rubabel/pm.rb
|
166
163
|
- lib/rubabel/smarts.rb
|
@@ -186,7 +183,6 @@ files:
|
|
186
183
|
- spec/chemistry_toolkit_rosetta/tpsa.tab
|
187
184
|
- spec/rubabel/atom_spec.rb
|
188
185
|
- spec/rubabel/bond_spec.rb
|
189
|
-
- spec/rubabel/molecule/fragmentable_spec.rb
|
190
186
|
- spec/rubabel/molecule_data_spec.rb
|
191
187
|
- spec/rubabel/molecule_spec.rb
|
192
188
|
- spec/rubabel_spec.rb
|
@@ -236,7 +232,6 @@ test_files:
|
|
236
232
|
- spec/chemistry_toolkit_rosetta/tpsa.tab
|
237
233
|
- spec/rubabel/atom_spec.rb
|
238
234
|
- spec/rubabel/bond_spec.rb
|
239
|
-
- spec/rubabel/molecule/fragmentable_spec.rb
|
240
235
|
- spec/rubabel/molecule_data_spec.rb
|
241
236
|
- spec/rubabel/molecule_spec.rb
|
242
237
|
- spec/rubabel_spec.rb
|
data/bin/fragmenter.rb
DELETED
@@ -1,67 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'trollop'
|
4
|
-
require 'rubabel'
|
5
|
-
require 'rubabel/molecule/fragmentable'
|
6
|
-
|
7
|
-
default_ph = 2.5
|
8
|
-
|
9
|
-
Fragment = Struct.new(:frag, :id, :title, :mz, :mass, :charge, :smiles, :pairing)
|
10
|
-
|
11
|
-
parser = Trollop::Parser.new do
|
12
|
-
banner "usage: #{File.basename($0)} [OPTIONS|RULES] <SMARTS> ..."
|
13
|
-
text "\noptions:"
|
14
|
-
opt :ph, "the pH to use (experimental option)", :default => default_ph
|
15
|
-
opt :images, "print out svg images of fragments"
|
16
|
-
opt :format, "format of the molecules", :default => 'smiles'
|
17
|
-
#opt :uniq, "no repeated fragments", :default => false
|
18
|
-
text "\nrules:"
|
19
|
-
Rubabel::Molecule::Fragmentable::RULES.each do |rule|
|
20
|
-
opt rule, rule.to_s.gsub("_",' ')
|
21
|
-
end
|
22
|
-
text "\nexample:"
|
23
|
-
text "fragmenter.rb -xeh 'CCC(=O)OCCC' 'CCC(=O)OCCC(=O)O'"
|
24
|
-
end
|
25
|
-
|
26
|
-
options = parser.parse(ARGV)
|
27
|
-
opts = {rules: []}
|
28
|
-
opts[:uniq] = options.delete(:uniq)
|
29
|
-
ph = options.delete(:ph)
|
30
|
-
opts[:rules] = Rubabel::Molecule::Fragmentable::RULES.map do |rule|
|
31
|
-
rule if options["#{rule}_given".to_sym]
|
32
|
-
end.compact
|
33
|
-
|
34
|
-
if ARGV.size == 0
|
35
|
-
parser.educate && exit
|
36
|
-
end
|
37
|
-
|
38
|
-
ARGV.each do |smiles|
|
39
|
-
mol = Rubabel[smiles, options[:format].to_sym]
|
40
|
-
puts "\nmolecule: #{mol.csmiles}"
|
41
|
-
mol.correct_for_ph!(ph)
|
42
|
-
puts "at ph #{ph}: #{mol.csmiles}"
|
43
|
-
fragment_sets = mol.fragment(opts)
|
44
|
-
puts %w(mz mass charge title smiles pairing).join("\t")
|
45
|
-
frags = []
|
46
|
-
fragment_sets.each_with_index do |frag_set,i|
|
47
|
-
frag_set.each_with_index do |frag,j|
|
48
|
-
unless frag.charge == 0
|
49
|
-
mz = (frag.mass / frag.charge).round(5)
|
50
|
-
end
|
51
|
-
|
52
|
-
frag.title = "#{i}-#{j}pair_" + (mz ? "#{mz}_mz" : "#{frag.mass.round(3)}_Mass")
|
53
|
-
frag_obj = Fragment.new(frag, frag.title, frag.title, mz, frag.exact_mass, frag.charge, frag.csmiles, i)
|
54
|
-
frags << frag_obj
|
55
|
-
end
|
56
|
-
end
|
57
|
-
frags = frags.sort_by {|frag| [-frag.charge, frag.mz] }
|
58
|
-
if options[:images]
|
59
|
-
frags.each do |frag|
|
60
|
-
fn = "#{frag.title}.png"
|
61
|
-
frag.frag.write(fn)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
frags.each do |frag|
|
65
|
-
puts [:mz, :mass, :charge, :title, :smiles, :pairing].map {|cat| frag.send(cat) }.join("\t")
|
66
|
-
end
|
67
|
-
end
|
@@ -1,162 +0,0 @@
|
|
1
|
-
require 'set'
|
2
|
-
require 'rubabel/core_ext/putsv'
|
3
|
-
require 'rubabel/core_ext/enumerable'
|
4
|
-
|
5
|
-
module Rubabel
|
6
|
-
class Molecule
|
7
|
-
module Fragmentable
|
8
|
-
|
9
|
-
#RULES = Set[:cod, :codoo, :oxe, :oxepd, :oxh]
|
10
|
-
RULES = Set[:cod, :codoo, :oxe, :oxepd, :oxh, :oxhpd]
|
11
|
-
|
12
|
-
DEFAULT_OPTIONS = {
|
13
|
-
rules: RULES,
|
14
|
-
errors: :remove,
|
15
|
-
# return only the set of unique fragments
|
16
|
-
uniq: false,
|
17
|
-
}
|
18
|
-
|
19
|
-
# molecules and fragments should all have hydrogens added (add_h!)
|
20
|
-
# before calling this method
|
21
|
-
#
|
22
|
-
# For instance, water loss with double bond formation is not allowable
|
23
|
-
# for NCC(O)CC => CCC=C[NH2+], presumably because of the lone pair and
|
24
|
-
# double bond resonance.
|
25
|
-
def allowable_fragmentation?(frags)
|
26
|
-
self.num_atoms(true) == frags.reduce(0) {|cnt,fr| cnt + fr.num_atoms(true) }
|
27
|
-
end
|
28
|
-
|
29
|
-
# splits the molecule between the carbon and carbon_nbr, adds a double
|
30
|
-
# bond between the carbon and oxygen, and moves whatever was on the
|
31
|
-
# oxygen (e.g., an OH or a charge) to the carbon_nbr. Returns two new
|
32
|
-
# molecules.
|
33
|
-
def carbonyl_oxygen_dump(carbon, oxygen, carbon_nbr)
|
34
|
-
appendage = oxygen.atoms.find {|a| a.el != :C }
|
35
|
-
if oxygen.charge != 0
|
36
|
-
ocharge = oxygen.charge
|
37
|
-
end
|
38
|
-
nmol = self.dup
|
39
|
-
new_oxygen = nmol.atom(oxygen.id)
|
40
|
-
new_carbon = nmol.atom(carbon.id)
|
41
|
-
new_carbon_nbr = nmol.atom(carbon_nbr.id)
|
42
|
-
new_appendage = nmol.atom(appendage.id) if appendage
|
43
|
-
nmol.delete_bond(new_carbon.get_bond(new_carbon_nbr))
|
44
|
-
if new_appendage
|
45
|
-
nmol.delete_bond(new_oxygen.get_bond(new_appendage))
|
46
|
-
nmol.add_bond!(new_carbon_nbr, new_appendage)
|
47
|
-
end
|
48
|
-
if ocharge
|
49
|
-
new_carbon_nbr.charge += ocharge
|
50
|
-
new_oxygen.charge -= ocharge
|
51
|
-
end
|
52
|
-
new_carbon.get_bond(new_oxygen).bond_order = 2
|
53
|
-
nmol.split
|
54
|
-
end
|
55
|
-
|
56
|
-
# breaks the bond and gives the electrons to the oxygen
|
57
|
-
def carbon_oxygen_esteal(carbon, oxygen)
|
58
|
-
nmol = self.dup
|
59
|
-
ncarbon = nmol.atom(carbon.id)
|
60
|
-
noxygen = nmol.atom(oxygen.id)
|
61
|
-
|
62
|
-
is_carboxyl = noxygen.carboxyl_oxygen?
|
63
|
-
|
64
|
-
nmol.delete_bond(ncarbon, noxygen)
|
65
|
-
ncarbon.remove_a_hydride!
|
66
|
-
noxygen.remove_a_proton!
|
67
|
-
nmol.split
|
68
|
-
end
|
69
|
-
|
70
|
-
# returns the duplicated molecule and the equivalent atoms
|
71
|
-
def dup_molecule(atoms=[])
|
72
|
-
nmol = self.dup
|
73
|
-
[nmol, atoms.map {|old_atom| nmol.atom(old_atom.id) }]
|
74
|
-
end
|
75
|
-
|
76
|
-
# returns molecules created from splitting between the electrophile and
|
77
|
-
# the center and where the bond order is increased between the center
|
78
|
-
# and center_nbr
|
79
|
-
def break_with_double_bond(electrophile, center, center_nbr)
|
80
|
-
(nmol, (nele, ncarb, ncarb_nbr)) = self.dup_molecule([electrophile, center, center_nbr])
|
81
|
-
nmol.delete_bond(nele, ncarb)
|
82
|
-
ncarb_nbr.get_bond(ncarb) + 1
|
83
|
-
nmol.split
|
84
|
-
end
|
85
|
-
|
86
|
-
# an empty array is returned if there are no fragments generated.
|
87
|
-
# Hydrogens are added at a pH of 7.4, unless they have already been
|
88
|
-
# added.
|
89
|
-
#
|
90
|
-
# :rules => queryable by :include? set of rules
|
91
|
-
# :uniq => false
|
92
|
-
# :errors => :remove | :fix | :ignore (default is :remove)
|
93
|
-
def fragment(opts={})
|
94
|
-
only_uniqs = true
|
95
|
-
opts = DEFAULT_OPTIONS.merge(opts)
|
96
|
-
opts[:rules].each do |rule|
|
97
|
-
raise ArgumentError, "bad rule: #{rule}" unless RULES.include?(rule)
|
98
|
-
end
|
99
|
-
|
100
|
-
had_hydrogens = self.h_added?
|
101
|
-
self.correct_for_ph!(7.4) unless had_hydrogens
|
102
|
-
self.remove_h!
|
103
|
-
|
104
|
-
fragment_sets = []
|
105
|
-
|
106
|
-
if opts[:rules].any? {|r| [:cod, :codoo].include?(r) }
|
107
|
-
self.each_match("C[O;h1,O]", only_uniqs) do |carbon, oxygen|
|
108
|
-
carbon.atoms.select {|a| a.el == :C }.each do |carbon_nbr|
|
109
|
-
fragment_sets << carbonyl_oxygen_dump(carbon, oxygen, carbon_nbr)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
if opts[:rules].any? {|r| [:oxe].include?(r) }
|
114
|
-
self.each_match("C-O", only_uniqs) do |carbon, oxygen|
|
115
|
-
fragment_sets << carbon_oxygen_esteal(carbon, oxygen)
|
116
|
-
end
|
117
|
-
end
|
118
|
-
# right now implemented so that a beta hydrogen has to be availabe for
|
119
|
-
# extraction
|
120
|
-
if opts[:rules].any? {|r| [:oxh].include?(r) }
|
121
|
-
self.each_match("C[C,O]-O", only_uniqs) do |beta_c, center, oxygen|
|
122
|
-
next unless beta_c.hydrogen_count > 0
|
123
|
-
fragment_sets << break_with_double_bond(oxygen, center, beta_c)
|
124
|
-
end
|
125
|
-
end
|
126
|
-
if opts[:rules].any? {|r| [:oxhpd].include?(r) }
|
127
|
-
self.each_match("C-O-P-O", only_uniqs) do |carbon, alc_oxy, phosphate, beta_carb_oxy|
|
128
|
-
next unless beta_carb_oxy.hydrogen_count > 0
|
129
|
-
frag_set = break_with_double_bond(alc_oxy, phosphate, beta_carb_oxy)
|
130
|
-
frag_set.map! &:convert_dative_bonds!
|
131
|
-
fragment_sets << frag_set
|
132
|
-
end
|
133
|
-
end
|
134
|
-
if opts[:rules].any? {|r| [:oxepd].include?(r) }
|
135
|
-
self.each_match("P-O-C", only_uniqs) do |phosphate, oxygen, carbon|
|
136
|
-
frag_set = carbon_oxygen_esteal(phosphate, oxygen)
|
137
|
-
frag_set.map! &:convert_dative_bonds!
|
138
|
-
fragment_sets << frag_set
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
case opts[:errors]
|
143
|
-
when :remove
|
144
|
-
fragment_sets.select! {|set| allowable_fragmentation?(set) }
|
145
|
-
when :fix
|
146
|
-
raise NotImplementedError
|
147
|
-
when :ignore # do nothing
|
148
|
-
end
|
149
|
-
|
150
|
-
self.remove_h!
|
151
|
-
if opts[:uniq]
|
152
|
-
# TODO: impelent properly
|
153
|
-
raise NotImplementedError
|
154
|
-
#fragment_sets = fragment_sets.uniq_by(&:csmiles)
|
155
|
-
end
|
156
|
-
|
157
|
-
fragment_sets
|
158
|
-
end
|
159
|
-
end
|
160
|
-
include Fragmentable
|
161
|
-
end
|
162
|
-
end # Rubabel
|
@@ -1,199 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
require 'rubabel'
|
4
|
-
|
5
|
-
$VERBOSE = nil
|
6
|
-
|
7
|
-
describe Rubabel::Molecule::Fragmentable do
|
8
|
-
|
9
|
-
# :peroxy_to_carboxy
|
10
|
-
# :oxygen_asymmetric_sp3, :nitrogen_asymmetric_sp3,
|
11
|
-
# :internal_phosphoester
|
12
|
-
|
13
|
-
describe 'fragmentation rules' do
|
14
|
-
# coenzyme: CC1=CC(=O)C=CC1=O
|
15
|
-
# 2-methylcyclohexa-2,5-diene-1,4-dione
|
16
|
-
|
17
|
-
#let(:test_mol) { "COP(=O)(O)OCNCOCC(OO)C(=O)O" }
|
18
|
-
|
19
|
-
it 'raises an error for a bad rule' do
|
20
|
-
mol = Rubabel["CCNC"]
|
21
|
-
expect { mol.fragment(rules: [:wackiness]) }.to raise_error
|
22
|
-
end
|
23
|
-
|
24
|
-
describe 'cod: carbonyl appendage dump' do
|
25
|
-
# a primary oxygen or peroxide => C=O appendage dump
|
26
|
-
|
27
|
-
specify 'cod: primary alcohol' do
|
28
|
-
mol = Rubabel["NCC(O)CC"]
|
29
|
-
frags = mol.fragment(rules: [:cod])
|
30
|
-
frags.flatten(1).map(&:csmiles).should == ["C[NH3+]", "CCC=O", "C([NH3+])C=O", "CC"]
|
31
|
-
end
|
32
|
-
|
33
|
-
specify 'peroxide' do
|
34
|
-
mol = Rubabel["NCC(OO)CC"]
|
35
|
-
frags = mol.fragment(rules: [:codoo])
|
36
|
-
frags.flatten(1).map(&:csmiles).should == ["OC[NH3+]", "CCC=O", "C([NH3+])C=O", "CCO"]
|
37
|
-
end
|
38
|
-
|
39
|
-
specify 'cod: carboxylate' do
|
40
|
-
mol = Rubabel["CCC(=O)O"]
|
41
|
-
pieces = mol.fragment(rules: [:cod])
|
42
|
-
pieces.flatten(1).map(&:csmiles).should == ["[CH2-]C", "O=C=O"]
|
43
|
-
end
|
44
|
-
|
45
|
-
specify 'cod: carboxylic acid' do
|
46
|
-
mol = Rubabel["CCC(=O)O"]
|
47
|
-
mol.add_h!(1.5)
|
48
|
-
pieces = mol.fragment(rules: [:cod])
|
49
|
-
pieces.flatten(1).map(&:csmiles).should == ["CC", "O=C=O"]
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
describe 'oxe: oxygen electron stealing' do
|
54
|
-
# oxygen just steals the electron pair it is attached to. This
|
55
|
-
# typically results in a negatively charged oxygen and a positively
|
56
|
-
# charged carbo-cation.
|
57
|
-
specify 'ether to ions' do
|
58
|
-
mol = Rubabel["CCOCCN"]
|
59
|
-
frag_set = mol.fragment(rules: [:oxe])
|
60
|
-
frags = frag_set.first
|
61
|
-
frags.first.csmiles.should == "C[CH2+]"
|
62
|
-
frags.last.csmiles.should == '[O-]CC[NH3+]'
|
63
|
-
frags.first.formula.should == 'C2H5+'
|
64
|
-
frags.last.formula.should == 'C2H7NO'
|
65
|
-
frags.first.exact_mass.should be_within(1e-6).of(29.03912516)
|
66
|
-
frags.last.exact_mass.should be_within(1e-6).of(61.052763849)
|
67
|
-
end
|
68
|
-
|
69
|
-
specify 'ester to ions' do
|
70
|
-
mol = Rubabel["CCOC(=O)CCN"]
|
71
|
-
frag_set = mol.fragment(rules: [:oxe])
|
72
|
-
ff = frag_set.first
|
73
|
-
ff.first.csmiles.should == 'C[CH2+]'
|
74
|
-
ff.last.csmiles.should == '[O-]C(=O)CC[NH3+]'
|
75
|
-
ff.first.formula.should == "C2H5+"
|
76
|
-
|
77
|
-
ff.last.formula.should == "C3H7NO2"
|
78
|
-
ff.first.exact_mass.should be_within(1e-6).of(29.03912516035)
|
79
|
-
ff.last.exact_mass.should be_within(1e-6).of(89.04767846841)
|
80
|
-
end
|
81
|
-
|
82
|
-
specify 'carboxyl group' do
|
83
|
-
mol = Rubabel["CCC(=O)O"]
|
84
|
-
frag_set = mol.fragment(rules: [:oxe])
|
85
|
-
ff = frag_set.first
|
86
|
-
ff.first.csmiles.should == 'CC[C+]=O'
|
87
|
-
# this is a carboxylate oxygen that falls off
|
88
|
-
ff.last.csmiles.should == '[O-2]'
|
89
|
-
#ff.first.formula.should == "C3H5O"
|
90
|
-
ff.first.formula.should == "C3H5O+"
|
91
|
-
ff.first.exact_mass.should be_within(1e-6).of(57.034039779909996)
|
92
|
-
#ff.last.formula.should == "O"
|
93
|
-
ff.last.formula.should == "O--"
|
94
|
-
end
|
95
|
-
|
96
|
-
specify 'phosphodiester' do
|
97
|
-
mol = Rubabel["CC(COP(=O)([O-])OCCN"]
|
98
|
-
frag_set = mol.fragment(rules: [:oxepd])
|
99
|
-
ff = frag_set.first
|
100
|
-
ff.first.csmiles.should == '[O-]CCC'
|
101
|
-
#ff.last.csmiles.should == '[NH3+]CCO[P](=O)=O'
|
102
|
-
ff.last.csmiles.should == "[NH3+]CCOP(=O)=O"
|
103
|
-
#ff.first.formula.should == 'C3H7O'
|
104
|
-
ff.first.formula.should == 'C3H7O-'
|
105
|
-
ff.first.exact_mass.should be_within(1e-6).of(59.049689844)
|
106
|
-
#ff.last.formula.should == 'C2H7NO3P'
|
107
|
-
ff.last.formula.should == 'C2H7NO3P+'
|
108
|
-
ff.last.exact_mass.should be_within(1e-6).of(124.016354719)
|
109
|
-
|
110
|
-
mol = Rubabel["CCCOP(=O)(OCC[N+](C)(C)C)[O-]"]
|
111
|
-
frag_set = mol.fragment(rules: [:oxepd, :oxe])
|
112
|
-
# some of these don't like right on first inspection, but that is
|
113
|
-
# because we 'converted dative bonds' meaning + and - next to each
|
114
|
-
# other are allowed to cancel one another out!
|
115
|
-
frag_set.size.should == 4
|
116
|
-
mols = frag_set.flatten
|
117
|
-
mols.map(&:csmiles).should == ["CC[CH2+]", "[O-]P(=O)(OCC[N+](C)(C)C)[O-]", "CCCOP(=O)([O-])[O-]", "[CH2+]C[N+](C)(C)C", "[O-]CCC", "O=P(=O)OCC[N+](C)(C)C", "CCCOP(=O)=O", "[O-]CC[N+](C)(C)C"]
|
118
|
-
mols.map(&:formula).should == ["C3H7+", "C5H13NO4P-", "C3H7O4P--", "C5H13N++", "C3H7O-", "C5H13NO3P+", "C3H7O3P", "C5H13NO"]
|
119
|
-
mols.map(&:exact_mass).zip([43.05477522449, 182.05821952995, 138.00819533273, 87.10479942171, 59.04968984405, 166.06330491039, 122.01328071317, 103.09971404127]) do |act, exp|
|
120
|
-
act.should be_within(1e-6).of(exp)
|
121
|
-
end
|
122
|
-
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
# this is really a subset of oxygen bond stealing: if the negatively
|
127
|
-
# charged oxygen can rip off a nearby proton, it will.
|
128
|
-
describe 'oxh: oxygen alpha/beta/gamma hydrogen stealing' do
|
129
|
-
specify 'primary alcohol giving water loss' do
|
130
|
-
mol = Rubabel["CC(O)CCN"]
|
131
|
-
frags = mol.fragment(rules: [:oxh])
|
132
|
-
ff = frags.first
|
133
|
-
ff.first.csmiles.should == 'C=CCC[NH3+]'
|
134
|
-
ff.last.csmiles.should == 'O'
|
135
|
-
ll = frags.last
|
136
|
-
ll.first.csmiles.should == 'CC=CC[NH3+]'
|
137
|
-
ll.last.csmiles.should == 'O'
|
138
|
-
#ff.first.formula.should == 'C4H10N'
|
139
|
-
ff.first.formula.should == 'C4H10N+'
|
140
|
-
ff.first.exact_mass.should be_within(1e-6).of(72.0813243255)
|
141
|
-
end
|
142
|
-
|
143
|
-
specify 'peroxide carbonyl formation (or peroxide formation [that what we want??])' do
|
144
|
-
# do we really see peroxide formation? Tamil didn't include this in
|
145
|
-
# the rules but it follows from the broad way for creating these
|
146
|
-
# rules. Can prohibit peroxide formation in future if necessary...
|
147
|
-
mol = Rubabel["CC(OO)CCN"]
|
148
|
-
frags = mol.fragment(rules: [:oxh])
|
149
|
-
mols = frags.flatten
|
150
|
-
mols.map(&:csmiles).should == ["C=CCC[NH3+]", "OO", "CC(=O)CC[NH3+]", "O", "CC=CC[NH3+]", "OO"]
|
151
|
-
mols.map(&:formula).should == ["C4H10N+", "H2O2", "C4H10NO+", "H2O", "C4H10N+", "H2O2"]
|
152
|
-
#mols.map(&:formula).should == ["C4H10N", "H2O2", "C4H10NO", "H2O", "C4H10N", "H2O2"]
|
153
|
-
mols.map(&:exact_mass).zip([72.081324325, 34.005479304, 88.076238945, 18.010564684, 72.081324325, 34.005479304]) do |act, exp|
|
154
|
-
act.should be_within(1e-6).of(exp)
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
specify 'ether to alcohol, ignoring errors' do
|
159
|
-
# this is a good example of a 'disallowed structure' where the
|
160
|
-
# formula's do not match up to the original formulas
|
161
|
-
mol = Rubabel["CCOCCN"]
|
162
|
-
frags = mol.fragment(rules: [:oxh], errors: :ignore)
|
163
|
-
mols = frags.flatten
|
164
|
-
mols.map(&:csmiles).should == ["C=C", "OCC[NH3+]", "CCO", "C=C[NH2+]"]
|
165
|
-
end
|
166
|
-
|
167
|
-
specify 'ether to alcohol, removing errors' do
|
168
|
-
mol = Rubabel["CCOCCN"]
|
169
|
-
frags = mol.fragment(rules: [:oxh])
|
170
|
-
mols = frags.flatten
|
171
|
-
mols.map(&:csmiles).should == ["C=C", "OCC[NH3+]"]
|
172
|
-
end
|
173
|
-
|
174
|
-
specify 'ester to alcohol' do
|
175
|
-
mol = Rubabel["CC(=O)OCCCN"]
|
176
|
-
frags = mol.fragment(rules: [:oxh])
|
177
|
-
mols = frags.flatten
|
178
|
-
mols.map(&:csmiles).should == ["C=C=O", "OCCC[NH3+]", "CC(=O)O", "C=CC[NH3+]"]
|
179
|
-
#mols.map(&:formula).should == ["C2H2O", "C3H10NO", "C2H4O2", "C3H8N"]
|
180
|
-
mols.map(&:formula).should == ["C2H2O", "C3H10NO+", "C2H4O2", "C3H8N+"]
|
181
|
-
mols.map(&:exact_mass).zip([42.010564684, 76.076238945, 60.021129368000004, 58.065674261]) do |act,exp|
|
182
|
-
act.should be_within(1e-6).of(exp)
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
specify 'phosphodiester (right now needs very low pH and NOT SURE WORKING PROPERLY)' do
|
187
|
-
mol = Rubabel["CC(COP(=O)(O)OCCCN"]
|
188
|
-
mol.add_h!(1.0)
|
189
|
-
frags = mol.fragment(rules: [:oxhpd])
|
190
|
-
frags = frags.flatten
|
191
|
-
frags.map(&:csmiles).should == ["CCCO", "[NH3+]CCCOP(=O)=O", "CCCOP(=O)=O", "OCCC[NH3+]"]
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
|
199
|
-
|