mspire 0.6.2 → 0.6.6

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE CHANGED
@@ -1,13 +1,54 @@
1
- Copyright (c) 2006, The University of Texas at Austin("U.T. Austin"). All rights reserved.
1
+ (The MIT License)
2
2
 
3
- Software by John T. Prince under the direction of Edward M. Marcotte.
3
+ Copyright (c) 2011 Brigham Young University
4
+ authored by John T. Prince
4
5
 
5
- By using this software the USER indicates that he or she has read, understood and will comply with the following:
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ "Software"), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
6
13
 
7
- U. T. Austin hereby grants USER permission to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of this software and its documentation for any purpose and without fee, provided that a full copy of this notice is included with the software and its documentation.
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
8
16
 
9
- Title to copyright this software and its associated documentation shall at all times remain with U. T. Austin. No right is granted to use in advertising, publicity or otherwise any trademark, service mark, or the name of U. T. Austin.
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10
24
 
11
- This software and any associated documentation are provided "as is," and U. T. AUSTIN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESSED OR IMPLIED, INCLUDING THOSE OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, OR THAT USE OF THE SOFTWARE, MODIFICATIONS, OR ASSOCIATED DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER INTELLECTUAL PROPERTY RIGHTS OF A THIRD PARTY. U. T. Austin, The University of Texas System, its Regents, officers, and employees shall not be liable under any circumstances for any direct, indirect, special, incidental, or consequential damages with respect to any claim by USER or any third party on account of or arising from the use, or inability to use, this software or its associated documentation, even if U. T. Austin has been advised of the possibility of those damages.
25
+ ========================================================================
26
+ The following files are under the following license:
27
+ ms/spectrum.rb
28
+ ========================================================================
12
29
 
13
- Submit software operation questions to: Edward M. Marcotte, Department of Chemistry and Biochemistry, U. T. Austin, Austin, Texas 78712.
30
+ (The MIT License)
31
+
32
+ Copyright (c) 2006-2010 University of Texas at Austin, Howard Hughes Medical
33
+ Institute, Reagents of the University of Colorado, and Brigham Young
34
+ University
35
+
36
+ Authored by John T. Prince and Simon Chiang.
37
+
38
+ Permission is hereby granted, free of charge, to any person obtaining a copy
39
+ of this software and associated documentation files (the "Software"), to deal
40
+ in the Software without restriction, including without limitation the rights
41
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
42
+ copies of the Software, and to permit persons to whom the Software is
43
+ furnished to do so, subject to the following conditions:
44
+
45
+ The above copyright notice and this permission notice shall be included in
46
+ all copies or substantial portions of the Software.
47
+
48
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
49
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
50
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
51
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
52
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
53
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
54
+ THE SOFTWARE.
data/Rakefile CHANGED
@@ -14,6 +14,7 @@ Jeweler::Tasks.new do |gem|
14
14
  gem.authors = ["John T. Prince", "Simon Chiang"]
15
15
  gem.add_dependency "nokogiri", "~> 1.5"
16
16
  gem.add_dependency "bsearch", ">= 1.5.0"
17
+ gem.add_dependency "andand", ">= 1.3.1"
17
18
  gem.add_dependency "obo", ">= 0.1.0"
18
19
  gem.add_development_dependency "rspec", "~> 2.6"
19
20
  gem.add_development_dependency "jeweler", "~> 1.5.2"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.2
1
+ 0.6.6
data/lib/bin.rb ADDED
@@ -0,0 +1,65 @@
1
+
2
+ class Bin < Range
3
+ attr_accessor :data
4
+
5
+ def initialize(*args)
6
+ super(*args)
7
+ @data = []
8
+ end
9
+
10
+ def inspect
11
+ "<(" + super + ") @data=#{data.inspect}>"
12
+ end
13
+
14
+ def <<(val)
15
+ @data << val
16
+ end
17
+
18
+ # O(m + n) speed to bin objects.
19
+ # bin objects must respond to === .
20
+ # the object to bin must be a value that is sortable (< > ==), or you can
21
+ # pass in a block to get the value.
22
+ # bins and objects must be accessible by index (e.g., bins[11]).
23
+ # if data_capture is given, it should be a parallel array to bins, and each
24
+ # object should respond to the '<<' method. Otherwise, the bins themselves
25
+ # will be used to push data onto.
26
+ #
27
+ # Here's a simple example of binning x,y points where we want to bin the
28
+ # points based on the x value:
29
+ #
30
+ # bins = (0...10).map {|i| Bin.new(i, i+1, false) }
31
+ # points = [[2.2, 100], [3.5, 200], [8.8, 150]]
32
+ #
33
+ # Bin.bin!(bins, points) {|point| point.first }
34
+ # # --or--: Bin.bin!(bins, points, &:first)
35
+ #
36
+ # An example where we want to use a separate data store:
37
+ #
38
+ #
39
+ def self.bin(bins, objects, *data_capture_obj, &block)
40
+ obj_e = objects.each ; obj = obj_e.next
41
+
42
+ data_capture = data_capture_obj.first || bins
43
+
44
+ bin_i = 0 # the bin index
45
+ cbin = bins[bin_i] # the current bin
46
+ done = false
47
+ until done
48
+ value = (block.nil? ? obj : block.call(obj))
49
+ if cbin.begin <= value
50
+ until cbin === value && data_capture[bin_i] << obj
51
+ bin_i += 1
52
+ cbin=bins[bin_i] || (done=true && break)
53
+ end
54
+ obj=obj_e.next rescue done=true
55
+ else
56
+ while cbin.begin > value && !done
57
+ obj=obj_e.next rescue done=true && break
58
+ value = (block.nil? ? obj : block.call(obj))
59
+ end
60
+ end
61
+ end
62
+ data_capture
63
+ end
64
+
65
+ end
@@ -0,0 +1,29 @@
1
+
2
+ class Array
3
+ # copied from ActiveSupport CoreExtensions
4
+ def in_groups(number, fill_with = nil)
5
+ # size / number gives minor group size;
6
+ # size % number gives how many objects need extra accomodation;
7
+ # each group hold either division or division + 1 items.
8
+ division = size / number
9
+ modulo = size % number
10
+
11
+ # create a new array avoiding dup
12
+ groups = []
13
+ start = 0
14
+
15
+ number.times do |index|
16
+ length = division + (modulo > 0 && modulo > index ? 1 : 0)
17
+ padding = fill_with != false &&
18
+ modulo > 0 && length == division ? 1 : 0
19
+ groups << slice(start, length).concat([fill_with] * padding)
20
+ start += length
21
+ end
22
+
23
+ if block_given?
24
+ groups.each{|g| yield(g) }
25
+ else
26
+ groups
27
+ end
28
+ end
29
+ end
@@ -11,13 +11,13 @@ module MS::Ident
11
11
  alias_method :seq, :sequence
