mspire 0.7.18 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/VERSION +1 -1
  2. data/bin/mspire +5 -0
  3. data/lib/core_ext/enumerable.rb +8 -0
  4. data/lib/mspire/commandline.rb +39 -0
  5. data/lib/mspire/cv/paramable.rb +72 -35
  6. data/lib/mspire/imzml/writer/commandline.rb +16 -7
  7. data/lib/mspire/imzml/writer.rb +22 -14
  8. data/lib/mspire/mzml/activation.rb +0 -5
  9. data/lib/mspire/mzml/chromatogram.rb +41 -6
  10. data/lib/mspire/mzml/chromatogram_list.rb +2 -19
  11. data/lib/mspire/mzml/component.rb +28 -4
  12. data/lib/mspire/mzml/cv.rb +1 -0
  13. data/lib/mspire/mzml/data_array.rb +164 -154
  14. data/lib/mspire/mzml/data_array_container_like.rb +6 -13
  15. data/lib/mspire/mzml/data_processing.rb +19 -5
  16. data/lib/mspire/mzml/file_description.rb +22 -4
  17. data/lib/mspire/mzml/index.rb +53 -0
  18. data/lib/mspire/mzml/index_list.rb +64 -55
  19. data/lib/mspire/mzml/instrument_configuration.rb +22 -7
  20. data/lib/mspire/mzml/io_index.rb +79 -0
  21. data/lib/mspire/mzml/io_indexable_list.rb +71 -0
  22. data/lib/mspire/mzml/isolation_window.rb +0 -5
  23. data/lib/mspire/mzml/parser.rb +10 -0
  24. data/lib/mspire/mzml/plms1.rb +14 -24
  25. data/lib/mspire/mzml/precursor.rb +41 -19
  26. data/lib/mspire/mzml/processing_method.rb +34 -7
  27. data/lib/mspire/mzml/product.rb +14 -1
  28. data/lib/mspire/mzml/reader.rb +154 -0
  29. data/lib/mspire/mzml/referenceable_param_group.rb +9 -2
  30. data/lib/mspire/mzml/run.rb +62 -5
  31. data/lib/mspire/mzml/sample.rb +16 -6
  32. data/lib/mspire/mzml/scan.rb +31 -16
  33. data/lib/mspire/mzml/scan_list.rb +18 -5
  34. data/lib/mspire/mzml/scan_settings.rb +4 -5
  35. data/lib/mspire/mzml/scan_window.rb +0 -6
  36. data/lib/mspire/mzml/selected_ion.rb +1 -8
  37. data/lib/mspire/mzml/software.rb +9 -4
  38. data/lib/mspire/mzml/source_file.rb +8 -4
  39. data/lib/mspire/mzml/spectrum.rb +60 -35
  40. data/lib/mspire/mzml/spectrum_list.rb +5 -34
  41. data/lib/mspire/mzml.rb +72 -210
  42. data/lib/mspire/plms1.rb +3 -0
  43. data/spec/mspire/cv/paramable_spec.rb +3 -3
  44. data/spec/mspire/mzml/data_array_spec.rb +19 -6
  45. data/spec/mspire/mzml/file_content_spec.rb +1 -4
  46. data/spec/mspire/mzml/index_list_spec.rb +5 -12
  47. data/spec/mspire/mzml/plms1_spec.rb +5 -9
  48. data/spec/mspire/mzml/referenceable_param_group_spec.rb +3 -3
  49. data/spec/mspire/mzml/source_file_spec.rb +1 -2
  50. data/spec/mspire/mzml/spectrum_list_spec.rb +54 -0
  51. data/spec/mspire/mzml/spectrum_spec.rb +2 -4
  52. data/spec/mspire/mzml_spec.rb +241 -21
  53. data/spec/spec_helper.rb +1 -0
  54. data/spec/testfiles/mspire/mzml/1_BB7_SIM_478.5.mzML +103 -0
  55. data/spec/testfiles/mspire/mzml/j24z.idx_comp.3.mzML +6 -6
  56. metadata +14 -6
  57. data/bin/mzml_to_imzml +0 -9
  58. data/spec/mspire/mzml/file_description_spec.rb +0 -12
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.7.18
1
+ 0.8.0
data/bin/mspire ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'mspire/commandline'
4
+
5
+ Mspire::Commandline.run(ARGV)
@@ -0,0 +1,8 @@
1
+
2
+ module Enumerable
3
+ # File activesupport/lib/active_support/core_ext/enumerable.rb, line 94
4
+ def index_by
5
+ return to_enum :index_by unless block_given?
6
+ Hash[map { |elem| [yield(elem), elem] }]
7
+ end
8
+ end
@@ -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
@@ -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 = params.find {|param| param.name == name}
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(opts={params: []})
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
- accessionable_params.find {|v| v.accession == acc }
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 or Mapire::UserParam.
87
- # Will also accept an Nokogiri::XML::Node or Nokogiri::XML::NodeSet
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
- (@cv_params << arg) if arg
164
+ @cv_params << arg
128
165
  end
129
166
  end
130
167
  self
131
168
  end
132
169
 
133
- # iterates over @params and calls .to_xml on each object.
134
- def to_xml(xml)
135
- [:ref_param_groups, :cv_params, :user_params].each do |kind|
136
- self.send(kind).each do |obj|
137
- obj.to_xml(xml)
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
- def self.run(argv, progname=$0)
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: #{File.basename(progname)} [OPTIONS] <file>.mzML ..."
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
-
@@ -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 :params => [
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 id, params: list
270
+ Mspire::Mzml::ReferenceableParamGroup.new(id).describe_many!(list)
271
271
  end
272
- Hash[ rparms.map {|parm| [parm.id, parm]} ]
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.each do |spec|
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( "mspire", Mspire::VERSION, params: ["MS:1000799"] )
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", params: scan_setting_params)]
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(1, mspire_software, params: ['MS:1000530'] )
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
- spec_list = Mspire::Mzml::SpectrumList.new(data_processing_obj)
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}", params: [rparms_by_id[:spectrum1]])
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(params: ['MS:1000795']) # no combination
392
- scan = Mspire::Mzml::Scan.new( params: [rparms_by_id[:scan1], ["IMS:1000050", xy[0]], ["IMS:1000051", xy[1]]] )
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
- spec_list << spectrum
413
+ spectra << spectrum
406
414
  end
407
- run.spectrum_list = spec_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])
@@ -28,11 +28,6 @@ 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
36
31
  end
37
32
  end
38
33
  end
@@ -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(*args, &block)
16
- super(*args)
17
- block.call(self) if block
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
- super(builder) do |node|
23
- @precursor.to_xml(node) if @precursor
24
- @product.to_xml(node) if @product
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 < Array
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
- attr_accessor :order
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: @order) do |c_n|
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
- extend(Mspire::Mzml::List)
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
@@ -2,6 +2,7 @@
2
2
  module Mspire
3
3
  class Mzml
4
4
  class CV
5
+ # note: CV is NOT paramable!
5
6
 
6
7
  # (required) The short label to be used as a reference tag with which to refer to
7
8
  # this particular Controlled Vocabulary source description (e.g., from