4D Or Dynamic Volume
We think this is important enough to have a section for itself
imageIdsGroups is now imageIdGroups
if you were using splitImageIdsBy4DTags to get the imageIdsGroups now you should expect the return object to have ImageIdGroups instead of ImageIdsGroups
migration
const { imageIdsGroups } = splitImageIdsBy4DTags(imageIds);
should be
const { imageIdGroups } = splitImageIdsBy4DTags(imageIds);
StreamingDynamicImageVolume
Constructor Changes
The constructor signature has been updated to include imageIdGroups
instead of separate scalarData
arrays.
- Before 📦
- After 🚀🚀
constructor(
imageVolumeProperties: Types.ImageVolumeProps & { splittingTag: string },
streamingProperties: Types.IStreamingVolumeProperties
) {
// ...
}
constructor(
imageVolumeProperties: ImageVolumeProps & {
splittingTag: string;
imageIdGroups: string[][];
},
streamingProperties: IStreamingVolumeProperties
) {
// ...
}
Migration Steps:
- Update the constructor call to include
imageIdGroups
instead ofscalarData
. - Remove any code that previously handled
scalarData
arrays.
New Methods for ImageId Management
Version 2 introduces new methods for managing image IDs:
getCurrentTimePointImageIds()
flatImageIdIndexToTimePointIndex()
flatImageIdIndexToImageIdIndex()
Migration Steps:
- Use
getCurrentTimePointImageIds()
to get image IDs for the current time point. - Utilize
flatImageIdIndexToTimePointIndex()
andflatImageIdIndexToImageIdIndex()
for converting between flat indices and time point/image indices.
Removal of getScalarData Method and Using VoxelManager for Dynamic Image Volumes
The getScalarData()
method has been removed in version 2 in favor of the new voxel Manager
In version 2, the StreamingDynamicImageVolume
class now uses a VoxelManager
to handle time point data. This change provides more efficient memory management and easier access to voxel data across different time points. Here's how you can use the VoxelManager
to access and manipulate data in your dynamic image volumes:
Accessing Voxel Data
To access voxel data for the current time point:
const voxelValue = volume.voxelManager.get(index);
To access voxel data for a specific time point:
const voxelValue = volume.voxelManager.getAtIndexAndTimePoint(index, timePoint);
Getting Scalar Data
To get the complete scalar data array for the current time point:
const scalarData = volume.voxelManager.getCurrentTimePointScalarData();
To get the scalar data for a specific time point:
const scalarData = volume.voxelManager.getTimePointScalarData(timePoint);
Getting Volume Information
You can access various volume properties through the VoxelManager
:
const scalarDataLength = volume.voxelManager.getScalarDataLength();
const dataType = volume.voxelManager.getConstructor();
const dataRange = volume.voxelManager.getRange();
const middleSliceData = volume.voxelManager.getMiddleSliceData();
Migration Steps:
- Replace direct access to
scalarData
arrays with calls to the appropriateVoxelManager
methods. - Update any code that manually managed time points to use the
VoxelManager
's time point-aware methods. - Use
getCurrentTimePointScalarData()
orgetTimePointScalarData(tp)
instead of the removedgetScalarData()
method. - If you need to perform operations across all time points, you can iterate through them using the
numTimePoints
property and thegetTimePointScalarData(tp)
method.
By leveraging the VoxelManager
, you can efficiently work with dynamic image volumes without manually managing multiple scalar data arrays. This approach provides better performance and memory usage, especially for large datasets with many time points.
Exports Imports
If you were previously using @cornerstonejs/streaming-image-volume-loader
, you'll need to update your imports and potentially adjust your code to use the new integrated volume loading API in @cornerstonejs/core
.
- Before 📦
- After 🚀🚀
import {
cornerstoneStreamingDynamicImageVolumeLoader,
StreamingDynamicImageVolume,
helpers,
Enums,
} from '@cornerstonejs/streaming-image-volume-loader';
Enums.Events.DYNAMIC_VOLUME_TIME_POINT_INDEX_CHANGED;
import {
cornerstoneStreamingDynamicImageVolumeLoader,
StreamingDynamicImageVolume,
} from '@cornerstonejs/core';
import { getDynamicVolumeInfo } from '@cornerstonejs/core/utilities';
import { Enums } from '@cornerstonejs/core/enums';
Enums.Events.DYNAMIC_VOLUME_TIME_POINT_INDEX_CHANGED;
getDataInTime
The imageCoordinate option is now worldCoordinate, to better reflect that it's a world coordinate and not an image coordinate.
- Before 📦
- After 🚀
function getDataInTime(
dynamicVolume: Types.IDynamicImageVolume,
options: {
frameNumbers?;
maskVolumeId?;
imageCoordinate?;
}
): number[] | number[][];
function getDataInTime(
dynamicVolume: Types.IDynamicImageVolume,
options: {
frameNumbers?;
maskVolumeId?;
worldCoordinate?;
}
): number[] | number[][];
Usage Example
- Before 📦
- After 🚀
const result = getDataInTime(dynamicVolume, {
frameNumbers: [0, 1, 2],
imageCoordinate: [100, 100, 100],
});
const result = getDataInTime(dynamicVolume, {
frameNumbers: [0, 1, 2],
worldCoordinate: [100, 100, 100],
});
generateImageFromTimeData
- Before 📦
- After 🚀
function generateImageFromTimeData(
dynamicVolume: Types.IDynamicImageVolume,
operation: string,
frameNumbers?: number[]
);
function generateImageFromTimeData(
dynamicVolume: Types.IDynamicImageVolume,
operation: Enums.GenerateImageType,
options: {
frameNumbers?: number[];
}
): Float32Array;
Key Changes
operation
now usesEnums.GenerateImageType
enum.- Frame numbers are passed in an options object.
- Function explicitly returns
Float32Array
.
Usage Example
- Before 📦
- After 🚀
const result = generateImageFromTimeData(dynamicVolume, 'SUM', [0, 1, 2]);
const result = generateImageFromTimeData(
dynamicVolume,
Enums.GenerateImageType.SUM,
{
frameNumbers: [0, 1, 2],
}
);
Summary of Other Changes
- New
updateVolumeFromTimeData
function added for in-place volume updates. - Both functions now use
voxelManager
for improved performance. - Enhanced error handling and standardized error messages.
- Operations now use
Enums.GenerateImageType
for better type safety.