|
|
@ -45,9 +45,13 @@ class RawMetadata(object): |
|
|
|
"frames": self._parse_frames(), |
|
|
|
"z_levels": self._parse_z_levels(), |
|
|
|
"z_coordinates": parse_if_not_none(self.z_data, self._parse_z_coordinates), |
|
|
|
"x_coordinates": parse_if_not_none(self.x_data, self._parse_x_coordinates), |
|
|
|
"y_coordinates": parse_if_not_none(self.y_data, self._parse_y_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), |
|
|
|
"camera_stage_angle": parse_if_not_none(self.image_metadata_sequence, self._parse_camera_angle), |
|
|
|
"camera_stage_matrix": parse_if_not_none(self.image_metadata_sequence, self._parse_camera_matrix) |
|
|
|
} |
|
|
|
|
|
|
|
self._set_default_if_not_empty('fields_of_view') |
|
|
@ -195,6 +199,62 @@ class RawMetadata(object): |
|
|
|
""" |
|
|
|
return self.z_data.tolist() |
|
|
|
|
|
|
|
def _parse_x_coordinates(self): |
|
|
|
"""The coordinate in micron for all x frames. |
|
|
|
|
|
|
|
Returns: |
|
|
|
list: the x coordinates in micron |
|
|
|
""" |
|
|
|
return self.x_data.tolist() |
|
|
|
|
|
|
|
def _parse_y_coordinates(self): |
|
|
|
"""The coordinate in micron for all y frames. |
|
|
|
|
|
|
|
Returns: |
|
|
|
list: the y coordinates in micron |
|
|
|
""" |
|
|
|
return self.y_data.tolist() |
|
|
|
|
|
|
|
def _parse_camera_angle(self): |
|
|
|
if self.image_metadata_sequence is None: |
|
|
|
return [] |
|
|
|
|
|
|
|
try: |
|
|
|
metadata = self.image_metadata_sequence[six.b('SLxPictureMetadata')] |
|
|
|
except KeyError: |
|
|
|
return [] |
|
|
|
|
|
|
|
try: |
|
|
|
return metadata[b'dAngle'] |
|
|
|
except KeyError: |
|
|
|
return None |
|
|
|
|
|
|
|
def _parse_camera_matrix(self): |
|
|
|
if self.image_metadata_sequence is None: |
|
|
|
return [] |
|
|
|
|
|
|
|
try: |
|
|
|
metadata = self.image_metadata_sequence[six.b('SLxPictureMetadata')][b'sPicturePlanes'] |
|
|
|
except KeyError: |
|
|
|
return [] |
|
|
|
|
|
|
|
validity = self._get_channel_validity_list(metadata) |
|
|
|
|
|
|
|
channels = [] |
|
|
|
for valid, (label, chan) in zip(validity, sorted(metadata[b'sSampleSetting'].items())): |
|
|
|
if not valid: |
|
|
|
continue |
|
|
|
if chan[b'matCameraToStage'] is not None: |
|
|
|
mat_data = chan[b'matCameraToStage'][b'Data'] |
|
|
|
mat_rows = chan[b'matCameraToStage'][b'Rows'] |
|
|
|
mat_columns = chan[b'matCameraToStage'][b'Columns'] |
|
|
|
mat = np.frombuffer(mat_data, dtype=np.float64).reshape([mat_rows, mat_columns]) |
|
|
|
channels.append(mat) |
|
|
|
else: |
|
|
|
channels.append(None) |
|
|
|
return channels |
|
|
|
|
|
|
|
|
|
|
|
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 |
|
|
|