mspire 0.7.5 → 0.7.6

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.
Files changed (39) hide show
  1. data/VERSION +1 -1
  2. data/lib/cv/param.rb +30 -24
  3. data/lib/mspire/bin.rb +67 -0
  4. data/lib/mspire/cv/param.rb +4 -2
  5. data/lib/mspire/cv/paramable.rb +67 -12
  6. data/lib/mspire/isotope/distribution.rb +0 -1
  7. data/lib/mspire/mzml.rb +49 -1
  8. data/lib/mspire/mzml/activation.rb +5 -0
  9. data/lib/mspire/mzml/cv.rb +5 -0
  10. data/lib/mspire/mzml/data_array_container_like.rb +1 -1
  11. data/lib/mspire/mzml/file_description.rb +5 -1
  12. data/lib/mspire/mzml/instrument_configuration.rb +1 -1
  13. data/lib/mspire/mzml/isolation_window.rb +5 -0
  14. data/lib/mspire/mzml/precursor.rb +15 -0
  15. data/lib/mspire/mzml/processing_method.rb +1 -1
  16. data/lib/mspire/mzml/referenceable_param_group.rb +1 -1
  17. data/lib/mspire/mzml/run.rb +1 -1
  18. data/lib/mspire/mzml/sample.rb +1 -1
  19. data/lib/mspire/mzml/scan.rb +11 -1
  20. data/lib/mspire/mzml/scan_list.rb +1 -1
  21. data/lib/mspire/mzml/scan_settings.rb +1 -1
  22. data/lib/mspire/mzml/scan_window.rb +19 -0
  23. data/lib/mspire/mzml/selected_ion.rb +6 -0
  24. data/lib/mspire/mzml/software.rb +1 -1
  25. data/lib/mspire/mzml/source_file.rb +1 -1
  26. data/lib/mspire/mzml/spectrum.rb +49 -36
  27. data/lib/mspire/spectrum.rb +1 -1
  28. data/lib/mspire/user_param.rb +9 -23
  29. data/mspire.gemspec +8 -4
  30. data/spec/cv/param_spec.rb +21 -0
  31. data/spec/{bin_spec.rb → mspire/bin_spec.rb} +6 -6
  32. data/spec/mspire/cv/param_spec.rb +2 -12
  33. data/spec/mspire/mzml/file_content_spec.rb +2 -1
  34. data/spec/mspire/mzml/file_description_spec.rb +2 -24
  35. data/spec/mspire/mzml/source_file_spec.rb +24 -0
  36. data/spec/mspire/mzml/spectrum_spec.rb +61 -0
  37. data/spec/mspire/mzml_spec.rb +13 -11
  38. metadata +8 -4
  39. data/lib/bin.rb +0 -65
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.7.5
1
+ 0.7.6
@@ -1,37 +1,30 @@
1
- =begin
2
- # if you want to use Nokogiri as the builder, you need something like this
3
- # code:
4
- class XML::Nokogiri::Builder
5
- def tag!(name, *data)
6
- send(name, *data)
7
- end
8
- end
9
- =end
10
-
11
1
 
12
2
  module CV
13
- # the xml writer is written with the assumption that the object is a
14
- # Builder::XmlMarkup object. You can get away with using Nokogiri
15
- class Param
16
3
 
17
- attr_accessor :cv_ref, :accession, :name, :value
4
+ Param = Struct.new(:cv_ref, :accession, :name, :value, :unit)
18
5
 
19
- # A valueless CV::Param object that describes the units being used
20
- attr_accessor :unit
6
+ class Param
21
7
 
22
- def initialize(cv_ref, accession, name, value=nil, unit=nil)
23
- @cv_ref, @accession, @name, @value, @unit = cv_ref, accession, name, value, unit
8
+ # standard struct invocation. Ensures that value is nil if an empty
9
+ # string is given.
10
+ def initialize(*args)
11
+ args[3] = nil if (args[3] == '')
12
+ super(*args)
24
13
  end
25
14
 
26
15
  # for now, assumes this is a Builder::XmlMarkup object.
27
16
  # returns the xml builder object
28
17
  def to_xml(xml, name=:cvParam)
29
- hash_to_send = {:cvRef => @cv_ref, :accession => @accession, :name => @name}
30
- hash_to_send[:value] = @value if @value
18
+ hash_to_send = {:cvRef => self.cv_ref, :accession => self.accession, :name => self.name}
19
+ if v=self.value
20
+ hash_to_send[:value] = v
21
+ end
31
22
  if unit
32
- hash_to_send.merge!( { :unitCvRef => unit.cv_ref,
23
+ hash_to_send.merge!(
24
+ { :unitCvRef => unit.cv_ref,
33
25
  :unitAccession => unit.accession,
34
- :unitName => unit.name } )
26
+ :unitName => unit.name }
27
+ )
35
28
  end
36
29
 
37
30
  # xml.send for builder results in tags with 'send' in the front
@@ -42,13 +35,26 @@ module CV
42
35
  end
43
36
 
44
37
  def ==(other)
45
- if !other.nil? && other.is_a?(CV::Param)
38
+ if !other.nil?
46
39
  [:cv_ref, :accession, :name, :value, :unit].inject(true) do |bool, mthd|
47
40
  bool && (self.send(mthd) == other.send(mthd))
48
41
  end
49
- else ; false
42
+ else
43
+ false
50
44
  end
51
45
  end
52
46
  end
53
47
  end
54
48
 