12
12
  alias_method :seq=, :sequence=
13
13
 
14
- # a description of the protein
15
- attr_accessor :description
14
+ # a description of the protein
15
+ attr_accessor :description
16
16
 
17
17
  # if the GN=([^\s]+) regexp is found in the description, returns the first
18
18
  # match, or nil if not found
19
19
  def gene_id
20
- description.andand.match(/ GN=(\w+) ?/)[1]
20
+ description.andand[/ GN=(\w+) ?/, 1]
21
21
  end
22
22
  end
23
23
 
data/lib/ms/isotope/aa.rb CHANGED
@@ -1,55 +1,33 @@
1
1
  module MS
2
2
  module Isotope
3
3
  module AA
4
+ # These represent counts for the individual residues (i.e., no extra H
5
+ # and OH on the ends)
4
6
  ATOM_COUNTS_STR = {
5
- 'A' => { :c =>3, :h =>7 , :o =>2 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
6
- 'R' => { :c =>6, :h =>14 , :o =>2 , :n =>4 , :s =>0 , :p =>0, :se =>0 },
7
- 'N' => { :c =>4, :h =>8 , :o =>3 , :n =>2 , :s =>0 , :p =>0, :se =>0 },
8
- 'D' => { :c =>4, :h =>7 , :o =>4 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
9
- 'C' => { :c =>3, :h =>7 , :o =>2 , :n =>1 , :s =>1 , :p =>0, :se =>0 },
10
- 'E' => { :c =>5, :h =>9 , :o =>4 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
11
- 'Q' => { :c =>5, :h =>10 , :o =>3 , :n =>2 , :s =>0 , :p =>0, :se =>0 },
12
- 'G' => { :c =>2, :h =>5 , :o =>2 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
13
- 'H' => { :c =>6, :h =>9 , :o =>2 , :n =>3 , :s =>0 , :p =>0, :se =>0 },
14
- 'I' => { :c =>6, :h =>13 , :o =>2 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
15
- 'L' => { :c =>6, :h =>13 , :o =>2 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
16
- 'K' => { :c =>6, :h =>14 , :o =>2 , :n =>2 , :s =>0 , :p =>0, :se =>0 },
17
- 'M' => { :c =>5, :h =>11 , :o =>2 , :n =>1 , :s =>1 , :p =>0, :se =>0 },
18
- 'F' => { :c =>9, :h =>11 , :o =>2 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
19
- 'P' => { :c =>5, :h =>9 , :o =>2 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
20
- 'S' => { :c =>3, :h =>7 , :o =>3 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
21
- 'T' => { :c =>4, :h =>9 , :o =>3 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
22
- 'W' => { :c =>11, :h =>12 , :o =>2 , :n =>2 , :s =>0 , :p =>0, :se =>0 },
23
- 'Y' => { :c =>9, :h =>11 , :o =>3 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
24
- 'V' => { :c =>5, :h =>11 , :o =>2 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
25
- 'U' => { :c =>3, :h =>7 , :o =>2 , :n =>1 , :s =>0 , :p =>0, :se =>1 },
26
- 'O' => { :c =>12, :h =>21 , :o =>3 , :n =>3 , :s =>0 , :p =>0, :se =>0 }
7
+ 'A' => { :c =>3, :h =>5 , :o =>1 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
8
+ 'R' => { :c =>6, :h =>12 , :o =>1 , :n =>4 , :s =>0 , :p =>0, :se =>0 },
9
+ 'N' => { :c =>4, :h =>6 , :o =>2 , :n =>2 , :s =>0 , :p =>0, :se =>0 },
10
+ 'D' => { :c =>4, :h =>5 , :o =>3 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
11
+ 'C' => { :c =>3, :h =>5 , :o =>1 , :n =>1 , :s =>1 , :p =>0, :se =>0 },
12
+ 'E' => { :c =>5, :h =>7 , :o =>3 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
13
+ 'Q' => { :c =>5, :h =>8 , :o =>2 , :n =>2 , :s =>0 , :p =>0, :se =>0 },
14
+ 'G' => { :c =>2, :h =>3 , :o =>1 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
15
+ 'H' => { :c =>6, :h =>7 , :o =>1 , :n =>3 , :s =>0 , :p =>0, :se =>0 },
16
+ 'I' => { :c =>6, :h =>11 , :o =>1 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
17
+ 'L' => { :c =>6, :h =>11 , :o =>1 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
18
+ 'K' => { :c =>6, :h =>12 , :o =>1 , :n =>2 , :s =>0 , :p =>0, :se =>0 },
19
+ 'M' => { :c =>5, :h =>9 , :o =>1 , :n =>1 , :s =>1 , :p =>0, :se =>0 },
20
+ 'F' => { :c =>9, :h =>9 , :o =>1 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
21
+ 'P' => { :c =>5, :h =>7 , :o =>1 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
22
+ 'S' => { :c =>3, :h =>5 , :o =>2 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
23
+ 'T' => { :c =>4, :h =>7 , :o =>2 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
24
+ 'W' => { :c =>11, :h =>10 , :o =>1 , :n =>2 , :s =>0 , :p =>0, :se =>0 },
25
+ 'Y' => { :c =>9, :h =>9 , :o =>2 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
26
+ 'V' => { :c =>5, :h =>9 , :o =>1 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
27
+ 'U' => { :c =>3, :h =>5 , :o =>1 , :n =>1 , :s =>0 , :p =>0, :se =>1 },
28
+ 'O' => { :c =>12, :h =>19 , :o =>2 , :n =>3 , :s =>0 , :p =>0, :se =>0 }
27
29
  }
28
- ATOM_COUNTS_SYM = {
29
- :A => { :c =>3, :h =>7 , :o =>2 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
30
- :R => { :c =>6, :h =>14 , :o =>2 , :n =>4 , :s =>0 , :p =>0, :se =>0 },
31
- :N => { :c =>4, :h =>8 , :o =>3 , :n =>2 , :s =>0 , :p =>0, :se =>0 },
32
- :D => { :c =>4, :h =>7 , :o =>4 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
33
- :C => { :c =>3, :h =>7 , :o =>2 , :n =>1 , :s =>1 , :p =>0, :se =>0 },
34
- :E => { :c =>5, :h =>9 , :o =>4 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
35
- :Q => { :c =>5, :h =>10 , :o =>3 , :n =>2 , :s =>0 , :p =>0, :se =>0 },
36
- :G => { :c =>2, :h =>5 , :o =>2 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
37
- :H => { :c =>6, :h =>9 , :o =>2 , :n =>3 , :s =>0 , :p =>0, :se =>0 },
38
- :I => { :c =>6, :h =>13 , :o =>2 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
39
- :L => { :c =>6, :h =>13 , :o =>2 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
40
- :K => { :c =>6, :h =>14 , :o =>2 , :n =>2 , :s =>0 , :p =>0, :se =>0 },
41
- :M => { :c =>5, :h =>11 , :o =>2 , :n =>1 , :s =>1 , :p =>0, :se =>0 },
42
- :F => { :c =>9, :h =>11 , :o =>2 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
43
- :P => { :c =>5, :h =>9 , :o =>2 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
44
- :S => { :c =>3, :h =>7 , :o =>3 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
45
- :T => { :c =>4, :h =>9 , :o =>3 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
46
- :W => { :c =>11, :h =>12 , :o =>2 , :n =>2 , :s =>0 , :p =>0, :se =>0 },
47
- :Y => { :c =>9, :h =>11 , :o =>3 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
48
- :V => { :c =>5, :h =>11 , :o =>2 , :n =>1 , :s =>0 , :p =>0, :se =>0 },
49
- :U => { :c =>3, :h =>7 , :o =>2 , :n =>1 , :s =>0 , :p =>0, :se =>1 },
50
- :O => { :c =>12, :h =>21 , :o =>3 , :n =>3 , :s =>0 , :p =>0, :se =>0 }
51
- }
52
- ATOM_COUNTS_STR.each {|aa,val| ATOM_COUNTS[aa.to_sym] = val }
30
+ ATOM_COUNTS_SYM = Hash[ATOM_COUNTS_STR.map {|k,v| [k.to_sym, v] }]
53
31
 
54
32
  # string and symbol access of amino acid (atoms are all lower case
55
33
  # symbols)
data/lib/ms/mass.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  module MS
3
3
  module Mass
4
4
 
5
- # takes a chemical formula in this format: C2BrH12O
5
+ # takes a molecular formula in this format: C2BrH12O
6
6
  def self.formula_to_exact_mass(formula)
7
7
  # TODO: add other input methods
8
8
  pairs = formula.scan(/([A-Z][a-z]?)(\d*)/).map do |match|
data/lib/ms/mzml.rb CHANGED
@@ -10,7 +10,7 @@ module MS
10
10
  # scan = spectrum.scan
11
11
  # spectrum.mzs # array of m/zs
12
12
  # spectrum.intensities # array of intensities
13
- # spectrum.peaks.each do |mz,intensity|
13
+ # spectrum.points.each do |mz,intensity|
14
14
  # puts "mz: #{mz} intensity: #{intensity}"
15
15
  # end
16
16
  # end
@@ -0,0 +1,13 @@
1
+
2
+ module MS
3
+ class Peak
4
+ # A point is typically a doublet: an x value and a y value. In a spectrum
5
+ # this will be an m/z and intensity. In a chromatogram this will be a
6
+ # retention time and an intensity. (This class can be subclassed if
7
+ # desired)
8
+ class Point < Array
9
+ alias_method :x, :first
10
+ alias_method :y, :last
11
+ end
12
+ end
13
+ end
data/lib/ms/peak.rb ADDED
@@ -0,0 +1,108 @@
1
+
2
+ module MS ; end
3
+ # an MS::Peak instance is an array of contiguous points (where each point is
4
+ # a doublet: an x coordinate and a y coordinate)
5
+ class MS::Peak < Array
6
+
7
+ # returns an Array of peaks. Splits peak with 1 or more local minima into
8
+ # multiple peaks. When a point is 'shared' between two adjacent peak-ish
9
+ # areas, the choice of how to resolve multi-peaks (runs of data above
10
+ # zero) is one of:
11
+ #
12
+ # false/nil => only split on zeros
13
+ # :share => give each peak its rightful portion of shared peaks, dividing the
14
+ # intensity based on the intensity of adjacent peaks
15
+ # :greedy_y => give the point to the peak with highest point next to
16
+ # the point in question. tie goes lower.
17
+ #
18
+ # if return_local_minima is true, a parallel array of local minima indices is
19
+ # returned (only makes sense if split_multipeaks is false)
20
+ #
21
+ # assumes that a new point can be made with an array containing the x
22
+ # value and the y value.
23
+ def split(split_multipeaks=false, return_local_minima=false)
24
+ if split_multipeaks
25
+ (zeroed_peaks, local_min_ind_ar) = self.split(false, true)
26
+ $stderr.print "splitting on local minima ..." if $VERBOSE
27
+ no_local_minima_peaks = zeroed_peaks.zip(local_min_ind_ar).map do |peak, lm_indices|
28
+ new_peaks = [ peak.class.new ]
29
+ if lm_indices.size > 0
30
+ prev_lm_i = -1 # <- it's okay, we don't use until it is zero
31
+ lm_indices.each do |lm_i|
32
+ lm = peak[lm_i]
33
+ point_class = lm.class
34
+
35
+ # push onto the last peak all the points from right after the previous local min
36
+ # to just before this local min
37
+ new_peaks.last.push( *peak[(prev_lm_i+1)..(lm_i-1)] )
38
+ before_pnt = peak[lm_i-1]
39
+ after_pnt = peak[lm_i+1]
40
+
41
+ case split_multipeaks
42
+ when :share
43
+ sum = before_pnt[1] + after_pnt[1]
44
+ # push onto the last peak its portion of the local min
45
+ new_peaks.last << point_class.new( [lm[0], lm[1] * (before_pnt[1].to_f/sum)] )
46
+ # create a new peak that contains its portion of the local min
47
+ new_peaks << self.class.new( [point_class.new([lm[0], lm[1] * (after_pnt[1].to_f/sum)])] )
48
+ prev_lm_i = lm_i
49
+ when :greedy_y
50
+ if before_pnt[1] >= after_pnt[1]
51
+ new_peaks.last << lm
52
+ new_peaks << self.class.new
53
+ prev_lm_i = lm_i
54
+ else
55
+ new_peaks << self.class.new( [lm] )
56
+ prev_lm_i = lm_i
57
+ end
58
+ else
59
+ raise ArgumentError, "only recognize :share, :greedy_y, or false for the arg in #split(arg)"
60
+ end
61
+ end
62
+ new_peaks.last.push( *peak[(prev_lm_i+1)...peak.size] )
63
+ new_peaks
64
+ else
65
+ [peak]
66
+ end
67
+ end.flatten(1) # end zip
68
+ $stderr.puts "now #{no_local_minima_peaks.size} peaks." if $VERBOSE
69
+ no_local_minima_peaks
70
+ else
71
+ $stderr.print "splitting on zeros..." if $VERBOSE
72
+ # first, split the peaks based on zero intensity values
73
+ # and simultaneously keep track of the local minima within each
74
+ # resulting peak
75
+ peaks = []
76
+ local_min_ind_ar = []
77
+ in_peak = false
78
+ self.each_with_index do |point, index|
79
+ previous_y = self[index - 1][1]
80
+ if point[1] > 0
81
+ if !in_peak
82
+ in_peak = 0
83
+ peaks << self.class.new([point])
84
+ local_min_ind_ar << []
85
+ else
86
+ peaks.last << point
87
+ # if on_upslope(previous_y, point[1])
88
+ if previous_y < point[1]
89
+ # If we were previously on a downslope and we are now on an upslope
90
+ # then the previous index is a local min
91
+ prev_previous_y = self[index - 2][1]
92
+ # on_downslope(prev_previous_y, previous_y)
93
+ if prev_previous_y > previous_y
94
+ # We have found a local min
95
+ local_min_ind_ar.last << (in_peak-1)
96
+ end
97
+ end # end if (upslope)
98
+ end # end if !in_peak
99
+ in_peak += 1
100
+ elsif in_peak
101
+ in_peak = false
102
+ end # end if point[1] > 0
103
+ end
104
+ $stderr.puts "#{peaks.size} no-whitespace-inside peaks." if $VERBOSE
105
+ return_local_minima ? [peaks, local_min_ind_ar] : peaks
106
+ end #
107
+ end # def split
108
+ end
@@ -0,0 +1,17 @@
1
+
2
+ module MS
3
+ class Spectrum
4
+ # this module can be used to extend the behavior of some peaks as desired
5
+ module Centroidish
6
+ def mz() first end
7
+ def intensity() last end
8
+ end
9
+ # an Array implementation of Centroidish using alias_method. Accessing
10
+ # :mz and :intensity using this object will be nearly 2X as fast as
11
+ # extending the Centroidish behavior (confirmed by testing)
12
+ class Centroid < Array
13
+ alias_method :mz, :first
14
+ alias_method :intensity, :last
15
+ end
16
+ end
17
+ end
data/lib/ms/spectrum.rb CHANGED
@@ -1,21 +1,180 @@
1
1
  require 'bsearch'
2
+ require 'bin'
3
+ require 'ms/peak'
2
4
 
3
5
  module MS
6
+ # note that a point is an [m/z, intensity] doublet.
7
+ # A peak is considered a related string of points
4
8
  class Spectrum
5
9
  include Enumerable
6
10
 
11
+ DEFAULT_MERGE = {
12
+ :bin_width => 5,
13
+ :bin_unit => :ppm,
14
+ :normalize => true,
15
+ :return_data => false,
16
+ :split => :share
17
+ }
18
+
19
+ # returns a new spectrum which has been merged with the others. If the
20
+ # spectra are centroided (just checks the first one and assumes the others
21
+ # are the same) then it will bin the points (bin width determined by
22
+ # opts[:resolution]) and then segment according to monotonicity (sharing
23
+ # intensity between abutting points). The final m/z is the weighted
24
+ # averaged of all the m/z's in each peak. Valid opts (with default listed
25
+ # first):
26
+ #
27
+ # :bin_width => 5
28
+ # :bin_unit => :ppm | :amu interpret bin_width as ppm or amu
29
+ # :bins => array of Bin objects for custom bins (overides other bin options)
30
+ # :normalize => false if true, divides total intensity by
31
+ # number of spectra
32
+ # :return_data => false returns a parallel array containing
33
+ # the peaks associated with each returned point
34
+ # :split => :share | :greedy_y see MS::Peak#split
35
+ #
36
+ # The binning algorithm is the fastest possible algorithm that would allow
37
+ # for arbitrary, non-constant bin widths (a ratcheting algorithm O(n + m))
38
+ def self.merge(spectra, opts={})
39
+ opt = DEFAULT_MERGE.merge(opts)
40
+ (spectrum, returned_data) =
41
+ if spectra.first.centroided?
42
+ # find the min and max across all spectra
43
+ first_mzs = spectra.first.mzs
44
+ min = first_mzs.first ; max = first_mzs.last
45
+ spectra.each do |spectrum|
46
+ mzs = spectrum.mzs
47
+ min = mzs.first if mzs.first < min
48
+ max = mzs.last if mzs.last > max
49
+ end
50
+
51
+ # Create Bin objects
52
+ bins =
53
+ if opt[:bins]
54
+ opt[:bins]
55
+ else
56
+ divisions = []
57
+ bin_width = opt[:bin_width]
58
+ use_ppm = (opt[:bin_unit] == :ppm)
59
+ current_mz = min
60
+ loop do
61
+ if current_mz >= max
62
+ divisions << max
63
+ break
64
+ else
65
+ divisions << current_mz
66
+ current_mz += ( use_ppm ? current_mz./(1e6).*(bin_width) : bin_width )
67
+ end
68
+ end
69
+ # make each bin exclusive so there is no overlap
70
+ bins = divisions.each_cons(2).map {|pair| Bin.new(*pair, true) }
71
+ # make the last bin *inclusive* of the terminating value
72
+ bins[-1] = Bin.new(bins.last.begin, bins.last.end)
73
+ bins
74
+ end
75
+
76
+ spectra.each do |spectrum|
77
+ Bin.bin(bins, spectrum.points, &:first)
78
+ end
79
+
80
+ pseudo_points = bins.map do |bin|
81
+ #int = bin.data.reduce(0.0) {|sum,point| sum + point.last }.round(3) # <- just for info:
82
+ [bin, bin.data.reduce(0.0) {|sum,point| sum + point.last }]
83
+ end
84
+
85
+ #p_mzs = []
86
+ #p_ints = []
87
+ #p_num_points = []
88
+ #pseudo_points.each do |psp|
89
+ # p_mzs << ((psp.first.begin + psp.first.end)/2)
90
+ # p_ints << psp.last
91
+ # p_num_points << psp.first.data.size
92
+ #end
93
+
94
+ #File.write("file_#{opt[:bin_width]}_to_plot.txt", [p_mzs, p_ints, p_num_points].map {|ar| ar.join(' ') }.join("\n"))
95
+ #abort 'here'
96
+
97
+
98
+ peaks = MS::Peak.new(pseudo_points).split(opt[:split])
99
+
100
+ return_data = []
101
+ _mzs = [] ; _ints = []
102
+
103
+ #p peaks[97]
104
+ #puts "HIYA"
105
+ #abort 'here'
106
+
107
+ peaks.each_with_index do |peak,i|
108
+ #peaks.each do |peak|
109
+ tot_intensity = peak.map(&:last).reduce(:+)
110
+ return_data_per_peak = [] if opt[:return_data]
111
+ weighted_mz = 0.0
112
+ peak.each do |point|
113
+ pre_scaled_intensity = point[0].data.reduce(0.0) {|sum,v| sum + v.last }
114
+ post_scaled_intensity = point[1]
115
+ # some peaks may have been shared. In this case the intensity
116
+ # for that peak was downweighted. However, the actually data
117
+ # composing that peak is not altered when the intensity is
118
+ # shared. So, to calculate a proper weighted avg we need to
119
+ # downweight the intensity of any data point found within a bin
120
+ # whose intensity was scaled.
121
+ correction_factor =
122
+ if pre_scaled_intensity != post_scaled_intensity
123
+ post_scaled_intensity / pre_scaled_intensity
124
+ else
125
+ 1.0
126
+ end
127
+
128
+ return_data_per_peak.push(*point[0].data) if opt[:return_data]
129
+
130
+ point[0].data.each do |lil_point|
131
+ weighted_mz += lil_point[0] * ( (lil_point[1].to_f * correction_factor) / tot_intensity)
132
+ end
133
+ end
134
+ return_data << return_data_per_peak if opt[:return_data]
135
+ _mzs << weighted_mz
136
+ _ints << tot_intensity
137
+ end
138
+ [Spectrum.new([_mzs, _ints]), return_data]
139
+ else
140
+ raise NotImplementedError, "the way to do this is interpolate the profile evenly and sum"
141
+ end
142
+
143
+ if opt[:normalize]
144
+ sz = spectra.size
145
+ spectrum.data[1].map! {|v| v.to_f / sz }
146
+ end
147
+ if opt[:return_data]
148
+ $stderr.puts "returning spectrum (#{spectrum.mzs.size}) and data" if $VERBOSE
149
+ [spectrum, return_data]
150
+ else
151
+ $stderr.puts "returning spectrum (#{spectrum.mzs.size})" if $VERBOSE
152
+ spectrum
153
+ end
154
+ end
155
+
156
+
157
+ # boolean for if the spectrum represents centroided data or not
158
+ attr_accessor :centroided
159
+
160
+ def centroided?() centroided end
161
+
7
162
  # The underlying data store. methods are implemented so that data[0] is
8
163
  # the m/z's and data[1] is intensities
9
164
  attr_reader :data
10
165
 
166
+
167
+
168
+
11
169
  # data takes an array: [mzs, intensities]
12
170
  # @return [MS::Spectrum]
13
171
  # @param [Array] data two element array of mzs and intensities
14
- def initialize(data)
172
+ def initialize(data, centroided=true)
15
173
  @data = data
174
+ @centroided = centroided
16
175
  end
17
176
 
18
- def self.from_peaks(ar_of_doublets)
177
+ def self.from_points(ar_of_doublets)
19
178
  _mzs = []
20
179
  _ints = []
21
180
  ar_of_doublets.each do |mz, int|
@@ -55,12 +214,12 @@ module MS
55
214
  end
56
215
 
57
216
  # yields(mz, inten) across the spectrum, or array of doublets if no block
58
- def peaks(&block)
217
+ def points(&block)
59
218
  @data[0].zip(@data[1], &block)
60
219
  end
61
220
 
62
- alias_method :each, :peaks
63
- alias_method :each_peak, :peaks
221
+ alias_method :each, :points
222
+ alias_method :each_point, :points
64
223
 
65
224
  # if the mzs and intensities are the same then the spectra are considered
66
225
  # equal
@@ -83,9 +242,9 @@ module MS
83
242
  # instruments are bad about this)
84
243
  # returns self
85
244
  def sort!
86
- _peaks = peaks.to_a
87
- _peaks.sort!
88
- _peaks.each_with_index {|(mz,int), i| @data[0][i] = mz ; @data[1][i] = int }
245
+ _points = points.to_a
246
+ _points.sort!
247
+ _points.each_with_index {|(mz,int), i| @data[0][i] = mz ; @data[1][i] = int }
89
248
  self
90
249
  end
91
250
 
@@ -95,7 +254,7 @@ module MS
95
254
  mzs[find_nearest_index(val)]
96
255
  end
97
256
 
98
- # same as find_nearest but returns the index of the peak
257
+ # same as find_nearest but returns the index of the point
99
258
  def find_nearest_index(val)
100
259
  find_all_nearest_index(val).first
101
260
  end
@@ -126,6 +285,12 @@ module MS
126
285
  find_all_nearest_index(val).map {|i| mzs[i] }
127
286
  end
128
287
 
288
+ # uses MS::Spectrum.merge
289
+ def merge(other_spectra, opts={})
290
+ MS::Spectrum.merge([self, *other_spectra], opts)
291
+ end
292
+
293
+
129
294
  end
130
295
  end
131
296
 
data/spec/bin_spec.rb ADDED
@@ -0,0 +1,78 @@
1
+ require 'spec_helper'
2
+
3
+ require 'bin'
4
+
5
+ describe Bin do
6
+
7
+ describe 'putting data into bins' do
8
+
9
+ def matching(bins, peaks, bin_to_peak_index_pairs)
10
+ bins_dup = bins.dup
11
+ bin_to_peak_index_pairs.sort_by(&:first).reverse.each do |bin_i, peak_i|
12
+ _bin = bins_dup.delete_at(bin_i)
13
+ data = _bin.respond_to?(:data) ? _bin.data[0] : _bin[0]
14
+ data.should == peaks[peak_i]
15
+ end
16
+ bins_dup.map! {|bin| bin.respond_to?(:data) ? bin.data : bin }
17
+ bins_dup.all? {|bin| bin.size == 0 }.should be_true
18
+ end
19
+
20
+ def self.make_ranges(range, use_bin=false)
21
+ klass = use_bin ? Bin : Range
22
+ range.map {|i| klass.new(i.to_f, (i+1).to_f, true) }
23
+ end
24
+
25
+ def self.make_pairs(x_vals)
26
+ x_vals.each_with_index.map {|v,i| [v, i*100] }
27
+ end
28
+
29
+ def ranges_to_bins(ranges)
30
+ ranges.map {|range| Bin.new(range.begin, range.end, true) }
31
+ end
32
+
33
+ data = {
34
+ lower_and_lower: {
35
+ range: 0..9,
36
+ peaks: [3.0, 4.4, 11.0],
37
+ bin_to_peak_index_pairs: [[3,0], [4,1]]
38
+ },
39
+ higher_and_higher: {
40
+ range: 3..9,
41
+ peaks: [1.0, 2.99, 5.2],
42
+ bin_to_peak_index_pairs: [[2,2]]
43
+ },
44
+ lower_and_higher: {
45
+ range: 3..11,
46
+ peaks: [5.2, 11.0],
47
+ bin_to_peak_index_pairs: [[2,0], [8,1]]
48
+ },
49
+ higher_and_lower: {
50
+ range: 2..9,
51
+ peaks: [1.0, 2.99, 5.2, 11.0],
52
+ bin_to_peak_index_pairs: [[0,1],[3,2]]
53
+ }
54
+ }
55
+ data = data.map do |key, hash|
56
+ [ key, { ranges: make_ranges(hash[:range]),
57
+ peaks: make_pairs(hash[:peaks]),
58
+ bin_to_peak_index_pairs: hash[:bin_to_peak_index_pairs]} ]
59
+ end
60
+ data = Hash[data]
61
+ # not really the subject, but it is the data we care about here...
62
+
63
+ data.each do |type, init|
64
+ it "works for bins to data #{type.to_s.gsub('_',' ')}" do
65
+ rbins = Bin.bin(ranges_to_bins(init[:ranges]), init[:peaks], &:first)
66
+ matching(rbins, init[:peaks], init[:bin_to_peak_index_pairs])
67
+ end
68
+ end
69
+
70
+ data.each do |type, init|
71
+ it "works for ranges to data #{type.to_s.gsub('_',' ')}" do
72
+ custom_data_store = (0...init[:ranges].size).map { [] }
73
+ rbins = Bin.bin(init[:ranges], init[:peaks], custom_data_store, &:first)
74
+ matching(rbins, init[:peaks], init[:bin_to_peak_index_pairs])
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ require 'ms/isotope/aa'
4
+
5
+ describe 'accessing an amino acid atom count' do
6
+ before do
7
+ @alanine = {:c=>3, :h=>5, :o=>1, :n=>1, :s=>0, :p=>0, :se=>0}
8
+ end
9
+
10
+ it 'residue can be accessed with a symbol' do
11
+ hash = MS::Isotope::AA::ATOM_COUNTS[:A]
12
+ [:c, :h, :o, :n, :s].each {|key| hash[key].should == @alanine[key] }
13
+ end
14
+
15
+ it 'residue can be accessed with a string' do
16
+ hash = MS::Isotope::AA::ATOM_COUNTS['A']
17
+ [:c, :h, :o, :n, :s].each {|key| hash[key].should == @alanine[key] }
18
+ end
19
+
20
+ end
@@ -0,0 +1,90 @@
1
+ require 'spec_helper'
2
+
3
+ require 'ms/peak'
4
+ require 'ms/peak/point'
5
+
6
+ describe MS::Peak do
7
+
8
+ describe '#split' do
9
+
10
+ before do
11
+ # xs could be m/z values or retention times
12
+ simple = [ 0, 3, 8, 9, 7, 2, 0 ]
13
+ multi_large1 = [ 0, 3, 8, 2, 9, 7, 1, 3, 0 ]
14
+ multi_large2 = [ 0, 10, 8, 2, 9, 7, 1, 3, 0 ]
15
+ doublet = [ 0, 10, 8, 0 ]
16
+
17
+ start_mz = 50
18
+ @intensities = simple + multi_large1 + multi_large2 + doublet
19
+ @xs = []
20
+ mz = start_mz
21
+ diff = 0.01
22
+ loop do
23
+ @xs << mz
24
+ break if @xs.size == @intensities.size
25
+ mz += diff
26
+ end
27
+ @xs.map! {|mz| mz.round(2) }
28
+ @points = @xs.zip(@intensities).map {|pair| MS::Peak::Point.new(pair) }
29
+ end
30
+
31
+ it 'splits on zeros by default' do
32
+ peak = MS::Peak.new(@points) # <- maybe more like a collection of peaks, but Peak is flexible
33
+ peaks = peak.split
34
+ peaks.size.should == 4
35
+ peaks.should == [
36
+ [[50.01, 3], [50.02, 8], [50.03, 9], [50.04, 7], [50.05, 2]],
37
+ [[50.08, 3], [50.09, 8], [50.1, 2], [50.11, 9], [50.12, 7], [50.13, 1], [50.14, 3]],
38
+ [[50.17, 10], [50.18, 8], [50.19, 2], [50.2, 9], [50.21, 7], [50.22, 1], [50.23, 3]],
39
+ [[50.26, 10], [50.27, 8]]
40
+ ]
41
+ # returns local minima if asked
42
+ (peaks2, local_minima) = peak.split(false, true)
43
+ peaks2.should == peaks
44
+ local_minima.should == [[], [2, 5], [2, 5], []]
45
+ end
46
+
47
+ # which it should since zeros are the ultimate local min!
48
+ it 'always cleans up surrounding zeros and does not split non-multipeaks' do
49
+ peak = MS::Peak.new(@points[0,7]) # simple
50
+ [:share, :greedy_y].each do |multipeak_split_method|
51
+ peaks = peak.split(multipeak_split_method)
52
+ peaks.first.should be_an_instance_of(MS::Peak)
53
+ peaks.first.to_a.should == [[50.01, 3], [50.02, 8], [50.03, 9], [50.04, 7], [50.05, 2]]
54
+ end
55
+ end
56
+
57
+ it 'does #split(:share) and shares the peak proportional to adjacent peaks' do
58
+ data = [[50.07, 0], [50.08, 3], [50.09, 8], [50.1, 2], [50.11, 9], [50.12, 7], [50.13, 1], [50.14, 3], [50.15, 0]]
59
+ multipeak1 = MS::Peak.new( data )
60
+
61
+ answer = [
62
+ [[50.08, 3], [50.09, 8], [50.1, (2*8.0/17)]],
63
+ [[50.1, 2*9.0/17], [50.11, 9], [50.12, 7], [50.13, 0.7]],
64
+ [[50.13, 0.3], [50.14, 3]]
65
+ ]
66
+ multipeak1.split(:share).should == answer
67
+
68
+ answer = [
69
+ [[50.08, 3], [50.09, 8]],
70
+ [[50.1, 2], [50.11, 9], [50.12, 7], [50.13, 1]],
71
+ [[50.14, 3]]
72
+ ]
73
+ multipeak1.split(:greedy_y).should == answer
74
+
75
+ answer = [
76
+ [[50.08, 3], [50.09, 9], [50.1, 2]],
77
+ [[50.11, 9], [50.12, 7], [50.13, 1]],
78
+ [[50.14, 3]]
79
+ ]
80
+
81
+ # test a tie -> goes left!
82
+ points = @points[7,9]
83
+ points[2] = MS::Peak::Point.new([points[2][0], 9])
84
+ multipeak2 = MS::Peak.new( points )
85
+ multipeak2.split(:greedy_y).should == answer
86
+
87
+ end
88
+ end
89
+
90
+ end
@@ -45,4 +45,21 @@ describe MS::Spectrum do
45
45
  end
46
46
  end
47
47
 
48
+ describe 'merging spectra' do
49
+ subject do
50
+ data = [ [10.10, 10.5, 10.7, 11.5], [1, 2, 3, 4] ],
51
+ [ [10.11, 10.49, 10.71, 11.48], [5, 6, 7, 8] ],
52
+ [ [10.09, 10.51, 10.72, 11.51], [9, 10, 11, 12]
53
+ ]
54
+ data.map {|datum| MS::Spectrum.new( datum ) }
55
+ end
56
+ it 'merges, giving exact weighted average m/z values for each cluster' do
57
+ (spec1, data) = MS::Spectrum.merge(subject, :bin_width => 0.08, :bin_unit => :amu, :return_data => true)
58
+ spec2 = MS::Spectrum.merge(subject, :bin_width => 0.08, :bin_unit => :amu)
59
+ spec1.should == spec2
60
+ spec1.should == MS::Spectrum.new([[10.097333333333331, 10.502222222222223, 10.713809523809525, 11.498333333333333], [5.0, 6.0, 7.0, 8.0]])
61
+ data.should == [[[10.1, 1], [10.11, 5], [10.09, 9]], [[10.5, 2], [10.49, 6], [10.51, 10]], [[10.7, 3], [10.71, 7], [10.72, 11]], [[11.5, 4], [11.48, 8], [11.51, 12]]]
62
+ end
63
+ end
64
+
48
65
  end
metadata CHANGED
@@ -1,96 +1,111 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: mspire
3
- version: !ruby/object:Gem::Version
4
- version: 0.6.2
3
+ version: !ruby/object:Gem::Version
5
4
  prerelease:
5
+ version: 0.6.6
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - John T. Prince
9
9
  - Simon Chiang
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-02-02 00:00:00.000000000 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
13
+
14
+ date: 2012-02-13 00:00:00 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
16
17
  name: nokogiri
17
- requirement: &8784820 !ruby/object:Gem::Requirement
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
18
20
  none: false
19
- requirements:
21
+ requirements:
20
22
  - - ~>
21
- - !ruby/object:Gem::Version
22
- version: '1.5'
23
+ - !ruby/object:Gem::Version
24
+ version: "1.5"
23
25
  type: :runtime
24
- prerelease: false
25
- version_requirements: *8784820
26
- - !ruby/object:Gem::Dependency
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
27
28
  name: bsearch
28
- requirement: &8782400 !ruby/object:Gem::Requirement
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
29
31
  none: false
30
- requirements:
31
- - - ! '>='
32
- - !ruby/object:Gem::Version
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
33
35
  version: 1.5.0
34
36
  type: :runtime
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: andand
35
40
  prerelease: false
36
- version_requirements: *8782400
37
- - !ruby/object:Gem::Dependency
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 1.3.1
47
+ type: :runtime
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
38
50
  name: obo
39
- requirement: &8781260 !ruby/object:Gem::Requirement
51
+ prerelease: false
52
+ requirement: &id004 !ruby/object:Gem::Requirement
40
53
  none: false
41
- requirements:
42
- - - ! '>='
43
- - !ruby/object:Gem::Version
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
44
57
  version: 0.1.0
45
58
  type: :runtime
46
- prerelease: false
47
- version_requirements: *8781260
48
- - !ruby/object:Gem::Dependency
59
+ version_requirements: *id004
60
+ - !ruby/object:Gem::Dependency
49
61
  name: rspec
50
- requirement: &8780220 !ruby/object:Gem::Requirement
62
+ prerelease: false
63
+ requirement: &id005 !ruby/object:Gem::Requirement
51
64
  none: false
52
- requirements:
65
+ requirements:
53
66
  - - ~>
54
- - !ruby/object:Gem::Version
55
- version: '2.6'
67
+ - !ruby/object:Gem::Version
68
+ version: "2.6"
56
69
  type: :development
57
- prerelease: false
58
- version_requirements: *8780220
59
- - !ruby/object:Gem::Dependency
70
+ version_requirements: *id005
71
+ - !ruby/object:Gem::Dependency
60
72
  name: jeweler
61
- requirement: &8795440 !ruby/object:Gem::Requirement
73
+ prerelease: false
74
+ requirement: &id006 !ruby/object:Gem::Requirement
62
75
  none: false
63
- requirements:
76
+ requirements:
64
77
  - - ~>
65
- - !ruby/object:Gem::Version
78
+ - !ruby/object:Gem::Version
66
79
  version: 1.5.2
67
80
  type: :development
68
- prerelease: false
69
- version_requirements: *8795440
70
- - !ruby/object:Gem::Dependency
81
+ version_requirements: *id006
82
+ - !ruby/object:Gem::Dependency
71
83
  name: rcov
72
- requirement: &8792600 !ruby/object:Gem::Requirement
84
+ prerelease: false
85
+ requirement: &id007 !ruby/object:Gem::Requirement
73
86
  none: false
74
- requirements:
75
- - - ! '>='
76
- - !ruby/object:Gem::Version
77
- version: '0'
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: "0"
78
91
  type: :development
79
- prerelease: false
80
- version_requirements: *8792600
81
- description: mass spectrometry proteomics, lipidomics, and tools, a rewrite of mspire,
82
- merging of ms-* gems
92
+ version_requirements: *id007
93
+ description: mass spectrometry proteomics, lipidomics, and tools, a rewrite of mspire, merging of ms-* gems
83
94
  email: jtprince@gmail.com
84
95
  executables: []
96
+
85
97
  extensions: []
86
- extra_rdoc_files:
98
+
99
+ extra_rdoc_files:
87
100
  - LICENSE
88
101
  - README.rdoc
89
- files:
102
+ files:
90
103
  - LICENSE
91
104
  - README.rdoc
92
105
  - Rakefile
93
106
  - VERSION
107
+ - lib/bin.rb
108
+ - lib/core_ext/array/in_groups.rb
94
109
  - lib/cv.rb
95
110
  - lib/cv/description.rb
96
111
  - lib/cv/param.rb
@@ -128,10 +143,13 @@ files:
128
143
  - lib/ms/mzml/index_list.rb
129
144
  - lib/ms/mzml/plms1.rb
130
145
  - lib/ms/obo.rb
146
+ - lib/ms/peak.rb
147
+ - lib/ms/peak/point.rb
131
148
  - lib/ms/plms1.rb
132
149
  - lib/ms/quant/qspec.rb
133
150
  - lib/ms/quant/qspec/protein_group_comparison.rb
134
151
  - lib/ms/spectrum.rb
152
+ - lib/ms/spectrum/centroid.rb
135
153
  - lib/msplat.rb
136
154
  - lib/obo/ims.rb
137
155
  - lib/obo/ms.rb
@@ -142,6 +160,7 @@ files:
142
160
  - obo/ims.obo
143
161
  - obo/ms.obo
144
162
  - obo/unit.obo
163
+ - spec/bin_spec.rb
145
164
  - spec/ms/cvlist_spec.rb
146
165
  - spec/ms/digester_spec.rb
147
166
  - spec/ms/fasta_spec.rb
@@ -150,10 +169,12 @@ files:
150
169
  - spec/ms/ident/pepxml/search_hit/modification_info_spec.rb
151
170
  - spec/ms/ident/pepxml_spec.rb
152
171
  - spec/ms/ident/protein_group_spec.rb
172
+ - spec/ms/isotope/aa_spec.rb
153
173
  - spec/ms/mass_spec.rb
154
174
  - spec/ms/mzml/index_list_spec.rb
155
175
  - spec/ms/mzml/plms1_spec.rb
156
176
  - spec/ms/mzml_spec.rb
177
+ - spec/ms/peak_spec.rb
157
178
  - spec/ms/plms1_spec.rb
158
179
  - spec/ms/quant/qspec_spec.rb
159
180
  - spec/ms/spectrum_spec.rb
@@ -185,28 +206,31 @@ files:
185
206
  - spec/testfiles/ms/quant/unlog_transform.rb
186
207
  - spec/testfiles/plms1/output.key
187
208
  homepage: http://github.com/princelab/mspire
188
- licenses:
209
+ licenses:
189
210
  - MIT
190
211
  post_install_message:
191
212
  rdoc_options: []
192
- require_paths:
213
+
214
+ require_paths:
193
215
  - lib
194
- required_ruby_version: !ruby/object:Gem::Requirement
216
+ required_ruby_version: !ruby/object:Gem::Requirement
195
217
  none: false
196
- requirements:
197
- - - ! '>='
198
- - !ruby/object:Gem::Version
199
- version: '0'
200
- required_rubygems_version: !ruby/object:Gem::Requirement
218
+ requirements:
219
+ - - ">="
220
+ - !ruby/object:Gem::Version
221
+ version: "0"
222
+ required_rubygems_version: !ruby/object:Gem::Requirement
201
223
  none: false
202
- requirements:
203
- - - ! '>='
204
- - !ruby/object:Gem::Version
205
- version: '0'
224
+ requirements:
225
+ - - ">="
226
+ - !ruby/object:Gem::Version
227
+ version: "0"
206
228
  requirements: []
229
+
207
230
  rubyforge_project:
208
- rubygems_version: 1.8.15
231
+ rubygems_version: 1.8.10
209
232
  signing_key:
210
233
  specification_version: 3
211
234
  summary: mass spectrometry proteomics, lipidomics, and tools
212
235
  test_files: []
236
+