def test_Writer(self): opData = OpArrayCache( graph=self.graph ) opData.blockShape.setValue( self.testData.shape ) opData.Input.setValue( self.testData ) opWriter = OpStackWriter(graph=self.graph) opWriter.FilepathPattern.setValue( self._stack_filepattern ) opWriter.Input.connect( opData.Output ) #opWriter.Input.setValue( self.testData ) opWriter.SliceIndexOffset.setValue(22) # Run the export opWriter.run_export() globstring = self._stack_filepattern.format( slice_index=999 ) globstring = globstring.replace('999', '*') opReader = OpStackLoader( graph=self.graph ) opReader.globstring.setValue( globstring ) # (The OpStackLoader produces txyzc order.) opReorderAxes = OpReorderAxes( graph=self.graph ) opReorderAxes.AxisOrder.setValue( self._axisorder ) opReorderAxes.Input.connect( opReader.stack ) readData = opReorderAxes.Output[:].wait() logger.debug("Expected shape={}".format( self.testData.shape ) ) logger.debug("Read shape={}".format( readData.shape ) ) assert opReorderAxes.Output.meta.shape == self.testData.shape, "Exported files were of the wrong shape or number." assert (opReorderAxes.Output[:].wait() == self.testData.view( numpy.ndarray )).all(), "Exported data was not correct"
def _updateDescription(self, *args): if not self._imageSlot.ready(): self.descriptionLabel.setText("") return tagged_shape = self._imageSlot.meta.getTaggedShape() axes = OpStackWriter.get_nonsingleton_axes_for_tagged_shape(tagged_shape) step_axis = axes[0].upper() image_axes = "".join(axes[1:]).upper() description = "{} {} Images (Stacked across {})".format( tagged_shape[axes[0]], image_axes, step_axis ) self.descriptionLabel.setText( description )
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", "compressed hdf5", "n5", "compressed n5", "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 list(tagged_shape.keys())[-1] != "c": return "DVID requires the last axis to be channel." # Make sure DVID supports this dtype/channel combo. from libdvid.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 libdvid.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 _export_3d_sequence(self, extension): self.progressSignal(0) export_path_base, export_path_ext = os.path.splitext( self.ExportPath.value ) export_path_pattern = export_path_base + "." + extension try: opWriter = OpStackWriter( parent=self ) opWriter.FilepathPattern.setValue( export_path_pattern ) opWriter.Input.connect( self.Input ) opWriter.progressSignal.subscribe( self.progressSignal ) if self.CoordinateOffset.ready(): step_axis = opWriter.get_nonsingleton_axes()[0] step_axis_index = self.Input.meta.getAxisKeys().index(step_axis) step_axis_offset = self.CoordinateOffset.value[step_axis_index] opWriter.SliceIndexOffset.setValue( step_axis_offset ) # Run the export opWriter.run_export() finally: opWriter.cleanUp() self.progressSignal(100)
def _is_format_selection_valid(self, *args): """ Return True if the currently selected format is valid to export the current input dataset """ if not self.Input.ready(): return False output_format = self.OutputFormat.value # hdf5 and npy support all combinations if output_format == 'hdf5' or output_format == 'npy': return True tagged_shape = self.Input.meta.getTaggedShape() axes = OpStackWriter.get_nonsingleton_axes_for_tagged_shape( tagged_shape ) output_dtype = self.Input.meta.dtype # None of the remaining formats support more than 4 channels. if 'c' in tagged_shape and tagged_shape['c'] > 4: return False # HDR format supports float32 only, and must have exactly 3 channels if output_format == 'hdr' or output_format == 'hdr sequence': return output_dtype == numpy.float32 and \ 'c' in tagged_shape and tagged_shape['c'] == 3 # Apparently, TIFF supports everything but signed byte if 'tif' in output_format and output_dtype == numpy.int8: return False # 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 False # 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 False # 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) return len(nonchannel_axes) == 2 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' return len(nonchannel_axes) == 2 # 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' return len(nonchannel_axes) == 3 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 )
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 _is_format_selection_valid(self, *args): """ Return True if the currently selected format is valid to export the current input dataset """ if not self.Input.ready(): return False output_format = self.OutputFormat.value # These cases support all combinations if output_format in ('hdf5', 'npy'): return True 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 False # Make sure DVID supports this dtype/channel combo. from pydvid.volume_metainfo import MetaInfo metainfo = MetaInfo(self.Input.meta.shape, output_dtype, self.Input.meta.axistags) try: metainfo.determine_dvid_typename() except: return False else: return True # None of the remaining formats support more than 4 channels. if 'c' in tagged_shape and tagged_shape['c'] > 4: return False # HDR format supports float32 only, and must have exactly 3 channels if output_format == 'hdr' or output_format == 'hdr sequence': return output_dtype == numpy.float32 and \ 'c' in tagged_shape and tagged_shape['c'] == 3 # Apparently, TIFF supports everything but signed byte if 'tif' in output_format and output_dtype == numpy.int8: return False # 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 False # 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 False # 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) return len(nonchannel_axes) == 2 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' return len(nonchannel_axes) == 2 # 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' return len(nonchannel_axes) == 3 assert False, "Unknown format case: {}".format(output_format)