49
+
50
+
51
+ =begin
52
+ # if you want to use Nokogiri as the builder, you need something like this
53
+ # code:
54
+ class XML::Nokogiri::Builder
55
+ def tag!(name, *data)
56
+ send(name, *data)
57
+ end
58
+ end
59
+ =end
60
+
@@ -0,0 +1,67 @@
1
+
2
+ module Mspire
3
+ class Bin < Range
4
+ attr_accessor :data
5
+
6
+ def initialize(*args)
7
+ super(*args)
8
+ @data = []
9
+ end
10
+
11
+ def inspect
12
+ "<(" + super + ") @data=#{data.inspect}>"
13
+ end
14
+
15
+ def <<(val)
16
+ @data << val
17
+ end
18
+
19
+ # O(m + n) speed to bin objects.
20
+ # bin objects must respond to === .
21
+ # the object to bin must be a value that is sortable (< > ==), or you can
22
+ # pass in a block to get the value.
23
+ # bins and objects must be accessible by index (e.g., bins[11]).
24
+ # if data_capture is given, it should be a parallel array to bins, and each
25
+ # object should respond to the '<<' method. Otherwise, the bins themselves
26
+ # will be used to push data onto.
27
+ #
28
+ # Here's a simple example of binning x,y points where we want to bin the
29
+ # points based on the x value:
30
+ #
31
+ # bins = (0...10).map {|i| Mspire::Bin.new(i, i+1, false) }
32
+ # points = [[2.2, 100], [3.5, 200], [8.8, 150]]
33
+ #
34
+ # Mspire::Bin.bin(bins, points) {|point| point.first }
35
+ # # --or--: Mspire::Bin.bin(bins, points, &:first)
36
+ #
37
+ # An example where we want to use a separate data store:
38
+ #
39
+ #
40
+ def self.bin(bins, objects, *data_capture_obj, &block)
41
+ obj_e = objects.each ; obj = obj_e.next
42
+
43
+ data_capture = data_capture_obj.first || bins
44
+
45
+ bin_i = 0 # the bin index
46
+ cbin = bins[bin_i] # the current bin
47
+ done = false
48
+ until done
49
+ value = (block.nil? ? obj : block.call(obj))
50
+ if cbin.begin <= value
51
+ until cbin === value && data_capture[bin_i] << obj
52
+ bin_i += 1
53
+ cbin=bins[bin_i] || (done=true && break)
54
+ end
55
+ obj=obj_e.next rescue done=true
56
+ else
57
+ while cbin.begin > value && !done
58
+ obj=obj_e.next rescue done=true && break
59
+ value = (block.nil? ? obj : block.call(obj))
60
+ end
61
+ end
62
+ end
63
+ data_capture
64
+ end
65
+
66
+ end
67
+ end
@@ -5,7 +5,7 @@ module Mspire
5
5
  module CV
6
6
 
7
7
  # a mass spec related CVParam.
8
- class Param < ::CV::Param
8
+ module Param
9
9
 
10
10
  # Takes one of these invocations:
11
11
  #
@@ -15,6 +15,8 @@ module Mspire
15
15
  # Where acc_num and unit_acc_num are strings containing valid accession
16
16
  # numbers (e.g., 'MS:1000514' or 'UO:0000108'). Note that sometimes units are
17
17
  # from obo's other than UO.
18
+ #
19
+ # returns a CV::Param object
18
20
  def self.[](*args)
19
21
  #puts "param args #{args.inspect}"
20
22
  unit =
@@ -27,7 +29,7 @@ module Mspire
27
29
  Mspire::CV::Param[args.pop]
28
30
  end
29
31
  obo_type = args[0][/([A-Za-z]+):/,1]
30
- self.new(obo_type, args[0], Mspire::CV::Obo[obo_type][args.first], args[1], unit)
32
+ ::CV::Param.new(obo_type, args[0], Mspire::CV::Obo[obo_type][args.first], args[1], unit)
31
33
  end
32
34
  end
33
35
  end
@@ -1,4 +1,7 @@
1
+ require 'cv/param'
2
+ require 'mspire/user_param'
1
3
  require 'mspire/cv/param'
4
+ require 'nokogiri'
2
5
 
3
6
  module Mspire
4
7
  module CV
@@ -7,26 +10,78 @@ module Mspire
7
10
  attr_accessor :params
8
11
 
9
12
  def initialize(opts={params: []})
10
- describe!(*opts[:params])
13
+ describe_many!(opts[:params])
11
14
  end
12
15
 
13
- # casts each string or array as a Param object (using Mspire::CV::Param[]),
14
- # pushes it onto the params attribute and returns the growing params object
15
- def describe!(*args)
16
- @params ||= []
17
- as_params = args.map do |arg|
16
+ # cast may be something like :to_i or :to_f
17
+ def find_param_value_by_accession(accession, cast=nil)
18
+ param = params.find {|v| v.accession == accession }
19
+ if param
20
+ val = param.value
21
+ cast ? (val && val.send(cast)) : val
22
+ end
23
+ end
24
+
25
+ # cast may be something like :to_i or :to_f
26
+ def find_param_by_accession(accession)
27
+ params.find {|v| v.accession == accession }
28
+ end
29
+
30
+
31
+ def param_exists_by_accession?(accession)
32
+ params.any? {|v| v.accession == accession }
33
+ end
34
+
35
+ # takes an array of values, each of which is fed into describe!
36
+ def describe_many!(array)
37
+ array.each do |arg|
18
38
  if arg.is_a?(Array)
19
- Mspire::CV::Param[ *arg ]
20
- elsif arg.is_a?(String)
21
- Mspire::CV::Param[ arg ]
39
+ describe!(*arg)
22
40
  else
23
- arg
41
+ describe!(arg)
42
+ end
43
+ end
44
+ end
45
+
46
+ # Expects arguments describing a single CV::Param or Mapire::UserParam.
47
+ # Will also accept an Nokogiri::XML::Node or Nokogiri::XML::NodeSet
48
+ #
49
+ # obj.describe! 'MS:1000130' # a positive scan
50
+ # obj.describe! CV::Param['MS:1000130'] # same behavior
51
+ #
52
+ # # base peak intensity, units=number of counts
53
+ # obj.describe! "MS:1000505", 1524.5865478515625, 'MS:1000131'
54
+ #
55
+ # # given an XML::NodeSet
56
+ # obj.describe! xml_node.xpath('.//cvParam')
57
+ #
58
+ # # given an XML
59
+ # obj.describe! xml_node.xpath('.//cvParam').first
60
+ def describe!(*args)
61
+ @params ||= []
62
+ case (arg=args.first)
63
+ when String
64
+ @params << Mspire::CV::Param[ *args ]
65
+ when Nokogiri::XML::Node # a nokogiri node in particular
66
+ param =
67
+ case arg.name
68
+ when 'cvParam'
69
+ ::CV::Param.new(arg[:cvRef], arg[:accession], arg[:name], arg[:value])
70
+ when 'userParam'
71
+ Mspire::UserParam.new(arg[:name], arg[:value], arg[:type])
72
+ end
73
+ if (unit_acc = arg[:unitAccession])
74
+ param.unit = ::CV::Param.new(arg[:unitCvRef], unit_acc, arg[:unitName])
24
75
  end
