imzml 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|