IceImarisConnector( )
IceImarisConnector is a simple commodity class that eases communication
between Imaris and MATLAB using the Imaris XT interface.
[+/-] SYNOPSIS
conn = IceImarisConnector(imarisApplication, indexingStart)
INPUT
imarisApplication : (optional) if omitted (or set to []), an
IceImarisConnector object is created that is
not connected to any Imaris instance.
Imaris can then be started (and connected) using
the startImaris() method, i.e.
conn.startImaris()
Alternatively, imarisApplication can be:
- an Imaris Application ID as provided by Imaris
- an IceImarisConnector reference
- an Imaris Application ICE object.
indexingStart : (optional, default is 0) either 0 or 1, depending
on whether you prefer to index arrays in
IceImarisConnector starting at 0 or 1.
All indexing in ICE starts at 0; in contrast,
MATLAB indexing starts at 1.
To keep consistency, indexing in IceImarisConnector
is also 0-based (i.e. indexingStart defaults to 0).
This means that to get the data volume for the
first channel and first time point of the dataset
you will use conn.GetDataVolume(0, 0).
It you are come confortable with 1-based indexing,
i.e. you prefer using conn.GetDataVolume(1, 1),
you can set indexingStart to 1.
Whatever you choose, be consistent!
REMARK
The Imaris Application ICE object is stored in the read-only property
mImarisApplication. The mImarisApplication property gives access to
the entire Imaris ICE API. Example:
conn.mImarisApplication.GetSurpassSelection()
returns the currently selected object in the Imaris surpass scene.
OUTPUT
conn : an object of class IceImarisConnector
autocast( )
This method casts IDataItems to their derived types
[+/-] SYNOPSIS
derivedType = conn.autocast(IDataItem)
INPUT
IDataItem: an Imaris::IDataItem object
OUTPUT
derivedType : one of the Imaris::IDataItem subclasses:
- Imaris::IClippingPlane
- Imaris::IDataContainer
- Imaris::IFilaments
- Imaris::IFrame
- Imaris::IDataSet
- Imaris::IICells
- Imaris::ILightSource
- Imaris::IMeasurementPoints
- Imaris::ISpots
- Imaris::ISurfaces
- Imaris::IVolume
- Imaris::ISurpassCamera
- Imaris::IImageProcessing
- Imaris::IFactory
closeImaris( )
This method close the Imaris instance associated to the
IceImarisConnector object and resets the
mImarisApplication property.
[+/-] SYNOPSIS
(1) success = conn.closeImaris()
(2) success = conn.closeImaris(quiet)
INPUT
quiet : (Optional) If 1, Imaris won't pop-up a save dialog and close
silently. Default: 0
OUTPUT
success : 1 if closing Imaris was successful, 0 otherwise
createAndSetSpots( )
This method creates Spots and adds them to the Surpass Scene.
[+/-] SYNOPSIS
(1) newSpots = createAndSetSpots(coords, timeIndices, radii, ...
name, color)
(2) newSpots = createAndSetSpots(coords, timeIndices, radii, ...
name, color, container)
INPUT
coords : (nx3) [x y z]n coordinate matrix in dataset units
timeIndices : (nx1) vector of spots time indices
radii : (nx1) vector of spots radii
name : name of the Spots object
color : (1x4), (0..1) vector of [R G B A] values
container : (optional) if not set, the Spots object is added at the
root of the Surpass Scene.
Please note that it is the user's responsibility to
attach the container to the surpass scene!
OUTPUT
newSpots : the generated Spots object.
createDataset( )
This method creates an Imaris dataset and replaces current one.
[+/-] SYNOPSIS
(1) iDataset = createDataset(datatype, sizeX, sizeY, sizeZ, sizeC, sizeT)
(2) iDataset = createDataset(datatype, sizeX, sizeY, sizeZ, sizeC, sizeT, ...
voxelSizeX, voxelsSizeY, voxelSizeZ, deltaTime)
INPUT
datatype : one of 'uint8', 'uint16', 'single', Imaris.tType.eTypeUInt8,
Imaris.tType.eTypeUInt16, Imaris.tType.eTypeFloat
sizeX : dataset width
sizeY : dataset height
sizeZ : number of planes
sizeC : number of channels
sizeT : number of timepoints
voxelSizeX: (optional, default = 1) voxel size in X direction
voxelSizeY: (optional, default = 1) voxel size in Y direction
voxelSizeZ: (optional, default = 1) voxel size in Z direction
deltaTime : (optional, default = 1) time difference between consecutive
time points
OUTPUT
iDataset : created DataSet
EXAMPLE
% Create a 2-by-3-by-2 stack
data(:, :, 1) = [ 11 12 13; 14 15 16 ];
data(:, :, 2) = [ 17 18 19; 20 21 22];
data = uint8(data);
% Create a dataset with sizeX = 3, sizeY = 2 and sizeZ = 2
conn.createDataset('uint8', 3, 2, 2, 1, 1);
% Copy data into the Imaris dataset
conn.setDataVolumeRM(data, 0, 0);
REMARK
If you plan to set data volumes in column-major form, swap sizeX and
sizeY.
display( )
This method overloads standard display functionality.
[+/-] SYNOPSIS
conn.display()
INPUT
None
OUTPUT
None
getAllSurpassChildren( )
This method returns all children of the surpass scene recursively.
Folders (i.e. IDataContainer objects) may be scanned (recursively)
but are not returned. Optionally, the returned objects may be filtered
by type.
[+/-] SYNOPSIS
children = conn.getAllSurpassChildren(recursive, filter)
INPUT
recursive: {0 | 1} If 1, folders will be scanned recursively;
if 0, only objects at root level will be inspected.
filter : (optional) Filters the children by type. Only the
surpass children of the specified type are
returned; filter is one of:
'Cells'
'ClippingPlane'
'Dataset'
'Filaments'
'Frame'
'LightSource'
'MeasurementPoints'
'Spots'
'Surfaces'
'SurpassCamera'
'Volume'
OUTPUT
children : cell array of objects
getDataSubVolume( )
This method returns a data subvolume from Imaris.
[+/-] SYNOPSIS
(1) stack = conn.getDataSubVolume(x0, y0, z0, channel, timepoint, ...
dX, dY, dZ)
(2) stack = conn.getDataSubVolume(x0, y0, z0, channel, timepoint, ...
dX, dY, dZ, iDataSet)
INPUT
x0, y0, z0: coordinates (0/1-based depending on indexing start) of
the top-left vertex of the subvolume to be returned.
channel : channel number (0/1-based depending on indexing start)
timepoint : timepoint number (0/1-based depending on indexing start)
dX, dY, dZ: extension of the subvolume to be returned
dataset : (optional) get the data volume from the passed IDataset
object instead of current one; if omitted, current dataset
(i.e. this.mImarisApplication.GetDataSet()) will be used.
This is useful for instance when masking channels.
Coordinates and extension are in voxels and not in units!
The following holds:
if conn.indexingStart == 0:
subA = conn.getDataSubVolume(x0, y0, z0, 0, 0, dX, dY, dZ);
A = conn.getDataVolume(0, 0);
A(x0 + 1 : x0 + dX, y0 + 1 : y0 + dY, z0 + 1 : z0 + dZ) === subA
if conn.indexingStart == 1:
subA = conn.getDataSubVolume(x0, y0, z0, 1, 1, dX, dY, dZ);
A = conn.getDataVolume(1, 1);
A(x0 : x0 + dX - 1, y0 : y0 + dY - 1, z0 : z0 + dZ - 1) === subA
OUTPUT
stack : data subvolume (3D matrix)
REMARK
This function gets the volume as a 1D array and reshapes it in place.
It also performs a type cast to take care of the signed/unsigned int
mismatch when transferring data over Ice. The speed-up compared to
calling the ImarisXT GetDataVolumeBytes() or GetDataVolumeWords()
methods is of the order of 20x.
getDataSubVolumeRM( )
This method returns the data subvolume from Imaris in row-major order.
Practically, this means that each plane of a 3D stack is transposed
and will display in a plot in MATLAB with the same geometry and
orientation as in Imaris.
[+/-] SYNOPSIS
(1) stack = conn.getDataSubVolumeRM(x0, y0, z0, channel, timepoint, ...
dX, dY, dZ)
(2) stack = conn.getDataSubVolumeRM(x0, y0, z0, channel, timepoint, ...
dX, dY, dZ, iDataSet)
Please notice that the coordinates (x0, y0, z0) and the extension
(dX, dY, dZ) point to the same subvolume in the Imaris dataset. What
changes is the order by which it is returned to MATLAB.
INPUT
x0, y0, z0: coordinates (0/1-based depending on indexing start) of
the top-left vertex of the subvolume to be returned
channel : channel number (0/1-based depending on indexing start)
timepoint : timepoint number (0/1-based depending on indexing start)
dX, dY, dZ: extension of the subvolume to be returned
dataset : (optional) get the data volume from the passed IDataset
object instead of current one; if omitted, current dataset
(i.e. this.mImarisApplication.GetDataSet()) will be used.
This is useful for instance when masking channels.
Coordinates and extension are in voxels and not in units!
The following holds:
if conn.indexingStart == 0:
subA = conn.getDataSubVolumeRM(x0, y0, z0, 0, 0, dX, dY, dZ);
A = conn.getDataVolumeRM(0, 0);
A(y0 + 1 : y0 + dY, x0 + 1 : x0 + dX, z0 + 1 : z0 + dZ) === subA
Please notice the x - y dimension swap.
if conn.indexingStart == 1:
subA = conn.getDataSubVolumeRM(x0, y0, z0, 1, 1, dX, dY, dZ);
A = conn.getDataVolumeRM(1, 1);
A(y0 : y0 + dY - 1, x0 : x0 + dX - 1, z0 : z0 + dZ - 1) === subA
Please notice the x - y dimension swap.
OUTPUT
stack : data subvolume (3D matrix)
getDataVolume( )
This method returns the data volume from Imaris.
[+/-] SYNOPSIS
(1) stack = conn.getDataVolume(channel, timepoint)
(2) stack = conn.getDataVolume(channel, timepoint, iDataSet)
INPUT
channel : channel number (0/1-based depending on indexing start)
timepoint: timepoint number (0/1-based depending on indexing start)
iDataSet : (optional) get the data volume from the passed IDataset
object instead of current one; if omitted, current dataset
(i.e. this.mImarisApplication.GetDataSet()) will be used.
This is useful for instance when masking channels.
OUTPUT
stack : data volume (3D matrix)
REMARK
This function gets the volume as a 1D array and reshapes it in place.
It also performs a type cast to take care of the signed/unsigned int
mismatch when transferring data over Ice. The speed-up compared to
calling the ImarisXT GetDataVolumeBytes() or GetDataVolumeWords()
methods is of the order of 20x.
getDataVolumeRM( )
This method returns the data volume from Imaris in row-major order.
Practically, this means that each plane of a 3D stack is transposed
and will display in a plot in MATLAB with the same geometry and
orientation as in Imaris.
[+/-] SYNOPSIS
(1) stack = conn.getDataVolumeRM(channel, timepoint)
(2) stack = conn.getDataVolumeRM(channel, timepoint, iDataset)
INPUT
channel : channel number (0/1-based depending on indexing start)
timepoint: timepoint number (0/1-based depending on indexing start)
iDataset : (optional) get the data volume from the passed IDataset
object instead of current one; if omitted, current dataset
(i.e. this.mImarisApplication.GetDataSet()) will be used.
This is useful for instance when masking channels.
OUTPUT
stack : data volume (3D matrix)
getExtends( )
This method returns the dataset extends.
[+/-] SYNOPSIS
(1) extends = conn.getExtends()
(2) [minX, maxX, minY, maxY, minZ, maxZ] = conn.getExtends()
INPUT
None
OUTPUT
(1) extends : vector of extends, [minX maxX minY maxY minZ maxZ]
(2) minX : minimum dataset extend in X direction
maxX : maximum dataset extend in X direction
minY : minimum dataset extend in Y direction
maxY : maximum dataset extend in Y direction
minZ : minimum dataset extend in Z direction
maxZ : maximum dataset extend in Z direction
getImarisVersionAsInteger( )
This static method returns the version number of Imaris as integer:
v = 100000 * Major + 10000 * Minor + 100 * Patch
[+/-] SYNOPSIS
version = IceImarisConnector.getVersionAsInteger()
INPUT
None
OUTPUT
version : Imaris version as integer
getMatlabDatatype( )
This method returns the datatype of the dataset as a MATLAB type
(e.g. one of 'uint8', 'uint16', 'single').
[+/-] SYNOPSIS
type = conn.getMatlabDatatype()
INPUT
None
OUTPUT
type : datatype of the dataset as a MATLAB type: one of one of 'uint8',
'uint16', 'single', or '' if the type is unknown in Imaris.
getSizes( )
This method returns the dataset sizes.
[+/-] SYNOPSIS
(1) sizes = conn.getSizes()
(2) [sizeX, sizeY, sizeZ, sizeC, sizeT] = conn.getSizes()
INPUT
None
OUTPUT
(1) sizes : vector of sizes, [sizeX sizeY sizeZ sizeC sizeT]
(2) sizeX : dataset size X
sizeY : dataset size Y
sizeZ : number of planes
sizeC : number of channels
sizeT : number of time points
getSurpassCameraRotationMatrix( )
This method calculates the rotation matrix that corresponds to current
view in the Surpass Scene (from the Camera Quaternion) for the axes
with "Origin Bottom Left".
TO DO
Verify the correctness for the other axes orientations.
[+/-] SYNOPSIS
[R, isI] = conn.getSurpassCameraRotationMatrix()
INPUT
None
OUTPUT
R : (4 x 4) rotation matrix
isI : true if the rotation matrix is the Identity matrix, i.e. the
camera is perpendicular to the dataset
getSurpassSelection( )
This method returns the auto-casted current surpass selection. If
the 'type' parameter is specified, the object class is checked
against it and [] is returned instead of the object if the type
does not match.
[+/-] SYNOPSIS
(1) selection = conn.getSurpassSelection()
(2) selection = conn.getSurpassSelection(type)
INPUT
type : (optional) Specify the expected object class. If the selected
object is not of the specified type, the function will return
[] instead. Type is one of:
'Cells'
'ClippingPlane'
'Dataset'
'Filaments'
'Frame'
'LightSource'
'MeasurementPoints'
'Spots'
'Surfaces'
'SurpassCamera'
'Volume'
OUTPUT
selection : autocasted, currently selected surpass object; if nothing
is selected, or if the object class does not match the
passed type, selection will be [] instead.
getVoxelSizes( )
This method returns the X, Y, and Z voxel sizes of the dataset.
[+/-] SYNOPSIS
(1) voxelSizes = conn.getVoxelSizes()
(2) [voxelSizeX voxelSizeY voxelSizeZ] = conn.getVoxelSizes()
INPUT
None
OUTPUT
(1) voxelSizes : vector of voxel sizes, [voxelSizeX voxelSizeY voxelSizeZ]
(2) voxelSizeX : voxel size in X direction
voxelSizeY : voxel size in Y direction
voxelSizeZ : voxel size in Z direction
indexingStart( )
This method returns the base for indexing.
[+/-] SYNOPSIS
n = conn.indexingStart()
INPUT
None
OUTPUT
n : either 0 or 1, depending on whether IceImarisConnector's indexing
was initialized as 0- or 1- based.
info( )
This methods displays the full paths to the Imaris and ImarisServer
executables and the ImarisLib jar archive.
[+/-] SYNOPSIS
conn.info()
INPUT
None
OUTPUT
None
REMARK
A summary of the object properties is output to console.
isAlive( )
This method checks whether the (stored) connection to Imaris is
still alive.
[+/-] SYNOPSIS
alive = conn.isAlive()
INPUT
None
OUTPUT
alive : 1 if the connection is still alive, 0 otherwise
isSupportedPlatform( )
This method checks whether IceImarisConnector is running on a supported
platform.
[+/-] SYNOPSIS
b = IceImarisConnector.isSupportedPlatform()
INPUT
None
OUTPUT
b : 1 if IceImarisConnector is running on a supported platform, 0
otherwise
mapPositionsUnitsToVoxels( )
This method maps voxel coordinates in dataset units to voxel indices.
[+/-] SYNOPSIS
(1) pos = conn.mapPositionsUnitsToVoxels(uPos)
(2) pos = ...
conn.mapPositionsUnitsToVoxels(uPosX, uPosY, uPosZ)
(3) [posX, posY, posZ] = ...
conn.mapPositionsUnitsToVoxels(uPos)
(4) [posX, posY, posZ] = ...
conn.mapPositionsUnitsToVoxels(uPosX, uPosY, uPosZ)
INPUT
(1) and (3):
uPos : (N x 3) matrix containing the X, Y, Z coordinates in dataset
units
(2) and (4):
uPosX : (M x 1) vector containing the X coordinates in dataset units
uPosY : (N x 1) vector containing the Y coordinates in dataset units
uPosZ : (O x 1) vector containing the Z coordinates in dataset units
M, N, a O will most likely be the same (and must be the same for
synopsis 2).
OUTPUT
(1) and (2):
pos : (N x 3) matrix containing the X, Y, Z voxel indices
(3) and (4):
posX : (M x 1) vector containing the X voxel indices
posY : (N x 1) vector containing the Y voxel indices
posZ : (O x 1) vector containing the Z voxel indices
M, N, a O will most likely be the same.
mapPositionsVoxelsToUnits( )
This method maps voxel indices in dataset units to unit coordinates.
[+/-] SYNOPSIS
(1) pos = conn.mapPositionsVoxelsToUnits(vPos)
(2) pos = ...
conn.mapPositionsVoxelsToUnits(vPosX, vPosY, vPosZ)
(3) [posX, posY, posZ] = ...
conn.mapPositionsVoxelsToUnits(vPos)
(4) [posX, posY, posZ] = ...
conn.mapPositionsVoxelsToUnits(vPosX, vPosY, vPosZ)
INPUT
(1) and (3):
vPos : (N x 3) matrix containing the X, Y, Z unit coordinates
mapped onto a voxel grid
(2) and (4):
vPosX : (M x 1) vector containing the X coordinates mapped onto a
voxel grid
vPosY : (N x 1) vector containing the Y coordinates mapped onto a
voxel grid
vPosZ : (O x 1) vector containing the Z coordinates mapped onto a
voxel grid
M, N, a O will most likely be the same (and must be the same for
synopsis 2).
OUTPUT
(1) and (2):
pos : (N x 3) matrix containing the X, Y, Z coordinates in
dataset units
(3) and (4):
posX : (M x 1) vector containing the X coordinates in dataset units
posY : (N x 1) vector containing the Y coordinates in dataset units
posZ : (O x 1) vector containing the Z coordinates in dataset units
M, N, a O will most likely be the same.
mapRgbaScalarToVector( )
This method maps an uint32 RGBA scalar to an 1-by-4, (0..1) vector
[+/-] SYNOPSIS
rgbaScalar = mapRgbaVectorToScalar(rgbaScalar)
INPUT
rgbaScalar: int32 scalar number coding for RGBA (for Imaris use)
OUTPUT
rgbaVector: 1-by-4 array with [R G B A] indicating (R)ed, (G)reen,
(B)lue, and (A)lpha (=transparency; 0 is opaque)
IMPORTANT REMARK
The scalar returned by ImarisXT is signed int32 (since ImarisLib() is
written in Java). This means that if the transparency is not zero
(i.e. the value for A in the RGBA scalar is not zero), the returned
value WILL BE NEGATIVE (i.e. Imaris pushes an uint32 through ImarisXT
and thus Java and this reaches MATLAB as a signed int32)!
The mapRgbaScalarToVector() function will work around this problem
by forcing a typecast (and not just a cast!) to int32 passing through
a forced cast to int32 (since ImarisXT's .GetColorRGBA() returns a
double...).
Please notice that the combined values for R, G, and B will be
represented correctly no matter if the RGBA scalar is stored in an
int32 or an uint32, therefore the transparency "bug" does not affect
the actual colors.
SEE ALSO
mapRgbaScalarToVector
mapRgbaVectorToScalar( )
This method maps an 1-by-4, (0..1) RGBA vector to an uint32 scalar
[+/-] SYNOPSIS
rgbaScalar = mapRgbaVectorToScalar(rgbaVector)
INPUT
rgbaVector: 1-by-4 array with [R G B A] indicating (R)ed, (G)reen,
(B)lue, and (A)lpha (=transparency; 0 is opaque).
All values are between 0 and 1.
OUTPUT
rgbaScalar: uint32 scalar number coding for RGBA (for Imaris use)
IMPORTANT REMARK
The way one calculates the RGBA value from an [R G B A] vector (with
the values of R, G, B, and A all between 0 and 1) is simply:
uint32([R G B A] * [1 256 256^2 256^3])
(where * is the matrix product). This gives a number between 0 and
intmax('uint32') = 4294967295.
When we pass this number to Imaris through ImarisXT, the Java layer in
Ice will mess with this number, since there are no unsigned values
in Java and our original uint32 will end up negative if its value is
larger than 0.5 * intmax('uint32'): the first bit becomes the sign
bit.
The bit that changes is in the transparency (A) byte. Which means, if
we change the value for the tranparency, we will end up with an
incorrect result in Imaris.
To work around this problem, we must typecast (and not just cast!)
the calculated uint32 value to int32 before it is ready to be sent
to Imaris (i.e. to be passed to the SetColorRGBA() method of the
IDataItem object.
SEE ALSO
mapRgbaVectorToScalar
setDataVolume( )
This method sets the data volume to Imaris.
[+/-] SYNOPSIS
conn.setDataVolume(stack, channel, timepoint)
INPUT
stack : 3D array of type uint8, uint16 or single
channel : channel number (0/1-based depending on indexing start)
timepoint: timepoint number (0/1-based depending on indexing start)
OUTPUT
none
REMARK
If a dataset exists, the X, Y, and Z dimensions must match the ones of
the stack being copied in. If no dataset exists, one will be created
to fit it with default other values.
setDataVolumeRM( )
This method sends the data volume to Imaris in row-major order.
Practically, this means that each plane of a 3D stack from MATLAB
is transposed before it is pushed back into Imaris to maintain the
same geometry and orientation.
[+/-] SYNOPSIS
conn.setDataVolumeRM(stack, channel, timepoint)
INPUT
stack : 3D array of type uint8, uint16 or single
channel : channel number (0/1-based depending on indexing start)
timepoint: timepoint number (0/1-based depending on indexing start)
OUTPUT
None
REMARK
If a dataset exists, the X, Y, and Z dimensions must match the ones of
the stack being copied in. If no dataset exists, one will be created
to fit it with default other values.
startImaris( )
This method starts an Imaris instance and stores the ImarisApplication
ICE object.
[+/-] SYNOPSIS
success = conn.startImaris(userControl)
INPUT
userControl : (optional, default = 0)
The optional parameter userControl sets the fate of
Imaris when the client is closed: if userControl is
true (1), Imaris terminates when the IceImarisConnector
object (conn) is deleted. If is it set to false (0),
Imaris stays open after the IceImarisConnector object
(conn) is deleted.
OUTPUT
success : 1 if starting Imaris was successful, 0 otherwise
version( )
This method returns the IceImarisConnector version number.
[+/-] SYNOPSIS
v = IceImarisConnector.version()
INPUT
None
OUTPUT
v : IceImarisConnector version