76
+ @params << param
77
+ when Nokogiri::XML::NodeSet
78
+ arg.each {|node| describe!(node) }
79
+ else
80
+ (@params << arg) if arg
25
81
  end
26
- @params.push(*as_params)
82
+ @params
27
83
  end
28
84
 
29
- # if params respond_to?(:to_xml) then will call that, otherwise
30
85
  # iterates over @params and calls .to_xml on each object.
31
86
  def to_xml(xml)
32
87
  if @params
@@ -104,7 +104,6 @@ module Mspire
104
104
 
105
105
  end
106
106
 
107
-
108
107
  class Isotope
109
108
  module Distribution
110
109
  def self.calculate(molecular_formula_like, normalize=Mspire::Isotope::Distribution::NORMALIZE, percent_cutoff=nil)
@@ -152,7 +152,7 @@ module Mspire
152
152
  @io = arg
153
153
  @encoding = @io.bookmark(true) {|io| io.readline.match(/encoding=["'](.*?)["']/)[1] }
154
154
  @index_list = get_index_list
155
- # TODO: and read in 'header' info (everything until 'run'
155
+ read_header!
156
156
  when Hash
157
157
  arg.each {|k,v| self.send("#{k}=", v) }
158
158
  end
@@ -161,6 +161,49 @@ module Mspire
161
161
  end
162
162
  end
163
163
 
164
+ def read_header!
165
+ @io.rewind
166
+ chunk_size = 2**12
167
+ loc = 0
168
+ string = ''
169
+ while chunk = @io.read(chunk_size)
170
+ string << chunk
171
+ start_looking = ((loc-20) < 0) ? 0 : (loc-20)
172
+ break if string[start_looking..-1] =~ /<(spectrum|chromatogram)/
173
+ loc += chunk_size
174
+ end
175
+ doc = Nokogiri::XML.parse(string, nil, @encoding, Parser::NOBLANKS)
176
+ mzml_n = doc.root
177
+ if mzml_n.name == 'indexedmzML'
178
+ mzml_n = mzml_n.child
179
+ end
180
+ cv_list_n = mzml_n.child
181
+ file_description_n = cv_list_n.next
182
+ self.cvs = cv_list_n.children.map do |cv_n|
183
+ Mspire::Mzml::CV.from_xml(cv_n)
184
+ end
185
+ self.file_description = Mspire::Mzml::FileDescription.from_xml(file_description_n)
186
+ next_n = file_description_n.next
187
+ loop do
188
+ case next_n.name
189
+ when 'referenceableParamGroupList'
190
+ # get a hash ready
191
+ when 'sampleList'
192
+ # set objects
193
+ when 'softwareList' # required
194
+ # set objects
195
+ when 'instrumentConfigurationList'
196
+ # set objects
197
+ when 'dataProcessingList'
198
+ # set objects
199
+ when 'run'
200
+ # get defaults ready
201
+ break
202
+ end
203
+ next_n = next_n.next
204
+ end
205
+ end
206
+
164
207
  class << self
165
208
 
166
209
  # read-only right now
@@ -212,6 +255,11 @@ module Mspire
212
255
 
213
256
  alias_method :each, :each_spectrum
214
257
 
258
+ # returns the nokogiri xml node for the spectrum at that index
259
+ def spectrum_node(index)
260
+ spectrum_node_from_start_byte(@index_list[:spectrum][index])
261
+ end
262
+
215
263
  def spectrum_node_from_start_byte(start_byte)
216
264
  xml = get_xml_string(start_byte, :spectrum)
217
265
  doc = Nokogiri::XML.parse(xml, nil, @encoding, Parser::NOBLANKS)
@@ -28,6 +28,11 @@ module Mspire
28
28
  # et al.
29
29
  class Activation
30
30
  include Mspire::CV::Paramable
31
+ def self.from_xml(xml)
32
+ obj = self.new
33
+ [:cvParam, :userParam].each {|v| obj.describe! xml.xpath("./#{v}") }
34
+ obj
35
+ end
31
36
  end
32
37
  end
33
38
  end
@@ -26,12 +26,17 @@ module Mspire
26
26
  end
27
27
 
28
28
  def self.list_xml(objs, builder)
29
+ # we don't extend Mzml::List because of custom name below
29
30
  builder.cvList(count: objs.size) do |cvl_n|
30
31
  objs.each {|obj| obj.to_xml(cvl_n) }
31
32
  end
32
33
  builder
33
34
  end
34
35
 
36
+ def self.from_xml(xml)
37
+ self.new(xml[:id], xml[:fullName], xml[:URI], xml[:version])
38
+ end
39
+
35
40
  # These are derived by looking in the obo folder at the top of mspire
36
41
  IMS = self.new("IMS", "Imaging MS Ontology", "http://www.maldi-msi.org/download/imzml/imagingMS.obo", "0.9.1")
37
42
  MS = self.new('MS', "Proteomics Standards Initiative Mass Spectrometry Ontology", "http://psidev.cvs.sourceforge.net/*checkout*/psidev/psi/psi-ms/mzML/controlledVocabulary/psi-ms.obo", "3.18.0")
@@ -28,7 +28,7 @@ module Mspire
28
28
 
29
29
  def initialize(id, opts={params: []})
30
30
  @id = id
31
- describe!(*opts[:params])
31
+ describe_many!(opts[:params])
32
32
  end
33
33
 
34
34
  def default_array_length
@@ -24,7 +24,11 @@ module Mspire
24
24
  def initialize(file_content=nil, source_files=[], contacts=[], &block)
25
25
  @file_content, @source_files, @contacts = file_content, source_files, contacts
26
26
  block.call(self) if block
27
- raise ArgumentError, "FileDescription must have file_content" unless @file_content
27
+ #raise ArgumentError, "FileDescription must have file_content" unless @file_content
28
+ end
29
+
30
+ def self.from_xml(xml)
31
+ self.new
28
32
  end
29
33
 
30
34
  def to_xml(builder)
@@ -17,7 +17,7 @@ module Mspire
17
17
  attr_accessor :software
18
18
 
19
19
  def initialize(id, components=[], opts={params: []})
20
- describe!(*opts[:params])
20
+ describe_many!(opts[:params])
21
21
  @id = id
22
22
  @components = components
23
23
  end
@@ -16,6 +16,11 @@ module Mspire
16
16
  # e.g.: MS:1000829 (isolation window upper offset)
17
17
  class IsolationWindow
18
18
  include Mspire::CV::Paramable
19
+ def self.from_xml(xml)
20
+ obj = self.new
21
+ [:cvParam, :userParam].each {|v| obj.describe! xml.xpath("./#{v}") }
22
+ obj
23
+ end
19
24
  end
20
25
  end
21
26
  end
@@ -1,5 +1,7 @@
1
1
  require 'mspire/mzml/list'
2
2
  require 'mspire/mzml/selected_ion'
3
+ require 'mspire/mzml/isolation_window'
4
+ require 'mspire/mzml/activation'
3
5
 
4
6
  module Mspire
5
7
  class Mzml
@@ -25,6 +27,19 @@ module Mspire
25
27
  @spectrum=spectrum_derived_from
26
28
  end
27
29
 
30
+ def self.from_xml(xml)
31
+ obj = self.new
32
+ %w(isolationWindow activation).each do |el|
33
+ sub_node = xml.xpath("./#{el}").first
34
+ el[0] = el[0].capitalize
35
+ Mspire::Mzml.const_get(el).from_xml(sub_node) if sub_node
36
+ end
37
+ obj.selected_ions = xml.xpath('./selectedIonList/selectedIon').map do |si_n|
38
+ Mspire::Mzml::SelectedIon.from_xml(si_n)
39
+ end
40
+ obj
41
+ end
42
+
28
43
  def to_xml(builder)
29
44
  atts = {}
30
45
  if @from_external_source_file
@@ -9,7 +9,7 @@ module Mspire
9
9
 
10
10
  def initialize(order, software, opts={params: []}, &block)
11
11
  @order, @software = order, software
12
- describe!(*opts[:params])
12
+ describe_many!(opts[:params])
13
13
  block.call(self) if block
14
14
  end
15
15
 
@@ -14,7 +14,7 @@ module Mspire
14
14
 
15
15
  def initialize(id, opts={params: []} )
16
16
  @id = id
17
- describe!(*opts[:params])
17
+ describe_many!(opts[:params])
18
18
  end
19
19
 
20
20
  def to_xml(builder)
@@ -30,7 +30,7 @@ module Mspire
30
30
  def initialize(id, default_instrument_configuration, opts={params: []}, &block)
31
31
  @id = id
32
32
  @default_instrument_configuration = default_instrument_configuration
33
- describe!(*opts[:params])
33
+ describe_many!(opts[:params])
34
34
  block.call(self) if block
35
35
  end
36
36
 
@@ -10,7 +10,7 @@ module Mspire
10
10
 
11
11
  def initialize(id, name, opts={params: []}, &block)
12
12
  @id, @name = id, name
13
- describe!(*opts[:params])
13
+ describe_many!(opts[:params])
14
14
  block.call(self) if block
15
15
  end
16
16
 
@@ -1,4 +1,5 @@
1
1
  require 'mspire/cv/paramable'
2
+ require 'mspire/mzml/scan_window'
2
3
 
3
4
  module Mspire
4
5
  class Mzml
@@ -20,7 +21,7 @@ module Mspire
20
21
  attr_accessor :scan_windows
21
22
 
22
23
  def initialize(opts={params: []}, &block)
23
- describe!(*opts[:params])
24
+ describe_many!(opts[:params])
24
25
  block.call(self) if block
25
26
  end
26
27
 
@@ -28,6 +29,15 @@ module Mspire
28
29
  #def self.from_xml(xml)
29
30
  #end
30
31
 
32
+ def self.from_xml(xml)
33
+ scan = self.new
34
+ [:cvParam, :userParam].each {|v| scan.describe! xml.xpath("./#{v}") }
35
+ scan.scan_windows = xml.xpath('./scanWindowList/scanWindow').map do |scan_window_n|
36
+ Mspire::Mzml::ScanWindow.from_xml(scan_window_n)
37
+ end
38
+ scan
39
+ end
40
+
31
41
  def to_xml(builder)
32
42
  atts = {}
33
43
  if @from_external_source_file
@@ -13,7 +13,7 @@ module Mspire
13
13
  include Mspire::CV::Paramable
14
14
 
15
15
  def initialize(opts={params: []}, &block)
16
- describe!(*opts[:params])
16
+ describe_many!(opts[:params])
17
17
  block.call(self) if block
18
18
  end
19
19
 
@@ -10,7 +10,7 @@ module Mspire
10
10
 
11
11
  def initialize(id, opts={params: []}, &block)
12
12
  @id = id
13
- describe!(*opts[:params])
13
+ describe_many!(opts[:params])
14
14
  block.call(self) if block
15
15
  end
16
16
 
@@ -0,0 +1,19 @@
1
+ require 'mspire/cv/paramable'
2
+
3
+ module Mspire
4
+ class Mzml
5
+ # Typical params might be like:
6
+ #
7
+ # accession="MS:1000501" name="scan window lower limit" value="400"
8
+ # accession="MS:1000500" name="scan window upper limit" value="1800"
9
+ class ScanWindow
10
+ include Mspire::CV::Paramable
11
+
12
+ def self.from_xml(xml)
13
+ obj = self.new
14
+ [:cvParam, :userParam].each {|v| obj.describe! xml.xpath("./#{v}") }
15
+ obj
16
+ end
17
+ end
18
+ end
19
+ end
@@ -13,6 +13,12 @@ module Mspire
13
13
  class SelectedIon
14
14
  include Mspire::CV::Paramable
15
15
  extend(Mspire::Mzml::List)
16
+
17
+ def self.from_xml(xml)
18
+ obj = self.new
19
+ [:cvParam, :userParam].each {|v| obj.describe! xml.xpath("./#{v}") }
20
+ obj
21
+ end
16
22
  end
17
23
  end
18
24
  end
@@ -11,7 +11,7 @@ module Mspire
11
11
 
12
12
  def initialize(id='mspire', version=Mspire::VERSION, opts={params: []}, &block)
13
13
  @id, @version = id, version
14
- describe!(*opts[:params])
14
+ describe_many!(opts[:params])
15
15
  block.call(self) if block
16
16
  end
17
17
 
@@ -33,7 +33,7 @@ module Mspire
33
33
 
34
34
  def initialize(id="sourcefile1", name="mspire-simulated", location='file://', opts={params: []}, &block)
35
35
  @id, @name, @location = id, name, location
36
- describe!(*opts[:params])
36
+ describe_many!(opts[:params])
37
37
  block.call(self) if block
38
38
  end
39
39
 
@@ -5,6 +5,8 @@ require 'mspire/mzml/scan_list'
5
5
  require 'mspire/mzml/precursor'
6
6
  require 'mspire/mzml/product'
7
7
 
8
+ require 'andand'
9
+
8
10
  module Mspire
9
11
  class Mzml
10
12
 
@@ -64,62 +66,73 @@ module Mspire
64
66
  # currently being described, ordered.
65
67
  attr_accessor :products
66
68
 
67
- # retention time in seconds
68
- attr_accessor :retention_time
69
- # when properly implemented, this will access the first scan and the
70
- # 'scan start time' cv element.
71
-
72
- # takes a Nokogiri node and sets relevant properties
73
- def self.from_xml(xml)
74
- spec = Mspire::Mzml::Spectrum.new(xml[:id])
75
-
76
- params = {}
77
- xml.xpath("./cvParam").each do |cvparam|
78
- params[cvparam[:accession]] = cvparam[:value]
79
- end
80
- spec.ms_level = params['MS:1000511'].to_i
81
- # we assume centroid if they don't tell us profile
82
- spec.centroided = !params.key?("MS:1000128") # profile spectrum
83
- # centroid -> "MS:1000127"
84
-
85
- # this is a quick hack to get retention time, implement fully as shown
86
- # below!
87
- cv_param = xml.xpath("./scanList/scan/cvParam[@accession='MS:1000016']").first
88
- if cv_param
89
- retention_time = cv_param['value'].to_f
90
- units = cv_param['unitAccession']
69
+ # returns the retention time of the first scan object in the scan list
70
+ # *in seconds*!
71
+ def retention_time
72
+ rt_param = scan_list.first.find_param_by_accession('MS:1000016')
73
+ if rt_param
91
74
  multiplier =
92
- case units
75
+ case rt_param.unit.accession
93
76
  when 'UO:0000010' ; 1 # second
94
77
  when 'UO:0000031' ; 60 # minute
95
78
  when 'UO:0000032' ; 3600 # hour
96
79
  when 'UO:0000028' ; 0.001 # millisecond
97
80
  else raise 'unsupported units'
98
81
  end
99
- retention_time *= multiplier
82
+ rt_param.value.to_f * multiplier
100
83
  end
84
+ end
85
+
86
+ # returns the ms_level as an Integer
87
+ def ms_level
88
+ find_param_value_by_accession('MS:1000511', :to_i)
89
+ end
90
+
91
+ def centroided?
92
+ param_exists_by_accession?('MS:1000127')
93
+ end
94
+
95
+ def profile?
96
+ param_exists_by_accession?('MS:1000128')
97
+ end
98
+
99
+ # returns the charge state of the first precursor as an integer
100
+ def precursor_charge
101
+ precursors.andand.first.andand.selected_ions.andand.first.andand.find_param_value_by_accession('MS:1000041', :to_i)
102
+ end
101
103
 
102
- # this is roughly how the scan list stuff should be implemented:
103
- =begin
104
- sl_obj = Mspire::Mzml::ScanList.new
104
+ def precursor_mz
105
+ precursors.andand.first.andand.selected_ions.andand.first.andand.find_param_value_by_accession('MS:1000744', :to_f)
106
+ end
105
107
 
106
- # TODO: need to slot in all the other info in reasonable ways
107
- # TODO: need to make sure we deal with referencable params
108
- scan_list = xml.xpath('.scanList/scan').each do |scan_n|
109
- sl_obj << Mspire::Mzml::Scan.from_xml(scan_n)
108
+ # takes a Nokogiri node and sets relevant properties
109
+ def self.from_xml(xml)
110
+ spec = Mspire::Mzml::Spectrum.new(xml[:id])
111
+
112
+ spec.spot_id = xml[:spotID]
113
+
114
+ [:cvParam, :userParam].each {|v| spec.describe! xml.xpath("./#{v}") }
115
+
116
+ scan_list = Mspire::Mzml::ScanList.new
117
+ xml.xpath('./scanList/scan').each do |scan_n|
118
+ scan_list << Mspire::Mzml::Scan.from_xml(scan_n)
119
+ end
120
+ spec.scan_list = scan_list
121
+
122
+ spec.precursors = xml.xpath('./precursorList/precursor').map do |prec_n|
123
+ Mspire::Mzml::Precursor.from_xml(prec_n)
110
124
  end
111
- =end
112
125
 
113
126
  data_arrays = xml.xpath('./binaryDataArrayList/binaryDataArray').map do |binary_data_array_n|
114
127
  accessions = binary_data_array_n.xpath('./cvParam').map {|node| node['accession'] }
115
128
  base64 = binary_data_array_n.xpath('./binary').text
116
129
  Mspire::Mzml::DataArray.from_binary(base64, accessions)
117
130
  end
131
+
118
132
  # if there is no spectrum, we will still return a spectrum object, it
119
133
  # just has no mzs or intensities
120
134
  data_arrays = [Mspire::Mzml::DataArray.new, Mspire::Mzml::DataArray.new] if data_arrays.size == 0
121
135
  spec.data_arrays = data_arrays
122
- spec.retention_time = retention_time
123
136
  spec
124
137
  end
125
138
 
@@ -131,7 +144,7 @@ module Mspire
131
144
  #
132
145
  def initialize(id, opts={params: []}, &block)
133
146
  @id = id
134
- describe! *opts[:params]
147
+ describe_many! opts[:params]
135
148
  block.call(self) if block
136
149
  end
137
150
 
@@ -1,6 +1,6 @@
1
1
  require 'mspire/spectrum_like'
2
2
  require 'bsearch'
3
- require 'bin'
3
+ require 'mspire/bin'
4
4
  require 'mspire/peak'
5
5
 
6
6
  module Mspire
@@ -1,19 +1,15 @@
1
1
 
2
2
  module Mspire
3
3
 
4
- class UserParam
5
-
6
- # (optional) a CV::Param object
7
- attr_accessor :unit
8
-
9
- # (required)
10
- attr_accessor :name
4
+ UserParam = Struct.new(:name, :value, :type, :unit)
11
5
 
12
- # (optional)
13
- attr_accessor :value
6
+ class UserParam
14
7
 
15
- # (optional) e.g. 'xsd:float'
16
- attr_accessor :type
8
+ # returns nil
9
+ def accession
10
+ # that way all params can be queried by accession and not raise error
11
+ nil
12
+ end
17
13
 
18
14
  # takes a few different incantations:
19
15
  #
@@ -21,23 +17,13 @@ module Mspire
21
17
  # name, value, unit_acc# or CV::Param object
22
18
  # name, value, type, unit_acc# or CV::Param object
23
19
  def initialize(*args)
24
- @unit =
20
+ self.unit =
25
21
  if args.size > 1 && ((args.last.is_a?(::CV::Param) || args.last =~ /^[A-Za-z]+:\d+$/))
26
22
  unit_arg = args.pop
27
23
  unit_arg.is_a?(::CV::Param) ? unit_arg : Mspire::CV::Param[unit_arg]
28
24
  end
29
- @name, @value, @type = args
25
+ self.name, self.value, self.type = args
30
26
  end
31
27
 
32
28
  end
33
29
  end
34
-
35
- # A UserParam
36
- # (has no accession)
37
- # (has no cvRef)
38
- # name (required)
39
- # type
40
- # unitAccession
41
- # unitCvRef
42
- # unitName
43
- # value
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "mspire"
8
- s.version = "0.7.5"
8
+ s.version = "0.7.6"
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-23"
12
+ s.date = "2012-03-27"
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 = [
@@ -21,7 +21,6 @@ Gem::Specification.new do |s|
21
21
  "README.rdoc",
22
22
  "Rakefile",
23
23
  "VERSION",
24
- "lib/bin.rb",
25
24
  "lib/core_ext/array/in_groups.rb",
26
25
  "lib/cv.rb",
27
26
  "lib/cv/param.rb",
@@ -29,6 +28,7 @@ Gem::Specification.new do |s|
29
28
  "lib/io/bookmark.rb",
30
29
  "lib/merge.rb",
31
30
  "lib/mspire.rb",
31
+ "lib/mspire/bin.rb",
32
32
  "lib/mspire/cv.rb",
33
33
  "lib/mspire/cv/param.rb",
34
34
  "lib/mspire/cv/paramable.rb",
@@ -90,6 +90,7 @@ Gem::Specification.new do |s|
90
90
  "lib/mspire/mzml/scan.rb",
91
91
  "lib/mspire/mzml/scan_list.rb",
92
92
  "lib/mspire/mzml/scan_settings.rb",
93
+ "lib/mspire/mzml/scan_window.rb",
93
94
  "lib/mspire/mzml/selected_ion.rb",
94
95
  "lib/mspire/mzml/software.rb",
95
96
  "lib/mspire/mzml/source_file.rb",
@@ -116,7 +117,8 @@ Gem::Specification.new do |s|
116
117
  "obo/ms.obo",
117
118
  "obo/unit.obo",
118
119
  "script/mzml_read_binary.rb",
119
- "spec/bin_spec.rb",
120
+ "spec/cv/param_spec.rb",
121
+ "spec/mspire/bin_spec.rb",
120
122
  "spec/mspire/cv/param_spec.rb",
121
123
  "spec/mspire/digester_spec.rb",
122
124
  "spec/mspire/error_rate/qvalue_spec.rb",
@@ -138,6 +140,8 @@ Gem::Specification.new do |s|
138
140
  "spec/mspire/mzml/index_list_spec.rb",
139
141
  "spec/mspire/mzml/plms1_spec.rb",
140
142
  "spec/mspire/mzml/referenceable_param_group_spec.rb",
143
+ "spec/mspire/mzml/source_file_spec.rb",
144
+ "spec/mspire/mzml/spectrum_spec.rb",
141
145
  "spec/mspire/mzml_spec.rb",
142
146
  "spec/mspire/peak_spec.rb",
143
147
  "spec/mspire/plms1_spec.rb",
@@ -0,0 +1,21 @@
1
+
2
+ require 'spec_helper'
3
+
4
+ require 'cv/param'
5
+
6
+ describe ::CV::Param do
7
+ describe 'object creation from class methods' do
8
+
9
+ it '::new allows full description' do
10
+ param1 = ::CV::Param.new('MS', 'MS:1000052', 'suspension')
11
+ param1.value.should be_nil
12
+ # just nonsense: 32 ng suspensions
13
+ param2 = ::CV::Param.new('MS', 'MS:1000052', 'suspension', 32, ::CV::Param.new('UO', 'UO:0000024', 'nanogram'))
14
+ param2.cv_ref.should == 'MS'
15
+ param2.value.should == 32
16
+ param2.unit.accession.should == 'UO:0000024'
17
+ end
18
+ end
19
+ end
20
+
21
+
@@ -1,8 +1,8 @@
1
1
  require 'spec_helper'
2
2
 
3
- require 'bin'
3
+ require 'mspire/bin'
4
4
 
5
- describe Bin do
5
+ describe Mspire::Bin do
6
6
 
7
7
  describe 'putting data into bins' do
8
8
 
@@ -18,7 +18,7 @@ describe Bin do
18
18
  end
19
19
 
20
20
  def self.make_ranges(range, use_bin=false)
21
- klass = use_bin ? Bin : Range
21
+ klass = use_bin ? Mspire::Bin : Range
22
22
  range.map {|i| klass.new(i.to_f, (i+1).to_f, true) }
23
23
  end
24
24
 
@@ -27,7 +27,7 @@ describe Bin do
27
27
  end
28
28
 
29
29
  def ranges_to_bins(ranges)
30
- ranges.map {|range| Bin.new(range.begin, range.end, true) }
30
+ ranges.map {|range| Mspire::Bin.new(range.begin, range.end, true) }
31
31
  end
32
32
 
33
33
  data = {
@@ -62,7 +62,7 @@ describe Bin do
62
62
 
63
63
  data.each do |type, init|
64
64
  it "works for bins to data #{type.to_s.gsub('_',' ')}" do
65
- rbins = Bin.bin(ranges_to_bins(init[:ranges]), init[:peaks], &:first)
65
+ rbins = Mspire::Bin.bin(ranges_to_bins(init[:ranges]), init[:peaks], &:first)
66
66
  matching(rbins, init[:peaks], init[:bin_to_peak_index_pairs])
67
67
  end
68
68
  end
@@ -70,7 +70,7 @@ describe Bin do
70
70
  data.each do |type, init|
71
71
  it "works for ranges to data #{type.to_s.gsub('_',' ')}" do
72
72
  custom_data_store = (0...init[:ranges].size).map { [] }
73
- rbins = Bin.bin(init[:ranges], init[:peaks], custom_data_store, &:first)
73
+ rbins = Mspire::Bin.bin(init[:ranges], init[:peaks], custom_data_store, &:first)
74
74
  matching(rbins, init[:peaks], init[:bin_to_peak_index_pairs])
75
75
  end
76
76
  end
@@ -4,19 +4,9 @@ require 'mspire/cv/param'
4
4
  require 'cv/param'
5
5
 
6
6
  describe Mspire::CV::Param do
7
- describe 'object creation from class methods' do
7
+ describe 'object creation from class method' do
8
8
 
9
- it '::new allows full description' do
10
- param1 = Mspire::CV::Param.new('MS', 'MS:1000052', 'suspension')
11
- param1.value.should be_nil
12
- # just nonsense: 32 ng suspensions
13
- param2 = Mspire::CV::Param.new('MS', 'MS:1000052', 'suspension', 32, ::CV::Param.new('UO', 'UO:0000024', 'nanogram'))
14
- param2.cv_ref.should == 'MS'
15
- param2.value.should == 32
16
- param2.unit.accession.should == 'UO:0000024'
17
- end
18
-
19
- it '::[] requires shortcut accession strings' do
9
+ it '::[] expects shortcut accession strings' do
20
10
  param1 = Mspire::CV::Param['MS:1000052']
21
11
  param1.cv_ref.should == 'MS'
22
12
  param1.value.should be_nil
@@ -10,7 +10,7 @@ describe Mspire::Mzml::FileContent do
10
10
 
11
11
  desc = filecontent.params
12
12
  desc.size.should == 2
13
- desc.all? {|par| par.class == Mspire::CV::Param }.should be_true
13
+ desc.all? {|par| par.class == ::CV::Param }.should be_true
14
14
  b = Builder::XmlMarkup.new
15
15
  filecontent.to_xml(b)
16
16
  xml = b.to_xml
@@ -19,6 +19,7 @@ describe Mspire::Mzml::FileContent do
19
19
  end
20
20
  end
21
21
 
22
+ it 'can be created from xml'
22
23
 
23
24
  end
24
25
 
@@ -3,32 +3,10 @@ require 'mspire/mzml/file_description'
3
3
  require 'builder'
4
4
 
5
5
  describe 'creating mzml xml' do
6
- describe 'making fileContent' do
7
-
8
- end
9
-
10
- describe 'making a SourceFile' do
11
- it 'can be generated with params and a block' do
12
- source_file = Mspire::Mzml::SourceFile.new("someFileID", "filename.mzML", "/home/jtprince/tmp", params: ['MS:1000584'])
13
-
14
- params = source_file.params
15
- params.size.should == 1
16
- params.all? {|par| par.class == Mspire::CV::Param }.should be_true
17
- b = Builder::XmlMarkup.new(:indent => 2)
18
- source_file.to_xml(b)
19
- xml = b.to_xml
20
- [/<sourceFile/, /id="some/, /name="filen/, /location="\/home/, /cvRef="MS"/].each do |regexp|
21
- xml.should match(regexp)
22
- end
23
- end
24
-
25
- end
26
-
27
6
  describe Mspire::Mzml::FileDescription do
28
7
 
29
- it 'creates valid xml' do
30
- #MS::Mzml::FileDescription
8
+ it 'creates valid xml'
31
9
 
32
- end
10
+ it 'can be set from xml'
33
11
  end
34
12
  end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ require 'mspire/mzml/source_file'
4
+ require 'builder'
5
+
6
+ describe 'making a SourceFile' do
7
+ it 'can be generated with params and a block' do
8
+ source_file = Mspire::Mzml::SourceFile.new("someFileID", "filename.mzML", "/home/jtprince/tmp", params: ['MS:1000584'])
9
+
10
+ params = source_file.params
11
+ params.size.should == 1
12
+ params.all? {|par| par.class == ::CV::Param }.should be_true
13
+ b = Builder::XmlMarkup.new(:indent => 2)
14
+ source_file.to_xml(b)
15
+ xml = b.to_xml
16
+ [/<sourceFile/, /id="some/, /name="filen/, /location="\/home/, /cvRef="MS"/].each do |regexp|
17
+ xml.should match(regexp)
18
+ end
19
+ end
20
+
21
+ it 'can be created from xml'
22
+ end
23
+
24
+
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ require 'mspire/mzml'
4
+ require 'mspire/mzml/spectrum'
5
+
6
+ describe Mspire::Mzml::Spectrum do
7
+
8
+ describe 'creating an ms1 spectrum from xml' do
9
+ before(:all) do
10
+ @io = File.open(TESTFILES + "/mspire/mzml/j24z.idx_comp.3.mzML")
11
+ @mzml = Mspire::Mzml.new(@io)
12
+ end
13
+
14
+ after(:all) do
15
+ @io.close
16
+ end
17
+
18
+ it 'gathers key data for ms1 spectrum' do
19
+ xml_node = @mzml.spectrum_node(0)
20
+ spec = Mspire::Mzml::Spectrum.from_xml(xml_node)
21
+
22
+ # convenient access to common attributes
23
+ spec.retention_time.should == 1981.5726
24
+ spec.ms_level.should == 1
25
+
26
+ spec.precursor_mz.should be_nil
27
+ spec.precursor_charge.should be_nil
28
+
29
+ # array info
30
+ spec.mzs.size.should == 20168
31
+ spec.intensities.size.should == 20168
32
+
33
+ params = spec.params
34
+ params.size.should == 9
35
+ params.first.should be_a(::CV::Param)
36
+ end
37
+
38
+ it 'gathers key data for ms2 spectrum' do
39
+ xml_node = @mzml.spectrum_node(1)
40
+ spec = Mspire::Mzml::Spectrum.from_xml(xml_node)
41
+
42
+ # convenient access to common attributes
43
+ spec.retention_time.should == 1982.1077
44
+ spec.ms_level.should == 2
45
+
46
+ spec.precursor_mz.should == 479.7644958496094
47
+ spec.precursor_charge.should == 2
48
+
49
+ # array info
50
+ spec.mzs.size.should == 315
51
+ spec.intensities.size.should == 315
52
+
53
+ params = spec.params
54
+ params.size.should == 9
55
+ params.first.should be_a(::CV::Param)
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+
@@ -38,12 +38,6 @@ describe Mspire::Mzml do
38
38
  spectrum.should be_a(Mspire::Mzml::Spectrum)
39
39
  end
40
40
 
41
- it 'each spectrum knows its retention_time' do
42
- spec = @mzml[1]
43
- rt = @mzml[1].retention_time
44
- rt.should == 1982.1077
45
- end
46
-
47
41
  it 'goes through spectrum with #each or #each_spectrum' do
48
42
  mz_sizes = [20168, 315, 634]
49
43
  centroided = [false, true, true]
@@ -67,6 +61,14 @@ describe Mspire::Mzml do
67
61
  lambda {iter.next}.should raise_error
68
62
  end
69
63
 
64
+ # not quite ready for this one yet
65
+ xit 'contains scans linked to their instrument config objects' do
66
+ instr_config_first = @mzml.file_description.instrument_configurations[0]
67
+ instr_config_last = @mzml.file_description.instrument_configurations[1]
68
+ @mzml[0].scan_list.first.instrument_configuration.should == instr_config_first
69
+ @mzml[1].scan_list.first.instrument_configuration.should == instr_config_last
70
+ end
71
+
70
72
  it 'can gracefully determine the m/z with highest peak in select scans' do
71
73
  highest_mzs = Mspire::Mzml.foreach(@file).select {|v| v.ms_level > 1 }.map do |spec|
72
74
  spec.points.sort_by(&:last).first.first
@@ -89,7 +91,7 @@ describe Mspire::Mzml do
89
91
  spec.scan_list = Mspire::Mzml::ScanList.new do |sl|
90
92
  scan = Mspire::Mzml::Scan.new do |scan|
91
93
  # retention time of 42 seconds
92
- scan.describe! ['MS:1000016', 40.0, 'UO:0000010']
94
+ scan.describe! 'MS:1000016', 40.0, 'UO:0000010'
93
95
  end
94
96
  sl << scan
95
97
  end
@@ -103,18 +105,18 @@ describe Mspire::Mzml do
103
105
  spec.scan_list = Mspire::Mzml::ScanList.new do |sl|
104
106
  scan = Mspire::Mzml::Scan.new do |scan|
105
107
  # retention time of 42 seconds
106
- scan.describe! ['MS:1000016', 45.0, 'UO:0000010']
108
+ scan.describe! 'MS:1000016', 45.0, 'UO:0000010'
107
109
  end
108
110
  sl << scan
109
111
  end
110
112
  precursor = Mspire::Mzml::Precursor.new( spec1 )
111
113
  si = Mspire::Mzml::SelectedIon.new
112
114
  # the selected ion m/z:
113
- si.describe! ["MS:1000744", 2.0]
115
+ si.describe! "MS:1000744", 2.0
114
116
  # the selected ion charge state
115
- si.describe! ["MS:1000041", 2]
117
+ si.describe! "MS:1000041", 2
116
118
  # the selected ion intensity
117
- si.describe! ["MS:1000042", 5]
119
+ si.describe! "MS:1000042", 5
118
120
  precursor.selected_ions = [si]
119
121
  spec.precursors = [precursor]
120
122
  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.5
4
+ version: 0.7.6
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-23 00:00:00.000000000 Z
13
+ date: 2012-03-27 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: nokogiri
@@ -185,7 +185,6 @@ files:
185
185
  - README.rdoc
186
186
  - Rakefile
187
187
  - VERSION
188
- - lib/bin.rb
189
188
  - lib/core_ext/array/in_groups.rb
190
189
  - lib/cv.rb
191
190
  - lib/cv/param.rb
@@ -193,6 +192,7 @@ files:
193
192
  - lib/io/bookmark.rb
194
193
  - lib/merge.rb
195
194
  - lib/mspire.rb
195
+ - lib/mspire/bin.rb
196
196
  - lib/mspire/cv.rb
197
197
  - lib/mspire/cv/param.rb
198
198
  - lib/mspire/cv/paramable.rb
@@ -254,6 +254,7 @@ files:
254
254
  - lib/mspire/mzml/scan.rb
255
255
  - lib/mspire/mzml/scan_list.rb
256
256
  - lib/mspire/mzml/scan_settings.rb
257
+ - lib/mspire/mzml/scan_window.rb
257
258
  - lib/mspire/mzml/selected_ion.rb
258
259
  - lib/mspire/mzml/software.rb
259
260
  - lib/mspire/mzml/source_file.rb
@@ -280,7 +281,8 @@ files:
280
281
  - obo/ms.obo
281
282
  - obo/unit.obo
282
283
  - script/mzml_read_binary.rb
283
- - spec/bin_spec.rb
284
+ - spec/cv/param_spec.rb
285
+ - spec/mspire/bin_spec.rb
284
286
  - spec/mspire/cv/param_spec.rb
285
287
  - spec/mspire/digester_spec.rb
286
288
  - spec/mspire/error_rate/qvalue_spec.rb
@@ -302,6 +304,8 @@ files:
302
304
  - spec/mspire/mzml/index_list_spec.rb
303
305
  - spec/mspire/mzml/plms1_spec.rb
304
306
  - spec/mspire/mzml/referenceable_param_group_spec.rb
307
+ - spec/mspire/mzml/source_file_spec.rb
308
+ - spec/mspire/mzml/spectrum_spec.rb
305
309
  - spec/mspire/mzml_spec.rb
306
310
  - spec/mspire/peak_spec.rb
307
311
  - spec/mspire/plms1_spec.rb
data/lib/bin.rb DELETED
@@ -1,65 +0,0 @@
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