mspire 0.7.6 → 0.7.7

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.7.6
1
+ 0.7.7
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require 'mspire/imzml/writer/commandline'
5
+
6
+ argv = ARGV.dup
7
+ ARGV.clear
8
+ Mspire::Imzml::Writer::Commandline.run(argv)
9
+
@@ -7,29 +7,48 @@ module Mspire
7
7
  module CV
8
8
  module Paramable
9
9
 
10
- attr_accessor :params
10
+ attr_accessor :cv_params
11
+ attr_accessor :user_params
12
+ attr_accessor :ref_param_groups
13
+
14
+ def params
15
+ cv_params + ref_param_groups.flat_map(&:params) + user_params
16
+ end
17
+
18
+ def accessionable_params
19
+ cv_params + ref_param_groups.flat_map(&:params)
20
+ end
21
+
22
+ def params_by_name
23
+ params.index_by &:name
24
+ end
25
+
26
+ def params_by_accession
27
+ accessionable_params.index_by &:accession
28
+ end
11
29
 
12
30
  def initialize(opts={params: []})
31
+ @cv_params = []
32
+ @user_params = []
33
+ @ref_param_groups = []
13
34
  describe_many!(opts[:params])
14
35
  end
15
36
 
16
37
  # cast may be something like :to_i or :to_f
17
38
  def find_param_value_by_accession(accession, cast=nil)
18
- param = params.find {|v| v.accession == accession }
39
+ param = accessionable_params.find {|v| v.accession == accession }
19
40
  if param
20
41
  val = param.value
21
42
  cast ? (val && val.send(cast)) : val
22
43
  end
23
44
  end
24
45
 
25
- # cast may be something like :to_i or :to_f
26
46
  def find_param_by_accession(accession)
27
- params.find {|v| v.accession == accession }
47
+ accessionable_params.find {|v| v.accession == accession }
28
48
  end
29
49
 
30
-
31
50
  def param_exists_by_accession?(accession)
32
- params.any? {|v| v.accession == accession }
51
+ accessionable_params.any? {|v| v.accession == accession }
33
52
  end
34
53
 
35
54
  # takes an array of values, each of which is fed into describe!
@@ -57,11 +76,15 @@ module Mspire
57
76
  #
58
77
  # # given an XML
59
78
  # obj.describe! xml_node.xpath('.//cvParam').first
79
+ #
80
+ # returns self
60
81
  def describe!(*args)
61
- @params ||= []
82
+ return self if args.first.nil?
62
83
  case (arg=args.first)
63
84
  when String
64
- @params << Mspire::CV::Param[ *args ]
85
+ @cv_params << Mspire::CV::Param[ *args ]
86
+ when Mspire::Mzml::ReferenceableParamGroup
87
+ @ref_param_groups << arg
65
88
  when Nokogiri::XML::Node # a nokogiri node in particular
66
89
  param =
67
90
  case arg.name
@@ -73,25 +96,29 @@ module Mspire
73
96
  if (unit_acc = arg[:unitAccession])
74
97
  param.unit = ::CV::Param.new(arg[:unitCvRef], unit_acc, arg[:unitName])
75
98
  end
76
- @params << param
99
+ @cv_params << param
77
100
  when Nokogiri::XML::NodeSet
78
101
  arg.each {|node| describe!(node) }
79
102
  else
80
- (@params << arg) if arg
103
+ if arg.is_a?(Mspire::UserParam)
104
+ @user_params << arg
105
+ else
106
+ (@cv_params << arg) if arg
107
+ end
81
108
  end
82
- @params
109
+ self
83
110
  end
84
111
 
85
- # iterates over @params and calls .to_xml on each object.
86
- def to_xml(xml)
87
- if @params
88
- @params.each do |el|
89
- el.to_xml(xml)
112
+ # iterates over @params and calls .to_xml on each object.
113
+ def to_xml(xml)
114
+ [:ref_param_groups, :cv_params, :user_params].each do |kind|
115
+ self.send(kind).each do |obj|
116
+ obj.to_xml(xml)
117
+ end
90
118
  end
119
+ xml
91
120
  end
92
- xml
93
- end
94
121
 
122
+ end
95
123
  end
96
124
  end
