edu.stanford.rsl.konrad.cuda
Class CUDAVolumeOperator

java.lang.Object
  extended by edu.stanford.rsl.konrad.volume3d.VolumeOperator
      extended by edu.stanford.rsl.konrad.cuda.CUDAVolumeOperator

public class CUDAVolumeOperator
extends VolumeOperator

Class to implement all functions of VolumeOperator on CUDA hardware. Code is made CUDA compatible by replacing the VolumeOperator with CUDAVolumeOperator. As a result all code is executed on CUDA instead of the CPU. On good hardware usually a substantial speed-up is achieved. Development and debugging should be done using Volume3D, as CUDA problems are usually hard to debug.

Author:
akmaier
See Also:
VolumeOperator

Nested Class Summary
 
Nested classes/interfaces inherited from class edu.stanford.rsl.konrad.volume3d.VolumeOperator
VolumeOperator.FILTER_TYPE
 
Constructor Summary
CUDAVolumeOperator()
           
 
Method Summary
 int abs(Volume3D vol)
          Determines the absolute volume of the input volume.
If the input volume is real Math.abs() is called for each element.
If the input volume is complex the power spectrum is computed.
 int addScalar(Volume3D vol, float realPart, float imagPart)
          Adds a scalar to the Volume3D.
 int addVolume(Volume3D vol1, Volume3D vol2)
          Adds the second volume to the first volume.
 int addVolume(Volume3D vol1, Volume3D vol2, double weight)
          Adds the second volume $y_j$ multiplied by the scalar weight $s$ to the first volume $x_j$.
