mspire 0.6.24 → 0.6.25

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.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.24
1
+ 0.6.25
@@ -0,0 +1,105 @@
1
+
2
+ require 'ms/mass'
3
+ require 'ms/isotope'
4
+ require 'ms/molecular_formula'
5
+ require 'ms/spectrum'
6
+
7
+ require 'fftw3'
8
+
9
+ module MS
10
+ class Isotope
11
+ module Distribution
12
+ NORMALIZE = :total
13
+ PERCENT_CUTOFF = 0.001
14
+ end
15
+ end
16
+ end
17
+
18
+ module MS
19
+ class MolecularFormula < Hash
20
+
21
+ # takes any element composition (see any_to_num_elements).
22
+ #
23
+ # returns isotopic distribution beginning with monoisotopic peak and
24
+ # finishing when the peak contributes less than percent_cutoff to the total
25
+ # distribution. Then, normalization occurs.
26
+ #
27
+ # all values will be fractional. normalize may be one of:
28
+ #
29
+ # :total normalize to the total intensity
30
+ # :max normalize to the highest peak intensity
31
+ # :low normalize to the intensity of the lowest m/z peak
32
+ # (this is typically the monoisotopic peak)
33
+ def isotope_distribution(normalize=MS::Isotope::Distribution::NORMALIZE, percent_cutoff=MS::Isotope::Distribution::PERCENT_CUTOFF)
34
+ mono_dist = raw_isotope_distribution
35
+ # percent_cutoff:
36
+ final_output = []
37
+ sum = 0.0
38
+ mono_dist.each do |peak|
39
+ break if (peak / sum)*100 < percent_cutoff
40
+ final_output << peak
41
+ sum += peak
42
+ end
43
+
44
+ # normalization
45
+ norm_by =
46
+ case normalize
47
+ when :total
48
+ sum
49
+ when :max
50
+ final_output.max
51
+ when :low
52
+ final_output.first
53
+ end
54
+ final_output.map {|i| i / norm_by }
55
+ end
56
+
57
+ # returns a spectrum object with mass values and intensity values.
58
+ # Arguments are passed directly to isotope_distribution.
59
+ def isotope_distribution_spectrum(*args)
60
+ intensities = isotope_distribution(*args)
61
+ mono = self.map {|el,cnt| MS::Mass::MONO[el]*cnt }.reduce(:+)
62
+ masses = Array.new(intensities.size)
63
+ neutron = MS::Mass::NEUTRON
64
+ masses[0] = mono
65
+ (1...masses.size).each {|i| masses[i] = masses[i-1] + neutron }
66
+ MS::Spectrum.new [masses, intensities]
67
+ end
68
+
69
+ # returns relative ratios from low nominal mass to high nominal mass.
70
+ # These are *not* normalized at all.
71
+ def raw_isotope_distribution
72
+ low_nominal = 0
73
+ high_nominal = 0
74
+ self.each do |el,cnt|
75
+ isotopes = MS::Isotope::BY_ELEMENT[el]
76
+ low_nominal += (isotopes.first.mass_number * cnt)
77
+ high_nominal += (isotopes.last.mass_number * cnt)
78
+ end
79
+
80
+ ffts = self.map do |el, cnt|
81
+ isotope_el_ar = NArray.float(high_nominal)
82
+ MS::Isotope::BY_ELEMENT[el].each do |isotope|
83
+ isotope_el_ar[isotope.mass_number] = isotope.relative_abundance
84
+ end
85
+ FFTW3.fft(isotope_el_ar)**cnt
86
+ end
87
+ FFTW3.ifft(ffts.reduce(:*)).real.to_a[low_nominal..high_nominal]
88
+ end
89
+
90
+ end
91
+
92
+
93
+ class Isotope
94
+ module Distribution
95
+ def self.calculate(molecular_formula_like, normalize=MS::Isotope::Distribution::NORMALIZE, percent_cutoff=MS::Isotope::Distribution::PERCENT_CUTOFF)
96
+ MS::MolecularFormula.new(molecular_formula_like).isotope_distribution(normalize, percent_cutoff)
97
+ end
98
+
99
+ def self.spectrum(molecular_formula_like, normalize=MS::Isotope::Distribution::NORMALIZE, percent_cutoff=MS::Isotope::Distribution::PERCENT_CUTOFF)
100
+ MS::MolecularFormula.new(molecular_formula_like).isotope_distribution_spectrum(normalize, percent_cutoff)
101
+ end
102
+ end
103
+ end
104
+
105
+ end
data/lib/ms/mass.rb CHANGED
@@ -1,56 +1,50 @@
1
+ require 'ms/isotope'
2
+ require 'ms/molecular_formula'
3
+
1
4
  module MS
