def test_metainfo_from_h5(self): shape = (3, 9, 10, 11) starting_metadata = VoxelsMetadata.create_default_metadata( shape, numpy.float32, "cxyz", 1.0, "nanometers" ) f = h5py.File("dummy.h5", mode='w', driver='core', backing_store=False) # In-memory dset = f.create_dataset( 'dset', shape=shape, dtype=numpy.float32, chunks=True ) metadata = VoxelsMetadata.create_from_h5_dataset( dset ) assert metadata.dtype.type is numpy.float32 assert metadata.shape == starting_metadata.shape, \ "Wrong shape: {} vs. {}".format( metadata.shape, starting_metadata.shape )
def test_basic_roundtrip(self): data = numpy.random.randint(0,255, (3, 100, 200)).astype(numpy.uint8) metadata = VoxelsMetadata.create_default_metadata(data.shape, data.dtype, 'cxy', 1.0, "nanometers") codec = VoxelsNddataCodec( metadata ) stream = StringIO.StringIO() codec.encode_from_ndarray(stream, data) stream.seek(0) roundtrip_data = codec.decode_to_ndarray(stream, data.shape) assert roundtrip_data.flags['F_CONTIGUOUS'] self._assert_matching(roundtrip_data, data)
def test_metainfo_from_h5(self): shape = (3, 9, 10, 11) starting_metadata = VoxelsMetadata.create_default_metadata( shape, numpy.float32, "cxyz", 1.0, "nanometers") f = h5py.File("dummy.h5", mode='w', driver='core', backing_store=False) # In-memory dset = f.create_dataset('dset', shape=shape, dtype=numpy.float32, chunks=True) metadata = VoxelsMetadata.create_from_h5_dataset(dset) assert metadata.dtype.type is numpy.float32 assert metadata.shape == starting_metadata.shape, \ "Wrong shape: {} vs. {}".format( metadata.shape, starting_metadata.shape )
def test_create_default_metadata(self): metadata = VoxelsMetadata.create_default_metadata( (2,10,11), numpy.int64, "cxy", 1.5, "nanometers" ) metadata["Properties"]["Values"][0]["Label"] = "R" metadata["Properties"]["Values"][1]["Label"] = "G" assert len( metadata["Axes"] ) == 2 assert metadata["Axes"][0]["Label"] == "X" assert metadata["Axes"][0]["Size"] == 10 assert metadata["Axes"][1]["Label"] == "Y" assert metadata["Axes"][1]["Size"] == 11 assert len(metadata["Properties"]["Values"]) == 2 # 2 channels assert metadata["Properties"]["Values"][0]["DataType"] == "int64" assert metadata["Properties"]["Values"][1]["DataType"] == "int64" assert metadata["Properties"]["Values"][0]["Label"] == "R" assert metadata["Properties"]["Values"][1]["Label"] == "G"
def test_create_default_metadata(self): metadata = VoxelsMetadata.create_default_metadata( (2, 10, 11), numpy.int64, "cxy", 1.5, "nanometers") metadata["Properties"]["Values"][0]["Label"] = "R" metadata["Properties"]["Values"][1]["Label"] = "G" assert len(metadata["Axes"]) == 2 assert metadata["Axes"][0]["Label"] == "X" assert metadata["Axes"][0]["Size"] == 10 assert metadata["Axes"][1]["Label"] == "Y" assert metadata["Axes"][1]["Size"] == 11 assert len(metadata["Properties"]["Values"]) == 2 # 2 channels assert metadata["Properties"]["Values"][0]["DataType"] == "int64" assert metadata["Properties"]["Values"][1]["DataType"] == "int64" assert metadata["Properties"]["Values"][0]["Label"] == "R" assert metadata["Properties"]["Values"][1]["Label"] == "G"
def _get_format_selection_error_msg(self, *args): """ If the currently selected format does not support the input image format, return an error message stating why. Otherwise, return an empty string. """ if not self.Input.ready(): return "Input not ready" output_format = self.OutputFormat.value # These cases support all combinations if output_format in ('hdf5', 'npy', 'blockwise hdf5'): return "" tagged_shape = self.Input.meta.getTaggedShape() axes = OpStackWriter.get_nonsingleton_axes_for_tagged_shape( tagged_shape ) output_dtype = self.Input.meta.dtype if output_format == 'dvid': # dvid requires a channel axis, which must come last. # Internally, we transpose it before sending it over the wire if tagged_shape.keys()[-1] != 'c': return "DVID requires the last axis to be channel." # Make sure DVID supports this dtype/channel combo. from pydvid.voxels import VoxelsMetadata axiskeys = self.Input.meta.getAxisKeys() # We reverse the axiskeys because the export operator (see below) uses transpose_axes=True reverse_axiskeys = "".join(reversed( axiskeys )) reverse_shape = tuple(reversed(self.Input.meta.shape)) metainfo = VoxelsMetadata.create_default_metadata( reverse_shape, output_dtype, reverse_axiskeys, 0.0, 'nanometers' ) try: metainfo.determine_dvid_typename() except Exception as ex: return str(ex) else: return "" return FormatValidity.check(self.Input.meta.getTaggedShape(), self.Input.meta.dtype, output_format)
def _get_format_selection_error_msg(self, *args): """ If the currently selected format does not support the input image format, return an error message stating why. Otherwise, return an empty string. """ if not self.Input.ready(): return "Input not ready" output_format = self.OutputFormat.value # These cases support all combinations if output_format in ('hdf5', 'npy', 'blockwise hdf5'): return "" tagged_shape = self.Input.meta.getTaggedShape() axes = OpStackWriter.get_nonsingleton_axes_for_tagged_shape( tagged_shape) output_dtype = self.Input.meta.dtype if output_format == 'dvid': # dvid requires a channel axis, which must come last. # Internally, we transpose it before sending it over the wire if tagged_shape.keys()[-1] != 'c': return "DVID requires the last axis to be channel." # Make sure DVID supports this dtype/channel combo. from pydvid.voxels import VoxelsMetadata axiskeys = self.Input.meta.getAxisKeys() # We reverse the axiskeys because the export operator (see below) uses transpose_axes=True reverse_axiskeys = "".join(reversed(axiskeys)) reverse_shape = tuple(reversed(self.Input.meta.shape)) metainfo = VoxelsMetadata.create_default_metadata( reverse_shape, output_dtype, reverse_axiskeys, 0.0, 'nanometers') try: metainfo.determine_dvid_typename() except Exception as ex: return str(ex) else: return "" return FormatValidity.check(self.Input.meta.getTaggedShape(), self.Input.meta.dtype, output_format)
def _get_format_selection_error_msg(self, *args): """ If the currently selected format does not support the input image format, return an error message stating why. Otherwise, return an empty string. """ if not self.Input.ready(): return "Input not ready" output_format = self.OutputFormat.value # These cases support all combinations if output_format in ('hdf5', 'npy'): return "" tagged_shape = self.Input.meta.getTaggedShape() axes = OpStackWriter.get_nonsingleton_axes_for_tagged_shape( tagged_shape ) output_dtype = self.Input.meta.dtype if output_format == 'dvid': # dvid requires a channel axis, which must come last. # Internally, we transpose it before sending it over the wire if tagged_shape.keys()[-1] != 'c': return "DVID requires the last axis to be channel." # Make sure DVID supports this dtype/channel combo. from pydvid.voxels import VoxelsMetadata axiskeys = self.Input.meta.getAxisKeys() # We reverse the axiskeys because the export operator (see below) uses transpose_axes=True reverse_axiskeys = "".join(reversed( axiskeys )) reverse_shape = tuple(reversed(self.Input.meta.shape)) metainfo = VoxelsMetadata.create_default_metadata( reverse_shape, output_dtype, reverse_axiskeys, 0.0, 'nanometers' ) try: metainfo.determine_dvid_typename() except Exception as ex: return str(ex) else: return "" # None of the remaining formats support more than 4 channels. if 'c' in tagged_shape and tagged_shape['c'] > 4 and not filter(lambda fmt: fmt.name == output_format, self._3d_sequence_formats): return "Too many channels." # HDR format supports float32 only, and must have exactly 3 channels if output_format == 'hdr' or output_format == 'hdr sequence': if output_dtype == numpy.float32 and\ 'c' in tagged_shape and tagged_shape['c'] == 3: return "" else: return "HDR volumes must be float32, with exactly 3 channels." # Apparently, TIFF supports everything but signed byte if 'tif' in output_format and output_dtype == numpy.int8: return "TIF output does not support signed byte (int8). Try unsigned (uint8)." # Apparently, these formats support everything except uint32 # See http://github.com/ukoethe/vigra/issues/153 if output_dtype == numpy.uint32 and \ ( 'pbm' in output_format or \ 'pgm' in output_format or \ 'pnm' in output_format or \ 'ppm' in output_format ): return "PBM/PGM/PNM/PPM do not support the uint32 pixel type." # These formats don't support 2 channels (must be either 1 or 3) non_dualband_formats = ['bmp', 'gif', 'jpg', 'jpeg', 'ras'] for fmt in non_dualband_formats: if fmt in output_format and axes[0] != 'c' and 'c' in tagged_shape: if 'c' in tagged_shape and tagged_shape['c'] != 1 and tagged_shape['c'] != 3: return "Invalid number of channels (must be exactly 1 or 3)." # 2D formats only support 2D images (singleton/channel axes excepted) if filter(lambda fmt: fmt.name == output_format, self._2d_formats): # Examples: # OK: 'xy', 'xyc' # NOT OK: 'xc', 'xyz' nonchannel_axes = filter(lambda a: a != 'c', axes) if len(nonchannel_axes) == 2: return "" else: return "Input has too many dimensions for a 2D output format." nonstep_axes = axes[1:] nonchannel_axes = filter( lambda a: a != 'c', nonstep_axes ) # 3D sequences of 2D images require a 3D image # (singleton/channel axes excepted, unless channel is the 'step' axis) if filter(lambda fmt: fmt.name == output_format, self._3d_sequence_formats)\ or output_format == 'multipage tiff': # Examples: # OK: 'xyz', 'xyzc', 'cxy' # NOT OK: 'cxyz' if len(nonchannel_axes) == 2: return "" else: return "Can't export 3D stack: Input is not 3D or axis are in the wrong order." # 4D sequences of 3D images require a 4D image # (singleton/channel axes excepted, unless channel is the 'step' axis) if output_format == 'multipage tiff sequence': # Examples: # OK: 'txyz', 'txyzc', 'cxyz' # NOT OK: 'xyzc', 'xyz', 'xyc' if len(nonchannel_axes) == 3: return "" else: return "Can't export 4D stack: Input is not 4D." assert False, "Unknown format case: {}".format( output_format )
def _get_format_selection_error_msg(self, *args): """ If the currently selected format does not support the input image format, return an error message stating why. Otherwise, return an empty string. """ if not self.Input.ready(): return "Input not ready" output_format = self.OutputFormat.value # These cases support all combinations if output_format in ('hdf5', 'npy'): return "" tagged_shape = self.Input.meta.getTaggedShape() axes = OpStackWriter.get_nonsingleton_axes_for_tagged_shape( tagged_shape) output_dtype = self.Input.meta.dtype if output_format == 'dvid': # dvid requires a channel axis, which must come last. # Internally, we transpose it before sending it over the wire if tagged_shape.keys()[-1] != 'c': return "DVID requires the last axis to be channel." # Make sure DVID supports this dtype/channel combo. from pydvid.voxels import VoxelsMetadata axiskeys = self.Input.meta.getAxisKeys() # We reverse the axiskeys because the export operator (see below) uses transpose_axes=True reverse_axiskeys = "".join(reversed(axiskeys)) reverse_shape = tuple(reversed(self.Input.meta.shape)) metainfo = VoxelsMetadata.create_default_metadata( reverse_shape, output_dtype, reverse_axiskeys, 0.0, 'nanometers') try: metainfo.determine_dvid_typename() except Exception as ex: return str(ex) else: return "" # None of the remaining formats support more than 4 channels. if 'c' in tagged_shape and tagged_shape['c'] > 4 and not filter( lambda fmt: fmt.name == output_format, self._3d_sequence_formats): return "Too many channels." # HDR format supports float32 only, and must have exactly 3 channels if output_format == 'hdr' or output_format == 'hdr sequence': if output_dtype == numpy.float32 and\ 'c' in tagged_shape and tagged_shape['c'] == 3: return "" else: return "HDR volumes must be float32, with exactly 3 channels." # Apparently, TIFF supports everything but signed byte if 'tif' in output_format and output_dtype == numpy.int8: return "TIF output does not support signed byte (int8). Try unsigned (uint8)." # Apparently, these formats support everything except uint32 # See http://github.com/ukoethe/vigra/issues/153 if output_dtype == numpy.uint32 and \ ( 'pbm' in output_format or \ 'pgm' in output_format or \ 'pnm' in output_format or \ 'ppm' in output_format ): return "PBM/PGM/PNM/PPM do not support the uint32 pixel type." # These formats don't support 2 channels (must be either 1 or 3) non_dualband_formats = ['bmp', 'gif', 'jpg', 'jpeg', 'ras'] for fmt in non_dualband_formats: if fmt in output_format and axes[0] != 'c' and 'c' in tagged_shape: if 'c' in tagged_shape and tagged_shape[ 'c'] != 1 and tagged_shape['c'] != 3: return "Invalid number of channels (must be exactly 1 or 3)." # 2D formats only support 2D images (singleton/channel axes excepted) if filter(lambda fmt: fmt.name == output_format, self._2d_formats): # Examples: # OK: 'xy', 'xyc' # NOT OK: 'xc', 'xyz' nonchannel_axes = filter(lambda a: a != 'c', axes) if len(nonchannel_axes) == 2: return "" else: return "Input has too many dimensions for a 2D output format." nonstep_axes = axes[1:] nonchannel_axes = filter(lambda a: a != 'c', nonstep_axes) # 3D sequences of 2D images require a 3D image # (singleton/channel axes excepted, unless channel is the 'step' axis) if filter(lambda fmt: fmt.name == output_format, self._3d_sequence_formats)\ or output_format == 'multipage tiff': # Examples: # OK: 'xyz', 'xyzc', 'cxy' # NOT OK: 'cxyz' if len(nonchannel_axes) == 2: return "" else: return "Can't export 3D stack: Input is not 3D or axis are in the wrong order." # 4D sequences of 3D images require a 4D image # (singleton/channel axes excepted, unless channel is the 'step' axis) if output_format == 'multipage tiff sequence': # Examples: # OK: 'txyz', 'txyzc', 'cxyz' # NOT OK: 'xyzc', 'xyz', 'xyc' if len(nonchannel_axes) == 3: return "" else: return "Can't export 4D stack: Input is not 4D." assert False, "Unknown format case: {}".format(output_format)