imzml 0.0.2 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1004a80f49dadaf56d396f7baa306fd55d5708c9
4
- data.tar.gz: 6188392c95e532991ebd80035013f4a8acf2e1bc
3
+ metadata.gz: f7be2442cc6f7ce7a1503a2a7c5380c9509043b2
4
+ data.tar.gz: f76e6a4ff83c1335b90389d6ea6348a2df7a3656
5
5
  SHA512:
6
- metadata.gz: e5fee636296de8d17e7f8bf927bdbb351288277ccea8919992cb6cdeea4134a58ecb81917b85aeba4b546321f0cace042e2474bfee9f8829a2827488d01e8289
7
- data.tar.gz: 6ac5981b89e67152ec0277de0cc6aa133965272799fa5ddc9c7fcf2c9a0524b19176984ee9be19d602aca50ef1bfd3f9d2b51e13c28d528bcd9a5ce7d8cd9f7b
6
+ metadata.gz: b6fa51fac3db3e0ed575eca4152b184063ab248da7c91989d1726781919119cb6def12d31965d7cea8a1b424d72d66f93da5ee3077b17ef02cc7dd837bc73409
7
+ data.tar.gz: d56ab3b35465d58974c80d3e7dd8f1037bd13be794261765ffcee13194510d893ea8e684cffd4a06a82614a954c5c74d7c3f79489b8447fde8ba123f9ea4f1b3
@@ -0,0 +1,23 @@
1
+ class Array
2
+
3
+ def binary_search(value, first = true)
4
+
5
+ if (self.size > 2)
6
+ middle_index = self.size/2
7
+ middle = self[middle_index]
8
+
9
+ if (middle > value)
10
+ self[0..middle_index].binary_search(value, first)
11
+ else
12
+ self[middle_index..self.size].binary_search(value, first)
13
+ end
14
+ else
15
+ if first
16
+ self.first
17
+ else
18
+ self.last
19
+ end
20
+ end
21
+ end
22
+
23
+ end
@@ -4,6 +4,14 @@ module ImzML
4
4
 
5
5
  class BinaryData
6
6
 
7
+ # Binary data types, always little endian
8
+ BINARY_TYPE_8BIT_INTEGER = "IMS:1100000"
9
+ BINARY_TYPE_16BIT_INTEGER = "IMS:1100001"
10
+ BINARY_TYPE_32BIT_INTEGER = "MS:1000519"
11
+ BINARY_TYPE_64BIT_INTEGER = "MS:1000522"
12
+ BINARY_TYPE_32BIT_FLOAT = "MS:1000521"
13
+ BINARY_TYPE_64BIT_FLOAT = "MS:1000523"
14
+
7
15
  # A data array of m/z values
8
16
  MZ_ARRAY = "MS:1000514"
9
17
 
@@ -22,11 +30,48 @@ module ImzML
22
30
  attr_accessor :encoded_length
23
31
  EXTERNAL_ENCODED_LENGHT = "IMS:1000104"
24
32
 
33
+ # Path to the external binary file
34
+ attr_accessor :filepath
35
+
36
+ # Binary values type [:int8, :int16, :int32, :int64, :float32, :float64]
37
+ attr_accessor :type
38
+
25
39
  # grabs the actual binary data from disk
26
- def data
40
+ def data(cached = true)
41
+
42
+ # Return the data from the cache
43
+ return @cached_data if cached && !@cached_data.nil?
44
+
45
+ # Remove possible data from the cache
46
+ @cached_data = nil
27
47
 
48
+ # Switch binary pattern reading type
49
+ pattern = case type
50
+ when :int8
51
+ "C"
52
+ when :int16
53
+ "S"
54
+ when :int32
55
+ "L"
56
+ when :int64
57
+ "Q"
58
+ when :float32
59
+ "e"
60
+ when :float64
61
+ "E"
62
+ end
63
+
64
+ # Read data based on metadata
65
+ data = IO.binread(@filepath, @encoded_length.to_i, @offset.to_i).unpack("#{pattern}*")
66
+
67
+ # Save data only if user want's to cache it, saving take some CPU
68
+ @cached_data = data if cached
28
69
  end
