mspire 0.7.4 → 0.7.5

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