2
5
  module Mass
3
6
 
4
7
  # takes a molecular formula in this format: C2BrH12O
5
8
  def self.formula_to_exact_mass(formula)
6
- # TODO: add other input methods
7
- pairs = formula.scan(/([A-Z][a-z]?)(\d*)/).map do |match|
8
- if match.last == ''
9
- match[-1] = 1
10
- end
11
- [match[0], match[1].to_i]
12
- end
13
- pairs.map do |pair|
14
- MONO[pair.first.downcase] * pair.last
9
+ MS::MolecularFormula.new(formula).map do |el,cnt|
10
+ MONO[el] * cnt
15
11
  end.reduce(:+)
16
12
  end
17
13
 
18
- ELECTRON = 0.0005486 # www.mikeblaber.org/oldwine/chm1045/notes/Atoms/.../Atoms03.htm
19
- H_PLUS = 1.00727646677
20
- # + http://www.unimod.org/masses.html
21
14
  MONO_STR = {
22
- 'c' => 12.0, # +
23
- 'br' => 78.9183361, # +
24
- 'd' => 2.014101779, # +
25
- 'f' => 18.99840322, # +
26
- 'n' => 14.003074, # +
27
- 'o' => 15.99491463, # +
28
- 'na' => 22.9897677, # +
29
- 'p' => 30.973762, # +
30
- 's' => 31.9720707, # +
31
- 'li' => 7.016003, # +
32
- 'cl' => 34.96885272, # +
33
- 'k' => 38.9637074, # +
34
- 'si' => 27.9769265325, # http://physics.nist.gov/cgi-bin/Compositions/stand_alone.pl?ele=Si&ascii=html&isotype=some
35
- 'i' => 126.904473, # +
36
15
  'h+' => 1.00727646677,
37
- 'h' => 1.007825035, # +
38
- 'h2o' => 18.0105647,
39
- 'oh' => 17.002739665,
40
- 'e' => 0.0005486,
41
- 'se' => 79.9165196
16
+ 'e' => 0.0005486, # www.mikeblaber.org/oldwine/chm1045/notes/Atoms/.../Atoms03.htm
17
+ 'neutron' => 1.0086649156,
42
18
  }
19
+ MS::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'] = MS::Isotope::BY_ELEMENT[:h].find {|iso| iso.element == :h && iso.mass_number == 2 }.atomic_mass
26
+
43
27
  AVG_STR = {
44
28
  'h+' => 1.007276, # using Mascot_H_plus mass (is this right for AVG??)
45
- 'h' => 1.00794,
46
- 'h2o' => 18.01528,
47
- 'oh' => 17.00734,
29
+ 'e' => 0.0005486,
30
+ 'neutron' => 1.0086649156,
48
31
  }
49
- # sets MONO_STR, MONO, AVG_STR, and AVG
32
+ MS::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(:+)
37
+
38
+ # sets MONO_SYM, MONO, AVG_SYM, and AVG
50
39
  %w(MONO AVG).each do |type|
51
40
  const_set "#{type}_SYM", Hash[ const_get("#{type}_STR").map {|k,v| [k.to_sym, v] } ]
52
41
  const_set type, const_get("#{type}_STR").merge( const_get("#{type}_SYM") )