97
- end
@@ -0,0 +1,404 @@
1
+
2
+ require 'nokogiri'
3
+ require 'uuid'
4
+ require 'cv'
5
+ require 'mspire/mzml'
6
+ require 'mspire/mzml/spectrum'
7
+ require 'pathname'
8
+ require 'digest/sha1'
9
+
10
+ module Mspire end
11
+
12
+ module Mspire::Imzml
13
+ # array length (number of values), the offset (start in file in bytes),
14
+ # and the encoded length (in bytes).
15
+ DataArrayInfo = Struct.new :array_length, :offset, :encoded_length
16
+
17
+ class Writer
18
+
19
+ DEFAULTS = {
20
+ mz_data_type: :float,
21
+ mz_precision: 64,
22
+ intensity_data_type: :float,
23
+ intensity_precision: 32,
24
+ }
25
+
26
+ # Integer values (dtype=:int) may be stored with precision = 8, 16, 32,
27
+ # 64 . Floating point values may be stored as 32 or 64 bit precision.
28
+ # The byte order is always little endian (intel style).
29
+ #
30
+ # NOTE: the documentation is not clear whether they want signed or
31
+ # unsigned integers! Right now this outputs signed integers (my
32
+ # educated guess as to what is required)
33
+ def write_data_array(fh, values, dtype=:float, precision=32)
34
+ pack_code =
35
+ case dtype
36
+ when :float
37
+ precision == 64 ? 'E*' : 'e*'
38
+ when :int
39
+ # using signed!!!! (should these be unsigned??? NOT DOCUMENTED in
40
+ # imzml resources anywhere!)
41
+ case precision
42
+ when 8 ; 'c<*'
43
+ when 16 ; 's<*'
44
+ when 32 ; 'l<*'
45
+ when 64 ; 'q<*'
46
+ else
47
+ raise 'precision must be 8, 16, 32, or 64 for dtype==:int'
48
+ end
49
+ else
50
+ raise 'dtype must be :int or :float!'
51
+ end
52
+ fh.print values.pack(pack_code)
53
+ end
54
+
55
+ # returns an array of DataArrayInfo pairs
56
+ #
57
+ # These must be defined in the config hash with valid values (see
58
+ # write_data_array for what those are):
59
+ #
60
+ # :mz_data_type
61
+ # :mz_precision
62
+ # :intensity_data_type
63
+ # :intensity_precision
64
+ #
65
+ # Also recognizes :data_structure (:processed or :continuous). If
66
+ # :continuous, then the first spectrum is used to write the initial m/z
67
+ # and intensity pair, then in every spectrum after that the m/z data (if
68
+ # any) is ignored and only the intensities are written). The return is
69
+ # the same, the data info for each intensity is coupled with the m/z
70
+ # info from the first m/z data.
71
+ def write_binary(filename, spectra_iterator, config)
72
+ config = DEFAULTS.merge(config)
73
+ raise ":data_structure must be :continuous or :processed" unless [:processed, :continuous].include?(config[:data_structure])
74
+ (mz_dtype, mz_prec, int_dtype, int_prec) = config.values_at(:mz_data_type, :mz_precision, :intensity_data_type, :intensity_precision)
75
+ mz_prec_in_bytes = mz_prec / 8
76
+ int_prec_in_bytes = int_prec / 8
77
+ File.open(filename, 'wb') do |out|
78
+ out.print [config[:uuid]].pack("H*")
79
+
80
+ if config[:data_structure] == :continuous
81
+ # write the first m/z and get its info
82
+ mzs = spectra_iterator.peek.mzs
83
+ mz_info = Mspire::Imzml::DataArrayInfo.new mzs.size, out.pos, mzs.size * mz_prec_in_bytes
84
+ write_data_array(out, mzs, mz_dtype, mz_prec)
85
+ end
86
+ spectra_iterator.map do |spec|
87
+
88
+ if config[:data_structure] == :processed
89
+ mzs = spec.mzs
90
+ mz_info = Mspire::Imzml::DataArrayInfo.new mzs.size, out.pos, mzs.size * mz_prec_in_bytes
91
+ write_data_array(out, spec.mzs, mz_dtype, mz_prec)
92
+ end
93
+
94
+ ints = spec.intensities
95
+ int_info = Mspire::Imzml::DataArrayInfo.new ints.size, out.pos, ints.size * int_prec_in_bytes
96
+ write_data_array(out, spec.intensities, int_dtype, int_prec)
97
+ [mz_info, int_info]
98
+ end
99
+ end
100
+ end
101
+
102
+ # converts image related hash values to an array of loose describe!
103
+ # params
104
+ def image_hash_to_cvs(hash)
105
+ cvs = []
106
+ cvs << case hash[:data_structure].to_sym
107
+ when :processed ; 'IMS:1000031'
108
+ when :continuous ; 'IMS:1000030'
109
+ else ; raise ":data_structure must be :processed or :continuous"
110
+ end
111
+
112
+ cvs << case hash[:scan_pattern].to_sym
113
+ when :meandering ; 'IMS:1000410'
114
+ when :random ; 'IMS:1000412'
115
+ when :flyback ; 'IMS:1000413'
116
+ else ; raise ":scan_pattern must be :meandering, :random or :flyback"
117
+ end
118
+
119
+ cvs << case hash[:scan_type].to_sym
120
+ when :horizontal ; 'IMS:1000480'
121
+ when :vertical ; 'IMS:1000481'
122
+ else ; raise ":scan_type must be :horizontal or :vertical"
123
+ end
124
+
125
+ cvs << case hash[:linescan_direction].to_s
126
+ when 'left-right' ; 'IMS:1000402'
127
+ when 'right-left' ; 'IMS:1000403'
128
+ when 'bottom-up' ; 'IMS:1000400'
129
+ when 'top-down' ; 'IMS:1000401'
130
+ when 'none' ; 'IMS:1000404'
131
+ else ; raise ":linescan_direction unacceptable"
132
+ end
133
+
134
+ cvs << case hash[:linescan_sequence].to_s
135
+ when 'top-down' ; 'IMS:1000493'
136
+ when 'bottom-up' ; 'IMS:1000492'
137
+ when 'left-right' ; 'IMS:1000491'
138
+ when 'right-left' ; 'IMS:1000490'
139
+ else ; raise "linescan_sequence unacceptable"
140
+ end
141
+
142
+ max_pix_dims = hash[:max_dimensions_pixels].split(/x/i)
143
+ cvs.push *['IMS:1000042', 'IMS:1000043'].zip(max_pix_dims).to_a
144
+
145
+ real_dims = hash[:max_dimensions_microns].split(/x/i)
146
+ cvs.push *['IMS:1000044', 'IMS:1000045'].zip(real_dims).map {|pair| [*pair, "UO:0000017"] }
147
+
148
+ pix_dims = hash[:pixel_size].split(/x/i)
149
+ cvs.push *["IMS:1000046", "IMS:1000047"].zip(pix_dims).map {|pair| [*pair, "UO:0000017"] }
150
+ cvs
151
+ end
152
+
153
+ def experiment_hash_to_cvs(hash)
154
+ cvs = {
155
+ :matrix_solution_concentration => "MS:1000835",
156
+ :matrix_solution => "MS:1000834",
157
+ :solvent => 'IMS:1001211',
158
+ :solvent_flowrate => 'IMS:1001213',
159
+ :spray_voltage => 'IMS:1001212',
160
+ :target_material => 'IMS:10000202'
161
+ }.map do |key,cv_acc|
162
+ [cv_acc, hash[key]] if hash[key]
163
+ end.compact
164
+
165
+ mats = hash[:matrix_application_types]
166
+ if mats
167
+ app_types = mats.map do |typ|
168
+ case typ.to_s
169
+ when 'sprayed' ; 'MS:1000838'
170
+ when 'precoated' ; 'MS:1000839'
171
+ when 'printed' ; 'MS:1000837'
172
+ when 'drieddroplet' ; 'MS:1000836'
173
+ else ; raise "invalid matrix_application_type"
174
+ end
175
+ end
176
+ cvs.push(*app_types)
177
+ end
178
+ cvs
179
+ end
180
+
181
+ # returns an array with x, y pairs in the correct order
182
+ # accounts for scan_pattern, scan_type, linescan_direction,
183
+ # linescan_sequence and shots_per_position
184
+ def x_y_positions(config)
185
+ (scan_pattern, scan_type, scan_direction, scan_sequence, shots_per_pos) = config.values_at(:scan_pattern, :scan_type, :linescan_direction, :linescan_sequence, :shots_per_position).map(&:to_s)
186
+ shots_per_pos = shots_per_pos.to_i
187
+ #puts "EXAMIN ARGS: "
188
+ #p [ scan_pattern, scan_type, scan_direction, scan_sequence, shots_per_pos, shots_per_pos]
189
+
190
+ # the true dimensions we need to work off come from the pixel dimensions.
191
+ (slen, plen) = config[:max_dimensions_pixels].split(/x/i).map(&:to_i)
192
+
193
+ flip = (scan_type == 'vertical')
194
+ plen, slen = slen, plen if flip
195
+
196
+ pindices = (1..plen).to_a # mindices if linescan_direction is 'horizontal'
197
+ sindices = (1..slen).to_a # nindices if linescan_direction is 'horizontal'
198
+
199
+ if flip
200
+ sindices.reverse! if scan_direction == 'bottom-top' || scan_direction == 'right-left'
201
+ pindices.reverse! if scan_sequence == 'right-left' || scan_sequence == 'bottom-top'
202
+ end
203
+
204
+ indices = pindices.map do |a|
205
+ row = sindices.map do |b|
206
+ flip ? [a,b] : [b,a]
207
+ end
208
+ sindices.reverse! if scan_pattern == 'meandering'
209
+ row
210
+ end.flatten(1)
211
+
212
+ indices.map {|pair| shots_per_pos.times.map { pair } }.flatten(1)
213
+ end
214
+
215
+ def create_file_description(source_files, config)
216
+ Mspire::Mzml::FileDescription.new do |fd|
217
+
218
+ fd.file_content = Mspire::Mzml::FileContent.new :params => [
219
+ 'MS:1000579', # MS1 Spectrum
220
+ config[:profile] ? 'MS:1000128' : 'MS:1000127',
221
+ ['IMS:1000080', "{"+config[:uuid_hyphenated]+"}"],
222
+ ['IMS:1000091', config[:ibd_sha1]],
223
+ (config[:data_structure] == :processed) ? 'IMS:1000031' : 'IMS:1000030',
224
+ ]
225
+
226
+ fd.source_files.replace(source_files)
227
+ if [:name, :organization, :address, :email].any? {|key| config[key] }
228
+ contact = Mspire::Mzml::Contact.new
229
+ [ [:name, 'MS:1000586'],
230
+ [:organization, 'MS:1000590'],
231
+ [:address, 'MS:1000587'],
232
+ [:email, 'MS:1000589']
233
+ ].each do |key, accession|
234
+ contact.describe!(accession, config[key]) if config[key]
235
+ end
236
+ fd.contacts << contact
237
+ end
238
+ end
239
+ end
240
+
241
+ def create_referenceable_params_by_id_hash
242
+ # m/z array and no compression (because we'll ref peaks in different
243
+ # file)
244
+ rparms = {
245
+ :mz_array => [
246
+ ["MS:1000514", "MS:1000040"], # m/z array, units = m/z
247
+ "MS:1000576", # no compression
248
+ ["IMS:1000101", true], # external data
249
+ 'MS:1000523' # 64-bit float
250
+ ],
251
+ :intensity_array => [
252
+ ["MS:1000515", "MS:1000131"], # intensity array, units = number of counts
253
+ "MS:1000576", # no compression
254
+ ["IMS:1000101", true], # external data
255
+ 'MS:1000521' # 32-bit float
256
+ ],
257
+ :scan1 => [
258
+ # this should probably be ascertained from the mzml file:
259
+ "MS:1000093", # increasing m/z scan
260
+ # "MS:1000095" # linear # <- this should probably be gathered
261
+ # from mzml (leave outfor now)
262
+ # could include the filter string here in future
263
+ ],
264
+ :spectrum1 => [
265
+ "MS:1000579", # MS1 spectrum
266
+ ["MS:1000511", 1], # ms level - default implementation uses 0 but I disagree...
267
+ "MS:1000127", # centroid spectrum
268
+ "MS:1000130" # <- positive scan
269
+ ]}.map do |id, list|
270
+ Mspire::Mzml::ReferenceableParamGroup.new id, params: list
271
+ end
272
+ Hash[ rparms.map {|parm| [parm.id, parm]} ]
273
+ end
274
+
275
+ # mzml_filenames can each be a partial or relative path
276
+ # by default the file will write to the same directory and basename
277
+ #
278
+ # contact:
279
+ # :name => name of the person or organization
280
+ # :address => address of the person or organization
281
+ # :url => url of person or organization
282
+ # :email => email of person or organization
283
+ # :organization => home institution of contact
284
+ # experiment:
285
+ # :solvent => the solvent used
286
+ # :solvent_flowrate => flowrate of the solvent (ml/min)
287
+ # :spray_voltage => spray voltage in kV
288
+ # :target_material => the material the target is made of
289
+ # general:
290
+ # :omit_zeros => remove zero values
291
+ # :combine => use this outfile base name to combine files
292
+ # also works on single files to rename them.
293
+ # MUST be present if more than one mzml given.
294
+ # imaging:
295
+ # :data_structure => :processed or :continuous
296
+ # :scan_pattern => meandering random flyback
297
+ # :scan_type => horizontal or vertical
298
+ # :linescan_direction => scan_direction.join('|')
299
+ # :linescan_sequence => scan_sequence.join('|')
300
+ # :max_dimensions_pixels => maximum X by Y pixels (e.g. 300x100)
301
+ # :shots_per_position => number of spectra per position
302
+ # :pixel_size => X by Y of a single pixel in microns (μm)
303
+ # :max_dimensions_microns => maximum X by Y in microns (e.g. 25x20)
304
+ def write(mzml_filenames, config={})
305
+
306
+ base = config[:combine] || mzml_filenames.first.chomp(File.extname(mzml_filenames.first))
307
+ config[:imzml_filename] = base + ".imzML"
308
+ config[:ibd_filename] = base + ".ibd"
309
+
310
+ uuid_with_hyphens = UUID.new.generate
311
+ config[:uuid_hyphenated] = uuid_with_hyphens
312
+ config[:uuid] = uuid_with_hyphens.gsub('-','')
313
+
314
+ sourcefile_id_parallel_to_spectra = []
315
+ sourcefile_ids = []
316
+ all_spectra_iter = Enumerator.new do |yielder|
317
+ mzml_filenames.each_with_index do |mzml_filename,i|
318
+ sourcefile_id = "source_file_#{i}"
319
+ sourcefile_ids << sourcefile_id
320
+ Mspire::Mzml.open(mzml_filename) do |mzml|
321
+ mzml.each do |spec|
322
+ sourcefile_id_parallel_to_spectra << sourcefile_id
323
+ yielder << spec
324
+ end
325
+ end
326
+ end
327
+ end
328
+
329
+ data_info_pairs = write_binary(config[:ibd_filename], all_spectra_iter, config)
330
+ config[:ibd_sha1] = Digest::SHA1.hexdigest(IO.read(config[:ibd_filename]))
331
+
332
+ source_files = mzml_filenames.zip(sourcefile_ids).map do |mzml_filename, source_file_id|
333
+ sfile = Mspire::Mzml::SourceFile[ mzml_filename ]
334
+ sfile.id = source_file_id
335
+ sfile.describe! 'MS:1000584'
336
+ sfile.describe! 'MS:1000569', Digest::SHA1.hexdigest(IO.read(mzml_filename))
337
+ sfile
338
+ end
339
+ sourcefile_id_to_sourcefile = Hash[ source_files.group_by(&:id).map {|k,v| [k,v.first] } ]
340
+
341
+ imzml_obj = Mspire::Mzml.new do |imzml|
342
+ imzml.id = UUID.new.generate.gsub('-','')
343
+ imzml.cvs = Mspire::Mzml::CV::DEFAULT_CVS
344
+
345
+ imzml.file_description = create_file_description(source_files, config)
346
+
347
+ rparms_by_id = create_referenceable_params_by_id_hash
348
+
349
+ warn "using positive scan in every case but need to get this from original mzml!"
350
+
351
+ imzml.referenceable_param_groups = rparms_by_id.values
352
+ # skip sample list for now
353
+ mspire_software = Mspire::Mzml::Software.new( "mspire", Mspire::VERSION, params: ["MS:1000799"] )
354
+ imzml.software_list << mspire_software
355
+
356
+ scan_setting_params = image_hash_to_cvs( config )
357
+ scan_setting_params.push *experiment_hash_to_cvs( config )
358
+ imzml.scan_settings_list = [Mspire::Mzml::ScanSettings.new("scansettings1", params: scan_setting_params)]
359
+
360
+ warn 'todo: need to borrow instrumentConfiguration from original mzml'
361
+
362
+ default_instrument_config = Mspire::Mzml::InstrumentConfiguration.new("borrow_from_mzml")
363
+ warn 'todo: need to include default softare from mzml in default_instrument_config'
364
+ #default_instrument_config.software = Software.new( from the mzml file! )
365
+ imzml.instrument_configurations << default_instrument_config
366
+
367
+ # this is a generic 'file format conversion' but its the closest we
368
+ # have for mzml to imzml (which is really mzml to mzml)
369
+ data_processing_obj = Mspire::Mzml::DataProcessing.new('mzml_to_imzml')
370
+ data_processing_obj.processing_methods << Mspire::Mzml::ProcessingMethod.new(1, mspire_software, params: ['MS:1000530'] )
371
+ imzml.data_processing_list << data_processing_obj
372
+
373
+ warn "not implemented 'omit_zeros' yet"
374
+ # low intensity data point removal: "MS:1000594"
375
+ imzml.run = Mspire::Mzml::Run.new("run1", default_instrument_config) do |run|
376
+ spec_list = Mspire::Mzml::SpectrumList.new(data_processing_obj)
377
+ data_info_pairs.zip(x_y_positions(config), sourcefile_id_parallel_to_spectra).each_with_index do |(pair, xy, sourcefile_id),i|
378
+ # TODO: we should probably copy the id from the orig mzml (e.g.
379
+ # scan=1)
380
+ spectrum = Mspire::Mzml::Spectrum.new("spectrum#{i}", params: [rparms_by_id[:spectrum1]])
381
+ spectrum.source_file = sourcefile_id_to_sourcefile[sourcefile_id]
382
+ scan_list = Mspire::Mzml::ScanList.new(params: ['MS:1000795']) # no combination
383
+ scan = Mspire::Mzml::Scan.new( params: [rparms_by_id[:scan1], ["IMS:1000050", xy[0]], ["IMS:1000051", xy[1]]] )
384
+ scan.instrument_configuration = default_instrument_config
385
+ spectrum.scan_list = (scan_list << scan)
386
+
387
+ data_arrays = %w(mz intensity).zip(pair).map do |type, data_array_info|
388
+ rparmgroup = rparms_by_id[(type + "_array").to_sym]
389
+ data_array = Mspire::Mzml::DataArray.new
390
+ data_array.type = type
391
+ data_array.external = true
392
+ data_array.describe_many! [rparmgroup, *%w(IMS:1000103 IMS:1000102 IMS:1000104).zip(data_array_info).map.to_a]
393
+ data_array
394
+ end
395
+ spectrum.data_arrays = data_arrays
396
+ spec_list << spectrum
397
+ end
398
+ run.spectrum_list = spec_list
399
+ end # run
400
+ end # imzml
401
+ imzml_obj.to_xml(config[:imzml_filename])
402
+ end
403
+ end
404
+ end
@@ -0,0 +1,109 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'mspire/imzml/writer'
4
+ require 'trollop'
5
+ require 'yaml'
6
+
7
+ module Mspire
8
+ module Imzml
9
+ class Writer
10
+ end
11
+ end
12
+ end
13
+
14
+ module Mspire::Imzml::Writer::Commandline
15
+
16
+ def self.run(argv, progname=$0)
17
+
18
+ default_config = "config.yaml"
19
+ scan_patterns = %w(flyback meandering random)
20
+ scan_types = %w(horizontal vertical)
21
+ scan_direction = %w(left-right right-left bottom-up top-down none)
22
+ scan_sequence = %w(top-down bottom-up left-right right-left)
23
+ default_dims = '800x600'
24
+ default_pixel_size = '1x1'
25
+ matrix_application_types = %w(sprayed precoated printed drieddroplet)
26
+
27
+ parser = Trollop::Parser.new do
28
+ banner <<-EOS
29
+ usage: #{File.basename(progname)} [OPTIONS] <file>.mzML ..."
30
+ output: <file>.imzML and <file>.ibd
31
+
32
+ * imzML docs:
33
+ http://www.maldi-msi.org/index.php?option=com_content&view=article&id=187&Itemid=67
34
+ * explanation of vocabulary (followed here):
35
+ http://www.maldi-msi.org/index.php?option=com_content&view=article&id=193&Itemid=66
36
+ * github repository:
37
+ https://github.com/princelab/mzml_to_imzml
38
+ EOS
39
+ text "\ngeneral:"
40
+ opt :config, "read a config file for default values. Command line options overide those from the config file ", :type => :string
41
+ opt :print_config, "print current options to #{default_config} and exit"
42
+ opt :omit_zeros, "remove zero values"
43
+ opt :combine, "combine all files and set the base name of resulting imzML and ibd files", :type => String
44
+ opt :outfile, "use a specific basename for the resulting file. Acts like --combine for multiple files", :type => String
45
+
46
+ text "\nimaging:"
47
+ opt :continuous, "assumes m/z values are the same for every scan. The 'processed' storage format is used unless this flag is given."
48
+ opt :scan_pattern, scan_patterns.join('|'), :default => scan_patterns.first
49
+ opt :scan_type, scan_types.join('|'), :default => scan_types.first
50
+ opt :linescan_direction, scan_direction.join('|'), :default => scan_direction.first
51
+ opt :linescan_sequence, scan_sequence.join('|'), :default => scan_sequence.first
52
+ opt :max_dimensions_pixels, "maximum X by Y pixels (e.g. 300x100)", :default => default_dims
53
+ opt :shots_per_position, "number of spectra per position", :default => 1
54
+ opt :pixel_size, "X by Y of a single pixel in microns (μm)", :default => default_pixel_size
55
+ opt :max_dimensions_microns, "maximum X by Y in microns (e.g. 25x20)", :default => default_dims
56
+
57
+ text "\ncontact: "
58
+ opt :name, "name of the person or organization", :type => :string
59
+ opt :address, "address of the person or organization", :type => :string
60
+ opt :url, "url of person or organization", :type => :string
61
+ opt :email, "email of person or organization", :type => :string
62
+ opt :organization, "home institution of contact", :type => :string
63
+
64
+ text "\nDESI: "
65
+ opt :solvent, "the solvent used", :type => :string
66
+ opt :solvent_flowrate, "flowrate of the solvent (ml/min)", :type => :float
67
+ opt :spray_voltage, "spray voltage in kV", :type => :float
68
+ opt :target_material, "the material the target is made of", :type => :string
69
+
70
+ text "\nMALDI: "
71
+ opt :matrix_application_types, "#{matrix_application_types.join('|')} (comma separated)", :type => :string
72
+ opt :matrix_solution_concentration, "in grams per liter", :type => :float
73
+ opt :matrix_solution, "the chemical solution used as matrix (e.g., DHB)", :type => :string
74
+
75
+ # things to add: data types for m/z and intensity
76
+ # filters (cutoff / max # peaks, etc.)
77
+ # ms_level, etc.
78
+ end
79
+
80
+ opts = parser.parse(argv)
81
+ opts = Hash[YAML.load_file(opts[:config]).map {|k,v| [k.to_sym, v]}].merge(opts) if opts[:config]
82
+
83
+ opts[:combine] ||= opts.delete(:outfile)
84
+
85
+ if opts.delete(:print_config)
86
+ puts "writing defaults to: #{default_config}"
87
+ string_opts = Hash[ opts.map {|k,v| [k.to_s, v] } ]
88
+ %w(help).each {|key| string_opts.delete key }
89
+ string_opts.delete_if {|k,v| k =~ /_given$/ }
90
+ File.write(default_config, string_opts.to_yaml)
91
+ exit
92
+ end
93
+
94
+ if argv.size == 0
95
+ return parser.educate
96
+ end
97
+
98
+ opts[:data_structure] = (opts.delete(:continuous) ? :continuous : :processed)
99
+ opts[:matrix_application_types] = opts[:matrix_application_types].split(',') if opts[:matrix_application_types]
100
+
101
+ # prep args a little
102
+ writer = Mspire::Imzml::Writer.new
103
+ writer.write(argv, opts)
104
+
105
+ end
106
+ end
107
+
108
+
109
+
@@ -7,6 +7,8 @@ module Mspire
7
7
  class DataArray < Array
