mspire 0.7.4 → 0.7.5

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.7.4
1
+ 0.7.5
@@ -10,7 +10,6 @@ module Mspire
10
10
  class Isotope
11
11
  module Distribution
12
12
  NORMALIZE = :total
13
- PERCENT_CUTOFF = 0.001
14
13
  end
15
14
  end
16
15
  end
@@ -20,42 +19,53 @@ module Mspire
20
19
 
21
20
  # takes any element composition (see any_to_num_elements).
22
21
  #
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.
22
+ # returns isotopic distribution beginning with monoisotopic peak. It cuts
23
+ # off when no more peaks contribute more than percent_cutoff to the total
24
+ # distribution. After that, normalization is performed.
26
25
  #
27
26
  # all values will be fractional. normalize may be one of:
28
27
  #
29
28
  # :total normalize to the total intensity
30
29
  # :max normalize to the highest peak intensity
31
- # :low normalize to the intensity of the lowest m/z peak
30
+ # :first normalize to the intensity of the first peak
32
31
  # (this is typically the monoisotopic peak)
33
- def isotope_distribution(normalize=Mspire::Isotope::Distribution::NORMALIZE, percent_cutoff=Mspire::Isotope::Distribution::PERCENT_CUTOFF)
32
+ def isotope_distribution(normalize=Mspire::Isotope::Distribution::NORMALIZE, percent_cutoff=nil)
34
33
  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
34
+
35
+ if percent_cutoff
36
+ total_signal = mono_dist.reduce(:+)
37
+ cutoff_index = (mono_dist.size-1).downto(0).find do |i|
38
+ (mono_dist[i] / total_signal) >= (percent_cutoff/100.0)
39
+ end
40
+ # deletes these elements
41
+ if cutoff_index
42
+ mono_dist.slice!((cutoff_index+1)..-1)
43
+ else
44
+ # no peaks pass that percent cutoff threshold!
45
+ mono_dist = []
46
+ end
42
47
  end
43
48
 
44
49
  # normalization
45
50
  norm_by =
46
51
  case normalize
47
52
  when :total
48
- sum
53
+ total_signal || mono_dist.reduce(:+)
49
54
  when :max
50
- final_output.max
51
- when :low
52
- final_output.first
55
+ mono_dist.max
56
+ when :first
57
+ mono_dist.first
53
58
  end
54
- final_output.map {|i| i / norm_by }
59
+ mono_dist.map do |i|
60
+ v = i / norm_by
61
+ (v > 0) ? v : 0
62
+ end
55
63
  end
56
64
 
57
65
  # returns a spectrum object with mass values and intensity values.
58
66
  # Arguments are passed directly to isotope_distribution.
67
+ # the molecule has a charge, this will be used to adjust the m/z values
68
+ # (by removing or adding electrons to the m/z and as the z)
59
69
  def isotope_distribution_spectrum(*args)
60
70
  intensities = isotope_distribution(*args)
61
71
  mono = self.map {|el,cnt| Mspire::Mass::MONO[el]*cnt }.reduce(:+)
@@ -63,6 +73,11 @@ module Mspire
63
73
  neutron = Mspire::Mass::NEUTRON
64
74
  masses[0] = mono
65
75
  (1...masses.size).each {|i| masses[i] = masses[i-1] + neutron }
76
+ if self.charge && self.charge != 0
77
+ masses.map! do |mass|
78
+ (mass - (self.charge * Mspire::Mass::ELECTRON)) / self.charge
79
+ end
80
+ end
66
81
  Mspire::Spectrum.new [masses, intensities]
67
82
  end
68
83
 
@@ -92,12 +107,14 @@ module Mspire
92
107
 
93
108
  class Isotope
94
109
  module Distribution
95
- def self.calculate(molecular_formula_like, normalize=Mspire::Isotope::Distribution::NORMALIZE, percent_cutoff=Mspire::Isotope::Distribution::PERCENT_CUTOFF)
96
- Mspire::MolecularFormula.new(molecular_formula_like).isotope_distribution(normalize, percent_cutoff)
110
+ def self.calculate(molecular_formula_like, normalize=Mspire::Isotope::Distribution::NORMALIZE, percent_cutoff=nil)
111
+ mf = molecular_formula_like.is_a?(Mspire::MolecularFormula) ? molecular_formula_like : Mspire::MolecularFormula.new(molecular_formula_like)
112
+ mf.isotope_distribution(normalize, percent_cutoff)
97
113
  end
98
114
 
99
- def self.spectrum(molecular_formula_like, normalize=Mspire::Isotope::Distribution::NORMALIZE, percent_cutoff=Mspire::Isotope::Distribution::PERCENT_CUTOFF)
100
- Mspire::MolecularFormula.new(molecular_formula_like).isotope_distribution_spectrum(normalize, percent_cutoff)
115
+ def self.spectrum(molecular_formula_like, normalize=Mspire::Isotope::Distribution::NORMALIZE, percent_cutoff=nil)
116
+ mf = molecular_formula_like.is_a?(Mspire::MolecularFormula) ? molecular_formula_like : Mspire::MolecularFormula.new(molecular_formula_like)
117
+ mf.isotope_distribution_spectrum(normalize, percent_cutoff)
101
118
  end