53
42
  end
43
+
44
+ ELECTRON = MONO[:e]
45
+ NEUTRON = MONO[:neutron]
46
+ H_PLUS = MONO['h+']
47
+
54
48
  end
55
49
  end
56
50
 
@@ -0,0 +1,21 @@
1
+ require 'ms/isotope'
2
+
3
+ module MS
4
+ class MolecularFormula < Hash
5
+
6
+ # takes a string or a hash:
7
+ #
8
+ # "H22C12N1O3S2BeLi2" # <= order doesn't matter
9
+ # {h: 22, c: 12, n: 1, o: 3, s: 2} # case and string/sym doesn't matter
10
+ def initialize(arg)
11
+ if arg.is_a?(String)
12
+ arg.scan(/([A-Z][a-z]?)(\d*)/).each do |k,v|
13
+ self[k.downcase.to_sym] = (v == '' ? 1 : v.to_i)
14
+ end
15
+ else
16
+ self.merge!(arg)
17
+ end
18
+ end
19
+
20
+ end
21
+ end
@@ -39,12 +39,20 @@ module MS
39
39
  def mzs
40
40
  @data_arrays[0]
41
41
  end
42
+
43
+ def mzs=(ar)
44
+ @data_arrays[0] = ar
45
+ end
42
46
 
43
47
  # An array of the intensities data, corresponding to mzs.
44
48
  def intensities
45
49
  @data_arrays[1]
46
50
  end
47
51
 
52
+ def intensities=(ar)
53
+ @data_arrays[1] = ar
54
+ end
55
+
48
56
  def mzs_and_intensities
49
57
  [@data_arrays[0], @data_arrays[1]]
50
58
  end
data/mspire.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "mspire"
8
- s.version = "0.6.24"
8
+ s.version = "0.6.25"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["John T. Prince", "Simon Chiang"]
@@ -58,10 +58,12 @@ Gem::Specification.new do |s|
58
58
  "lib/ms/ident/search.rb",
59
59
  "lib/ms/isotope.rb",
60
60
  "lib/ms/isotope/aa.rb",
61
+ "lib/ms/isotope/distribution.rb",
61
62
  "lib/ms/isotope/nist_isotope_info.yml",
62
63
  "lib/ms/mascot.rb",
63
64
  "lib/ms/mass.rb",
64
65
  "lib/ms/mass/aa.rb",
66
+ "lib/ms/molecular_formula.rb",
65
67
  "lib/ms/mzml.rb",
66
68
  "lib/ms/mzml/activation.rb",
67
69
  "lib/ms/mzml/chromatogram.rb",
@@ -126,8 +128,10 @@ Gem::Specification.new do |s|
126
128
  "spec/ms/ident/pepxml_spec.rb",
127
129
  "spec/ms/ident/protein_group_spec.rb",
128
130
  "spec/ms/isotope/aa_spec.rb",
131
+ "spec/ms/isotope/distribution_spec.rb",
129
132
  "spec/ms/isotope_spec.rb",
130
133
  "spec/ms/mass_spec.rb",
134
+ "spec/ms/molecular_formula_spec.rb",
131
135
  "spec/ms/mzml/cv_spec.rb",
132
136
  "spec/ms/mzml/data_array_spec.rb",
133
137
  "spec/ms/mzml/file_content_spec.rb",
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ require 'ms/isotope/distribution'
4
+
5
+ describe 'MS::Isotope::Distribution class methods' do
6
+ before do
7
+ @data = [1.0, 0.08919230588715289, 0.017894161377222082, 0.0013573997600723623, 0.0001398330738144092]
8
+ end
9
+
10
+ it 'can calculate isotope distributions' do
11
+ MS::Isotope::Distribution.calculate('C8O7', :max).should == @data
12
+ end
13
+
14
+ # no m/z values, just mass values
15
+ it 'can calculate isotope distribution spectrum' do
16
+ spec = MS::Isotope::Distribution.spectrum('C8O7', :max)
17
+ spec.mzs.should == [207.96440233692, 208.97306725252, 209.98173216812, 210.99039708372, 211.99906199932002]
18
+ spec.intensities.should == [1.0, 0.08919230588715289, 0.017894161377222082, 0.0013573997600723623, 0.0001398330738144092]
19
+ end
20
+ end
data/spec/ms/mass_spec.rb CHANGED
@@ -1,8 +1,42 @@
1
1
  require 'spec_helper'
