Esempio n. 1
0
    def test_2d_along_t(self):
        data = numpy.random.randint(0, 255,
                                    (20, 100, 200, 3)).astype(numpy.uint8)
        expected_axistags = vigra.AxisTags([
            vigra.AxisInfo("t", typeFlags=vigra.AxisType.Time),
            vigra.AxisInfo("y", typeFlags=vigra.AxisType.Space),
            vigra.AxisInfo("x", typeFlags=vigra.AxisType.Space),
            vigra.AxisInfo("c", typeFlags=vigra.AxisType.Channels),
        ])

        with tempdir() as d:
            tiff_path = d + "/test-2d-{slice_index:02d}.tiff"
            tiff_glob_path = d + "/test-2d-*.tiff"
            for slice_index, t_slice in enumerate(data):
                vigra.impex.writeImage(
                    vigra.taggedView(t_slice, "yxc"),
                    tiff_path.format(slice_index=slice_index),
                    dtype="NATIVE",
                    mode="w",
                )

            op = OpTiffSequenceReader(graph=Graph())
            op.SequenceAxis.setValue("t")
            op.GlobString.setValue(tiff_glob_path)
            assert op.Output.ready()
            assert op.Output.meta.axistags == expected_axistags
            assert (op.Output[5:10, 50:100,
                              100:150].wait() == data[5:10, 50:100,
                                                      100:150]).all()
Esempio n. 2
0
    def setupOutputs(self):
        inputSlot = self.inputs["Input"]
        self.outputs["Output"].meta.assignFrom(inputSlot.meta)

        self.Output.meta.axistags = vigra.AxisTags(
            [vigra.AxisInfo("t"), vigra.AxisInfo("x"), vigra.AxisInfo("y"), vigra.AxisInfo("z"), vigra.AxisInfo("c")]
        )
Esempio n. 3
0
    def setupOutputs(self):
        assert len(self.Input.meta.shape
                   ) == 4, "Data must be exactly 3D+c (no time axis)"
        assert self.Input.meta.getAxisKeys()[-1] == 'c'
        assert self.Input.meta.shape[-1] == 1, "Input must be 1-channel"
        self.Output.meta.assignFrom(self.Input.meta)
        self.Output.meta.dtype = numpy.float32
        self.Output.meta.shape = self.Input.meta.shape[:-1] + (3, 3)

        # axistags: start with input, drop channel and append i,j
        input_axistags = copy.copy(self.Input.meta.axistags)
        tag_list = [tag for tag in input_axistags]
        tag_list = tag_list[:-1]
        tag_list.append(vigra.AxisInfo('i', description='eigenvector index'))
        tag_list.append(
            vigra.AxisInfo('j', description='eigenvector component'))

        self.Output.meta.axistags = vigra.AxisTags(tag_list)

        # Calculate anisotropy factor.
        x_tag = self.Input.meta.axistags['x']
        z_tag = self.Input.meta.axistags['z']
        self.z_anisotropy_factor = 1.0
        if z_tag.resolution != 0.0 and x_tag.resolution != 0.0:
            self.z_anisotropy_factor = z_tag.resolution / x_tag.resolution
            logger.debug("Anisotropy factor: {}/{} = {}".format(
                z_tag.resolution, x_tag.resolution, self.z_anisotropy_factor))
Esempio n. 4
0
    def test_withAxisTags(self):
        # Write it again, this time with weird axistags
        axistags = vigra.AxisTags(
            vigra.AxisInfo("x", vigra.AxisType.Space),
            vigra.AxisInfo("y", vigra.AxisType.Space),
            vigra.AxisInfo("z", vigra.AxisType.Space),
            vigra.AxisInfo("c", vigra.AxisType.Channels),
            vigra.AxisInfo("t", vigra.AxisType.Time),
        )

        # Write the dataset to an hdf5 file
        # (Note: Don't use vigra to do this, which may reorder the axes)
        self.h5File["volume"].create_dataset("tagged_data", data=self.data)
        self.n5File["volume"].create_dataset("tagged_data", data=self.data)
        # Write the axistags attribute
        self.h5File["volume/tagged_data"].attrs["axistags"] = axistags.toJSON()
        self.n5File["volume/tagged_data"].attrs["axistags"] = axistags.toJSON()

        # Read the data with an operator
        self.h5_op.H5N5File.setValue(self.h5File)
        self.n5_op.H5N5File.setValue(self.n5File)
        self.h5_op.InternalPath.setValue("volume/tagged_data")
        self.n5_op.InternalPath.setValue("volume/tagged_data")

        assert self.h5_op.OutputImage.meta.shape == self.data.shape
        assert self.n5_op.OutputImage.meta.shape == self.data.shape
        numpy.testing.assert_array_equal(self.h5_op.OutputImage.value,
                                         self.data)
        numpy.testing.assert_array_equal(self.n5_op.OutputImage.value,
                                         self.data)
