mspire 0.8.7 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- # takes a molecular formula as a string, hash or MolecularFormula object
8
- # and returns the exact mass.
9
- def self.formula_to_exact_mass(formula)
10
- Mspire::MolecularFormula.from_any(formula).mass
11
- end
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
- MONO_STR = {
14
- 'h+' => 1.00727646677,
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
- Mspire::Isotope::BY_ELEMENT.each do |el, isotopes|
20
- MONO_STR[el.to_s] = isotopes.find {|iso| iso.mono }.atomic_mass
21
- end
22
- MONO_STR['h2o'] = %w(h h o).map {|el| MONO_STR[el] }.reduce(:+)
23
- MONO_STR['oh'] = %w(o h).map {|el| MONO_STR[el] }.reduce(:+)
24
- # add on deuterium
25
- MONO_STR['d'] = Mspire::Isotope::BY_ELEMENT[:h].find {|iso| iso.element == :h && iso.mass_number == 2 }.atomic_mass
26
-
27
- AVG_STR = {
28
- 'h+' => 1.007276, # using Mascot_H_plus mass (is this right for AVG??)
29
- 'e' => 0.0005486,
30
- 'neutron' => 1.0086649156,
31
- }
32
- Mspire::Isotope::BY_ELEMENT.each do |el, isotopes|
33
- AVG_STR[el.to_s] = isotopes.first.average_mass
34
- end
35
- AVG_STR['h2o'] = %w(h h o).map {|el| AVG_STR[el] }.reduce(:+)
36
- AVG_STR['oh'] = %w(o h).map {|el| AVG_STR[el] }.reduce(:+)
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
@@ -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
- MONO_SYM = Hash[MONO_STRING.map {|aa,mass| [aa.to_sym, mass] } ]
68
+ MONO_SYMBOL = Mspire::Mass::Util.symbol_keys( MONO_STRING )
69
69
 
70
70
  # amino_acids keys as symbols, average masses
71
- AVG_SYM = Hash[AVG_STRING.map {|aa,mass| [aa.to_sym, mass] } ]
71
+ AVG_SYMBOL = Mspire::Mass::Util.symbol_keys( AVG_STRING )
72
72
 
73
- # Monoisotopic amino acid masses keyed as symbols and also strings (all
74
- # upper case). Also includes Mspire::Mass::MONO for things like protons ('h+' and 'h2o')
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 (all
78
- # uppder case). Also includes Mspire::Mass::AVG for things like protons ('h+' and 'h2o')
79
- AVG = AVG_SYM.merge(AVG_STRING).merge(Mspire::Mass::AVG)
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
@@ -0,0 +1,10 @@
1
+
2
+ module Mspire
3
+ module Mass
4
+ module Util
5
+ def self.symbol_keys(hash)
6
+ Hash[ hash.map {|key,val| [key.to_sym, val] } ]
7
+ end
8
+ end
9
+ end
10
+ 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(Mspire::Isotope::AA::FORMULAS[aa]) {|h,o,n| (o ? o : 0) +n }
10
+ hash.merge(formula_hash[aa]) {|hash,old,new| (old ? old : 0) + new }
11
11
  end
12
- hash[:h] += 2
13
- hash[:o] += 1
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.downcase.to_sym] = (v == '' ? 1 : v.to_i)
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
- # {h: 22, c: 12, n: 1, o: 3, s: 2} # case and string/sym doesn't matter
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) {|sum,(el,cnt)| sum + (Mspire::Mass::MONO[el]*cnt) }
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
@@ -1,3 +1,3 @@
1
1
  module Mspire
2
- VERSION = "0.8.7"
2
+ VERSION = "0.9.0"
3
3
  end
@@ -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['oh'] + 23.3333,
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::MONO['h+'] + 25.42322,
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 = {:c=>3, :h=>5, :o=>1, :n=>1, :s=>0, :p=>0, :se=>0}
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
- [:c, :h, :o, :n, :s].each {|key| hash[key].should == @alanine[key] }
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
- [:c, :h, :o, :n, :s].each {|key| hash[key].should == @alanine[key] }
17
+ [:C, :H, :O, :N, :S].each {|key| hash[key].should == @alanine[key] }
18
18
  end
19
19
 
20
20
  end
@@ -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 == :h }
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: :h, mass_number: 1, atomic_mass: 1.00782503207, relative_abundance: 0.999885, average_mass: 1.00794, mono: true }.each do |k,v|
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: :h, mass_number: 2, atomic_mass: 2.0141017778, relative_abundance: 0.000115, average_mass: 1.00794, mono: false}.each do |k,v|
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: :u, mass_number: 238, atomic_mass: 238.0507882, relative_abundance: 0.992742, average_mass: 238.02891, mono: true}.each do |k,v|
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: :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|
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[:h].size.should == 2
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