diff --git a/nd2reader/model/roi.py b/nd2reader/model/roi.py index 23c0f04..6488575 100644 --- a/nd2reader/model/roi.py +++ b/nd2reader/model/roi.py @@ -5,19 +5,31 @@ import numpy as np class Roi(object): """ A ND2 ROI representation. - Coordinates are the center coordinates of the ROI in (x, y, z) order. - Sizes are the sizes of the ROI in (x, y, z) order. + Coordinates are the center coordinates of the ROI in (x, y, z) order in micron. + Sizes are the sizes of the ROI in (x, y, z) order in micron. Shapes are represented by numbers, defined by constants in this class. - All these properties can be set for multiple timepoints. + All these properties can be set for multiple time points (in ms). """ SHAPE_RECTANGLE = 3 SHAPE_CIRCLE = 9 - def __init__(self, raw_roi_dict): + TYPE_BACKGROUND = 2 + + def __init__(self, raw_roi_dict, metadata): + """ + + :param raw_roi_dict: + :param metadata + """ self.timepoints = [] self.positions = [] self.sizes = [] - self.shapes = [] + self.shape = self.SHAPE_CIRCLE + self.type = self.TYPE_BACKGROUND + + self._width_micron = metadata.width * metadata.pixel_microns + self._height_micron = metadata.height * metadata.pixel_microns + self._pixel_microns = metadata.pixel_microns self._extract_vect_anims(raw_roi_dict) @@ -31,33 +43,37 @@ class Roi(object): number_of_timepoints = raw_roi_dict[six.b('m_vectAnimParams_Size')] for i in range(number_of_timepoints): - shape = raw_roi_dict[six.b('m_sInfo')][six.b('m_uiShapeType')] - self._parse_vect_anim(raw_roi_dict[six.b('m_vectAnimParams_%d') % i], shape) + self._parse_vect_anim(raw_roi_dict[six.b('m_vectAnimParams_%d') % i]) + + self.shape = raw_roi_dict[six.b('m_sInfo')][six.b('m_uiShapeType')] + self.type = raw_roi_dict[six.b('m_sInfo')][six.b('m_uiInterpType')] # convert to NumPy arrays self.timepoints = np.array(self.timepoints, dtype=np.float) self.positions = np.array(self.positions, dtype=np.float) self.sizes = np.array(self.sizes, dtype=np.float) - self.shapes = np.array(self.shapes, dtype=np.uint) - def _parse_vect_anim(self, animation_dict, shape): + def _parse_vect_anim(self, animation_dict): """ Parses a ROI vector animation object and adds it to the global list of timepoints and positions. :param animation_dict: :return: """ self.timepoints.append(animation_dict[six.b('m_dTimeMs')]) - self.positions.append((animation_dict[six.b('m_dCenterX')], - animation_dict[six.b('m_dCenterY')], - animation_dict[six.b('m_dCenterZ')])) + + position = np.array((self._width_micron / 2.0 + animation_dict[six.b('m_dCenterX')], + self._height_micron / 2.0 + animation_dict[six.b('m_dCenterY')], + animation_dict[six.b('m_dCenterZ')])) + self.positions.append(position) + size_dict = animation_dict[six.b('m_sBoxShape')] + self.sizes.append((size_dict[six.b('m_dSizeX')], size_dict[six.b('m_dSizeY')], size_dict[six.b('m_dSizeZ')])) - self.shapes.append(shape) - def is_circle(self, timepoint_id=0): - return self.shapes[timepoint_id] == self.SHAPE_CIRCLE + def is_circle(self): + return self.shape == self.SHAPE_CIRCLE - def is_rectangle(self, timepoint_id=0): - return self.shapes[timepoint_id] == self.SHAPE_RECTANGLE + def is_rectangle(self): + return self.shape == self.SHAPE_RECTANGLE diff --git a/nd2reader/parser/v3.py b/nd2reader/parser/v3.py index e7990a7..3898c3e 100644 --- a/nd2reader/parser/v3.py +++ b/nd2reader/parser/v3.py @@ -324,7 +324,7 @@ class V3Parser(BaseParser): roi_objects = [] for i in range(number_of_rois): current_roi = raw_roi_data[six.b('m_vectGlobal_%d' % i)] - roi_objects.append(Roi(current_roi)) + roi_objects.append(Roi(current_roi, self.metadata)) self.roi_metadata = roi_objects