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 +4 -4
- data/lib/core_ext/array.rb +23 -0
- data/lib/imzml/metadata/run/spectrum.rb +76 -1
- data/lib/imzml/metadata.rb +0 -12
- data/lib/imzml/parser.rb +27 -25
- data/lib/imzml/version.rb +1 -1
- data/lib/imzml.rb +1 -0
- metadata +2 -2
- data/lib/imzml/metadata/spectrum.rb +0 -79
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f7be2442cc6f7ce7a1503a2a7c5380c9509043b2
|
4
|
+
data.tar.gz: f76e6a4ff83c1335b90389d6ea6348a2df7a3656
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
data/lib/imzml/metadata.rb
CHANGED
@@ -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
|
288
|
+
when Spectrum::BinaryData::BINARY_TYPE_8BIT_INTEGER
|
289
289
|
:int8
|
290
|
-
when
|
290
|
+
when Spectrum::BinaryData::BINARY_TYPE_16BIT_INTEGER
|
291
291
|
:int16
|
292
|
-
when
|
292
|
+
when Spectrum::BinaryData::BINARY_TYPE_32BIT_INTEGER
|
293
293
|
:int32
|
294
|
-
when
|
294
|
+
when Spectrum::BinaryData::BINARY_TYPE_64BIT_INTEGER
|
295
295
|
:int64
|
296
|
-
when
|
296
|
+
when Spectrum::BinaryData::BINARY_TYPE_32BIT_FLOAT
|
297
297
|
:float32
|
298
|
-
when
|
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
|
-
|
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
data/lib/imzml.rb
CHANGED
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
|
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
|