The first volume is overwritten.
 void cleanup()
           
 Volume3D createDirectionalWeights(int dimensions, int[] size, float[] dim, float[] dir, int A, VolumeOperator.FILTER_TYPE t_filt)
          Creates an anisotropic, i.e.
 Volume3D createExponentialDirectionalHighPassFilter(int dimensions, int[] size, float[] dim, float[] dir, int A, float B, float ri, VolumeOperator.FILTER_TYPE t_filt)
          Creates an radially symetric anisotropic quadrature filter according to this definition: %preamble{\\usepackage{amsmath}} \\begin{align*} F(\\mathbf{u}) & = \\left \\{ \\begin{array}{ll} \\left(\\frac{\\displaystyle (\\mathbf{u} \\cdot \\hat{\\mathbf{n}}_k)}{\\displaystyle |\\rho|}\\right)^{2A} \\cdot R(\\rho)& \\text{if}\\qquad\\mathbf{u} \\cdot \\hat{\\mathbf{n}}_k >0 \\\\ 0 & \\text{else} \\end{array} \\right .
 Volume3D createGaussLowPassFilter(int dimensions, int[] size, float[] dim, float alpha)
          Creates an isotropic, i.e.
 Volume3D createHighPassFilter(int dimensions, int[] size, float[] dim, int filt_loop, float lp_upper)
          Creates a directional high pass filter $F_{\displaystyle\text{HP}_k}(\mathbf{u}) = 1 - (R_\text{LP}(\rho) \cdot D_k(\mathbf{u}))$.
 Volume3D createLowPassFilter(int dimensions, int[] size, float[] dim, float lp_upper)
          Creates an isotropic low-pass filter, i.e.
 Volume3D createVolume(ij.ImagePlus image, int mirror, int cuty, boolean uneven)
          Creates a Volume3D Object from an ImagePlus.
 Volume3D createVolume(int[] size, float[] dim, int in_dim)
          Creates a new empty volume according to the parameters.
 int divideByVolume(Volume3D vol1, Volume3D vol2)
          Divides the first volume by the second volume element by element
 int fftShift(Volume3D vol)
          Performs the shift required for the FFT, i.e.
 void fill(Volume3D vol, float number)
           
 int imag(Volume3D vol)
          Maps a complex volume onto its imaginary part.
 void initCUDA()
           
 void makeComplex(Volume3D vol)
          Makes the volume complex, i.e.
 float max(Volume3D vol)
          Determines the maximum intensity of a pixel in the given volume.
 float mean(Volume3D vol)
          Determines the arithmetic average $\mu$ of all $N = \prod_i d_i$ voxels $x_j$.
 float min(Volume3D vol)
          Determines the minimum intensity of the volume.
 int minOfTwoVolumes(Volume3D vol1, Volume3D vol2)
          Determines the minimal volume element by element.
The output is stored in the first volume.
 int multiply(Volume3D vol1, Volume3D vol2)
          Multiplies two volumes element by element.
 int multiplyScalar(Volume3D vol, float realPart, float imagPart)
          Multiplies the volume by a scalar.
 int real(Volume3D vol)
          Maps volume onto its real part.
 int sigmoid(Volume3D vol, float smoothing, float lowValue, float highValue, float highPassLowerLevel, float highPassUpperLevel)
          Remaps gray values using a sigmoid function.
 Volume3D solveMaximumEigenvalue(Volume3D[][] structureTensor)
          Method to compute the maximal eigenvalue $\lambda_1$ per volume element for a volume structure tensor.
 int sqrt(Volume3D vol)
          Replaces every element in the volume with the output of Math.sqrt(), i.e.
 int upperLimit(Volume3D vol, float max)
          Iterates the volume and replaces all entries greater than max with max.
 
Methods inherited from class edu.stanford.rsl.konrad.volume3d.VolumeOperator
divideScalar, getFrequencyBoundings, subtractVolume
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

CUDAVolumeOperator

public CUDAVolumeOperator()
Method Detail

initCUDA

public void initCUDA()

cleanup

public void cleanup()

fill

public void fill(Volume3D vol,
                 float number)

divideByVolume

public int divideByVolume(Volume3D vol1,
                          Volume3D vol2)
Description copied from class: VolumeOperator
Divides the first volume by the second volume element by element

Overrides:
divideByVolume in class VolumeOperator
Parameters:
vol1 - the first volume
vol2 - the second volume
Returns:
0, if successful

solveMaximumEigenvalue

public Volume3D solveMaximumEigenvalue(Volume3D[][] structureTensor)
Description copied from class: VolumeOperator
Method to compute the maximal eigenvalue $\lambda_1$ per volume element for a volume structure tensor.

Overrides:
solveMaximumEigenvalue in class VolumeOperator
Parameters:
structureTensor - the structure tensor as 2D array of volumes.
Returns:
the values of $\lambda_1$ as volume

createDirectionalWeights

public Volume3D createDirectionalWeights(int dimensions,
                                         int[] size,
                                         float[] dim,
                                         float[] dir,
                                         int A,
                                         VolumeOperator.FILTER_TYPE t_filt)
Description copied from class: VolumeOperator
Creates an anisotropic, i.e. $D(\mathbf{u})$ is not constant, filter as Volume3D if FILTER_TYPE is QUADRATIC.
\begin{align*} D_k(\mathbf{u}) & = \left \{ \begin{array}{ll} \left(\frac{(\displaystyle \mathbf{u} \cdot \hat{\mathbf{n}}_k)}{\displaystyle |\rho|}\right)^{2A} & \text{if}\qquad\mathbf{u} \cdot \hat{\mathbf{n}}_k >0 \\ 0 & \text{else} \end{array} \right . \phantom{\}} \end{align*}
$\rho = |\mathbf{u}|$ and $\hat{\mathbf{n}}_k$ is the direction of the anisotropy. The case selection is only valid in the QUADRATIC case.

Overrides:
createDirectionalWeights in class VolumeOperator
Parameters:
dimensions - dimension should be 3
size - number of pixels per dimension
dim - resolution
dir - direction vector $\hat{\mathbf{n}}_k$
A - parameter A
t_filt - filter type
Returns:
the filter

createVolume

public Volume3D createVolume(int[] size,
                             float[] dim,
                             int in_dim)
Description copied from class: VolumeOperator
Creates a new empty volume according to the parameters. Volume is initialized with zero at all elements.

Overrides:
createVolume in class VolumeOperator
Parameters:
size - the sizes in each direction as array
dim - the dimension of the pixel in mm in each direction
in_dim - the internal dimension (1 = real, 2 = complex)
Returns:
the new volume

createExponentialDirectionalHighPassFilter

public Volume3D createExponentialDirectionalHighPassFilter(int dimensions,
                                                           int[] size,
                                                           float[] dim,
                                                           float[] dir,
                                                           int A,
                                                           float B,
                                                           float ri,
                                                           VolumeOperator.FILTER_TYPE t_filt)
Description copied from class: VolumeOperator
Creates an radially symetric anisotropic quadrature filter according to this definition:
\begin{align*} F(\mathbf{u}) & = \left \{ \begin{array}{ll} \left(\frac{\displaystyle (\mathbf{u} \cdot \hat{\mathbf{n}}_k)}{\displaystyle |\rho|}\right)^{2A} \cdot R(\rho)& \text{if}\qquad\mathbf{u} \cdot \hat{\mathbf{n}}_k >0 \\ 0 & \text{else} \end{array} \right . \phantom{\}}\\ R(\rho) & = e^{\displaystyle -\frac{\displaystyle 4}{\displaystyle B^2ln(2)}ln^2\left(\frac{\rho}{\rho_i}\right)} \end{align*}

The filter is suitable to estimate the local orientation in direction $\hat{\mathbf{n}}_k$.

This plot shows $R(\rho)$ with B = 2, A = 1, and $\rho_i$ = 1.5:



Note that the volume is moved to FFT octants with the highest frequencies in the center. It can be directly multiplied to the FFT of a volume.

Overrides:
createExponentialDirectionalHighPassFilter in class VolumeOperator
Parameters:
dimensions - dimension should be 3
size - number of pixels per dimension
dim - resolution
dir - the filter direction $\hat{\mathbf{n}}_k$
A - factor A
B - the relative bandwith of the filter B
ri - $\rho_i$
t_filt - parameter to
Returns:
the filter as volume
See Also:
VolumeOperator.fftShift(Volume3D)

fftShift

public int fftShift(Volume3D vol)
Description copied from class: VolumeOperator
Performs the shift required for the FFT, i.e. moves the high frequencies to the center and the low frequencies to the periphery. If called again on the same volume, its changes are reversed.

Overrides:
fftShift in class VolumeOperator
Parameters:
vol - the volume
Returns:
0, if successful

createHighPassFilter

public Volume3D createHighPassFilter(int dimensions,
                                     int[] size,
                                     float[] dim,
                                     int filt_loop,
                                     float lp_upper)
Description copied from class: VolumeOperator
Creates a directional high pass filter $F_{\displaystyle\text{HP}_k}(\mathbf{u}) = 1 - (R_\text{LP}(\rho) \cdot D_k(\mathbf{u}))$. The definition of $D_k(\mathbf{u})$ from createDirectionalFilter is used. The low-pass filter is defined as:
\begin{align*} R_\text{LP}(\rho) & = \text{cos}^2\left(\frac{\displaystyle \pi \cdot \rho}{\displaystyle 2 \rho_\text{LP}} \right) \end{align*}

$\rho_\text{LP}$ is the upper limit of the low-pass filter.

This plot shows the low-pass filter for $\rho_\text{LP}$ = 1.5:


Note that the volume is moved to FFT octants with the highest frequencies in the center. It can be directly multiplied to the FFT of a volume.

Overrides:
createHighPassFilter in class VolumeOperator
Parameters:
dimensions - dimension should be 3
size - number of pixels per dimension
dim - resolution
filt_loop - $k$ for the creation of $\hat{\mathbf{n}}_k$
lp_upper - $\rho_\text{LP}$
Returns:
the filter as volume
See Also:
VolumeOperator.fftShift(Volume3D), VolumeOperator.createDirectionalWeights(int, int[], float[], float[], int, FILTER_TYPE)

multiply

public int multiply(Volume3D vol1,
                    Volume3D vol2)
Description copied from class: VolumeOperator
Multiplies two volumes element by element. Volume vol1 is overwritten.

Overrides:
multiply in class VolumeOperator
Parameters:
vol1 - the first volume
vol2 - the second volume
Returns:
0, if successful

createVolume

public Volume3D createVolume(ij.ImagePlus image,
                             int mirror,
                             int cuty,
                             boolean uneven)
Description copied from class: VolumeOperator
Creates a Volume3D Object from an ImagePlus. Parameters match the ImagePlus constructor of Volume3D. If a different type of Volume3D is used (such as CUDAVolume3D) this method is overloaded in the respective inhereted version of of CUDAVolumeOperator. In order to write CUDA compatible code, use this version instead of the Volume3D constructor.

Overrides:
createVolume in class VolumeOperator
Parameters:
image - the ImagePlus with the image data
mirror - the number of pixels which are mirrored at the boundary
cuty - number of pixels to be cut from the ImagePlus (in order to remove emtpy areas at the top and the bottom of the image
uneven - true if the original number of slices was uneven (may have been altered by cutting y)
Returns:
the volume as Volume3D
See Also:
Volume3D#Volume3D(ImagePlus, double, double, double, int, int, boolean)

makeComplex

public void makeComplex(Volume3D vol)
Description copied from class: VolumeOperator
Makes the volume complex, i.e. the internal dimension of the volume is increased to 2, if required and the data is transfered to interleaved complex format.

Overrides:
makeComplex in class VolumeOperator
Parameters:
vol - the volume

createLowPassFilter

public Volume3D createLowPassFilter(int dimensions,
                                    int[] size,
                                    float[] dim,
                                    float lp_upper)
Description copied from class: VolumeOperator
Creates an isotropic low-pass filter, i.e. $D_k(\mathbf{u})$ = 1. The radial shape of the filter is determined by:
\begin{align*} R_\text{LP}(\rho) & = \text{cos}^2\left(\frac{\displaystyle \pi \cdot \rho}{\displaystyle 2 \rho_\text{LP}} \right) \end{align*}

This plot shows the low-pass filter for $\rho_\text{LP}$ = 1.5:


Note that the volume is moved to FFT octants with the highest frequencies in the center. It can be directly multiplied to the FFT of a volume.

Overrides:
createLowPassFilter in class VolumeOperator
Parameters:
dimensions - dimension should be 3
size - number of pixels per dimension
dim - resolution
lp_upper - $\rho_\text{LP}$
Returns:
the filter as volume
See Also:
VolumeOperator.fftShift(Volume3D)

createGaussLowPassFilter

public Volume3D createGaussLowPassFilter(int dimensions,
                                         int[] size,
                                         float[] dim,
                                         float alpha)
Description copied from class: VolumeOperator
Creates an isotropic, i.e. $D_k(\mathbf{u})$ = 1, 3-D Gaussian filter as Volume. The radial shape is determined as:
\begin{align*} R_\text{Gauss}(\rho) & = e^{\displaystyle-\frac{\displaystyle\alpha^2\rho^2}{\displaystyle2}} \end{align*}


This plot shows the radial shape for $\alpha$ = 0.5, 1.0, 1.5:


Note that the volume is moved to FFT octants with the highest frequencies in the center. It can be directly multiplied to the FFT of a volume.

Overrides:
createGaussLowPassFilter in class VolumeOperator
See Also:
VolumeOperator.fftShift(Volume3D)

sigmoid

public int sigmoid(Volume3D vol,
                   float smoothing,
                   float lowValue,
                   float highValue,
                   float highPassLowerLevel,
                   float highPassUpperLevel)
Description copied from class: VolumeOperator
Remaps gray values using a sigmoid function. A smoothing factor for the slope of the sigmoid can be set. lowValue and highValue determine the input values into the sigmoid. highPaddLowerLevel and highPassUpperLevel determine the output levels of the sigmoid.
The following figure describes the remapping process:

One configuration in the plot remaps the values 5 to 10 to the range from 0 to 1. If the levels are adjusted, the same range can also be remapped to the range from 0.2 to 1.5.

Overrides:
sigmoid in class VolumeOperator
Parameters:
vol - the volume
smoothing - slope of sigmoid
lowValue - the lower input limit
highValue - the upper input limit
highPassLowerLevel - the lower output value
highPassUpperLevel - the upper output value
Returns:
0, if successful

addVolume

public int addVolume(Volume3D vol1,
                     Volume3D vol2)
Description copied from class: VolumeOperator
Adds the second volume to the first volume.

Overrides:
addVolume in class VolumeOperator
Parameters:
vol1 - the first volume
vol2 - the second volume
Returns:
0, if successful

real

public int real(Volume3D vol)
Description copied from class: VolumeOperator
Maps volume onto its real part.

Overrides:
real in class VolumeOperator
Parameters:
vol - the volume to be mapped.
Returns:
0, if successful

imag

public int imag(Volume3D vol)
Description copied from class: VolumeOperator
Maps a complex volume onto its imaginary part.

Overrides:
imag in class VolumeOperator
Parameters:
vol - the volume
Returns:
0, if successful

addVolume

public int addVolume(Volume3D vol1,
                     Volume3D vol2,
                     double weight)
Description copied from class: VolumeOperator
Adds the second volume $y_j$ multiplied by the scalar weight $s$ to the first volume $x_j$.
The first volume is overwritten. The second volume remains unchanged:
\begin{align*} x_j & := x_j + s \cdot y_j \end{align*}

Overrides:
addVolume in class VolumeOperator
Parameters:
vol1 - the first volume $x_j$
vol2 - the second volume $y_j$
weight - the weighting factor $s$
Returns:
0, if successful

min

public float min(Volume3D vol)
Description copied from class: VolumeOperator
Determines the minimum intensity of the volume.

Overrides:
min in class VolumeOperator
Parameters:
vol - the volume
Returns:
the minimal value

minOfTwoVolumes

public int minOfTwoVolumes(Volume3D vol1,
                           Volume3D vol2)
Description copied from class: VolumeOperator
Determines the minimal volume element by element.
The output is stored in the first volume.

Overrides:
minOfTwoVolumes in class VolumeOperator
Parameters:
vol1 - the first volume
vol2 - the second volume
Returns:
0, if successful

mean

public float mean(Volume3D vol)
Description copied from class: VolumeOperator
Determines the arithmetic average $\mu$ of all $N = \prod_i d_i$ voxels $x_j$.
\begin{align*} \mu & = \frac{1}{N} \sum_i x_i \end{align*}

Overrides:
mean in class VolumeOperator
Parameters:
vol - the volume
Returns:
the mean value $\mu$

max

public float max(Volume3D vol)
Description copied from class: VolumeOperator
Determines the maximum intensity of a pixel in the given volume.

Overrides:
max in class VolumeOperator
Parameters:
vol - the volume
Returns:
the maximal value

addScalar

public int addScalar(Volume3D vol,
                     float realPart,
                     float imagPart)
Description copied from class: VolumeOperator
Adds a scalar to the Volume3D. If the volume is real the imaginary part should be set to 0. Otherwise, the volume is made complex.

Overrides:
addScalar in class VolumeOperator
Parameters:
vol - the volume
realPart - the real part
imagPart - the imaginary part
Returns:
0, if successful.
See Also:
VolumeOperator.makeComplex(Volume3D)

abs

public int abs(Volume3D vol)
Description copied from class: VolumeOperator
Determines the absolute volume of the input volume.
If the input volume is real Math.abs() is called for each element.
If the input volume is complex the power spectrum is computed.
In any case, the resulting volume is real and has internal dimension 1.
Method works in place and overwrites the old input volume.

Overrides:
abs in class VolumeOperator
Parameters:
vol - the input volume.
Returns:
0, if successful

multiplyScalar

public int multiplyScalar(Volume3D vol,
                          float realPart,
                          float imagPart)
Description copied from class: VolumeOperator
Multiplies the volume by a scalar. If the volume is real the imaginary part of the scalar should be set to 0. Any value different from 0 will cause the volume to be converted to complex values.

Overrides:
multiplyScalar in class VolumeOperator
Parameters:
vol - the volume
realPart - the real part of the scalar
imagPart - the imaginary part of the scalar
Returns:
0, if successful
See Also:
VolumeOperator.makeComplex(Volume3D)

sqrt

public int sqrt(Volume3D vol)
Description copied from class: VolumeOperator
Replaces every element in the volume with the output of Math.sqrt(), i.e. each element's square root.

Overrides:
sqrt in class VolumeOperator
Parameters:
vol - the volume to be processed.
Returns:
0, if successful

upperLimit

public int upperLimit(Volume3D vol,
                      float max)
Description copied from class: VolumeOperator
Iterates the volume and replaces all entries greater than max with max.

Overrides:
upperLimit in class VolumeOperator
Parameters:
vol - the volume
max - the maximum
Returns:
0, if successful