From 872255c61c7b3847b5338de4599b1aa2d3904ce5 Mon Sep 17 00:00:00 2001 From: Jim Rybarski Date: Mon, 24 Nov 2014 01:11:30 -0600 Subject: [PATCH] sorta built new parser --- nd2reader/model/__init__.py | 112 +++++++++++++++++++++++++++++++++++- tests.py | 9 +++ tests/__init__.py | 0 tests/model/__init__.py | 20 +++++++ tests/service/__init__.py | 0 5 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 tests.py create mode 100644 tests/__init__.py create mode 100644 tests/model/__init__.py create mode 100644 tests/service/__init__.py diff --git a/nd2reader/model/__init__.py b/nd2reader/model/__init__.py index fcb4be0..df1ed75 100644 --- a/nd2reader/model/__init__.py +++ b/nd2reader/model/__init__.py @@ -1,6 +1,10 @@ import numpy as np import skimage.io import logging +from io import BytesIO +import array +import struct + log = logging.getLogger("nd2reader") @@ -76,9 +80,111 @@ class Image(object): skimage.io.show() -from io import BytesIO -import array -import struct +class MetadataItem(object): + def __init__(self, start, data): + self._datatype = ord(data[start]) + self._label_length = 2 * ord(data[start + 1]) + self._data = data + + @property + def is_valid(self): + return self._datatype > 0 + + @property + def key(self): + return self._data[2:self._label_length].decode("utf16").encode("utf8") + + @property + def length(self): + return self._length + + @property + def data_start(self): + return self._label_length + 2 + + @property + def _body(self): + """ + All data after the header. + + """ + return self._data[self.data_start:] + + def _get_bytes(self, count): + return self._data[self.data_start: self.data_start + count] + + @property + def value(self): + parser = {1: self._parse_unsigned_char, + 2: self._parse_unsigned_int, + 3: self._parse_unsigned_int, + 5: self._parse_unsigned_long, + 6: self._parse_double, + 8: self._parse_string, + 9: self._parse_char_array, + } + return parser[self._datatype]() + + def _parse_unsigned_char(self): + self._length = 1 + return self._unpack("B", self._get_bytes(self._length)) + + def _parse_unsigned_int(self): + self._length = 4 + return self._unpack("I", self._get_bytes(self._length)) + + def _parse_unsigned_long(self): + self._length = 8 + return self._unpack("Q", self._get_bytes(self._length)) + + def _parse_double(self): + self._length = 8 + return self._unpack("d", self._get_bytes(self._length)) + + def _parse_string(self): + # the string is of unknown length but ends at the first instance of \x00\x00 + stop = self._body.index("\x00\x00") + self._length = stop + return self._body[:stop - 1].decode("utf16").encode("utf8") + + def _parse_char_array(self): + array_length = self._unpack("Q", self._get_bytes(8)) + self._length = array_length + 8 + return array.array("B", self._body[8:array_length]) + + def _parse_metadata_item(self): + count, length = struct.unpack("