Esempio n. 5
0
 def setupOutputs(self):
     self.Output.meta.shape = self.shape
     self.Output.meta.dtype = self.dtype
     self.Output.meta.axistags = vigra.AxisTags([
         vigra.AxisInfo("t"),
         vigra.AxisInfo("x"),
         vigra.AxisInfo("y"),
         vigra.AxisInfo("z"),
         vigra.AxisInfo("c"),
     ])
Esempio n. 6
0
        def create_axistags(self):
            """
            Generate a vigra.AxisTags object corresponding to this VoxelsMetadata.
            (Requires vigra.)
            """
            tags_f = vigra.AxisTags()
            tags_f.insert(
                0, vigra.AxisInfo('c', typeFlags=vigra.AxisType.Channels))
            dtypes = []
            channel_labels = []
            for channel_fields in self["Properties"]["Values"]:
                dtypes.append(numpy.dtype(channel_fields["DataType"]).type)
                channel_labels.append(channel_fields["Label"])

            # We monkey-patch the channel labels onto the axistags object as a new member
            tags_f.channelLabels = channel_labels
            for axisfields in self['Axes']:
                key = str(axisfields["Label"]).lower()
                res = axisfields["Resolution"]
                tag = vigra.defaultAxistags(key)[0]
                tag.resolution = res
                tags_f.insert(len(tags_f), tag)
                # TODO: Check resolution units, because apparently
                #        they can be different from one axis to the next...

            assert all( [dtype == dtypes[0] for dtype in dtypes] ), \
                "Can't support heterogeneous channel types: {}".format( dtypes )

            # Reverse from F-order to C-order
            tags_c = vigra.AxisTags(list(tags_f)[::-1])
            return tags_c
Esempio n. 7
0
    def setRightShape(self):
        c = 0
        flag = self.inputs["AxisFlag"].value
        self.intervals = []

        inTagKeys = []

        for inSlot in self.inputs["Images"]:
            inTagKeys = [ax.key for ax in inSlot.meta.axistags]
            if inSlot.partner is not None:
                self.Output.meta.assignFrom(inSlot.meta)

                outTagKeys = [
                    ax.key for ax in self.outputs["Output"].meta.axistags
                ]

                if not flag in outTagKeys:
                    if self.AxisIndex.ready():
                        axisindex = self.AxisIndex.value
                    else:
                        axisindex = len(outTagKeys)
                    self.outputs["Output"].meta.axistags.insert(
                        axisindex, vigra.AxisInfo(flag, axisType(flag)))

                old_c = c
                if flag in inTagKeys:
                    c += inSlot.meta.shape[inSlot.meta.axistags.index(flag)]
                else:
                    c += 1
                self.intervals.append((old_c, c))

        if len(self.inputs["Images"]) > 0:
            newshape = list(self.inputs["Images"][0].meta.shape)
            if flag in inTagKeys:
                #here we assume that all axis are present
                axisindex = self.Output.meta.axistags.index(flag)
                newshape[axisindex] = c
            else:
                #FIXME axisindex is not necessarily defined yet (try setValue on subslot)
                newshape.insert(axisindex, c)
                ideal_blockshape = self.Output.meta.ideal_blockshape
                if ideal_blockshape is not None:
                    ideal_blockshape = ideal_blockshape[:axisindex] + (
                        1, ) + ideal_blockshape[axisindex:]
                    self.Output.meta.ideal_blockshape = ideal_blockshape

                max_blockshape = self.Output.meta.max_blockshape
                if max_blockshape is not None:
                    max_blockshape = max_blockshape[:axisindex] + (
                        1, ) + max_blockshape[axisindex:]
                    self.Output.meta.max_blockshape = max_blockshape

            self.outputs["Output"].meta.shape = tuple(newshape)
        else:
            self.outputs["Output"].meta.shape = None
    def test_withAxisTags(self):
        # Write it again, this time with weird axistags
        axistags = vigra.AxisTags(vigra.AxisInfo('x', vigra.AxisType.Space),
                                  vigra.AxisInfo('y', vigra.AxisType.Space),
                                  vigra.AxisInfo('z', vigra.AxisType.Space),
                                  vigra.AxisInfo('c', vigra.AxisType.Channels),
                                  vigra.AxisInfo('t', vigra.AxisType.Time))

        # Write the dataset to an hdf5 file
        # (Note: Don't use vigra to do this, which may reorder the axes)
        self.h5File['volume'].create_dataset('tagged_data', data=self.data)
        # Write the axistags attribute
        self.h5File['volume/tagged_data'].attrs['axistags'] = axistags.toJSON()

        # Read the data with an operator
        self.op.Hdf5File.setValue(self.h5File)
        self.op.InternalPath.setValue('volume/tagged_data')

        assert self.op.OutputImage.meta.shape == self.data.shape
        assert self.op.OutputImage[0, 1, 2, 1, 0].wait() == 4
