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.
- data/VERSION +1 -1
- data/lib/cv/param.rb +30 -24
- data/lib/mspire/bin.rb +67 -0
- data/lib/mspire/cv/param.rb +4 -2
- data/lib/mspire/cv/paramable.rb +67 -12
- data/lib/mspire/isotope/distribution.rb +0 -1
- data/lib/mspire/mzml.rb +49 -1
- data/lib/mspire/mzml/activation.rb +5 -0
- data/lib/mspire/mzml/cv.rb +5 -0
- data/lib/mspire/mzml/data_array_container_like.rb +1 -1
- data/lib/mspire/mzml/file_description.rb +5 -1
- data/lib/mspire/mzml/instrument_configuration.rb +1 -1
- data/lib/mspire/mzml/isolation_window.rb +5 -0
- data/lib/mspire/mzml/precursor.rb +15 -0
- data/lib/mspire/mzml/processing_method.rb +1 -1
- data/lib/mspire/mzml/referenceable_param_group.rb +1 -1
- data/lib/mspire/mzml/run.rb +1 -1
- data/lib/mspire/mzml/sample.rb +1 -1
- data/lib/mspire/mzml/scan.rb +11 -1
- data/lib/mspire/mzml/scan_list.rb +1 -1
- data/lib/mspire/mzml/scan_settings.rb +1 -1
- data/lib/mspire/mzml/scan_window.rb +19 -0
- data/lib/mspire/mzml/selected_ion.rb +6 -0
- data/lib/mspire/mzml/software.rb +1 -1
- data/lib/mspire/mzml/source_file.rb +1 -1
- data/lib/mspire/mzml/spectrum.rb +49 -36
- data/lib/mspire/spectrum.rb +1 -1
- data/lib/mspire/user_param.rb +9 -23
- data/mspire.gemspec +8 -4
- data/spec/cv/param_spec.rb +21 -0
- data/spec/{bin_spec.rb → mspire/bin_spec.rb} +6 -6
- data/spec/mspire/cv/param_spec.rb +2 -12
- data/spec/mspire/mzml/file_content_spec.rb +2 -1
- data/spec/mspire/mzml/file_description_spec.rb +2 -24
- data/spec/mspire/mzml/source_file_spec.rb +24 -0
- data/spec/mspire/mzml/spectrum_spec.rb +61 -0
- data/spec/mspire/mzml_spec.rb +13 -11
- metadata +8 -4
- data/lib/bin.rb +0 -65
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.7.
|
1
|
+
0.7.6
|
data/lib/cv/param.rb
CHANGED
@@ -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
|
-
|
4
|
+
Param = Struct.new(:cv_ref, :accession, :name, :value, :unit)
|
18
5
|
|
19
|
-
|
20
|
-
attr_accessor :unit
|
6
|
+
class Param
|
21
7
|
|
22
|
-
|
23
|
-
|
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 =>
|
30
|
-
|
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!(
|
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?
|
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
|
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
|
+
|
data/lib/mspire/bin.rb
ADDED
@@ -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
|
data/lib/mspire/cv/param.rb
CHANGED
@@ -5,7 +5,7 @@ module Mspire
|
|
5
5
|
module CV
|
6
6
|
|
7
7
|
# a mass spec related CVParam.
|
8
|
-
|
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
|
-
|
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
|
data/lib/mspire/cv/paramable.rb
CHANGED
@@ -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
|
-
|
13
|
+
describe_many!(opts[:params])
|
11
14
|
end
|
12
15
|
|
13
|
-
#
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
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
|
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
|
data/lib/mspire/mzml.rb
CHANGED
@@ -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
|
-
|
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)
|
data/lib/mspire/mzml/cv.rb
CHANGED
@@ -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")
|
@@ -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)
|
@@ -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
|
data/lib/mspire/mzml/run.rb
CHANGED
@@ -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
|
-
|
33
|
+
describe_many!(opts[:params])
|
34
34
|
block.call(self) if block
|
35
35
|
end
|
36
36
|
|
data/lib/mspire/mzml/sample.rb
CHANGED
data/lib/mspire/mzml/scan.rb
CHANGED
@@ -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
|
-
|
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
|
@@ -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
|
data/lib/mspire/mzml/software.rb
CHANGED
@@ -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
|
-
|
36
|
+
describe_many!(opts[:params])
|
37
37
|
block.call(self) if block
|
38
38
|
end
|
39
39
|
|
data/lib/mspire/mzml/spectrum.rb
CHANGED
@@ -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
|
68
|
-
|
69
|
-
|
70
|
-
|
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
|
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
|
-
|
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
|
-
|
103
|
-
|
104
|
-
|
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
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
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
|
-
|
147
|
+
describe_many! opts[:params]
|
135
148
|
block.call(self) if block
|
136
149
|
end
|
137
150
|
|
data/lib/mspire/spectrum.rb
CHANGED
data/lib/mspire/user_param.rb
CHANGED
@@ -1,19 +1,15 @@
|
|
1
1
|
|
2
2
|
module Mspire
|
3
3
|
|
4
|
-
|
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
|
-
|
13
|
-
attr_accessor :value
|
6
|
+
class UserParam
|
14
7
|
|
15
|
-
#
|
16
|
-
|
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
|
-
|
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
|
-
|
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
|
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.
|
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-
|
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/
|
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
|
7
|
+
describe 'object creation from class method' do
|
8
8
|
|
9
|
-
it '::
|
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 ==
|
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'
|
30
|
-
#MS::Mzml::FileDescription
|
8
|
+
it 'creates valid xml'
|
31
9
|
|
32
|
-
|
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
|
+
|
data/spec/mspire/mzml_spec.rb
CHANGED
@@ -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!
|
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!
|
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!
|
115
|
+
si.describe! "MS:1000744", 2.0
|
114
116
|
# the selected ion charge state
|
115
|
-
si.describe!
|
117
|
+
si.describe! "MS:1000041", 2
|
116
118
|
# the selected ion intensity
|
117
|
-
si.describe!
|
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.
|
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-
|
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/
|
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
|