Browse Source

resolves #39

feature/load_slices
Jim Rybarski 10 years ago
parent
commit
89ddce3a7b
3 changed files with 39 additions and 55 deletions
  1. +37
    -53
      nd2reader/__init__.py
  2. +1
    -1
      nd2reader/parser.py
  3. +1
    -1
      setup.py

+ 37
- 53
nd2reader/__init__.py View File

@ -34,64 +34,20 @@ class Nd2(Nd2Parser):
"""
return self._image_count * self._channel_count
@property
def height(self):
"""
:return: height of each image, in pixels
:rtype: int
"""
return self.metadata[six.b('ImageAttributes')][six.b('SLxImageAttributes')][six.b('uiHeight')]
@property
def width(self):
"""
:return: width of each image, in pixels
:rtype: int
"""
return self.metadata[six.b('ImageAttributes')][six.b('SLxImageAttributes')][six.b('uiWidth')]
def __iter__(self):
"""
Iterates over every image, in the order they were taken.
:return: model.Image()
"""
for i in range(self._image_count):
for fov in self._fields_of_view:
for z_level in self._z_levels:
for channel_name in self._channels:
image = self.get_image(i, fov, channel_name, z_level)
if image is not None:
yield image
def __getitem__(self, item):
if isinstance(item, int):
def __getitem__(self, frame_number):
if isinstance(frame_number, int):
try:
channel_offset = item % len(self.channels)
fov = self._calculate_field_of_view(item)
channel = self._calculate_channel(item)
z_level = self._calculate_z_level(item)
item -= channel_offset
item /= len(self.channels)
timestamp, raw_image_data = self._get_raw_image_data(item, channel_offset)
channel_offset = frame_number % len(self.channels)
fov = self._calculate_field_of_view(frame_number)
channel = self._calculate_channel(frame_number)
z_level = self._calculate_z_level(frame_number)
timestamp, raw_image_data = self._get_raw_image_data(frame_number, channel_offset)
image = Image(timestamp, raw_image_data, fov, channel, z_level, self.height, self.width)
except TypeError:
except (TypeError, ValueError):
return None
else:
return image
def _calculate_field_of_view(self, frame_number):
return int((frame_number - (frame_number % (len(self.z_levels) * len(self.channels)))) / (len(self.z_levels) * len(self.channels)))
def _calculate_channel(self, frame_number):
return self._channels[frame_number % len(self.channels)]
def _calculate_z_level(self, frame_number):
return self.z_levels[int(((frame_number - (frame_number % len(self.channels))) / 2) % len(self.z_levels))]
@property
def image_sets(self):
"""
@ -103,7 +59,7 @@ class Nd2(Nd2Parser):
:return: model.ImageSet()
"""
for time_index in self._time_indexes:
for time_index in self.time_indexes:
image_set = ImageSet()
for fov in self._fields_of_view:
for channel_name in self._channels:
@ -113,6 +69,34 @@ class Nd2(Nd2Parser):
image_set.add(image)
yield image_set
@property
def height(self):
"""
:return: height of each image, in pixels
:rtype: int
"""
return self.metadata[six.b('ImageAttributes')][six.b('SLxImageAttributes')][six.b('uiHeight')]
@property
def width(self):
"""
:return: width of each image, in pixels
:rtype: int
"""
return self.metadata[six.b('ImageAttributes')][six.b('SLxImageAttributes')][six.b('uiWidth')]
def _calculate_field_of_view(self, frame_number):
images_per_cycle = len(self.z_levels) * len(self.channels)
return int((frame_number - (frame_number % images_per_cycle)) / images_per_cycle) % len(self.fields_of_view)
def _calculate_channel(self, frame_number):
return self._channels[frame_number % len(self.channels)]
def _calculate_z_level(self, frame_number):
return self.z_levels[int(((frame_number - (frame_number % len(self.channels))) / len(self.channels)) % len(self.z_levels))]
def get_image(self, time_index, field_of_view, channel_name, z_level):
"""
Returns an Image if data exists for the given parameters, otherwise returns None. In general, you should avoid


+ 1
- 1
nd2reader/parser.py View File

@ -63,7 +63,7 @@ class Nd2Parser(object):
# The images for the various channels are interleaved within the same array. For example, the second image
# of a four image group will be composed of bytes 2, 6, 10, etc. If you understand why someone would design
# a data structure that way, please send the author of this library a message.
image_data = image_group_data[image_data_start::self._channel_count]
image_data = image_group_data[image_data_start::len(self.channels)]
# Skip images that are all zeros! This is important, since NIS Elements creates blank "gap" images if you
# don't have the same number of images each cycle. We discovered this because we only took GFP images every
# other cycle to reduce phototoxicity, but NIS Elements still allocated memory as if we were going to take


+ 1
- 1
setup.py View File

@ -1,6 +1,6 @@
from distutils.core import setup
VERSION = "1.0.1"
VERSION = "1.1.0"
setup(
name="nd2reader",


Loading…
Cancel
Save