29
70
 
71
+ private
72
+
73
+ attr_accessor :cached_data
74
+
30
75
  end
31
76
 
32
77
  # Attributes to describe the position of a spectrum in the image.
@@ -45,6 +90,36 @@ module ImzML
45
90
  #
46
91
  # Represented by class BinaryData
47
92
  attr_accessor :intensity_binary
93
+
94
+ def intensity(at, interval)
95
+
96
+ # read whole the binary data
97
+ mz_array = mz_binary.data
98
+ intensity_array = intensity_binary.data
99
+
100
+ default_from, default_to = mz_array.first, mz_array.first
101
+
102
+ # find designated intensity
103
+ if !at
104
+ from = default_from
105
+ to = default_to
106
+ else
107
+ from = at - interval
108
+ from = default_from if from < 0
109
+ to = at + interval
110
+ to = default_to if to > mz_array.last
111
+ end
112
+
113
+ # find values in mz array
114
+ low_value = mz_array.binary_search(from, false)
115
+ low_index = mz_array.index(low_value)
116
+ high_value = mz_array.binary_search(to)
117
+ high_index = mz_array.index(high_value)
118
+
119
+ # sum all values in subarray
120
+ intensity_array[low_index..high_index].inject{|sum, x| sum + x}
121
+
122
+ end
48
123
 
49
124
 
50
125
  end
@@ -19,18 +19,6 @@ module ImzML
19
19
 
20
20
  # All mass spectra and the acquisitions underlying them are described and attached here
21
21
  attr_accessor :spectrums
22
-
23
- # Binary data types, always little endian
24
- BINARY_TYPE_8BIT_INTEGER = "IMS:1100000"
25
- BINARY_TYPE_16BIT_INTEGER = "IMS:1100001"
26
- BINARY_TYPE_32BIT_INTEGER = "MS:1000519"
27
- BINARY_TYPE_64BIT_INTEGER = "MS:1000522"
28
- BINARY_TYPE_32BIT_FLOAT = "MS:1000521"
29
- BINARY_TYPE_64BIT_FLOAT = "MS:1000523"
30
-
31
- # both can have one of the symbols [:int8, :int16, :int32, :int63, :float32, :float64]
32
- attr_accessor :mz_binary_data_type
33
- attr_accessor :intensity_binary_data_type
34
22
 
35
23
  end
36
24
  end
data/lib/imzml/parser.rb CHANGED
@@ -6,12 +6,22 @@ module ImzML
6
6
 
7
7
  attr_reader :metadata
8
8
 
9
- def initialize(filepath)
9
+ def initialize(filepath, binary_filepath = nil)
10
10
 
11
11
  sax = ImzML::Sax.new
12
+
13
+ # If no external file were specified, behave like the file has the same name
14
+ # as the metadata
15
+ if binary_filepath.nil?
16
+ name = filepath.split(".")[0..-2].join(".")
17
+ binary_filepath = [name, "ibd"].join(".")
18
+ end
19
+ sax.binary_filepath = binary_filepath
20
+
21
+ # parse the XML
12
22
  Ox.sax_parse(sax, File.open(filepath))
13
23
  @metadata = sax.metadata
14
-
24
+
15
25
  end
16
26
 
17
27
  end
@@ -19,6 +29,11 @@ module ImzML
19
29
  class Sax < ::Ox::Sax
20
30
 
21
31
  attr_reader :metadata
32
+ attr_accessor :binary_filepath
33
+
34
+ # Both can have one of the symbols [:int8, :int16, :int32, :int64, :float32, :float64]
35
+ attr_accessor :mz_binary_data_type
36
+ attr_accessor :intensity_binary_data_type
22
37
 
23
38
  def initialize()
24
39
  @metadata = Metadata.new
@@ -224,22 +239,7 @@ module ImzML
224
239
  point.y = element[:value].to_i
225
240
  end
226
241
  end