Esempio n. 9
0
def axisTagObjectFromFlag(flag):

    if flag in ['x', 'y', 'z']:
        type = vigra.AxisType.Space
    elif flag == 'c':
        type = vigra.AxisType.Channel
    elif flag == 't':
        type = vigra.AxisType.Time
    else:
        print "Requested flag", str(flag)
        raise

    return vigra.AxisTags(vigra.AxisInfo(flag, type))
Esempio n. 10
0
    def func_wrapper(array, *args, **kwargs):
        if hasattr(array, 'axistags'):
            array = vigra.taggedView(np.ascontiguousarray(array),
                                     array.axistags)
            squeezed = array.squeeze()
            res = func(squeezed, *args, **kwargs)

            if res.shape == squeezed.shape:
                res = vigra.taggedView(res, squeezed.axistags)
            else:
                res = vigra.taggedView(
                    res,
                    list(squeezed.axistags) + [vigra.AxisInfo('c')])
            return res.withAxes(array.axistags)
        else:
            assert not any( np.array(array.shape) == 1 ), \
             "Can't handle arrays with singleton dimensions (unless they are tagged VigraArrays)."
            return func(array, *args, **kwargs)
def blockwise_view(a, blockshape, aslist=False, require_aligned_blocks=True):
    """
    Return a 2N-D view of the given N-D array, rearranged so each ND block (tile) 
    of the original array is indexed by its block address using the first N 
    indexes of the output array.
    
    Note: This function is nearly identical to ``skimage.util.view_as_blocks()``, except:
          - "imperfect" block shapes are permitted (via require_aligned_blocks=False)
          - only contiguous arrays are accepted.  (This function will NOT silently copy your array.)
            As a result, the return value is *always* a view of the input.
    
    Args:
        a: The ND array

        blockshape: The tile shape
        
        aslist: If True, return all blocks as a list of ND blocks
                instead of a 2D array indexed by ND block coordinate.

        require_aligned_blocks: If True, check to make sure no data is "left over" 
                                in each row/column/etc. of the output view.
                                That is, the blockshape must divide evenly into the full array shape.
                                If False, "leftover" items that cannot be made into complete blocks 
                                will be discarded from the output view.
 
    Here's a 2D example (this function also works for ND):
    
    >>> a = numpy.arange(1,21).reshape(4,5)
    >>> print a
    [[ 1  2  3  4  5]
     [ 6  7  8  9 10]
     [11 12 13 14 15]
     [16 17 18 19 20]]

    >>> view = blockwise_view(a, (2,2), False)
    >>> print view
    [[[[ 1  2]
       [ 6  7]]
    <BLANKLINE>
      [[ 3  4]
       [ 8  9]]]
    <BLANKLINE>
    <BLANKLINE>
     [[[11 12]
       [16 17]]
    <BLANKLINE>
      [[13 14]
       [18 19]]]]

    Inspired by the 2D example shown here: http://stackoverflow.com/a/8070716/162094
    """
    assert a.flags[
        'C_CONTIGUOUS'], "This function relies on the memory layout of the array."
    blockshape = tuple(blockshape)
    outershape = tuple(numpy.array(a.shape) // blockshape)
    view_shape = outershape + blockshape

    if require_aligned_blocks:
        assert (numpy.mod(a.shape, blockshape) == 0).all(), \
            "blockshape {} must divide evenly into array shape {}"\
            .format( blockshape, a.shape )

    # inner strides: strides within each block (same as original array)
    intra_block_strides = a.strides

    # outer strides: strides from one block to another
    inter_block_strides = tuple(a.strides * numpy.array(blockshape))

    # This is where the magic happens.
    # Generate a view with our new strides (outer+inner).
    view = numpy.lib.stride_tricks.as_strided(a,
                                              shape=view_shape,
                                              strides=(inter_block_strides +
                                                       intra_block_strides))

    # Special handling for VigraArrays
    if _vigra_available and isinstance(a, vigra.VigraArray) and hasattr(
            a, 'axistags'):
        view_axistags = vigra.AxisTags([vigra.AxisInfo() for _ in blockshape] +
                                       list(a.axistags))
        view = vigra.taggedView(view, view_axistags)

    if aslist:
        return list(map(view.__getitem__, numpy.ndindex(outershape)))
    return view
Esempio n. 12
0
def synthetic_EPSCaT_linescan(field_width, duration, 
                              spatial_resolution,  sampling_frequency, 
                              spine_parameters, epscat_parameters, 
                              space_units = None, time_units = None, data_units = pq.dimensionless,
                              twoChannels=False,
                              addChannelAxis=True,
                              returnCalibration=False):
    """Generates a synthetic 2D EPSCaT as a vigra.VigraArray
    
    Parameters:
    ===========
    
    field_width : spatial extent where the synthetic spines are to be generated:
                float value, or a scalar Python Quantity where units SHOULD be "um"
    
    duration    : temporal extent of the entire EPSCaT signal containing synthetic EPSCaT waveforms
                float value, or a scalar Python Quantity where units SHOULD be "s"
                
    spatial_resolution : size of a "pixel" (sample) in the spatial domain 
                either float or a scalar Python Quantity with units convertible to 
                those of field_width
                
    sampling_frequency : sampling frequency of the time domain
                either flooat or a scalar Python Quantity with units convertible to
                the inverse of duration's units
                
    spine_parameters: a sequence of parameters for the models.gaussianSum1D function
    
                see models.gaussianSum1D() docstring for details
    
    epscat_parameters: a sequence of parameters for the models.compound_exp_rise_multi_decay function
    
                see models.compound_exp_rise_multi_decay() docstring for details
                
    Named parameters (keywords):
    Default values indicated (in parenthesis are default values if field_width and duration are floats)
    ============================
    
    space_units = None (pq.um)
    time_units  = None (pq.s)
    data_units  = pq.dimensionless
    
    addChannelAxis: boolean (default True) adds a singleton channel axis as the last axis
    
    returnCalibration: boolean, default False:
                When True, also returns the datatypes.AxisCalibration object for the axistags
                if the result
                
    twoChannels : boolean (default is False)
        When True, the result will be two-channel image with the "spine" on channel 0 and the 
        epscat on channel 1 (a channel axis will be automatically inserted in the image
        regardless of the value of addChannelAxis parameter)
        
        When False, the result will be a single-channel images containing the synthetic
        EPSCaT linescan
    
    Returns:
    ========
    When returnCalibration is False (default):
        a vigra.VigraArray containing the outer product of the synthetic spine(s) 
            (on the horizontal space axis) with the synthetic epscat (on the vertical temporal axis)
            
    When returnCalibration is True, returns a tuple:
    
        (image, axiscalibration) where image is as above, and axiscalibration is a
        datatypes.AxisCalibration object for the image axes (axistags property). 
        
        NOTE that in any case the image axistags will contain a calibration data in 
        their decsription properties
    
    
    
    """
    
    if space_units is None:
        if isinstance(field_width, pq.Quantity):
            space_units = field_width.units
            
            field_width = field_width.magnitude
            
        else:
            space_units = pq.um
            
    if time_units is None:
        if isinstance(duration, pq.Quantity):
            time_units = duration.units
            
            duration = duration.magnitude
            
        else:
            time_units = pq.s
    
    # NOTE: 2018-09-14 14:13:56
    # below, we get each signal as a tuple (y,x) of numpy arrays (vector columns)
    # NOTE the order
    epscat = synthetic_transients(duration, sampling_frequency, epscat_parameters)[1] 
    
    spine  = synthetic_spine(field_width, spatial_resolution, *spine_parameters)[1]
    
    axistags = vigra.AxisTags(vigra.AxisInfo("x", vigra.AxisType.Space, resolution=spatial_resolution), 
                              vigra.AxisInfo("t", vigra.AxisType.Time, resolution=1/sampling_frequency))
    
    linescan = vigra.VigraArray(np.outer(spine, epscat), axistags = axistags)
    
    if twoChannels:
        spine2D = vigra.VigraArray(np.outer(spine, np.ones_like(epscat)), axistags = axistags)
        
        result = imgp.concatenateImages(spine2D, linescan, axis = "c") 
        
    else:
        result = linescan
    
    if addChannelAxis and result.channelIndex == linescan.ndim:
        linescan = linescan.insertChannelAxis()
    
    axiscal = dt.AxisCalibration(result)
    axiscal.setUnits(space_units, "x")
    axiscal.setResolution(spatial_resolution, "x")
    axiscal.setUnits(time_units, "t")
    axiscal.setResolution(1/sampling_frequency, "t")
    
    if result.channelIndex < result.ndim:
        # by default there is only one channel
        axiscal.setUnits(data_units, "c", 0)
        axiscal.setOrigin(np.min(result), "c", 0)
        axiscal.setResolution(np.finfo(float).eps, "c", 0)
    
    axiscal.calibrateAxes()
    
    if returnCalibration:
        return result, axiscal
    
    else:
        return result