8
8
  alias_method :array_initialize, :initialize
9
9
  include Mspire::CV::Paramable
10
+ alias_method :params_initialize, :initialize
11
+ alias_method :params_to_xml, :to_xml
10
12
 
11
13
  DEFAULT_DTYPE = :float64
12
14
  DEFAULT_COMPRESSION = true
@@ -18,11 +20,35 @@ module Mspire
18
20
  int32: 'MS:1000519', # signed
19
21
  }
20
22
 
21
- # the type of data array (:mz, :intensity, :mz_external, or :intensity_external)
22
- attr_accessor :type
23
+ def type=(arg)
24
+ all_accs = %w(MS:1000514 MS:1000515)
25
+ params.delete_if {|param| all_accs.include?(param.accession) } if params
26
+ case arg
27
+ when :mz
28
+ describe! all_accs[0] # , nil, "MS:1000040"
29
+ when :intensity
30
+ describe! all_accs[1] # , nil, "MS:1000131"
31
+ end
32
+ arg
33
+ end
34
+
35
+ def type
36
+ if params
37
+ if params.any? {|param| param.accession == 'MS:1000514' }
38
+ :mz
39
+ elsif params.any? {|param| param.accession == 'MS:1000515' }
40
+ :intensity
41
+ end
42
+ end
43
+ end
44
+
45
+ # set this if the data is written to an external file (such as the ibd
46
+ # file for imzML files)
47
+ attr_accessor :external
23
48
 
