示例#1
0
    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 )
示例#3
0
 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 )
示例#4
0
    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)
示例#5
0
    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)
示例#6
0
    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)
示例#7
0
    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)
示例#8
0
    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 )
示例#9
0
    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 )
示例#10
0
    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)
示例#11
0
    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)