Browse Source

Merge branch 'master' of github.com:rbnvrw/nd2reader

feature/load_slices
Ruben Verweij 5 years ago
parent
commit
c9a1e13936
4 changed files with 33 additions and 18 deletions
  1. +0
    -11
      nd2reader/exceptions.py
  2. +11
    -4
      nd2reader/parser.py
  3. +17
    -3
      nd2reader/raw_metadata.py
  4. +5
    -0
      nd2reader/reader.py

+ 0
- 11
nd2reader/exceptions.py View File

@ -6,17 +6,6 @@ class InvalidVersionError(Exception):
"""
pass
class NoImageError(Exception):
"""No image found.
Some apparent images in ND2s are just completely blank placeholders. These are used when the number of images per
cycle are unequal (e.g. if you take fluorescent images every 2 minutes, and bright field images every minute).
"""
pass
class EmptyFileError(Exception):
"""This .nd2 file seems to be empty.


+ 11
- 4
nd2reader/parser.py View File

@ -3,11 +3,12 @@ import struct
import array
import six
import warnings
from pims.base_frames import Frame
import numpy as np
from nd2reader.common import get_version, read_chunk
from nd2reader.exceptions import InvalidVersionError, NoImageError
from nd2reader.exceptions import InvalidVersionError
from nd2reader.label_map import LabelMap
from nd2reader.raw_metadata import RawMetadata
@ -72,7 +73,7 @@ class Parser(object):
try:
timestamp, image = self._get_raw_image_data(image_group_number, channel_offset, self.metadata["height"],
self.metadata["width"])
except (TypeError, NoImageError):
except (TypeError):
return Frame([], frame_no=frame_number, metadata=self._get_frame_metadata())
else:
return image
@ -101,7 +102,7 @@ class Parser(object):
try:
timestamp, raw_image_data = self._get_raw_image_data(image_group_number, channel,
height, width)
except (TypeError, NoImageError):
except (TypeError):
return Frame([], frame_no=frame_number, metadata=self._get_frame_metadata())
else:
return raw_image_data
@ -140,6 +141,7 @@ class Parser(object):
self._label_map = self._build_label_map()
self._raw_metadata = RawMetadata(self._fh, self._label_map)
self.metadata = self._raw_metadata.__dict__
self.acquisition_times = self._raw_metadata.acquisition_times
def _build_label_map(self):
"""
@ -283,7 +285,12 @@ class Parser(object):
if np.any(image_data):
return timestamp, Frame(image_data, metadata=self._get_frame_metadata())
raise NoImageError
# If a blank "gap" image is encountered, generate an array of corresponding height and width to avoid
# errors with ND2-files with missing frames. Array is filled with nan to reflect that data is missing.
else:
empty_frame = np.full((height, width), np.nan)
warnings.warn('ND2 file contains gap frames which are represented by np.nan-filled arrays; to convert to zeros use e.g. np.nan_to_num(array)')
return timestamp, Frame(empty_frame, metadata=self._get_frame_metadata())
def _get_frame_metadata(self):
"""Get the metadata for one frame


+ 17
- 3
nd2reader/raw_metadata.py View File

@ -43,9 +43,10 @@ class RawMetadata(object):
"fields_of_view": self._parse_fields_of_view(),
"frames": self._parse_frames(),
"z_levels": self._parse_z_levels(),
"z_coordinates": parse_if_not_none(self.z_data, self._parse_z_coordinates),
"total_images_per_channel": frames_per_channel,
"channels": self._parse_channels(),
"pixel_microns": parse_if_not_none(self.image_calibration, self._parse_calibration),
"pixel_microns": parse_if_not_none(self.image_calibration, self._parse_calibration)
}
self._set_default_if_not_empty('fields_of_view')
@ -161,6 +162,14 @@ class RawMetadata(object):
"""
return self._parse_dimension(r""".*?Z\((\d+)\).*?""")
def _parse_z_coordinates(self):
"""The coordinate in micron for all z planes.
Returns:
list: the z coordinates in micron
"""
return self.z_data.tolist()
def _parse_dimension_text(self):
"""While there are metadata values that represent a lot of what we want to capture, they seem to be unreliable.
Sometimes certain elements don't exist, or change their data type randomly. However, the human-readable text
@ -193,7 +202,7 @@ class RawMetadata(object):
if not match:
return []
count = int(match.group(1))
return list(range(count))
return range(count)
def _parse_total_images_per_channel(self):
"""The total number of images per channel.
@ -492,7 +501,12 @@ class RawMetadata(object):
Returns:
dict: z_data
"""
return read_array(self._fh, 'double', self._label_map.z_data)
try:
return read_array(self._fh, 'double', self._label_map.z_data)
except ValueError:
# Depending on the file format/exact settings, this value is
# sometimes saved as float instead of double
return read_array(self._fh, 'float', self._label_map.z_data)
@property
def roi_metadata(self):


+ 5
- 0
nd2reader/reader.py View File

@ -52,6 +52,11 @@ class ND2Reader(FramesSequenceND):
except KeyError:
return 0
def get_frame_2D(self, c=0, t=0, z=0, x=0, y=0, v=0):
"""Fallback function for backwards compatibility
"""
return get_frame_vczyx(v=v, c=c, t=t, z=z, x=x, y=y)
def get_frame_vczyx(self, v=None, c=None, t=None, z=None, x=None, y=None):
x = self.metadata["width"] if x <= 0 else x
y = self.metadata["height"] if y <= 0 else y


Loading…
Cancel
Save