2
2
 
3
+ require 'ms/mass'
4
+
3
5
  describe 'MS::Mass' do
4
6
  it 'can access elemental masses by string or symbol' do
5
- MS::Mass::MONO['h'].should be_a_kind_of Float
6
- MS::Mass::MONO[:h].should be_a_kind_of Float
7
+ {
8
+ 'c' => 12.0, # +
9
+ 'br' => 78.9183361, # +
10
+ 'd' => 2.014101779, # +
11
+ 'f' => 18.99840322, # +
12
+ 'n' => 14.003074, # +
13
+ 'o' => 15.99491463, # +
14
+ 'na' => 22.9897677, # +
15
+ 'p' => 30.973762, # +
16
+ 's' => 31.9720707, # +
17
+ 'li' => 7.016003, # +
18
+ 'cl' => 34.96885272, # +
19
+ 'k' => 38.9637074, # +
20
+ 'si' => 27.9769265325,
21
+ 'i' => 126.904473, # +
22
+ 'h+' => 1.00727646677,
23
+ 'h' => 1.007825035, # +
24
+ 'h2o' => 18.0105647,
25
+ 'oh' => 17.002739665,
26
+ 'e' => 0.0005486,
27
+ 'se' => 79.9165196
28
+ }.each do |el, mass|
29
+ MS::Mass::MONO[el].should_not be_nil
30
+ MS::Mass::MONO[el].should == MS::Mass::MONO[el.to_sym]
31
+ MS::Mass::MONO[el].should be_within(0.00001).of(mass)
32
+ end
33
+
34
+
35
+ { h: 1.00794, he: 4.002602, ni: 58.6934 }.each do |el, mass|
36
+ MS::Mass::AVG[el].should_not be_nil
37
+ MS::Mass::AVG[el].should == MS::Mass::AVG[el.to_sym]
38
+ MS::Mass::AVG[el].should be_within(0.00001).of(mass)
39
+ end
40
+
7
41
  end
8
42
  end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ require 'ms/molecular_formula'
4
+
5
+ describe MS::MolecularFormula do
6
+
7
+ it 'can be initialized with a String or Hash' do
8
+ data = {h: 22, c: 12, n: 1, o: 3, s: 2}
9
+ mf = MS::MolecularFormula.new "H22BeC12N1O3S2Li2"
10
+ mf.should == {:h=>22, :be=>1, :c=>12, :n=>1, :o=>3, :s=>2, :li=>2}
11
+ mf = MS::MolecularFormula.new(data)
12
+ mf.should == data
13
+ end
14
+
15
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mspire
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.24
4
+ version: 0.6.25
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -14,7 +14,7 @@ date: 2012-03-13 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: nokogiri
17
- requirement: &13307340 !ruby/object:Gem::Requirement
17
+ requirement: &13676060 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ~>
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: '1.5'
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *13307340
25
+ version_requirements: *13676060
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: bsearch
28
- requirement: &13323080 !ruby/object:Gem::Requirement
28
+ requirement: &13674700 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: 1.5.0
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *13323080
36
+ version_requirements: *13674700
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: andand
39
- requirement: &13322420 !ruby/object:Gem::Requirement
39
+ requirement: &13673200 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ! '>='
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: 1.3.1
45
45
  type: :runtime
46
46
  prerelease: false
47
- version_requirements: *13322420
47
+ version_requirements: *13673200
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: obo
50
- requirement: &13321500 !ruby/object:Gem::Requirement
50
+ requirement: &13672440 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ! '>='
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: 0.1.0
56
56
  type: :runtime