227
-
228
- # [
229
- # {:cvRef=>"IMS", :accession=>"IMS:1000401", :name=>"top down", :value=>""},
230
- # {:cvRef=>"IMS", :accession=>"IMS:1000413", :name=>"flyback", :value=>""},
231
- # {:cvRef=>"IMS", :accession=>"IMS:1000480", :name=>"horizontal line scan", :value=>""},
232
- # {:cvRef=>"IMS", :accession=>"IMS:1000491", :name=>"linescan left right", :value=>""},
233
- # {:cvRef=>"IMS", :accession=>"IMS:1000042", :name=>"max count of pixel x", :value=>"3"},
234
- # {:cvRef=>"IMS", :accession=>"IMS:1000043", :name=>"max count of pixel y", :value=>"3"},
235
- # {:cvRef=>"IMS", :accession=>"IMS:1000044", :name=>"max dimension x", :value=>"300", :unitCvRef=>"UO", :unitAccession=>"UO:0000017", :unitName=>"micrometer"},
236
- # {:cvRef=>"IMS", :accession=>"IMS:1000045", :name=>"max dimension y", :value=>"300", :unitCvRef=>"UO", :unitAccession=>"UO:0000017", :unitName=>"micrometer"},
237
- # {:cvRef=>"IMS", :accession=>"IMS:1000046", :name=>"pixel size x", :value=>"100", :unitCvRef=>"UO", :unitAccession=>"UO:0000017", :unitName=>"micrometer"},
238
- # {:cvRef=>"IMS", :accession=>"IMS:1000047", :name=>"pixel size y", :value=>"100", :unitCvRef=>"UO", :unitAccession=>"UO:0000017", :unitName=>"micrometer"},
239
- # {:cvRef=>"MS", :accession=>"MS:1000836", :name=>"dried dropplet", :value=>""},
240
- # {:cvRef=>"MS", :accession=>"MS:1000835", :name=>"matrix solution concentration", :value=>"10"},
241
- # {:cvRef=>"MS", :accession=>"MS:1000834", :name=>"matrix solution", :value=>"DHB"}
242
- # ]
242
+
243
243
  end
244
244
 
245
245
  # parse processing methods
@@ -285,23 +285,23 @@ module ImzML
285
285
  number_type = nil
286
286
  group.each do |param|
287
287
  number_type = case param[:accession]
288
- when Metadata::BINARY_TYPE_8BIT_INTEGER
288
+ when Spectrum::BinaryData::BINARY_TYPE_8BIT_INTEGER
289
289
  :int8
290
- when Metadata::BINARY_TYPE_16BIT_INTEGER
290
+ when Spectrum::BinaryData::BINARY_TYPE_16BIT_INTEGER
291
291
  :int16
292
- when Metadata::BINARY_TYPE_32BIT_INTEGER
292
+ when Spectrum::BinaryData::BINARY_TYPE_32BIT_INTEGER
293
293
  :int32
294
- when Metadata::BINARY_TYPE_64BIT_INTEGER
294
+ when Spectrum::BinaryData::BINARY_TYPE_64BIT_INTEGER
295
295
  :int64
296
- when Metadata::BINARY_TYPE_32BIT_FLOAT
296
+ when Spectrum::BinaryData::BINARY_TYPE_32BIT_FLOAT
297
297
  :float32
298
- when Metadata::BINARY_TYPE_64BIT_FLOAT
298
+ when Spectrum::BinaryData::BINARY_TYPE_64BIT_FLOAT
299
299
  :float64
300
300
  end
301
301
 
302
302
  break if !number_type.nil?
303
303
  end
304
- @metadata.send("#{@binary_type.to_s}_data_type=", number_type) if !number_type.nil?
304
+ self.send("#{@binary_type.to_s}_data_type=", number_type) if !number_type.nil?
305
305
  end
306
306
 
307
307
  # save info about binary
@@ -310,6 +310,8 @@ module ImzML
310
310
 
311
311
  # convert chosen type to mz_binary/intensity_binary property selector
