lib/imzml/metadata/run/spectrum.rb in imzml-0.0.2 vs lib/imzml/metadata/run/spectrum.rb in imzml-0.1.0
- old
+ new
@@ -2,10 +2,18 @@
class Spectrum
class BinaryData
+ # Binary data types, always little endian
+ BINARY_TYPE_8BIT_INTEGER = "IMS:1100000"
+ BINARY_TYPE_16BIT_INTEGER = "IMS:1100001"
+ BINARY_TYPE_32BIT_INTEGER = "MS:1000519"
+ BINARY_TYPE_64BIT_INTEGER = "MS:1000522"
+ BINARY_TYPE_32BIT_FLOAT = "MS:1000521"
+ BINARY_TYPE_64BIT_FLOAT = "MS:1000523"
+
# A data array of m/z values
MZ_ARRAY = "MS:1000514"
# A data array of intensity values
INTENSITY_ARRAY = "MS:1000515"
@@ -20,15 +28,52 @@
# Describes the length of the written data
attr_accessor :encoded_length
EXTERNAL_ENCODED_LENGHT = "IMS:1000104"
+ # Path to the external binary file
+ attr_accessor :filepath
+
+ # Binary values type [:int8, :int16, :int32, :int64, :float32, :float64]
+ attr_accessor :type
+
# grabs the actual binary data from disk
- def data
+ def data(cached = true)
+ # Return the data from the cache
+ return @cached_data if cached && !@cached_data.nil?
+
+ # Remove possible data from the cache
+ @cached_data = nil
+
+ # Switch binary pattern reading type
+ pattern = case type
+ when :int8
+ "C"
+ when :int16
+ "S"
+ when :int32
+ "L"
+ when :int64
+ "Q"
+ when :float32
+ "e"
+ when :float64
+ "E"
+ end
+
+ # Read data based on metadata
+ data = IO.binread(@filepath, @encoded_length.to_i, @offset.to_i).unpack("#{pattern}*")
+
+ # Save data only if user want's to cache it, saving take some CPU
+ @cached_data = data if cached
end
+ private
+
+ attr_accessor :cached_data
+
end
# Attributes to describe the position of a spectrum in the image.
#
# represented as Point with position x, y
@@ -43,9 +88,39 @@
# Info about intensity binary data
#
# Represented by class BinaryData
attr_accessor :intensity_binary
+
+ def intensity(at, interval)
+
+ # read whole the binary data
+ mz_array = mz_binary.data
+ intensity_array = intensity_binary.data
+
+ default_from, default_to = mz_array.first, mz_array.first
+
+ # find designated intensity
+ if !at
+ from = default_from
+ to = default_to
+ else
+ from = at - interval
+ from = default_from if from < 0
+ to = at + interval
+ to = default_to if to > mz_array.last
+ end
+
+ # find values in mz array
+ low_value = mz_array.binary_search(from, false)
+ low_index = mz_array.index(low_value)
+ high_value = mz_array.binary_search(to)
+ high_index = mz_array.index(high_value)
+
+ # sum all values in subarray
+ intensity_array[low_index..high_index].inject{|sum, x| sum + x}
+
+ end
end
end
\ No newline at end of file