VoxelManager Documentation
The VoxelManager is a key component of the Cornerstone library’s new architecture for handling voxel data and volume management. This updated design streamlines data flow and enhances performance, providing a single source of truth for image caching and data access, with a focus on reducing memory usage and improving performance in handling large image datasets.
Overview
With the integration of VoxelManager, voxel data handling shifts from relying on large scalar arrays to using individual images and targeted voxel data access methods. VoxelManager serves as an adapter for tools and functions that interact with voxel data, providing efficient methods for accessing, modifying, and streaming voxel information.
Key Features
- Single Source of Truth: Only the image cache is used, eliminating the need for separate volume caches and reducing synchronization issues.
- Efficient Volume Streaming: Loads image by image, caching only what’s necessary and streaming data directly to the GPU.
- Optimized Caching: Data is stored in its native format and converted only as needed, minimizing memory and processing overhead.
- Simplified Web Worker Implementation: Removed
SharedArrayBuffer
dependencies, simplifying security and worker requirements.
VoxelManager API
The VoxelManager API replaces direct scalar data access with methods that provide precise control over voxel data without generating large data arrays. Here are the primary methods and usage patterns:
Accessing Voxel Data
getScalarData()
: Returns the scalar data array for individual images (applicable only toIImage
).getScalarDataLength()
: Provides the total voxel count, replacingscalarData.length
.getAtIndex(index)
: Retrieves the voxel value at a specific linear index.setAtIndex(index, value)
: Sets the voxel value at a specific linear index.getAtIJK(i, j, k)
: Gets the voxel value at IJK coordinates.setAtIJK(i, j, k, value)
: Sets the voxel value at IJK coordinates.getArrayOfModifiedSlices()
: Lists modified slice indices.
Data Manipulation
forEach(callback, options)
: Iterates over voxels with a callback for processing or modifying data.toIndex(ijk)
: Converts IJK coordinates to a linear index.toIJK(index)
: Converts a linear index back to IJK coordinates.
Volume Information
getConstructor()
: Returns the scalar data type constructor.getBoundsIJK()
: Fetches the volume bounds in IJK coordinates.
Specialized Methods
setTimePoint(timePoint)
: For 4D datasets, sets the current time point.getAtIndexAndTimePoint(index, timePoint)
: Retrieves the voxel value at a specified index and time point.
Example: Migrating Data Access and Manipulation
Instead of accessing scalarData
directly, use VoxelManager for data manipulation. Here’s a migration example:
Before
function processVolume(volume) {
const scalarData = volume.getScalarData();
for (let i = 0; i < scalarData.length; i++) {
if (scalarData[i] > 100) {
scalarData[i] = 100;
}
}
}
After
function processVolume(volume) {
const voxelManager = volume.voxelManager;
const length = voxelManager.getScalarDataLength();
for (let i = 0; i < length; i++) {
const value = voxelManager.getAtIndex(i);
if (value > 100) {
voxelManager.setAtIndex(i, 100);
}
}
}
Handling Image Volume Construction
When creating volumes, scalarData
is no longer required. Instead, use VoxelManager
internally:
Before
const streamingImageVolume = new StreamingImageVolume({
volumeId,
metadata,
dimensions,
spacing,
origin,
direction,
scalarData,
sizeInBytes,
imageIds,
});
After
const streamingImageVolume = new StreamingImageVolume({
volumeId,
metadata,
dimensions,
spacing,
origin,
direction,
imageIds,
dataType,
numberOfComponents,
});
Best Practices
- Data Access Optimization: Use
getAtIndex
andsetAtIndex
for bulk operations due to their efficiency. UseforEach
for large-volume iteration. - Memory Management: Avoid
getCompleteScalarDataArray()
as it rebuilds large data arrays and can degrade performance. - Handling RGB Data:
getAtIndex
andgetAtIJK
return[r, g, b]
arrays for RGB volumes.
Conclusion
The VoxelManager is central to Cornerstone’s new volume management strategy, offering a flexible, efficient API for voxel data access and manipulation. This migration to VoxelManager allows for more efficient memory usage, faster performance, and improved compatibility with large datasets, ensuring a smoother workflow for developers working with complex medical imaging data.