57
57
  prerelease: false
58
- version_requirements: *13321500
58
+ version_requirements: *13672440
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: builder
61
- requirement: &13320060 !ruby/object:Gem::Requirement
61
+ requirement: &13671860 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ! '>='
@@ -66,10 +66,10 @@ dependencies:
66
66
  version: 3.0.0
67
67
  type: :runtime
68
68
  prerelease: false
69
- version_requirements: *13320060
69
+ version_requirements: *13671860
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: trollop
72
- requirement: &13319460 !ruby/object:Gem::Requirement
72
+ requirement: &13687020 !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
75
  - - ! '>='
@@ -77,10 +77,10 @@ dependencies:
77
77
  version: 1.16.2
78
78
  type: :runtime
79
79
  prerelease: false
80
- version_requirements: *13319460
80
+ version_requirements: *13687020
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: rspec
83
- requirement: &13318520 !ruby/object:Gem::Requirement
83
+ requirement: &13685880 !ruby/object:Gem::Requirement
84
84
  none: false
85
85
  requirements:
86
86
  - - ~>
@@ -88,10 +88,10 @@ dependencies:
88
88
  version: '2.6'
89
89
  type: :development
90
90
  prerelease: false
91
- version_requirements: *13318520
91
+ version_requirements: *13685880
92
92
  - !ruby/object:Gem::Dependency
93
93
  name: jeweler
94
- requirement: &13317560 !ruby/object:Gem::Requirement
94
+ requirement: &13684660 !ruby/object:Gem::Requirement
95
95
  none: false
96
96
  requirements:
97
97
  - - ~>
@@ -99,10 +99,10 @@ dependencies:
99
99
  version: 1.5.2
100
100
  type: :development
101
101
  prerelease: false
102
- version_requirements: *13317560
102
+ version_requirements: *13684660
103
103
  - !ruby/object:Gem::Dependency
104
104
  name: rcov
105
- requirement: &13316940 !ruby/object:Gem::Requirement
105
+ requirement: &13683500 !ruby/object:Gem::Requirement
106
106
  none: false
107
107
  requirements:
108
108
  - - ! '>='
@@ -110,7 +110,7 @@ dependencies:
110
110
  version: '0'
111
111
  type: :development
112
112
  prerelease: false
113
- version_requirements: *13316940
113
+ version_requirements: *13683500
114
114
  description: mass spectrometry proteomics, lipidomics, and tools, a rewrite of mspire,
115
115
  merging of ms-* gems
116
116
  email: jtprince@gmail.com
@@ -161,10 +161,12 @@ files:
161
161
  - lib/ms/ident/search.rb
162
162
  - lib/ms/isotope.rb
163
163
  - lib/ms/isotope/aa.rb
164
+ - lib/ms/isotope/distribution.rb
164
165
  - lib/ms/isotope/nist_isotope_info.yml
165
166
  - lib/ms/mascot.rb
166
167
  - lib/ms/mass.rb
167
168
  - lib/ms/mass/aa.rb
169
+ - lib/ms/molecular_formula.rb
168
170
  - lib/ms/mzml.rb
169
171
  - lib/ms/mzml/activation.rb
170
172
  - lib/ms/mzml/chromatogram.rb
@@ -229,8 +231,10 @@ files:
229
231
  - spec/ms/ident/pepxml_spec.rb
230
232
  - spec/ms/ident/protein_group_spec.rb
231
233
  - spec/ms/isotope/aa_spec.rb
234
+ - spec/ms/isotope/distribution_spec.rb
232
235
  - spec/ms/isotope_spec.rb
233
236
  - spec/ms/mass_spec.rb
237
+ - spec/ms/molecular_formula_spec.rb
234
238
  - spec/ms/mzml/cv_spec.rb
235
239
  - spec/ms/mzml/data_array_spec.rb
236
240
  - spec/ms/mzml/file_content_spec.rb