mspire 0.7.18 → 0.8.0
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/bin/mspire +5 -0
- data/lib/core_ext/enumerable.rb +8 -0
- data/lib/mspire/commandline.rb +39 -0
- data/lib/mspire/cv/paramable.rb +72 -35
- data/lib/mspire/imzml/writer/commandline.rb +16 -7
- data/lib/mspire/imzml/writer.rb +22 -14
- data/lib/mspire/mzml/activation.rb +0 -5
- data/lib/mspire/mzml/chromatogram.rb +41 -6
- data/lib/mspire/mzml/chromatogram_list.rb +2 -19
- data/lib/mspire/mzml/component.rb +28 -4
- data/lib/mspire/mzml/cv.rb +1 -0
- data/lib/mspire/mzml/data_array.rb +164 -154
- data/lib/mspire/mzml/data_array_container_like.rb +6 -13
- data/lib/mspire/mzml/data_processing.rb +19 -5
- data/lib/mspire/mzml/file_description.rb +22 -4
- data/lib/mspire/mzml/index.rb +53 -0
- data/lib/mspire/mzml/index_list.rb +64 -55
- data/lib/mspire/mzml/instrument_configuration.rb +22 -7
- data/lib/mspire/mzml/io_index.rb +79 -0
- data/lib/mspire/mzml/io_indexable_list.rb +71 -0
- data/lib/mspire/mzml/isolation_window.rb +0 -5
- data/lib/mspire/mzml/parser.rb +10 -0
- data/lib/mspire/mzml/plms1.rb +14 -24
- data/lib/mspire/mzml/precursor.rb +41 -19
- data/lib/mspire/mzml/processing_method.rb +34 -7
- data/lib/mspire/mzml/product.rb +14 -1
- data/lib/mspire/mzml/reader.rb +154 -0
- data/lib/mspire/mzml/referenceable_param_group.rb +9 -2
- data/lib/mspire/mzml/run.rb +62 -5
- data/lib/mspire/mzml/sample.rb +16 -6
- data/lib/mspire/mzml/scan.rb +31 -16
- data/lib/mspire/mzml/scan_list.rb +18 -5
- data/lib/mspire/mzml/scan_settings.rb +4 -5
- data/lib/mspire/mzml/scan_window.rb +0 -6
- data/lib/mspire/mzml/selected_ion.rb +1 -8
- data/lib/mspire/mzml/software.rb +9 -4
- data/lib/mspire/mzml/source_file.rb +8 -4
- data/lib/mspire/mzml/spectrum.rb +60 -35
- data/lib/mspire/mzml/spectrum_list.rb +5 -34
- data/lib/mspire/mzml.rb +72 -210
- data/lib/mspire/plms1.rb +3 -0
- data/spec/mspire/cv/paramable_spec.rb +3 -3
- data/spec/mspire/mzml/data_array_spec.rb +19 -6
- data/spec/mspire/mzml/file_content_spec.rb +1 -4
- data/spec/mspire/mzml/index_list_spec.rb +5 -12
- data/spec/mspire/mzml/plms1_spec.rb +5 -9
- data/spec/mspire/mzml/referenceable_param_group_spec.rb +3 -3
- data/spec/mspire/mzml/source_file_spec.rb +1 -2
- data/spec/mspire/mzml/spectrum_list_spec.rb +54 -0
- data/spec/mspire/mzml/spectrum_spec.rb +2 -4
- data/spec/mspire/mzml_spec.rb +241 -21
- data/spec/spec_helper.rb +1 -0
- data/spec/testfiles/mspire/mzml/1_BB7_SIM_478.5.mzML +103 -0
- data/spec/testfiles/mspire/mzml/j24z.idx_comp.3.mzML +6 -6
- metadata +14 -6
- data/bin/mzml_to_imzml +0 -9
- data/spec/mspire/mzml/file_description_spec.rb +0 -12
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.8.0
|
data/bin/mspire
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'trollop'
|
2
|
+
require 'mspire/imzml/writer/commandline'
|
3
|
+
|
4
|
+
module Mspire
|
5
|
+
module Commandline
|
6
|
+
SUB_COMMANDS = {
|
7
|
+
to_imzml: 'convert mzml to imzml',
|
8
|
+
}
|
9
|
+
|
10
|
+
def self.run(argv)
|
11
|
+
|
12
|
+
parser = Trollop::Parser.new do
|
13
|
+
banner "usage: mspire <subcommand> [OPTIONS]"
|
14
|
+
text ""
|
15
|
+
text "subcommands: "
|
16
|
+
SUB_COMMANDS.each do |k,v|
|
17
|
+
text " #{k} #{v}"
|
18
|
+
end
|
19
|
+
text ""
|
20
|
+
stop_on SUB_COMMANDS.keys.map(&:to_s)
|
21
|
+
end
|
22
|
+
|
23
|
+
begin
|
24
|
+
global_opts = parser.parse(argv)
|
25
|
+
rescue Trollop::HelpNeeded
|
26
|
+
parser.educate && exit
|
27
|
+
end
|
28
|
+
|
29
|
+
parser.educate && exit unless argv.size > 0
|
30
|
+
|
31
|
+
cmd = argv.shift
|
32
|
+
cmd_parser =
|
33
|
+
case cmd.to_sym
|
34
|
+
when :to_imzml
|
35
|
+
Mspire::Imzml::Writer::Commandline.run(argv, global_opts)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/mspire/cv/paramable.rb
CHANGED
@@ -16,6 +16,14 @@ module Mspire
|
|
16
16
|
cv_params + ref_param_groups.flat_map(&:params) + user_params
|
17
17
|
end
|
18
18
|
|
19
|
+
def each_param(&block)
|
20
|
+
return enum_for __method__ unless block
|
21
|
+
cv_params.each(&block)
|
22
|
+
ref_param_groups.flat_map(&:params).each(&block)
|
23
|
+
user_params.each(&block)
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
|
19
27
|
def params?
|
20
28
|
total_num_params = cv_params.size +
|
21
29
|
ref_param_groups.reduce(0) {|sum,group| sum +
|
@@ -23,6 +31,13 @@ module Mspire
|
|
23
31
|
total_num_params > 0
|
24
32
|
end
|
25
33
|
|
34
|
+
def each_accessionable_param(&block)
|
35
|
+
return enum_for __method__ unless block
|
36
|
+
cv_params.each(&block)
|
37
|
+
ref_param_groups.flat_map(&:params).each(&block)
|
38
|
+
nil
|
39
|
+
end
|
40
|
+
|
26
41
|
def accessionable_params
|
27
42
|
cv_params + ref_param_groups.flat_map(&:params)
|
28
43
|
end
|
@@ -38,7 +53,7 @@ module Mspire
|
|
38
53
|
# returns the value if the param exists by that name. Returns true if
|
39
54
|
# the param exists but has no value. returns false if no param
|
40
55
|
def fetch(name)
|
41
|
-
param =
|
56
|
+
param = each_param.find {|param| param.name == name}
|
42
57
|
if param
|
43
58
|
param.value || true
|
44
59
|
else
|
@@ -60,19 +75,20 @@ module Mspire
|
|
60
75
|
params.any? {|param| param.name == name }
|
61
76
|
end
|
62
77
|
|
63
|
-
def initialize
|
78
|
+
def initialize
|
64
79
|
@cv_params = []
|
65
80
|
@user_params = []
|
66
81
|
@ref_param_groups = []
|
67
|
-
describe_many!(opts[:params])
|
68
82
|
end
|
83
|
+
alias_method :params_init, :initialize
|
69
84
|
|
70
85
|
def param_by_accession(acc)
|
71
|
-
|
86
|
+
each_accessionable_param.find {|v| v.accession == acc }
|
72
87
|
end
|
73
88
|
alias_method :param_by_acc, :param_by_accession
|
74
89
|
|
75
90
|
# takes an array of values, each of which is fed into describe!
|
91
|
+
# returns self.
|
76
92
|
def describe_many!(array)
|
77
93
|
array.each do |arg|
|
78
94
|
if arg.is_a?(Array)
|
@@ -81,10 +97,51 @@ module Mspire
|
|
81
97
|
describe!(arg)
|
82
98
|
end
|
83
99
|
end
|
100
|
+
self
|
101
|
+
end
|
102
|
+
|
103
|
+
# reads the paramable nodes and returns self. Use this if your element
|
104
|
+
# does not have anything besides paramable elements.
|
105
|
+
def describe_self_from_xml!(xml_node, ref_hash=nil)
|
106
|
+
describe_from_xml!(xml_node, ref_hash)
|
107
|
+
self
|
108
|
+
end
|
109
|
+
|
110
|
+
# takes a node with children that are cvParam, userParam or
|
111
|
+
# referenceableParamGroupRef and a hash containing
|
112
|
+
# referenceableParamGroup objects indexed by id. The only time ref_hash
|
113
|
+
# should be left nil is for the referenceableParamGroup itself.
|
114
|
+
#
|
115
|
+
# All param elements are required to appear before other elements, so
|
116
|
+
# the code walks through each child node to see if it is a paramable
|
117
|
+
# element. The first child node that is not paramable is returned (or
|
118
|
+
# nil if none)
|
119
|
+
#
|
120
|
+
# returns the next child node after the paramable elements or nil if none
|
121
|
+
def describe_from_xml!(xml_node, ref_hash=nil)
|
122
|
+
return nil unless (child_n = xml_node.child)
|
123
|
+
loop do
|
124
|
+
array =
|
125
|
+
case child_n.name
|
126
|
+
when 'referenceableParamGroupRef'
|
127
|
+
@ref_param_groups << ref_hash[child_n[:ref]]
|
128
|
+
when 'cvParam'
|
129
|
+
@cv_params << Mspire::CV::Param[ child_n[:accession], child_n[:value] ]
|
130
|
+
when 'userParam'
|
131
|
+
@user_params << Mspire::UserParam.new(child_n[:name], child_n[:value], child_n[:type])
|
132
|
+
else # assumes that the above precede any following children as per the spec
|
133
|
+
break
|
134
|
+
end
|
135
|
+
if (unit_acc = child_n[:unitAccession])
|
136
|
+
array.last.unit = ::CV::Param.new(child_n[:unitCvRef], unit_acc, child_n[:unitName])
|
137
|
+
end
|
138
|
+
break unless child_n = child_n.next
|
139
|
+
end
|
140
|
+
child_n
|
84
141
|
end
|
85
142
|
|
86
|
-
# Expects arguments describing a single CV::Param
|
87
|
-
#
|
143
|
+
# Expects arguments describing a single CV::Param, Mspire::UserParam, or
|
144
|
+
# Mspire::Mzml::ReferenceableParamGroup
|
88
145
|
#
|
89
146
|
# obj.describe! 'MS:1000130' # a positive scan
|
90
147
|
# obj.describe! CV::Param['MS:1000130'] # same behavior
|
@@ -92,12 +149,6 @@ module Mspire
|
|
92
149
|
# # base peak intensity, units=number of counts
|
93
150
|
# obj.describe! "MS:1000505", 1524.5865478515625, 'MS:1000131'
|
94
151
|
#
|
95
|
-
# # given an XML::NodeSet
|
96
|
-
# obj.describe! xml_node.xpath('.//cvParam')
|
97
|
-
#
|
98
|
-
# # given an XML
|
99
|
-
# obj.describe! xml_node.xpath('.//cvParam').first
|
100
|
-
#
|
101
152
|
# returns self
|
102
153
|
def describe!(*args)
|
103
154
|
return self if args.first.nil?
|
@@ -106,40 +157,26 @@ module Mspire
|
|
106
157
|
@cv_params << Mspire::CV::Param[ *args ]
|
107
158
|
when Mspire::Mzml::ReferenceableParamGroup
|
108
159
|
@ref_param_groups << arg
|
109
|
-
when Nokogiri::XML::Node # a nokogiri node in particular
|
110
|
-
param =
|
111
|
-
case arg.name
|
112
|
-
when 'cvParam'
|
113
|
-
Mspire::CV::Param[ arg[:accession], arg[:value] ]
|
114
|
-
when 'userParam'
|
115
|
-
Mspire::UserParam.new(arg[:name], arg[:value], arg[:type])
|
116
|
-
end
|
117
|
-
if (unit_acc = arg[:unitAccession])
|
118
|
-
param.unit = ::CV::Param.new(arg[:unitCvRef], unit_acc, arg[:unitName])
|
119
|
-
end
|
120
|
-
@cv_params << param
|
121
|
-
when Nokogiri::XML::NodeSet
|
122
|
-
arg.each {|node| describe!(node) }
|
123
160
|
else
|
124
161
|
if arg.is_a?(Mspire::UserParam)
|
125
162
|
@user_params << arg
|
126
163
|
else
|
127
|
-
|
164
|
+
@cv_params << arg
|
128
165
|
end
|
129
166
|
end
|
130
167
|
self
|
131
168
|
end
|
132
169
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
end
|
170
|
+
# iterates over @params and calls .to_xml on each object.
|
171
|
+
def to_xml(xml)
|
172
|
+
[:ref_param_groups, :cv_params, :user_params].each do |kind|
|
173
|
+
self.send(kind).each do |obj|
|
174
|
+
obj.to_xml(xml)
|
139
175
|
end
|
140
|
-
xml
|
141
176
|
end
|
142
|
-
|
177
|
+
xml
|
143
178
|
end
|
179
|
+
|
144
180
|
end
|
145
181
|
end
|
182
|
+
end
|
@@ -13,7 +13,9 @@ end
|
|
13
13
|
|
14
14
|
module Mspire::Imzml::Writer::Commandline
|
15
15
|
|
16
|
-
|
16
|
+
# generates the Trollop parser
|
17
|
+
def self.parser
|
18
|
+
return @parser if @parser
|
17
19
|
|
18
20
|
default_config = "config.yaml"
|
19
21
|
scan_patterns = %w(flyback meandering random)
|
@@ -24,9 +26,9 @@ module Mspire::Imzml::Writer::Commandline
|
|
24
26
|
default_pixel_size = '1x1'
|
25
27
|
matrix_application_types = %w(sprayed precoated printed drieddroplet)
|
26
28
|
|
27
|
-
parser = Trollop::Parser.new do
|
29
|
+
@parser = Trollop::Parser.new do
|
28
30
|
banner <<-EOS
|
29
|
-
usage:
|
31
|
+
usage: mspire to_imzml [OPTIONS] <file>.mzML ..."
|
30
32
|
output: <file>.imzML and <file>.ibd
|
31
33
|
|
32
34
|
* imzML docs:
|
@@ -43,6 +45,9 @@ output: <file>.imzML and <file>.ibd
|
|
43
45
|
opt :combine, "combine all files and set the base name of resulting imzML and ibd files", :type => String
|
44
46
|
opt :outfile, "use a specific basename for the resulting file. Acts like --combine for multiple files", :type => String
|
45
47
|
|
48
|
+
text "\nediting:"
|
49
|
+
opt :trim_files, "determines the least number of spectra in a file and shortens all spectra to be the same length"
|
50
|
+
|
46
51
|
text "\nimaging:"
|
47
52
|
opt :continuous, "assumes m/z values are the same for every scan. The 'processed' storage format is used unless this flag is given."
|
48
53
|
opt :scan_pattern, scan_patterns.join('|'), :default => scan_patterns.first
|
@@ -76,8 +81,15 @@ output: <file>.imzML and <file>.ibd
|
|
76
81
|
# filters (cutoff / max # peaks, etc.)
|
77
82
|
# ms_level, etc.
|
78
83
|
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.run(argv, globalopts)
|
87
|
+
begin
|
88
|
+
opts = parser.parse(argv)
|
89
|
+
rescue Trollop::HelpNeeded
|
90
|
+
return parser.educate
|
91
|
+
end
|
79
92
|
|
80
|
-
opts = parser.parse(argv)
|
81
93
|
opts = Hash[YAML.load_file(opts[:config]).map {|k,v| [k.to_sym, v]}].merge(opts) if opts[:config]
|
82
94
|
|
83
95
|
opts[:combine] ||= opts.delete(:outfile)
|
@@ -104,6 +116,3 @@ output: <file>.imzML and <file>.ibd
|
|
104
116
|
|
105
117
|
end
|
106
118
|
end
|
107
|
-
|
108
|
-
|
109
|
-
|
data/lib/mspire/imzml/writer.rb
CHANGED
@@ -215,13 +215,13 @@ module Mspire::Imzml
|
|
215
215
|
def create_file_description(source_files, config)
|
216
216
|
Mspire::Mzml::FileDescription.new do |fd|
|
217
217
|
|
218
|
-
fd.file_content = Mspire::Mzml::FileContent.new
|
218
|
+
fd.file_content = Mspire::Mzml::FileContent.new.describe_many!( [
|
219
219
|
'MS:1000579', # MS1 Spectrum
|
220
220
|
config[:profile] ? 'MS:1000128' : 'MS:1000127',
|
221
221
|
['IMS:1000080', "{"+config[:uuid_hyphenated]+"}"],
|
222
222
|
['IMS:1000091', config[:ibd_sha1]],
|
223
223
|
(config[:data_structure] == :processed) ? 'IMS:1000031' : 'IMS:1000030',
|
224
|
-
]
|
224
|
+
] )
|
225
225
|
|
226
226
|
fd.source_files.replace(source_files)
|
227
227
|
if [:name, :organization, :address, :email].any? {|key| config[key] }
|
@@ -267,9 +267,9 @@ module Mspire::Imzml
|
|
267
267
|
"MS:1000127", # centroid spectrum
|
268
268
|
"MS:1000130" # <- positive scan
|
269
269
|
]}.map do |id, list|
|
270
|
-
Mspire::Mzml::ReferenceableParamGroup.new
|
270
|
+
Mspire::Mzml::ReferenceableParamGroup.new(id).describe_many!(list)
|
271
271
|
end
|
272
|
-
Hash[ rparms.map {|
|
272
|
+
Hash[ rparms.map {|prm_group_obj| [prm_group_obj.id, prm_group_obj]} ]
|
273
273
|
end
|
274
274
|
|
275
275
|
# mzml_filenames can each be a partial or relative path
|
@@ -286,6 +286,9 @@ module Mspire::Imzml
|
|
286
286
|
# :solvent_flowrate => flowrate of the solvent (ml/min)
|
287
287
|
# :spray_voltage => spray voltage in kV
|
288
288
|
# :target_material => the material the target is made of
|
289
|
+
# editing:
|
290
|
+
# :trim_files => determines min # spectra in file and lops
|
291
|
+
# off the ends of other files.
|
289
292
|
# general:
|
290
293
|
# :omit_zeros => remove zero values
|
291
294
|
# :combine => use this outfile base name to combine files
|
@@ -311,6 +314,10 @@ module Mspire::Imzml
|
|
311
314
|
config[:uuid_hyphenated] = uuid_with_hyphens
|
312
315
|
config[:uuid] = uuid_with_hyphens.gsub('-','')
|
313
316
|
|
317
|
+
if config[:trim_files]
|
318
|
+
config[:trim_to] = mzml_filenames.map {|fn| Mspire::Mzml.open(fn, &:size) }.min
|
319
|
+
end
|
320
|
+
|
314
321
|
sourcefile_id_parallel_to_spectra = []
|
315
322
|
sourcefile_ids = []
|
316
323
|
all_spectra_iter = Enumerator.new do |yielder|
|
@@ -318,7 +325,8 @@ module Mspire::Imzml
|
|
318
325
|
sourcefile_id = "source_file_#{i}"
|
319
326
|
sourcefile_ids << sourcefile_id
|
320
327
|
Mspire::Mzml.open(mzml_filename) do |mzml|
|
321
|
-
mzml.
|
328
|
+
mzml.each_with_index do |spec,i|
|
329
|
+
break if config[:trim_to] && (i >= config[:trim_to])
|
322
330
|
sourcefile_id_parallel_to_spectra << sourcefile_id
|
323
331
|
yielder << spec
|
324
332
|
end
|
@@ -359,12 +367,12 @@ module Mspire::Imzml
|
|
359
367
|
|
360
368
|
imzml.referenceable_param_groups = rparms_by_id.values
|
361
369
|
# skip sample list for now
|
362
|
-
mspire_software = Mspire::Mzml::Software.new(
|
370
|
+
mspire_software = Mspire::Mzml::Software.new("mspire", Mspire::VERSION).describe!("MS:1000799")
|
363
371
|
imzml.software_list << mspire_software
|
364
372
|
|
365
373
|
scan_setting_params = image_hash_to_cvs( config )
|
366
374
|
scan_setting_params.push *experiment_hash_to_cvs( config )
|
367
|
-
imzml.scan_settings_list = [Mspire::Mzml::ScanSettings.new("scansettings1"
|
375
|
+
imzml.scan_settings_list = [Mspire::Mzml::ScanSettings.new("scansettings1").describe_many!(scan_setting_params)]
|
368
376
|
|
369
377
|
warn 'todo: need to borrow instrumentConfiguration from original mzml'
|
370
378
|
|
@@ -376,20 +384,20 @@ module Mspire::Imzml
|
|
376
384
|
# this is a generic 'file format conversion' but its the closest we
|
377
385
|
# have for mzml to imzml (which is really mzml to mzml)
|
378
386
|
data_processing_obj = Mspire::Mzml::DataProcessing.new('mzml_to_imzml')
|
379
|
-
data_processing_obj.processing_methods << Mspire::Mzml::ProcessingMethod.new(
|
387
|
+
data_processing_obj.processing_methods << Mspire::Mzml::ProcessingMethod.new(mspire_software).describe!('MS:1000530')
|
380
388
|
imzml.data_processing_list << data_processing_obj
|
381
389
|
|
382
390
|
warn "not implemented 'omit_zeros' yet"
|
383
391
|
# low intensity data point removal: "MS:1000594"
|
384
392
|
imzml.run = Mspire::Mzml::Run.new("run1", default_instrument_config) do |run|
|
385
|
-
|
393
|
+
spectra = []
|
386
394
|
data_info_pairs.zip(xy_positions_array, sourcefile_id_parallel_to_spectra).each_with_index do |(pair, xy, sourcefile_id),i|
|
387
395
|
# TODO: we should probably copy the id from the orig mzml (e.g.
|
388
396
|
# scan=1)
|
389
|
-
spectrum = Mspire::Mzml::Spectrum.new("spectrum#{i}"
|
397
|
+
spectrum = Mspire::Mzml::Spectrum.new("spectrum#{i}").describe!(rparms_by_id[:spectrum1])
|
390
398
|
spectrum.source_file = sourcefile_id_to_sourcefile[sourcefile_id]
|
391
|
-
scan_list = Mspire::Mzml::ScanList.new(
|
392
|
-
scan = Mspire::Mzml::Scan.new(
|
399
|
+
scan_list = Mspire::Mzml::ScanList.new.describe!('MS:1000795') # no combination
|
400
|
+
scan = Mspire::Mzml::Scan.new.describe_many!([rparms_by_id[:scan1], ["IMS:1000050", xy[0]], ["IMS:1000051", xy[1]]])
|
393
401
|
scan.instrument_configuration = default_instrument_config
|
394
402
|
spectrum.scan_list = (scan_list << scan)
|
395
403
|
|
@@ -402,9 +410,9 @@ module Mspire::Imzml
|
|
402
410
|
data_array
|
403
411
|
end
|
404
412
|
spectrum.data_arrays = data_arrays
|
405
|
-
|
413
|
+
spectra << spectrum
|
406
414
|
end
|
407
|
-
run.spectrum_list =
|
415
|
+
run.spectrum_list = Mspire::Mzml::SpectrumList.new(data_processing_obj, spectra)
|
408
416
|
end # run
|
409
417
|
end # imzml
|
410
418
|
imzml_obj.to_xml(config[:imzml_filename])
|
@@ -4,6 +4,7 @@ module Mspire
|
|
4
4
|
class Mzml
|
5
5
|
class Chromatogram
|
6
6
|
include Mspire::Mzml::DataArrayContainerLike
|
7
|
+
alias_method :params_initialize, :initialize
|
7
8
|
|
8
9
|
# (optional) precursor isolations to the chromatogram currently being
|
9
10
|
# described
|
@@ -12,16 +13,50 @@ module Mspire
|
|
12
13
|
# (optional) Description of product isolation to the chromatogram
|
13
14
|
attr_accessor :product
|
14
15
|
|
15
|
-
def initialize(
|
16
|
-
|
17
|
-
|
16
|
+
def initialize(id)
|
17
|
+
@id = id
|
18
|
+
params_initialize
|
19
|
+
yield(self) if block_given?
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.from_xml(xml, link)
|
23
|
+
obj = self.new(xml[:id])
|
24
|
+
|
25
|
+
obj.data_processing = link[:data_processing_hash][xml[:dataProcessingRef]] || link[:spectrum_default_data_processing]
|
26
|
+
|
27
|
+
xml_n = obj.describe_from_xml!(xml, link[:ref_hash])
|
28
|
+
|
29
|
+
loop do
|
30
|
+
case xml_n.name
|
31
|
+
when 'precursor'
|
32
|
+
obj.precursor = Mspire::Mzml::Precursor.from_xml(xml_n, link)
|
33
|
+
when 'product'
|
34
|
+
obj.product = Mspire::Mzml::Product.from_xml(xml_n, link)
|
35
|
+
when 'binaryDataArrayList'
|
36
|
+
obj.data_arrays = Mspire::Mzml::DataArray.data_arrays_from_xml(xml_n, link)
|
37
|
+
break
|
38
|
+
end
|
39
|
+
break unless xml_n = xml_n.next
|
40
|
+
end
|
41
|
+
obj
|
42
|
+
end
|
43
|
+
|
44
|
+
def times
|
45
|
+
data_arrays[0]
|
46
|
+
end
|
47
|
+
|
48
|
+
def intensities
|
49
|
+
data_arrays[1]
|
18
50
|
end
|
19
51
|
|
20
52
|
# see SpectrumList for generating the entire list
|
21
53
|
def to_xml(builder, opts={})
|
22
|
-
|
23
|
-
|
24
|
-
|
54
|
+
atts = data_array_xml_atts(default_ids)
|
55
|
+
builder.chromatogram(atts) do |chrom_n|
|
56
|
+
super(chrom_n)
|
57
|
+
@precursor.to_xml(chrom_n) if @precursor
|
58
|
+
@product.to_xml(chrom_n) if @product
|
59
|
+
Mspire::Mzml::DataArray.list_xml(@data_arrays, chrom_n) if @data_arrays
|
25
60
|
end
|
26
61
|
end
|
27
62
|
end
|
@@ -1,26 +1,9 @@
|
|
1
1
|
|
2
|
+
require 'mspire/mzml/io_indexable_list'
|
2
3
|
|
3
4
|
module Mspire
|
4
5
|
class Mzml
|
5
|
-
class ChromatogramList <
|
6
|
-
|
7
|
-
# a DataProcessing object
|
8
|
-
attr_reader :default_data_processing
|
9
|
-
|
10
|
-
def initialize(default_data_processing, chromatograms=[])
|
11
|
-
@default_data_processing = default_data_processing
|
12
|
-
super(chromatograms)
|
13
|
-
end
|
14
|
-
|
15
|
-
def to_xml(builder)
|
16
|
-
builder.chromatogramList(count: self.size, defaultDataProcessingRef: @default_data_processing.id) do |chrl_n|
|
17
|
-
self.each do |chromatogram|
|
18
|
-
chromatogram.to_xml(chrl_n)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
builder
|
22
|
-
end
|
23
|
-
|
6
|
+
class ChromatogramList < IOIndexableList
|
24
7
|
end
|
25
8
|
end
|
26
9
|
end
|
@@ -3,19 +3,43 @@ require 'mspire/mzml/list'
|
|
3
3
|
|
4
4
|
module Mspire
|
5
5
|
class Mzml
|
6
|
+
# order is not an intrinsic property of this object, so it
|
6
7
|
module Component
|
7
8
|
include Mspire::CV::Paramable
|
9
|
+
# using custom list_xml, so no extend Mspire::Mzml::List
|
8
10
|
|
9
|
-
|
11
|
+
def initialize
|
12
|
+
params_init
|
13
|
+
yield(self) if block_given?
|
14
|
+
end
|
10
15
|
|
11
|
-
def to_xml(builder)
|
12
|
-
builder.component(order:
|
16
|
+
def to_xml(builder, order)
|
17
|
+
builder.component(order: order) do |c_n|
|
13
18
|
super(c_n)
|
14
19
|
end
|
15
20
|
builder
|
16
21
|
end
|
17
22
|
|
18
|
-
|
23
|
+
def self.list_xml(components, builder)
|
24
|
+
builder.componentList(count: components.size) do |xml_n|
|
25
|
+
components.each_with_index do |component, order|
|
26
|
+
component.to_xml(xml_n, order)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Source
|
33
|
+
include Component
|
19
34
|
end
|
35
|
+
|
36
|
+
class Analyzer
|
37
|
+
include Component
|
38
|
+
end
|
39
|
+
|
40
|
+
class Detector
|
41
|
+
include Component
|
42
|
+
end
|
43
|
+
|
20
44
|
end
|
21
45
|
end
|