24
49
  def initialize(*args)
25
50
  array_initialize(*args)
51
+ params_initialize
26
52
  end
27
53
 
28
54
  # returns a new Mspire::Mzml::DataArray object (an array)
@@ -72,7 +98,7 @@ module Mspire
72
98
  #
73
99
  # args:
74
100
  # array-like set-like # where set-like responds to include?
75
- # array-like type=:float64, compression=true
101
+ # array-like dtype=:float64, compression=true
76
102
  def self.to_binary(array_ish, *args)
77
103
  if args.first.respond_to?(:include?)
78
104
  accessions = args.first
@@ -117,15 +143,11 @@ module Mspire
117
143
  end
118
144
 
119
145
  builder.binaryDataArray(encodedLength: encoded_length) do |bda_n|
120
- @params.each {|param| param.to_xml(bda_n) } if @params
121
- unless @external
146
+ params_to_xml(bda_n)
147
+ unless self.external
122
148
  Mspire::CV::Param[ DTYPE_TO_ACC[dtype] ].to_xml(bda_n)
123
149
  Mspire::CV::Param[ compression ? 'MS:1000574' : 'MS:1000576' ].to_xml(bda_n)
124
- if @type
125
- accession = ( (@type == :mz) ? 'MS:1000514' : 'MS:1000515' )
126
- Mspire::CV::Param[accession].to_xml(bda_n)
127
- bda_n.binary(base64)
128
- end
150
+ bda_n.binary(base64)
129
151
  end
