Example #1
0
    def interpolate_pmf_at_state(self, stateCoordinates):
        if self.sh_coefficient is None:
            self._init_shm_coefficient()

        coefficient = trilinear_interpolate4d(self.sh_coefficient,
                                              stateCoordinates)
        pmf = np.dot(self._B, coefficient)
        pmf.clip(0, out=pmf)
        return pmf
Example #2
0
def test_trilinear_interpolate():
    """This tests that the trilinear interpolation returns the correct values.
    """
    a, b, c = np.random.random(3)

    def linear_function(x, y, z):
        return a * x + b * y + c * z

    N = 6
    x, y, z = np.mgrid[:N, :N, :N]
    data = np.empty((N, N, N, 2))
    data[..., 0] = linear_function(x, y, z)
    data[..., 1] = 99.

    # Use a point not near the edges
    point = np.array([2.1, 4.8, 3.3])
    out = trilinear_interpolate4d(data, point)
    expected = [linear_function(*point), 99.]
    npt.assert_array_almost_equal(out, expected)

    # Pass in out ourselves
    out[:] = -1
    trilinear_interpolate4d(data, point, out)
    npt.assert_array_almost_equal(out, expected)

    # use a point close to an edge
    point = np.array([-.1, -.1, -.1])
    expected = [0., 99.]
    out = trilinear_interpolate4d(data, point)
    npt.assert_array_almost_equal(out, expected)

    # different edge
    point = np.array([2.4, 5.4, 3.3])
    # On the edge 5.4 get treated as the max y value, 5.
    expected = [linear_function(point[0], 5., point[2]), 99.]
    out = trilinear_interpolate4d(data, point)
    npt.assert_array_almost_equal(out, expected)

    # Test index errors
    point = np.array([2.4, 5.5, 3.3])
    npt.assert_raises(IndexError, trilinear_interpolate4d, data, point)
    point = np.array([2.4, -1., 3.3])
    npt.assert_raises(IndexError, trilinear_interpolate4d, data, point)
Example #3
0
    def get_position_value(self, x, y, z):
        """
        Get the voxel value at voxel position x, y, z (mm) in the dataset.
        If the coordinates are out of bound, the nearest voxel value is taken.
        Value is interpolated based on the value of self.interpolation.

        Parameters
        ----------
        x, y, z: floats
            Position coordinate (mm) along x, y, z axis.

        Return
        ------
        value: ndarray (self.dims[-1],) or float
            Interpolated value at position x, y, z (mm). If the last dimension
            is of length 1, return a scalar value.
        """
        if self.interpolation is not None:
            if not self.is_position_in_bound(x, y, z):
                eps = float(1e-8)  # Epsilon to exclude upper borders
                x = max(-self.pixdim[0] / 2,
                        min(self.pixdim[0] * (self.dim[0] - 0.5 - eps), x))
                y = max(-self.pixdim[1] / 2,
                        min(self.pixdim[1] * (self.dim[1] - 0.5 - eps), y))
                z = max(-self.pixdim[2] / 2,
                        min(self.pixdim[2] * (self.dim[2] - 0.5 - eps), z))
            coord = np.array(self.get_voxel_coordinate(x, y, z),
                             dtype=np.float64)

            if self.interpolation == 'nearest':
                result = nearestneighbor_interpolate(self.data, coord)
            else:
                # Trilinear
                result = trilinear_interpolate4d(self.data, coord)

            # Squeezing returns only value instead of array of length 1 if 3D
            # data
            return np.squeeze(result)

        else:
            raise Exception("No interpolation method was given, cannot run "
                            "this method..")
Example #4
0
    def voxmm_to_value(self, x, y, z, origin):
        """
        Get the voxel value at voxel position x, y, z (mm) in the dataset.
        If the coordinates are out of bound, the nearest voxel value is taken.
        Value is interpolated based on the value of self.interpolation.

        Parameters
        ----------
        x, y, z: floats
            Position coordinate (mm) along x, y, z axis.
        origin: str
            'center': Voxel 0,0,0 goes from [-resx/2, -resy/2, -resz/2] to
                [resx/2, resy/2, resz/2].
            'corner': Voxel 0,0,0 goes from [0,0,0] to [resx, resy, resz].

        Return
        ------
        value: ndarray (self.dims[-1],) or float
            Interpolated value at position x, y, z (mm). If the last dimension
            is of length 1, return a scalar value.
        """
        if self.interpolation is not None:
            if not self.is_voxmm_in_bound(x, y, z, origin):
                eps = float(1e-8)  # Epsilon to exclude upper borders
                if origin == 'corner':
                    x = max(0, min(self.voxres[0] * (self.dim[0] - eps), x))
                    y = max(0, min(self.voxres[1] * (self.dim[1] - eps), y))
                    z = max(0, min(self.voxres[2] * (self.dim[2] - eps), z))
                elif origin == 'center':
                    x = max(-self.voxres[0] / 2,
                            min(self.voxres[0] * (self.dim[0] - 0.5 - eps), x))
                    y = max(-self.voxres[1] / 2,
                            min(self.voxres[1] * (self.dim[1] - 0.5 - eps), y))
                    z = max(-self.voxres[2] / 2,
                            min(self.voxres[2] * (self.dim[2] - 0.5 - eps), z))
                else:
                    raise ValueError("Origin should be 'center' or 'corner'.")

            coord = np.array(self.voxmm_to_vox(x, y, z, origin),
                             dtype=np.float64)

            # Interpolation: Using dipy's pyx methods. The doc can be found in
            # the file dipy.core.interpolation.pxd. Dipy works with origin
            # center.
            if origin == 'corner':
                coord -= 0.5
            if self.interpolation == 'nearest':
                # They use round(point), not floor. This is the equivalent of
                # origin = 'center'.
                result = nearestneighbor_interpolate(self.data, coord)
            else:
                # Trilinear
                # They do not say it explicitely but they verify if
                # point[i] < -.5 or point[i] >= (data.shape[i] - .5),
                # meaning that they work with origin='center'.
                result = trilinear_interpolate4d(self.data, coord)

            # Squeezing returns only value instead of array of length 1 if 3D
            # data
            return np.squeeze(result)
        else:
            raise Exception("No interpolation method was given, cannot run "
                            "this method..")