Browse Source

#123: created label map object, which parses the pointers to locations in the file where data is stored

master
jim 9 years ago
parent
commit
9548b92957
2 changed files with 144 additions and 18 deletions
  1. +121
    -0
      nd2reader/model/label.py
  2. +23
    -18
      nd2reader/parser/v3.py

+ 121
- 0
nd2reader/model/label.py View File

@ -0,0 +1,121 @@
import six
import struct
from collections import namedtuple
import re
data_location = namedtuple("DataLocation", ["location", "length"])
class LabelMap(object):
"""
"""
def __init__(self, raw_binary_data):
self._data = raw_binary_data
def _get_location(self, label):
try:
label_location = self._data.index(label) + len(label)
return self._parse_data_location(label_location)
except ValueError:
return None
def _parse_data_location(self, label_location):
location, length = struct.unpack("QQ", self._data[label_location: label_location + 16])
return data_location(location=location, length=length)
@property
def image_text_info(self):
return self._get_location(six.b("ImageTextInfoLV!"))
@property
def image_metadata_sequence(self):
# there is always only one of these, even though it has a pipe followed by a zero, which is how they do indexes
return self._get_location(six.b("ImageMetadataSeqLV|0!"))
@property
def image_data(self):
image_data = {}
regex = re.compile(six.b("""ImageDataSeq\|(\d+)!"""))
for match in regex.finditer(self._data):
if match:
print(match.start(), match.end())
location = self._parse_data_location(match.end())
image_data[int(match.group(1))] = location
return image_data
@property
def image_calibration(self):
return self._get_location(six.b("ImageCalibrationLV|0!"))
@property
def image_attributes(self):
return self._get_location(six.b("ImageAttributesLV!"))
@property
def x_data(self):
return self._get_location(six.b("CustomData|X!"))
@property
def y_data(self):
return self._get_location(six.b("CustomData|Y!"))
@property
def z_data(self):
return self._get_location(six.b("CustomData|Z!"))
@property
def roi_metadata(self):
return self._get_location(six.b("CustomData|RoiMetadata_v1!"))
@property
def pfs_status(self):
return self._get_location(six.b("CustomData|PFS_STATUS!"))
@property
def pfs_offset(self):
return self._get_location(six.b("CustomData|PFS_OFFSET!"))
@property
def guid(self):
return self._get_location(six.b("CustomData|GUIDStore!"))
@property
def description(self):
return self._get_location(six.b("CustomData|CustomDescriptionV1_0!"))
@property
def camera_exposure_time(self):
return self._get_location(six.b("CustomData|Camera_ExposureTime1!"))
@property
def camera_temp(self):
return self._get_location(six.b("CustomData|CameraTemp1!"))
@property
def acquisition_times(self):
return self._get_location(six.b("CustomData|AcqTimesCache!"))
@property
def acquisition_times_2(self):
return self._get_location(six.b("CustomData|AcqTimes2Cache!"))
@property
def acquisition_frames(self):
return self._get_location(six.b("CustomData|AcqFramesCache!"))
@property
def lut_data(self):
return self._get_location(six.b("CustomDataVar|LUTDataV1_0!"))
@property
def grabber_settings(self):
return self._get_location(six.b("CustomDataVar|GrabberCameraSettingsV1_0!"))
@property
def custom_data(self):
return self._get_location(six.b("CustomDataVar|CustomDataV2_0!"))
@property
def app_info(self):
return self._get_location(six.b("CustomDataVar|AppInfo_V1_0!"))

+ 23
- 18
nd2reader/parser/v3.py View File

@ -3,6 +3,7 @@
import array
from datetime import datetime
from nd2reader.model.metadata import Metadata
from nd2reader.model.label import LabelMap
from nd2reader.parser.base import BaseParser
from nd2reader.driver.v3 import V3Driver
from nd2reader.common.v3 import read_chunk
@ -40,11 +41,7 @@ class V3Parser(BaseParser):
def driver(self):
return V3Driver(self.metadata, self._label_map, self._fh)
def _parse_metadata(self):
"""
Reads all metadata and instantiates the Metadata object.
"""
def _build_metadata_dict(self):
metadata_dict = {}
self._label_map = self._build_label_map()
for label in self._label_map.keys():
@ -52,7 +49,14 @@ class V3Parser(BaseParser):
data = read_chunk(self._fh, self._label_map[label])
stop = label.index(six.b("LV"))
metadata_dict[label[:stop]] = self._read_metadata(data, 1)
return metadata_dict
def _parse_metadata(self):
"""
Reads all metadata and instantiates the Metadata object.
"""
metadata_dict = self._build_metadata_dict()
height = metadata_dict[six.b('ImageAttributes')][six.b('SLxImageAttributes')][six.b('uiHeight')]
width = metadata_dict[six.b('ImageAttributes')][six.b('SLxImageAttributes')][six.b('uiWidth')]
channels = self._parse_channels(metadata_dict)
@ -208,23 +212,24 @@ class V3Parser(BaseParser):
:rtype: dict
"""
label_map = {}
# label_map = {}
self._fh.seek(-8, 2)
chunk_map_start_location = struct.unpack("Q", self._fh.read(8))[0]
self._fh.seek(chunk_map_start_location)
raw_text = self._fh.read(-1)
label_start = raw_text.index(V3Parser.CHUNK_MAP_START) + 32
while True:
data_start = raw_text.index(six.b("!"), label_start) + 1
key = raw_text[label_start: data_start]
location, length = struct.unpack("QQ", raw_text[data_start: data_start + 16])
if key == V3Parser.CHUNK_MAP_END:
# We've reached the end of the chunk map
break
label_map[key] = location
label_start = data_start + 16
return label_map
# label_start = raw_text.index(V3Parser.CHUNK_MAP_START) + 32
return LabelMap(raw_text)
# while True:
# data_start = raw_text.index(six.b("!"), label_start) + 1
# key = raw_text[label_start: data_start]
# location, length = struct.unpack("QQ", raw_text[data_start: data_start + 16])
# if key == V3Parser.CHUNK_MAP_END:
# # We've reached the end of the chunk map
# break
# label_map[key] = location
# label_start = data_start + 16
# return label_map
def _parse_unsigned_char(self, data):
return struct.unpack("B", data.read(1))[0]


Loading…
Cancel
Save