130
152
  end
131
153
  end
@@ -138,9 +160,7 @@ module Mspire
138
160
  if data_ar.is_a?(Mspire::Mzml::DataArray)
139
161
  data_ar
140
162
  else
141
- real_data_array = Mspire::Mzml::DataArray.new(data_ar)
142
- real_data_array.type = typ
143
- real_data_array
163
+ Mspire::Mzml::DataArray.new(data_ar)
144
164
  end
145
165
  ar.type = typ unless ar.type
146
166
  ar.to_xml(bdal_n)
@@ -26,11 +26,6 @@ module Mspire
26
26
  # (optional) an array of Mspire::Mzml::DataArray
27
27
  attr_accessor :data_arrays
28
28
 
29
- def initialize(id, opts={params: []})
30
- @id = id
31
- describe_many!(opts[:params])
32
- end
33
-
34
29
  def default_array_length
35
30
  if @data_arrays
36
31
  if @data_arrays.first
@@ -17,7 +17,7 @@ module Mspire
17
17
  attr_accessor :software
18
18
 
19
19
  def initialize(id, components=[], opts={params: []})
20
- describe_many!(opts[:params])
20
+ super(opts)
21
21
  @id = id
22
22
  @components = components
23
23
  end
@@ -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_many!(opts[:params])
12
+ super(opts)
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_many!(opts[:params])
17
+ super(opts)
18
18
  end
