mspire 0.8.7 → 0.9.0
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/.gitignore +0 -1
- data/Gemfile +0 -2
- data/README.md +2 -2
- data/lib/mspire/isotope.rb +2 -2
- data/lib/mspire/isotope/aa.rb +22 -22
- data/lib/mspire/isotope/distribution.rb +1 -1
- data/lib/mspire/isotope/nist_isotope_info.yml +288 -288
- data/lib/mspire/mass.rb +29 -37
- data/lib/mspire/mass/aa.rb +13 -9
- data/lib/mspire/mass/all.rb +37 -0
- data/lib/mspire/mass/common.rb +34 -0
- data/lib/mspire/mass/element.rb +30 -0
- data/lib/mspire/mass/subatomic.rb +27 -0
- data/lib/mspire/mass/util.rb +10 -0
- data/lib/mspire/molecular_formula.rb +10 -8
- data/lib/mspire/version.rb +1 -1
- data/mspire.gemspec +46 -0
- data/spec/mspire/ident/pepxml_spec.rb +2 -2
- data/spec/mspire/isotope/aa_spec.rb +3 -3
- data/spec/mspire/isotope_spec.rb +6 -6
- data/spec/mspire/mass/aa_spec.rb +18 -0
- data/spec/mspire/mass/all_spec.rb +33 -0
- data/spec/mspire/mass/common_spec.rb +17 -0
- data/spec/mspire/mass/element_spec.rb +17 -0
- data/spec/mspire/mass/subatomic_spec.rb +13 -0
- data/spec/mspire/mass_spec.rb +6 -35
- data/spec/mspire/molecular_formula_spec.rb +19 -19
- data/spec/mspire/readme_spec.rb +3 -4
- data/spec/spec_helper.rb +0 -3
- metadata +18 -2
data/lib/mspire/mass.rb
CHANGED
@@ -1,49 +1,41 @@
|
|
1
|
-
require 'mspire/isotope'
|
2
|
-
require 'mspire/molecular_formula'
|
3
1
|
|
4
2
|
module Mspire
|
5
3
|
module Mass
|
4
|
+
end
|
5
|
+
end
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
require 'mspire/molecular_formula'
|
8
|
+
require 'mspire/mass/element'
|
9
|
+
require 'mspire/mass/subatomic'
|
10
|
+
require 'mspire/mass/common'
|
11
|
+
require 'mspire/mass/aa'
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
'e' => 0.0005486, # www.mikeblaber.org/oldwine/chm1045/notes/Atoms/.../Atoms03.htm
|
16
|
-
'neutron' => 1.0086649156,
|
17
|
-
}
|
13
|
+
module Mspire
|
14
|
+
module Mass
|
18
15
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
16
|
+
ELECTRON = Subatomic::MONO[:e]
|
17
|
+
NEUTRON = Subatomic::MONO[:neutron]
|
18
|
+
PROTON = Subatomic::MONO[:proton]
|
19
|
+
H_PLUS = PROTON
|
20
|
+
|
21
|
+
class << self
|
22
|
+
# takes a molecular formula as a string, hash or MolecularFormula object
|
23
|
+
# and returns the exact mass.
|
24
|
+
def formula_to_exact_mass(formula)
|
25
|
+
Mspire::MolecularFormula.from_any(formula).mass
|
26
|
+
end
|
27
|
+
alias_method :formula, :formula_to_exact_mass
|
28
|
+
|
29
|
+
def aa_to_exact_mass(aa_seq)
|
30
|
+
chain_mass = aa_seq.each_char.inject(0.0) do |sum, aa_char|
|
31
|
+
sum + AA[aa_char]
|
32
|
+
end
|
33
|
+
chain_mass + formula_to_exact_mass('H2O')
|
34
|
+
end
|
35
|
+
alias_method :aa, :aa_to_exact_mass
|
37
36
|
|
38
|
-
# sets MONO_SYM, MONO, AVG_SYM, and AVG
|
39
|
-
%w(MONO AVG).each do |type|
|
40
|
-
const_set "#{type}_SYM", Hash[ const_get("#{type}_STR").map {|k,v| [k.to_sym, v] } ]
|
41
|
-
const_set type, const_get("#{type}_STR").merge( const_get("#{type}_SYM") )
|
42
37
|
end
|
43
38
|
|
44
|
-
ELECTRON = MONO[:e]
|
45
|
-
NEUTRON = MONO[:neutron]
|
46
|
-
H_PLUS = MONO['h+']
|
47
39
|
|
48
40
|
end
|
49
41
|
end
|
data/lib/mspire/mass/aa.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'mspire/mass'
|
1
|
+
require 'mspire/mass/util'
|
2
2
|
|
3
3
|
module Mspire
|
4
4
|
module Mass
|
@@ -65,18 +65,22 @@ module Mspire
|
|
65
65
|
}
|
66
66
|
|
67
67
|
# amino_acids keys as symbols, monoisotopic masses
|
68
|
-
|
68
|
+
MONO_SYMBOL = Mspire::Mass::Util.symbol_keys( MONO_STRING )
|
69
69
|
|
70
70
|
# amino_acids keys as symbols, average masses
|
71
|
-
|
71
|
+
AVG_SYMBOL = Mspire::Mass::Util.symbol_keys( AVG_STRING )
|
72
72
|
|
73
|
-
# Monoisotopic amino acid masses keyed as symbols and also strings
|
74
|
-
|
75
|
-
MONO = MONO_SYM.merge(MONO_STRING).merge(Mspire::Mass::MONO)
|
73
|
+
# Monoisotopic amino acid masses keyed as symbols and also strings
|
74
|
+
MONO = MONO_SYMBOL.merge(MONO_STRING)
|
76
75
|
|
77
|
-
# Average amino acid masses keyed as symbols and also strings
|
78
|
-
|
79
|
-
|
76
|
+
# Average amino acid masses keyed as symbols and also strings
|
77
|
+
AVG = AVG_SYMBOL.merge(AVG_STRING)
|
78
|
+
|
79
|
+
class << self
|
80
|
+
def [](key)
|
81
|
+
MONO[key]
|
82
|
+
end
|
83
|
+
end
|
80
84
|
end
|
81
85
|
end
|
82
86
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'mspire/mass/util'
|
2
|
+
|
3
|
+
module Mspire
|
4
|
+
module Mass
|
5
|
+
# provides hashes with both Amino Acids (uppercase letters) and elements
|
6
|
+
# (lowercased) along with common abbreviations
|
7
|
+
module All
|
8
|
+
def self.downcase_keys(hash)
|
9
|
+
Hash[ hash.map {|key,val| [key.to_s.downcase, val] } ]
|
10
|
+
end
|
11
|
+
|
12
|
+
MONO_STRING = downcase_keys( Element::MONO_STRING )
|
13
|
+
.merge( downcase_keys( Common::MONO_STRING ) )
|
14
|
+
.merge( AA::MONO_STRING )
|
15
|
+
.merge( downcase_keys( Subatomic::MONO_STRING ) )
|
16
|
+
|
17
|
+
MONO_SYMBOL = Mspire::Mass::Util.symbol_keys( MONO_STRING )
|
18
|
+
MONO = MONO_STRING.merge( MONO_SYMBOL )
|
19
|
+
|
20
|
+
AVG_STRING = downcase_keys( Element::AVG_STRING )
|
21
|
+
.merge( downcase_keys( Common::AVG_STRING ) )
|
22
|
+
.merge( AA::AVG_STRING )
|
23
|
+
.merge( downcase_keys( Subatomic::MONO_STRING ) )
|
24
|
+
# ^^ NOTE: we use MONO values for Subatomic since avg makes no sense
|
25
|
+
|
26
|
+
AVG_SYMBOL = Mspire::Mass::Util.symbol_keys( AVG_STRING )
|
27
|
+
AVG = AVG_STRING.merge( AVG_SYMBOL )
|
28
|
+
|
29
|
+
class << self
|
30
|
+
def [](key)
|
31
|
+
MONO[key]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'mspire/mass/util'
|
2
|
+
require 'mspire/mass/element'
|
3
|
+
|
4
|
+
module Mspire
|
5
|
+
module Mass
|
6
|
+
module Common
|
7
|
+
mono_string = Mspire::Mass::Element::MONO_STRING
|
8
|
+
avg_string = Mspire::Mass::Element::AVG_STRING
|
9
|
+
|
10
|
+
MONO_STRING = {
|
11
|
+
'H2O' => %w(H H O).map {|el| mono_string[el] }.reduce(:+),
|
12
|
+
'OH' => %w(O H).map {|el| mono_string[el] }.reduce(:+),
|
13
|
+
}
|
14
|
+
|
15
|
+
AVG_STRING = {
|
16
|
+
'H2O' => %w(H H O).map {|el| avg_string[el] }.reduce(:+),
|
17
|
+
'OH' => %w(O H).map {|el| avg_string[el] }.reduce(:+),
|
18
|
+
}
|
19
|
+
|
20
|
+
MONO_SYMBOL = Mspire::Mass::Util.symbol_keys( MONO_STRING )
|
21
|
+
MONO = MONO_STRING.merge( MONO_SYMBOL )
|
22
|
+
|
23
|
+
AVG_SYMBOL = Mspire::Mass::Util.symbol_keys( AVG_STRING )
|
24
|
+
AVG = AVG_STRING.merge( AVG_SYMBOL )
|
25
|
+
|
26
|
+
class << self
|
27
|
+
def [](key)
|
28
|
+
MONO[key]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'mspire/isotope'
|
2
|
+
require 'mspire/mass/util'
|
3
|
+
|
4
|
+
module Mspire
|
5
|
+
module Mass
|
6
|
+
module Element
|
7
|
+
|
8
|
+
AVG_STRING = {}
|
9
|
+
MONO_STRING = {}
|
10
|
+
Mspire::Isotope::BY_ELEMENT.each do |el, isotopes|
|
11
|
+
AVG_STRING[el.to_s] = isotopes.first.average_mass
|
12
|
+
MONO_STRING[el.to_s] = isotopes.find {|iso| iso.mono }.atomic_mass
|
13
|
+
end
|
14
|
+
|
15
|
+
MONO_STRING['D'] = Mspire::Isotope::BY_ELEMENT[:H].find {|iso| iso.element == :H && iso.mass_number == 2 }.atomic_mass
|
16
|
+
|
17
|
+
MONO_SYMBOL = Mspire::Mass::Util.symbol_keys( MONO_STRING )
|
18
|
+
AVG_SYMBOL = Mspire::Mass::Util.symbol_keys( AVG_STRING )
|
19
|
+
MONO = MONO_SYMBOL.merge(MONO_STRING)
|
20
|
+
AVG = AVG_SYMBOL.merge(AVG_STRING)
|
21
|
+
|
22
|
+
class << self
|
23
|
+
def [](key)
|
24
|
+
MONO[key]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'mspire/mass/util'
|
2
|
+
require 'mspire/mass/element'
|
3
|
+
|
4
|
+
module Mspire
|
5
|
+
module Mass
|
6
|
+
module Subatomic
|
7
|
+
MONO_STRING = {
|
8
|
+
'electron' => 0.0005486, # www.mikeblaber.org/oldwine/chm1045/notes/Atoms/.../Atoms03.htm
|
9
|
+
'neutron' => 1.0086649156,
|
10
|
+
}
|
11
|
+
MONO_STRING['proton'] = Mspire::Mass::Element[:H] - MONO_STRING['electron']
|
12
|
+
MONO_STRING['H+'] = MONO_STRING['proton']
|
13
|
+
MONO_STRING['e'] = MONO_STRING['electron']
|
14
|
+
|
15
|
+
MONO_SYMBOL = Mspire::Mass::Util.symbol_keys( MONO_STRING )
|
16
|
+
MONO = MONO_STRING.merge( MONO_SYMBOL )
|
17
|
+
|
18
|
+
class << self
|
19
|
+
def [](key)
|
20
|
+
MONO[key]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# 'h+' => 1.00727646677,
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -5,12 +5,12 @@ module Mspire
|
|
5
5
|
class MolecularFormula < Hash
|
6
6
|
|
7
7
|
class << self
|
8
|
-
def from_aaseq(aaseq)
|
8
|
+
def from_aaseq(aaseq, formula_hash=Mspire::Isotope::AA::FORMULAS)
|
9
9
|
hash = aaseq.each_char.inject({}) do |hash,aa|
|
10
|
-
hash.merge(
|
10
|
+
hash.merge(formula_hash[aa]) {|hash,old,new| (old ? old : 0) + new }
|
11
11
|
end
|
12
|
-
hash[:
|
13
|
-
hash[:
|
12
|
+
hash[:H] += 2
|
13
|
+
hash[:O] += 1
|
14
14
|
self.new(hash)
|
15
15
|
end
|
16
16
|
|
@@ -19,7 +19,7 @@ module Mspire
|
|
19
19
|
def from_string(mol_form_str, charge=0)
|
20
20
|
mf = self.new({}, charge)
|
21
21
|
mol_form_str.scan(/([A-Z][a-z]?)(\d*)/).each do |k,v|
|
22
|
-
mf[k.
|
22
|
+
mf[k.to_sym] = (v == '' ? 1 : v.to_i)
|
23
23
|
end
|
24
24
|
mf
|
25
25
|
end
|
@@ -41,7 +41,7 @@ module Mspire
|
|
41
41
|
attr_accessor :charge
|
42
42
|
|
43
43
|
# Takes a hash and an optional Integer expressing the charge
|
44
|
-
# {
|
44
|
+
# {H: 22, C: 12, N: 1, O: 3, S: 2} # case and string/sym doesn't matter
|
45
45
|
def initialize(hash={}, charge=0)
|
46
46
|
@charge = charge
|
47
47
|
self.merge!(hash)
|
@@ -118,13 +118,15 @@ module Mspire
|
|
118
118
|
# gives the monoisotopic mass adjusted by the current charge (i.e.,
|
119
119
|
# adds/subtracts electron masses for the charges)
|
120
120
|
def mass(consider_electron_masses = true)
|
121
|
-
mss = inject(0.0)
|
121
|
+
mss = inject(0.0) do |sum,(el,cnt)|
|
122
|
+
sum + (Mspire::Mass::Element::MONO[el]*cnt)
|
123
|
+
end
|
122
124
|
mss -= (Mspire::Mass::ELECTRON * charge) if consider_electron_masses
|
123
125
|
mss
|
124
126
|
end
|
125
127
|
|
126
128
|
def avg_mass
|
127
|
-
inject(0.0) {|sum,(el,cnt)| sum + (Mspire::Mass::AVG[el]*cnt) }
|
129
|
+
inject(0.0) {|sum,(el,cnt)| sum + (Mspire::Mass::Element::AVG[el]*cnt) }
|
128
130
|
end
|
129
131
|
|
130
132
|
# returns nil if the charge == 0
|
data/lib/mspire/version.rb
CHANGED
data/mspire.gemspec
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'mspire/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "mspire"
|
8
|
+
spec.version = Mspire::VERSION
|
9
|
+
spec.authors = ["John T. Prince", "Simon Chiang"]
|
10
|
+
spec.email = ["jtprince@gmail.com"]
|
11
|
+
spec.description = %q{mass spectrometry proteomics, lipidomics, and tools, a rewrite of mspire, merging of ms-* gems}
|
12
|
+
spec.summary = %q{mass spectrometry proteomics, lipidomics, and tools}
|
13
|
+
spec.homepage = "http://github.com/princelab/mspire"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
[
|
22
|
+
["nokogiri", "~> 1.5.9"],
|
23
|
+
["bsearch", ">= 1.5.0"],
|
24
|
+
["andand", ">= 1.3.3"],
|
25
|
+
["obo", ">= 0.1.3"],
|
26
|
+
["builder", "~> 3.2.0"],
|
27
|
+
["bio", "~> 1.4.3"],
|
28
|
+
["trollop", "~> 2.0.0"],
|
29
|
+
].each do |args|
|
30
|
+
spec.add_dependency(*args)
|
31
|
+
end
|
32
|
+
|
33
|
+
[
|
34
|
+
["bundler", "~> 1.3"],
|
35
|
+
["rake"],
|
36
|
+
["rspec", "~> 2.13.0"],
|
37
|
+
["rdoc", "~> 3.12"],
|
38
|
+
["simplecov"],
|
39
|
+
["coveralls"],
|
40
|
+
# here because bad microsoft OS support
|
41
|
+
["fftw3", "~> 0.3"],
|
42
|
+
].each do |args|
|
43
|
+
spec.add_development_dependency(*args)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -43,12 +43,12 @@ describe "creating an Mspire::Ident::Pepxml" do
|
|
43
43
|
:variable => 'Y', :symbol => '*')
|
44
44
|
# invented, for example, a protein terminating mod
|
45
45
|
modifications << Mspire::Ident::Pepxml::TerminalModification.new(
|
46
|
-
:terminus => 'c', :massdiff => 23.3333, :mass => Mspire::Mass::MONO['
|
46
|
+
:terminus => 'c', :massdiff => 23.3333, :mass => Mspire::Mass::Common::MONO['OH'] + 23.3333,
|
47
47
|
:variable => 'Y', :symbol => '[', :protein_terminus => 'c',
|
48
48
|
:description => 'leave protein_terminus off if not protein mod'
|
49
49
|
)
|
50
50
|
modifications << Mspire::Ident::Pepxml::TerminalModification.new(
|
51
|
-
:terminus => 'c', :massdiff => 25.42322, :mass => Mspire::Mass::
|
51
|
+
:terminus => 'c', :massdiff => 25.42322, :mass => Mspire::Mass::PROTON + 25.42322,
|
52
52
|
:variable => 'N', :symbol => ']', :description => 'example: c term mod'
|
53
53
|
)
|
54
54
|
parameters.merge!(
|
@@ -4,17 +4,17 @@ require 'mspire/isotope/aa'
|
|
4
4
|
|
5
5
|
describe 'accessing an amino acid atom count' do
|
6
6
|
before do
|
7
|
-
@alanine = {:
|
7
|
+
@alanine = {:C=>3, :H=>5, :O=>1, :N=>1, :S=>0, :P=>0, :Se=>0}
|
8
8
|
end
|
9
9
|
|
10
10
|
it 'residue can be accessed with a symbol' do
|
11
11
|
hash = Mspire::Isotope::AA::FORMULAS[:A]
|
12
|
-
[:
|
12
|
+
[:C, :H, :O, :N, :S].each {|key| hash[key].should == @alanine[key] }
|
13
13
|
end
|
14
14
|
|
15
15
|
it 'residue can be accessed with a string' do
|
16
16
|
hash = Mspire::Isotope::AA::FORMULAS['A']
|
17
|
-
[:
|
17
|
+
[:C, :H, :O, :N, :S].each {|key| hash[key].should == @alanine[key] }
|
18
18
|
end
|
19
19
|
|
20
20
|
end
|
data/spec/mspire/isotope_spec.rb
CHANGED
@@ -6,26 +6,26 @@ describe 'Mspire::Isotope constants' do
|
|
6
6
|
it 'has all the common isotopes: Mspire::Isotope::ISOTOPES' do
|
7
7
|
# frozen
|
8
8
|
Mspire::Isotope::ISOTOPES.size.should == 288
|
9
|
-
hydrogen_isotopes = Mspire::Isotope::ISOTOPES.select {|iso| iso.element == :
|
9
|
+
hydrogen_isotopes = Mspire::Isotope::ISOTOPES.select {|iso| iso.element == :H }
|
10
10
|
hydrogen_isotopes.size.should == 2
|
11
11
|
|
12
|
-
{ atomic_number: 1, element: :
|
12
|
+
{ atomic_number: 1, element: :H, mass_number: 1, atomic_mass: 1.00782503207, relative_abundance: 0.999885, average_mass: 1.00794, mono: true }.each do |k,v|
|
13
13
|
hydrogen_isotopes.first.send(k).should == v
|
14
14
|
end
|
15
|
-
{atomic_number: 1, element: :
|
15
|
+
{atomic_number: 1, element: :H, mass_number: 2, atomic_mass: 2.0141017778, relative_abundance: 0.000115, average_mass: 1.00794, mono: false}.each do |k,v|
|
16
16
|
hydrogen_isotopes.last.send(k).should == v
|
17
17
|
end
|
18
18
|
u = Mspire::Isotope::ISOTOPES.last
|
19
|
-
{atomic_number: 92, element: :
|
19
|
+
{atomic_number: 92, element: :U, mass_number: 238, atomic_mass: 238.0507882, relative_abundance: 0.992742, average_mass: 238.02891, mono: true}.each do |k,v|
|
20
20
|
u.send(k).should == v
|
21
21
|
end
|
22
22
|
end
|
23
23
|
it 'has all common isotopes by element: Mspire::Isotope::BY_ELEMENT' do
|
24
|
-
[{atomic_number: 6, element: :
|
24
|
+
[{atomic_number: 6, element: :C, mass_number: 12, atomic_mass: 12.0, relative_abundance: 0.9893, average_mass: 12.0107, mono: true}, {atomic_number: 6, element: :C, mass_number: 13, atomic_mass: 13.0033548378, relative_abundance: 0.0107, average_mass: 12.0107, mono: false}].zip(Mspire::Isotope::BY_ELEMENT[:C]) do |hash, iso|
|
25
25
|
hash.each do |k,v|
|
26
26
|
iso.send(k).should == v
|
27
27
|
end
|
28
28
|
end
|
29
|
-
Mspire::Isotope::BY_ELEMENT[:
|
29
|
+
Mspire::Isotope::BY_ELEMENT[:H].size.should == 2
|
30
30
|
end
|
31
31
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'mspire/mass/aa'
|
4
|
+
|
5
|
+
describe Mspire::Mass::AA do
|
6
|
+
it 'provides string and symbol access to element masses' do
|
7
|
+
mono = Mspire::Mass::AA::MONO
|
8
|
+
|
9
|
+
mono['C'].should == 103.0091844778
|
10
|
+
mono[:C].should == mono['C']
|
11
|
+
|
12
|
+
Mspire::Mass::AA[:C].should == mono[:C] # <- not a hash but a method
|
13
|
+
|
14
|
+
avg = Mspire::Mass::AA::AVG
|
15
|
+
avg['C'].should == 103.1429
|
16
|
+
avg[:C].should == avg['C']
|
17
|
+
end
|
18
|
+
end
|