rubabel 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
|