19
19
 
20
20
  def to_xml(builder)
@@ -24,7 +24,7 @@ module Mspire
24
24
 
25
25
  def to_xml_definition(builder)
26
26
  builder.referenceableParamGroup(id: @id) do |fc_n|
27
- @params.each {|obj| obj.to_xml(fc_n) }
27
+ params.each {|obj| obj.to_xml(fc_n) }
28
28
  end
29
29
  builder
30
30
  end
@@ -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_many!(opts[:params])
33
+ super(opts)
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_many!(opts[:params])
13
+ super(opts)
14
14
  block.call(self) if block
15
15
  end
16
16
 
@@ -21,7 +21,7 @@ module Mspire
21
21
  attr_accessor :scan_windows
22
22
 
23
23
  def initialize(opts={params: []}, &block)
24
- describe_many!(opts[:params])
24
+ super(opts)
25
25
  block.call(self) if block
26
26
  end
27
27
 
@@ -13,13 +13,13 @@ module Mspire
13
13
  include Mspire::CV::Paramable
14
14
 
15
15
  def initialize(opts={params: []}, &block)
16
- describe_many!(opts[:params])
16
+ super(opts)
17
17
  block.call(self) if block
18
18
  end
19
19
 
20
20
  def to_xml(builder)
21
21
  builder.scanList(count: self.size) do |sl_n|
22
- @params.each {|param| param.to_xml(sl_n) } if @params
22
+ super(sl_n)
23
23
  self.each do |scan|
24
24
  scan.to_xml(sl_n)
25
25
  end
@@ -10,7 +10,7 @@ module Mspire
10
10
 
11
11
  def initialize(id, opts={params: []}, &block)
12
12
  @id = id
13
- describe_many!(opts[:params])
13
+ super(opts)
14
14
  block.call(self) if block
15
15
  end
16
16
 
@@ -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_many!(opts[:params])
14
+ super(opts)
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_many!(opts[:params])
36
+ super(opts)
37
37
  block.call(self) if block
38
38
  end
39
39
 
@@ -43,6 +43,7 @@ module Mspire
43
43
  class Spectrum
44
44
  include Mspire::SpectrumLike
45
45
  include Mspire::Mzml::DataArrayContainerLike
46
+ alias_method :params_initialize, :initialize
46
47
 
47
48
  # (optional) an Mspire::Mzml::SourceFile object
48
49
  attr_accessor :source_file
@@ -144,7 +145,7 @@ module Mspire
144
145
  #
145
146
  def initialize(id, opts={params: []}, &block)
146
147
  @id = id
147
- describe_many! opts[:params]
148
+ params_initialize(opts)
148
149
  block.call(self) if block
149
150
  end
150
151
 
@@ -5,13 +5,14 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "mspire"
8
- s.version = "0.7.6"
8
+ s.version = "0.7.7"
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
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
+ s.executables = ["mzml_to_imzml"]
15
16
  s.extra_rdoc_files = [
16
17
  "LICENSE",
17
18
  "README.rdoc"
@@ -21,6 +22,7 @@ Gem::Specification.new do |s|
21
22
  "README.rdoc",
22
23
  "Rakefile",
23
24
  "VERSION",
25
+ "bin/mzml_to_imzml",
24
26
  "lib/core_ext/array/in_groups.rb",
25
27
  "lib/cv.rb",
26
28
  "lib/cv/param.rb",
@@ -56,6 +58,8 @@ Gem::Specification.new do |s|
56
58
  "lib/mspire/ident/protein.rb",
57
59
  "lib/mspire/ident/protein_group.rb",
58
60
  "lib/mspire/ident/search.rb",
61
+ "lib/mspire/imzml/writer.rb",
62
+ "lib/mspire/imzml/writer/commandline.rb",
59
63
  "lib/mspire/isotope.rb",
60
64
  "lib/mspire/isotope/aa.rb",
61
65
  "lib/mspire/isotope/distribution.rb",
@@ -128,6 +132,7 @@ Gem::Specification.new do |s|
128
132
  "spec/mspire/ident/pepxml/search_hit/modification_info_spec.rb",
129
133
  "spec/mspire/ident/pepxml_spec.rb",
130
134
  "spec/mspire/ident/protein_group_spec.rb",
135
+ "spec/mspire/imzml/writer_spec.rb",
131
136
  "spec/mspire/isotope/aa_spec.rb",
132
137
  "spec/mspire/isotope/distribution_spec.rb",
133
138
  "spec/mspire/isotope_spec.rb",
@@ -151,8 +156,11 @@ Gem::Specification.new do |s|
151
156
  "spec/mspire_spec.rb",
152
157
  "spec/obo_spec.rb",
153
158
  "spec/spec_helper.rb",
159
+ "spec/testfiles/continuous_binary.tmp.ibd",
154
160
  "spec/testfiles/mspire/ident/peptide/db/uni_11_sp_tr.fasta",
155
161
  "spec/testfiles/mspire/ident/peptide/db/uni_11_sp_tr.msd_clvg2.min_aaseq4.yml",
162
+ "spec/testfiles/mspire/imzml/continuous_binary_check.ibd",
163
+ "spec/testfiles/mspire/imzml/processed_binary_check.ibd",
156
164
  "spec/testfiles/mspire/mzml/j24z.idx_comp.3.mzML",
157
165
  "spec/testfiles/mspire/mzml/mspire_simulated.MSn.check.mzML",
158
166
  "spec/testfiles/mspire/mzml/openms.noidx_nocomp.12.mzML",
@@ -175,7 +183,8 @@ Gem::Specification.new do |s|
175
183
  "spec/testfiles/mspire/quant/pdcd5_lfq_tabdel.txt_qspecgp",
176
184
  "spec/testfiles/mspire/quant/remove_rest_of_proteins.rb",
177
185
  "spec/testfiles/mspire/quant/unlog_transform.rb",
178
- "spec/testfiles/plms1/output.key"
186
+ "spec/testfiles/plms1/output.key",
187
+ "spec/testfiles/processed_binary.tmp.ibd"
179
188
  ]
180
189
  s.homepage = "http://github.com/princelab/mspire"
181
190
  s.licenses = ["MIT"]