102
119
  end
103
120
  end
data/mspire.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "mspire"
8
- s.version = "0.7.4"
8
+ s.version = "0.7.5"
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"]
12
- s.date = "2012-03-21"
12
+ s.date = "2012-03-23"
13
13
  s.description = "mass spectrometry proteomics, lipidomics, and tools, a rewrite of mspire, merging of ms-* gems"
14
14
  s.email = "jtprince@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -4,17 +4,56 @@ require 'mspire/isotope/distribution'
4
4
 
5
5
  describe 'Mspire::Isotope::Distribution class methods' do
6
6
  before do
7
- @data = [1.0, 0.08919230588715311, 0.017894161377222138, 0.0013573997600723345, 0.0001398330738144181]
7
+ @first = [1.0, 0.08919230588715311, 0.017894161377222138, 0.0013573997600723345, 0.0001398330738144181]
8
8
  end
9
+ # can also be used on a real MolecularFormula object
10
+ subject { 'C102H120O15' }
9
11
 
10
- it 'can calculate isotope distributions' do
11
- Mspire::Isotope::Distribution.calculate('C8O7', :max).should == @data
12
+ describe 'normalizing isotope distributions' do
13
+
14
+ it 'defaults to normalizing by total signal with no cutoff' do
15
+ dist = Mspire::Isotope::Distribution.calculate( subject )
16
+ dist.size.should == 253
17
+ dist[0,5].should == [0.31740518639058685, 0.35635707398291416, 0.20793431846543858, 0.08373257192958428, 0.026084566135229446]
18
+ end
19
+
20
+ it 'can normalize by first peak' do
21
+ dist = Mspire::Isotope::Distribution.calculate( subject, :first )
22
+ dist.size.should == 253
23
+ dist[0].should == 1.0
24
+ dist[1].should_not == 1.0
25
+ end
26
+
27
+ it 'can normalize by the max peak' do
28
+ dist = Mspire::Isotope::Distribution.calculate( subject, :max)
29
+ dist.size.should == 253
30
+ dist[0].should_not == 1.0
31
+ dist[1].should == 1.0
32
+ end
33
+
34
+ it 'can cutoff based on percent of total signal' do
35
+ Mspire::Isotope::Distribution.calculate(subject, :max, 100).should == []
36
+ Mspire::Isotope::Distribution.calculate(subject, :max, 20).should == [0.8906942209481861, 1.0, 0.5834999040187656]
37
+ Mspire::Isotope::Distribution.calculate(subject, :max, 5).should == [0.8906942209481861, 1.0, 0.5834999040187656, 0.23496817670469172]
38
+ Mspire::Isotope::Distribution.calculate(subject, :max, 0.0001).size.should == 11
39
+ end
12
40
  end
13
41
 
14
- # no m/z values, just mass values
15
- it 'can calculate isotope distribution spectrum' do
16
- spec = Mspire::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.08919230588715311, 0.017894161377222138, 0.0013573997600723345, 0.0001398330738144181]
42
+ describe 'calculating an isotope distribution spectrum' do
43
+
44
+ it 'gives neutral masses if no charge' do
45
+ spec = Mspire::Isotope::Distribution.spectrum( subject )
46
+ [:mzs, :intensities].each {|att| spec.send(att).size.should == 253 }
47
+ spec.mzs[0,5].should == [1584.8627231418, 1585.8713880574, 1586.8800529730001, 1587.8887178886002, 1588.8973828042003]
48
+ spec.intensities[0,5].should == [0.31740518639058685, 0.35635707398291416, 0.20793431846543858, 0.08373257192958428, 0.026084566135229446]
49
+ end
50
+
51
+ it 'gives proper m/z values if the molecule is charged' do
52
+ charged_molecule = Mspire::MolecularFormula.new( subject )
53
+ charged_molecule.charge = -3
54
+ spec = Mspire::Isotope::Distribution.spectrum( charged_molecule )
55
+ [:mzs, :intensities].each {|att| spec.send(att).size.should == 253 }
56
+ spec.mzs[0,5].should == [-528.2881229806, -528.6243446191334, -528.9605662576668, -529.2967878962, -529.6330095347334]
57
+ end
19
58
  end
20
59
  end
@@ -12,4 +12,12 @@ describe Mspire::MolecularFormula do
12
12
  mf.should == data
13
13
  end
14
14
 
15
+ it 'expects properly capitalized abbreviations' do
16
+ Mspire::MolecularFormula.new('Ni7Se3').should == {:ni=>7, :se=>3}
17
+ # there is no such thing as the E element, so this is going to get the
18
+ # user in trouble. However, this is the proper interpretation of the
19
+ # formula.
20
+ Mspire::MolecularFormula.new('Ni7SE3').should == {:ni=>7, :s=>1, :e=>3}
21
+ end
22
+
15
23
  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.7.4
4
+ version: 0.7.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-03-21 00:00:00.000000000 Z
13
+ date: 2012-03-23 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: nokogiri