312
312
  binary_data = spectrum.send(@binary_type.to_s)
313
+ binary_data.filepath = binary_filepath
314
+ binary_data.type = self.send("#{@binary_type}_data_type")
313
315
  case element[:accession]
314
316
  when ImzML::Spectrum::BinaryData::EXTERNAL_ARRAY_LENGTH
315
317
  binary_data.length = element[:value].to_i
data/lib/imzml/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module ImzML
2
2
 
3
- VERSION = "0.0.2"
3
+ VERSION = "0.1.0"
4
4
 
5
5
  end
data/lib/imzml.rb CHANGED
@@ -4,6 +4,7 @@ require "obo_ext/parser"
4
4
  require "obo_ext/stanza"
5
5
 
6
6
  require "core_ext/string"
7
+ require "core_ext/array"
7
8
 
8
9
  require "imzml/obo"
9
10
  require "imzml/metadata"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: imzml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ondra Beneš
@@ -73,6 +73,7 @@ files:
73
73
  - data/imagingMS.obo
74
74
  - data/psi-ms.obo
75
75
  - data/unit.obo
76
+ - lib/core_ext/array.rb
76
77
  - lib/core_ext/string.rb
77
78
  - lib/imzml.rb
78
79
  - lib/imzml/metadata.rb
@@ -83,7 +84,6 @@ files:
83
84
  - lib/imzml/metadata/run/spectrum.rb
84
85
  - lib/imzml/metadata/scan_settings.rb
85
86
  - lib/imzml/metadata/scan_settings/image.rb
86
- - lib/imzml/metadata/spectrum.rb
87
87
  - lib/imzml/obo.rb
88
88
  - lib/imzml/parser.rb
89
89
  - lib/imzml/version.rb
@@ -1,79 +0,0 @@
1
- module ImzML
2
-
3
- class Spectrum
4
-
5
- attr_accessor :id
6
- attr_accessor :mz_array_external_offset
7
- attr_accessor :mz_array_external_encoded_length
8
- attr_accessor :intensity_array_external_offset
9
- attr_accessor :intensity_array_external_encoded_length
10
-
11
- def intensity(data_path, at, interval)
12
-
13
- raise "Interval cannot be nil" if !interval
14
-
15
- # read array and intensity data
16
- mz_array = mz_array(data_path)
17
- intensity_array = intensity_array(data_path)
18
-
19
- default_from, default_to = mz_array.first, mz_array.first
20
-
21
- # find designated intensity
22
- if !at
23
- from = default_from
24
- to = default_to
25
- else
26
- from = at - interval
27
- from = default_from if from < 0
28
- to = at + interval
29
- to = default_to if to > mz_array.last
30
- end
31
-
32
- # find values in mz array
33
- low_value = search_binary(mz_array, from)
34
- low_index = mz_array.index(low_value)
35
- high_value = search_binary(mz_array, to)
36
- high_index = mz_array.index(high_value)
37
-
38
- # sum all values in subarray
39
- intensity_array[low_index..high_index].inject{|sum, x| sum + x}
40
- end
41
-
42
- def mz_array(data_path)
43
- IO.binread(data_path, @mz_array_external_encoded_length.to_i, @mz_array_external_offset.to_i).unpack("e*")
44
- end
45
-
46
- def intensity_array(data_path)
47
- IO.binread(data_path, @intensity_array_external_encoded_length.to_i, @intensity_array_external_offset.to_i).unpack("e*")
48
- end
49
-
50
- private
51
-
52
- def search_binary(array, value, first = true)
53
-
54
- if (array.size > 2)
55
- middle_index = array.size/2
56
- middle = array[middle_index]
57
-
58
- if (middle > value)
59
- search_binary(array[0..middle_index], value, first)
60
- else
61
- search_binary(array[middle_index..array.size], value, first)
62
- end
63
- else
64
- if first
65
- array.first
66
- else
67
- array.last
68
- end
69
- end
70
-
71
- end
72
-
73
- def search_last(array, value)
74
-
75
- end
76
-
77
- end
78
-
79
- end