@@ -0,0 +1,101 @@
1
+ require 'spec_helper'
2
+
3
+ require 'mspire/imzml/writer'
4
+ require 'mspire/spectrum'
5
+
6
+ describe Mspire::Imzml::Writer do
7
+
8
+ before(:each) do
9
+ @spectra = [
10
+ Mspire::Spectrum.new([[1,2,3],[4,5,6]]),
11
+ Mspire::Spectrum.new([[1,2,3],[4,5,6]]),
12
+ Mspire::Spectrum.new([[1,2,3],[4,5,6]]),
13
+ ]
14
+ @config = {
15
+ uuid: "d097f8103a8e012f2b130024e8b4cdae",
16
+ mz_data_type: :float,
17
+ mz_precision: 32,
18
+ # just for fun, use floats for m/z and ints for intensities
19
+ intensity_data_type: :int,
20
+ intensity_precision: 32,
21
+ }
22
+ end
23
+
24
+ it 'has an iterator that creates the proper x and y positions' do
25
+ #config = { :scan_pattern => 'meandering', :scan_type => 'horizontal', :linescan_direction => 'left-right', :linescan_sequence => 'top-down', :max_dimensions_pixels => '3x2', :pixel_size => '2x2', :max_dimensions_microns => '6x4', :shots_per_position => 2 }
26
+ writer = Mspire::Imzml::Writer.new
27
+ testing = {
28
+
29
+ %w(flyback horizontal left-right top-bottom) => [[1, 1], [1, 1], [2, 1], [2, 1], [3, 1], [3, 1], [1, 2], [1, 2], [2, 2], [2, 2], [3, 2], [3, 2]],
30
+ %w(flyback horizontal left-right bottom-top) => [[1, 1], [1, 1], [2, 1], [2, 1], [3, 1], [3, 1], [1, 2], [1, 2], [2, 2], [2, 2], [3, 2], [3, 2]],
31
+ %w(flyback horizontal right-left bottom-top) => [[1, 1], [1, 1], [2, 1], [2, 1], [3, 1], [3, 1], [1, 2], [1, 2], [2, 2], [2, 2], [3, 2], [3, 2]],
32
+ %w(flyback horizontal right-left top-bottom) => [[1, 1], [1, 1], [2, 1], [2, 1], [3, 1], [3, 1], [1, 2], [1, 2], [2, 2], [2, 2], [3, 2], [3, 2]],
33
+ %w(meandering horizontal left-right top-bottom) => [[1, 1], [1, 1], [2, 1], [2, 1], [3, 1], [3, 1], [3, 2], [3, 2], [2, 2], [2, 2], [1, 2], [1, 2]],
34
+ %w(meandering horizontal left-right bottom-top) => [[1, 1], [1, 1], [2, 1], [2, 1], [3, 1], [3, 1], [3, 2], [3, 2], [2, 2], [2, 2], [1, 2], [1, 2]],
35
+ %w(meandering horizontal right-left bottom-top) => [[1, 1], [1, 1], [2, 1], [2, 1], [3, 1], [3, 1], [3, 2], [3, 2], [2, 2], [2, 2], [1, 2], [1, 2]],
36
+ %w(meandering horizontal right-left top-bottom) => [[1, 1], [1, 1], [2, 1], [2, 1], [3, 1], [3, 1], [3, 2], [3, 2], [2, 2], [2, 2], [1, 2], [1, 2]],
37
+ %w(flyback vertical top-bottom left-right) => [[1, 1], [1, 1], [1, 2], [1, 2], [2, 1], [2, 1], [2, 2], [2, 2], [3, 1], [3, 1], [3, 2], [3, 2]],
38
+ %w(flyback vertical bottom-top right-left) => [[3, 2], [3, 2], [3, 1], [3, 1], [2, 2], [2, 2], [2, 1], [2, 1], [1, 2], [1, 2], [1, 1], [1, 1]],
39
+ %w(flyback vertical bottom-top left-right) => [[1, 2], [1, 2], [1, 1], [1, 1], [2, 2], [2, 2], [2, 1], [2, 1], [3, 2], [3, 2], [3, 1], [3, 1]],
40
+ %w(flyback vertical top-bottom right-left) => [[3, 1], [3, 1], [3, 2], [3, 2], [2, 1], [2, 1], [2, 2], [2, 2], [1, 1], [1, 1], [1, 2], [1, 2]],
41
+ %w(meandering vertical top-bottom left-right) => [[1, 1], [1, 1], [1, 2], [1, 2], [2, 2], [2, 2], [2, 1], [2, 1], [3, 1], [3, 1], [3, 2], [3, 2]],
42
+ %w(meandering vertical bottom-top right-left) => [[3, 2], [3, 2], [3, 1], [3, 1], [2, 1], [2, 1], [2, 2], [2, 2], [1, 2], [1, 2], [1, 1], [1, 1]],
43
+ %w(meandering vertical bottom-top left-right) => [[1, 2], [1, 2], [1, 1], [1, 1], [2, 1], [2, 1], [2, 2], [2, 2], [3, 2], [3, 2], [3, 1], [3, 1]],
44
+ %w(meandering vertical top-bottom right-left) => [[3, 1], [3, 1], [3, 2], [3, 2], [2, 2], [2, 2], [2, 1], [2, 1], [1, 1], [1, 1], [1, 2], [1, 2]]
45
+ }
46
+ cats = %w(scan_pattern scan_type linescan_direction linescan_sequence).map(&:to_sym)
47
+ testing. each do |(configs, expected)|
48
+ config = Hash[ cats.zip(configs).map.to_a ]
49
+ config[:max_dimensions_pixels] = '3x2'
50
+ config[:shots_per_position] = 2
51
+ writer.x_y_positions(config).should == expected
52
+ end
53
+ end
54
+
55
+ it 'writes :processed binary file with spectra and returns DataArrayInfo objects' do
56
+ expected_file = TESTFILES + "/mspire/imzml/processed_binary_check.ibd"
57
+ write_to = TESTFILES + "/mspire/imzml/processed_binary.tmp.ibd"
58
+ array = subject.write_binary(write_to, @spectra.each, @config.merge( {:data_structure => :processed} ))
59
+ IO.read(write_to).should == IO.read(expected_file)
60
+ array.should be_an(Array)
61
+ length = 3
62
+ offsets = (16..76).step(12)
63
+ encoded_length = 12
64
+
65
+ array.each do |info_pair|
66
+ info_pair.each do |obj|
67
+ obj.should be_a(Mspire::Imzml::DataArrayInfo)
68
+ obj.length.should == length
69
+ obj.encoded_length.should == encoded_length
70
+ obj.offset.should == offsets.next
71
+ end
72
+ end
73
+ File.unlink(write_to) if File.exist?(write_to)
74
+ end
75
+
76
+ it 'writes :continuous binary file with spectra and returns DataArrayInfo objects' do
77
+ expected_file = TESTFILES + "/mspire/imzml/continuous_binary_check.ibd"
78
+ write_to = TESTFILES + "/mspire/imzml/continuous_binary.tmp.ibd"
79
+ array = subject.write_binary(write_to, @spectra.each, @config.merge( {:data_structure => :continuous} ))
80
+ IO.read(write_to).should == IO.read(expected_file)
81
+ array.should be_an(Array)
82
+
83
+ length = 3
84
+ offsets = (28..52).step(12)
85
+ encoded_length = 12
86
+ first_offset = 16
87
+
88
+ array.each do |info_pair|
89
+ info_pair.each do |obj|
90
+ obj.should be_a(Mspire::Imzml::DataArrayInfo)
91
+ obj.length.should == length
92
+ obj.encoded_length.should == encoded_length
93
+ end
94
+ info_pair.first.offset.should == first_offset
95
+ info_pair.last.offset.should == offsets.next
96
+ end
97
+ File.unlink(write_to) if File.exist?(write_to)
98
+ end
99
+
100
+
101
+ end
@@ -40,15 +40,15 @@
40
40
  </scanList>
41
41
  <binaryDataArrayList count="2">
42
42
  <binaryDataArray encodedLength="28">
43
+ <cvParam cvRef="MS" accession="MS:1000514" name="m/z array"/>
43
44
  <cvParam cvRef="MS" accession="MS:1000523" name="64-bit float"/>
44
45
  <cvParam cvRef="MS" accession="MS:1000574" name="zlib compression"/>
45
- <cvParam cvRef="MS" accession="MS:1000514" name="m/z array"/>
46
46
  <binary>eJxjYACBD/YMEOAAoTgcABe3Abg=</binary>
47
47
  </binaryDataArray>
48
48
  <binaryDataArray encodedLength="28">
49
+ <cvParam cvRef="MS" accession="MS:1000515" name="intensity array"/>
49
50
  <cvParam cvRef="MS" accession="MS:1000523" name="64-bit float"/>
50
51
  <cvParam cvRef="MS" accession="MS:1000574" name="zlib compression"/>
51
- <cvParam cvRef="MS" accession="MS:1000515" name="intensity array"/>
52
52
  <binary>eJxjYAABAQcwxSACpSUcAAjwAP0=</binary>
53
53
  </binaryDataArray>
54
54
  </binaryDataArrayList>
@@ -73,15 +73,15 @@
73
73
  </precursorList>
74
74
  <binaryDataArrayList count="2">
75
75
  <binaryDataArray encodedLength="28">
76
+ <cvParam cvRef="MS" accession="MS:1000514" name="m/z array"/>
76
77
  <cvParam cvRef="MS" accession="MS:1000523" name="64-bit float"/>
77
78
  <cvParam cvRef="MS" accession="MS:1000574" name="zlib compression"/>
78
- <cvParam cvRef="MS" accession="MS:1000514" name="m/z array"/>
79
79
  <binary>eJxjYACBD/YMEOAAoXgcABe/Abw=</binary>
80
80
  </binaryDataArray>
81
81
  <binaryDataArray encodedLength="28">
82
+ <cvParam cvRef="MS" accession="MS:1000515" name="intensity array"/>
82
83
  <cvParam cvRef="MS" accession="MS:1000523" name="64-bit float"/>
83
84
  <cvParam cvRef="MS" accession="MS:1000574" name="zlib compression"/>
84
- <cvParam cvRef="MS" accession="MS:1000515" name="intensity array"/>
85
85
  <binary>eJxjYAABEQcwxSABpUUcAAlYAQE=</binary>
86
86
  </binaryDataArray>
87
87
  </binaryDataArrayList>
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.6
4
+ version: 0.7.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -175,7 +175,8 @@ dependencies:
175
175
  description: mass spectrometry proteomics, lipidomics, and tools, a rewrite of mspire,
176
176
  merging of ms-* gems
177
177
  email: jtprince@gmail.com
178
- executables: []
178
+ executables:
179
+ - mzml_to_imzml
179
180
  extensions: []
180
181
  extra_rdoc_files:
181
182
  - LICENSE
@@ -185,6 +186,7 @@ files:
185
186
  - README.rdoc
186
187
  - Rakefile
187
188
  - VERSION
189
+ - bin/mzml_to_imzml
188
190
  - lib/core_ext/array/in_groups.rb
189
191
  - lib/cv.rb
190
192
  - lib/cv/param.rb
@@ -220,6 +222,8 @@ files:
220
222
  - lib/mspire/ident/protein.rb
221
223
  - lib/mspire/ident/protein_group.rb
222
224
  - lib/mspire/ident/search.rb
225
+ - lib/mspire/imzml/writer.rb
226
+ - lib/mspire/imzml/writer/commandline.rb
223
227
  - lib/mspire/isotope.rb
224
228
  - lib/mspire/isotope/aa.rb
225
229
  - lib/mspire/isotope/distribution.rb
@@ -292,6 +296,7 @@ files:
292
296
  - spec/mspire/ident/pepxml/search_hit/modification_info_spec.rb
293
297
  - spec/mspire/ident/pepxml_spec.rb
294
298
  - spec/mspire/ident/protein_group_spec.rb
299
+ - spec/mspire/imzml/writer_spec.rb
295
300
  - spec/mspire/isotope/aa_spec.rb
296
301
  - spec/mspire/isotope/distribution_spec.rb
297
302
  - spec/mspire/isotope_spec.rb
@@ -315,8 +320,11 @@ files:
315
320
  - spec/mspire_spec.rb
316
321
  - spec/obo_spec.rb
317
322
  - spec/spec_helper.rb
323
+ - spec/testfiles/continuous_binary.tmp.ibd
318
324
  - spec/testfiles/mspire/ident/peptide/db/uni_11_sp_tr.fasta
319
325
  - spec/testfiles/mspire/ident/peptide/db/uni_11_sp_tr.msd_clvg2.min_aaseq4.yml
326
+ - spec/testfiles/mspire/imzml/continuous_binary_check.ibd
327
+ - spec/testfiles/mspire/imzml/processed_binary_check.ibd
320
328
  - spec/testfiles/mspire/mzml/j24z.idx_comp.3.mzML
321
329
  - spec/testfiles/mspire/mzml/mspire_simulated.MSn.check.mzML
322
330
  - spec/testfiles/mspire/mzml/openms.noidx_nocomp.12.mzML
@@ -340,6 +348,7 @@ files:
340
348
  - spec/testfiles/mspire/quant/remove_rest_of_proteins.rb
341
349
  - spec/testfiles/mspire/quant/unlog_transform.rb
342
350
  - spec/testfiles/plms1/output.key
351
+ - spec/testfiles/processed_binary.tmp.ibd
343
352
  homepage: http://github.com/princelab/mspire
344
353
  licenses:
345
354
  - MIT