-
Notifications
You must be signed in to change notification settings - Fork 289
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cornerstone 2.0 #1400
base: main
Are you sure you want to change the base?
Cornerstone 2.0 #1400
Conversation
❌ Deploy Preview for cornerstone-3d-docs failed. Why did it fail? →
|
); | ||
await viewport.setStack([imageId], 0); | ||
const viewport = renderingEngine.getViewport(viewportId); | ||
await (viewport as Types.IStackViewport).setStack([imageId], 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you leave this as a generic viewport and call setDataIds instead? I think that would be more consistent across viewport types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want the migration to be as minimal as possible. I understand it will be consistent, but perhaps this could be implemented in Cornerstone3D 3.0?
For the image volume, the access to that data is pretty low level, assuming that the internal organization of the pixel data is exactly a typed array and that there may or may not be slices associated with it. That causes us memory issues as we try to allocate larger buffers, and also forces us to share the image slice data in order to not need to copy the data all the time. If we could start having a better interface on top of the ImageVolume and other image data objects to hide some of the internal details, it would eventually allow us to use a single representation consistently. The VoxelManager is designed to be an abstraction on top of different types of views of both single and multiple images. Given that we don't get new versions of CS3D very often, starting to use the VoxelManager more consistently and perhaps deprecating the use of the full data object would be worthwhile. |
…ntation. (#1508) * docs(image loader/metadata provider): Clarify concept + how-to documentation. * Slight further addition to example
Breaking Changes: Cornerstone 1.x to 2.x
While it may appear that many files have been changed, with almost all files affected, it's important to note that most changes involve fixing import types and removing dependency cycles. Let's examine these changes in more detail below.
We've addressed and documented all changes, but if you notice any undocumented modifications in the migration guides, please create a pull request to add them.
General
Typescript Version
We have upgraded the typescript version from 4.6 to 5.5 in the 2.0 version of the cornerstone3D.
This upgrade most likely doesn't require any changes in your codebase, but it is recommended to update the typescript version in your project to 5.5 to avoid any issues in the future.
Note
The upgrade to TypeScript 5.4 allows us to leverage the latest features and improvements offered by the TypeScript standard. You can read more about it here: https://devblogs.microsoft.com/typescript/announcing-typescript-5-5/
ECMAScript Target
🔄 Before: In Cornerstone3D version 1.x, we targeted ES5.
🆕 After: With the release of version 2.0, we have updated our target to
ES2022
.Note
It will result in a smaller bundle size and improved performance. There is a good chance that your setup already supports ES2022:
https://compat-table.github.io/compat-table/es2016plus/
Remove of CJS, only ESM builds
🔄 Before: Cornerstone3D 1.x shipped with both CommonJS (CJS) and ECMAScript Modules (ESM) builds.
🆕 After: Starting with Cornerstone3D 2.x, we will no longer ship the CommonJS (CJS) build of the library.
You most likely won't need to make any changes to your codebase. If you are aliasing the cjs library in your bundler, you can remove it completely.
Note
Both Node.js and modern browsers now support ECMAScript Modules (ESM) by default. However, in the rare case where you need a non-ESM version, you can use the Universal Module Definition (UMD) build of the library.
Package Exports
The Cornerstone libraries now utilize the
exports
field in theirpackage.json
files. This allows for more precise control over how modules are imported and ensures compatibility with different build systems.Below are examples of how to import modules from each package, along with explanations of the
exports
field configuration.@cornerstonejs/adapters
Import Examples:
@cornerstonejs/core
Import Examples:
@cornerstonejs/tools
Import Examples:
@cornerstonejs/dicom-image-loader
Import Examples:
cloneDeep
🔄 Before: Used a custom or third-party
cloneDeep
function.🆕 After: The
structuredClone
function has replaced the previous method.You don't need to make any changes to your codebase that uses Cornerstone3D.
Note
Why depend on a third-party library when we can use the native browser API?
@cornerstonejs/streaming-image-volume-loader
After years of development on Cornerstone3D, we recognized that volume loading should be treated as a first-class feature rather than a separate library. As a result, we have merged all functionality related to streaming image loading into the core library.
@cornerstonejs/streaming-image-volume-loader
package has been removed.@cornerstonejs/core
package.How to Migrate:
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:
Note
The
helpers
module has been replaced with specific utility functions likegetDynamicVolumeInfo
from the@cornerstonejs/core/utilities
import.Important
Make sure to update all relevant import statements throughout your codebase to reflect these changes.
@cornerstonejs/core
Initialization
Removal of
detect-gpu
anddetectGPUConfig
🔄 Before: Used
detect-gpu
for GPU tier detection.🆕 After: Default GPU tier of 2 (medium tier) is used, with option to configure.
Important
Cornerstone3D 2.x has removed the dependency on
detect-gpu
. This addresses issues in environments with restricted internet access.Key Changes:
How to Migrate:
If you were previously relying on
detect-gpu
, update your initialization code:Removal of
use16BitDataType
🔄 Before: Used
use16BitDataType
flag to request 16-bit data type from web worker.🆕 After: Always uses native data type for cache storage and converts for rendering when necessary.
Removal of
enableCacheOptimization
🔄 Before: Used
enableCacheOptimization
flag.🆕 After: Cache optimization is automatic.
Volume Viewports Actor UID, ReferenceId, and VolumeId
Previous Behavior
When adding a volume to volume viewports, the logic used to determine the actor's UID was as follows:
Updated Behavior
We've made changes to improve clarity and functionality. The actor UID is now distinct:
Key Changes
uuidv4()
).referenceId
toreferencedId
: For improved clarity.Migrations
🔄 Before:
or
or
🆕 After:
Viewport APIs
ImageDataMetaData
🔄 Before:
🆕 After:
Reset Camera
🔄 Before:
🆕 After:
Rotation
🔄 Before:
🆕 After:
Note
rotation
is not a property of the viewport but rather a view prop. You can now access it throughgetViewPresentation
.getReferenceId
🔄 Before:
viewport.getReferenceId()
🆕 After:
viewport.getViewReferenceId()
Note
It is more accurate to use
getViewReferenceId
to reflect the actual function of the method since it returns view-specific information, and not about the actor reference.New PixelData Model and VoxelManager
Important
The Cornerstone library has undergone significant changes in how it handles image volumes and texture management.
Key changes include:
Introduction of VoxelManager
A new
VoxelManager
class has been introduced to handle voxel data more efficiently.Migration Steps:
VoxelManager
methods.voxelManager.getScalarDataLength()
instead ofscalarData.length
.getAtIndex(index)
andsetAtIndex(index, value)
for accessing and modifying voxel data.voxelManager.getArrayOfModifiedSlices()
to get the list of modified slices.forEach
method for efficient iteration.Example of migrating a simple volume processing function:
🔄 Before:
🆕 After:
Note
For volumes (IImageVolume): Search your custom codebase for
getScalarData
orscalarData
. Instead, usevoxelManager
to access the scalar data API.Tip
If you can't use the atomic data API through
getAtIndex
andgetAtIJK
, you can fall back tovoxelManager.getCompleteScalarDataArray()
to rebuild the full scalar data array like cornerstone3D 1.0. However, this is not recommended due to performance and memory concerns. Use it only as a last resort.Note
For stack images (IImage): You can still use
image.getPixelData()
OR access the scalarData array from thevoxelManager
withimage.voxelManager.getScalarData()
.Image Volume Construction
The construction of image volumes has been updated to use
VoxelManager
and new properties, eliminating the need for large scalar data arrays.Note
There is no scalarData array in the volume object, and imageIds is sufficient to describe the volume.
🔄 Before:
🆕 After:
Migration Steps:
scalarData
andsizeInBytes
from the constructor parameters.dataType
andnumberOfComponents
to the constructor parameters.VoxelManager
will be created internally based on these parameters.Note
This change reflects the shift from using large scalar data arrays to using the VoxelManager for data management. It allows for more efficient memory usage and better handling of streaming data.
Accessing Volume Properties
Some volume properties are now accessed differently due to the
VoxelManager
integration.🔄 Before:
🆕 After:
Migration Steps:
getPointData().getScalars().getNumberOfComponents()
withget('numberOfComponents')
.numberOfComponents
property.Important
These changes represent a significant update to the Cornerstone library's handling of image volumes and textures. The introduction of the VoxelManager and the elimination of large scalar data arrays for volumes provide several benefits:
Developers will need to update their code to use the new VoxelManager API and adjust how they interact with volume data and textures.
Image Loader
Changes in Volume Creation Functions
The
createLocalVolume
function has been updated:🔄 Before:
🆕 After:
Migration Steps:
createLocalVolume
by moving thevolumeId
parameter to the first position.preventCache
parameter and handle caching separately if needed.Changes in Derived Volume Creation
The
createAndCacheDerivedVolume
function now returns synchronously:🔄 Before:
🆕 After:
Migration Steps:
await
keywords when callingcreateAndCacheDerivedVolume
.Renamed Functions
createAndCacheDerivedSegmentationVolume
is nowcreateAndCacheDerivedLabelmapVolume
createLocalSegmentationVolume
is nowcreateLocalLabelmapVolume
Migration Steps:
Target Buffer Type Migration
The
targetBufferType
option has been replaced with atargetBuffer
object:🔄 Before:
🆕 After:
Migration Steps:
targetBufferType
to usetargetBuffer
instead.targetBufferType: 'SomeType'
totargetBuffer: { type: 'SomeType' }
.Changes in
createAndCacheDerivedImage
FunctionThe function now returns an
IImage
object directly:🔄 Before:
🆕 After:
Migration Steps:
createAndCacheDerivedImage
to work with the directly returnedIImage
object.preventCache
parameter from function calls.Segmentation Image Helpers
The segmentation image helper functions have been renamed and updated:
🔄 Before:
🆕 After:
Migration Steps:
createAndCacheDerivedSegmentationImages
tocreateAndCacheDerivedLabelmapImages
.createAndCacheDerivedSegmentationImage
tocreateAndCacheDerivedLabelmapImage
.await
or.then()
calls when usingcreateAndCacheDerivedLabelmapImage
.Tip
These changes aim to improve performance, reduce memory usage, and provide more efficient data access, especially for large datasets. While they require significant updates to existing code, they provide a more efficient and flexible foundation for working with large medical imaging datasets.
Cache Class
The
Cache
class has undergone significant changes in version 2:Removal of Volume-specific Cache Size
🔄 Before: Separate volume cache size existed.
🆕 After: Only image cache is used.
Migration Steps:
_volumeCacheSize
if you had them.isCacheable Method Update
The
isCacheable
method now considers shared cache keys.New putImageSync and putVolumeSync Methods
🔄 Before: These methods did not exist.
🆕 After:
Migration Steps:
putImageSync
andputVolumeSync
methods when you need to add an image or volume to the cache synchronously.Renaming and Nomenclature
Enums
Removal of SharedArrayBufferModes
The following methods have been removed from @cornerstonejs/core:
GeometryType
🔄 Before:
GeometryType.CONTOUR
,GeometryType.Surface
🆕 After:
GeometryType.Contour
,GeometryType.Surface
ViewportType
🔄 Before:
ViewportType.WholeSlide
🆕 After:
ViewportType.WHOLE_SLIDE
Example:
Events and Event Details
VOLUME_SCROLL_OUT_OF_BOUNDS -> VOLUME_VIEWPORT_SCROLL_OUT_OF_BOUNDS
STACK_VIEWPORT_NEW_STACK -> VIEWPORT_NEW_IMAGE_SET
🔄 Before:
🆕 After:
Note
This change maintains consistency, as all other events like VOLUME_NEW_IMAGE were occurring on the element.
CameraModifiedEventDetail
The
rotation
is now accessed from the camera object in the event detail.ImageVolumeModifiedEventDetail
The
imageVolume
is no longer available in the event detail. Usecache.getVolume
method to get the imageVolume if needed.4D Or Dynamic Volume
imageIdsGroups is now imageIdGroups
🔄 Before:
🆕 After:
StreamingDynamicImageVolume
Constructor Changes
🔄 Before:
🆕 After:
Migration Steps:
imageIdGroups
instead ofscalarData
.scalarData
arrays.New Methods for ImageId Management
New methods introduced:
getCurrentTimePointImageIds()
flatImageIdIndexToTimePointIndex()
flatImageIdIndexToImageIdIndex()
Removal of getScalarData Method and Using VoxelManager for Dynamic Image Volumes
🔄 Before: Used
getScalarData()
method🆕 After: Use
VoxelManager
methodsExample:
Exports Imports
🔄 Before:
🆕 After:
getDataInTime
The
imageCoordinate
option is nowworldCoordinate
.generateImageFromTimeData
🔄 Before:
🆕 After:
@cornerstonejs/tools
triggerAnnotationRenderForViewportIds
🔄 Before:
🆕 After:
Tools
StackScrollMouseWheelTool -> StackScrollTool
🔄 Before:
🆕 After:
VolumeRotateMouseWheelTool -> StackScrollTool
🔄 Before:
🆕 After:
BaseTool
🔄 Before:
🆕 After:
ToolGroups
Note
If the ID for a toolgroup already exists, it will return that toolgroup. Previously, it would throw an error.
Here's the converted version of the migration guide for the new segmentation model in Cornerstone3D 2.0, using GitHub Markdown format:
New Segmentation Model
Important
In Cornerstone3D 2.0, we've transitioned from tool group-based segmentation representation rendering to viewport-based ones.
Why?
Segmentation State
The
Segmentation
type has been restructured:🔄 Before:
🆕 After:
Representation Data Key
The
SegmentationRepresentations
enum has been updated to use title case:🔄 Before:
🆕 After:
Segmentation Representation
The representation structure is now viewport-specific:
🔄 Before:
🆕 After:
Removal of SegmentationDisplayTool
🔄 Before:
🆕 After:
// No need to add or enable SegmentationDisplayTool
Stack Labelmaps
🔄 Before:
🆕 After:
Adding Segmentations
Function Signature Update
🔄 Before:
🆕 After:
SegmentationPublicInput Type Updates
🔄 Before:
🆕 After:
Adding Segmentation Representations
Viewport-Centric Approach
🔄 Before:
🆕 After:
RepresentationPublicInput Changes
🔄 Before:
🆕 After:
New Representation-Specific Functions
🆕 After:
Multi-Viewport Functions
🆕 After:
Events
Removal of ToolGroup Specific Events
🔄 Before:
🆕 After:
Simplified Segmentation Modified Event
🔄 Before:
🆕 After:
Updated Event Detail Types
🔄 Before:
🆕 After:
Segmentation Config/Style
New Functions
getStyle(specifier)
setStyle(specifier, style)
setRenderInactiveSegmentations(viewportId, renderInactiveSegmentations)
getRenderInactiveSegmentations(viewportId)
resetToGlobalStyle()
hasCustomStyle(specifier)
Getting Global Segmentation Config
🔄 Before:
🆕 After:
Setting Global Segmentation Config
🔄 Before:
🆕 After:
Getting and Setting ToolGroup-Specific Config
🔄 Before:
🆕 After:
Getting and Setting Segmentation Representation-Specific Config
🔄 Before:
🆕 After:
Getting and Setting Segment-Specific Config
🔄 Before:
🆕 After:
Note
These changes represent a significant update to the Cornerstone library's handling of segmentations. The new approach provides more flexibility and better control over segmentation representations at the viewport level.
Here's the converted version of the migration guide for the additional changes in Cornerstone3D 2.0, using GitHub Markdown format:
Setting Render Inactive Segmentations
🔄 Before:
🆕 After:
Resetting to Global Style
🆕 After:
Example Migration
🔄 Before:
🆕 After:
Note
getStyle
andsetStyle
functions provide a unified way to manage segmentation styles across different levels.specifier
object allows you to target specific viewports, segmentations, and segments.Active
Viewport-based Operations
🔄 Before:
🆕 After:
Migration Steps:
toolGroupId
withviewportId
in function calls.getActiveSegmentationRepresentation
andgetActiveSegmentation
calls to use the newgetActiveSegmentation
function.setActiveSegmentationRepresentation
calls withsetActiveSegmentation
, using the new parameter structure.Visibility
Viewport-Centric Approach
🔄 Before:
🆕 After:
Migration Steps:
toolGroupId
withviewportId
in function calls.specifier
object instead ofsegmentationRepresentationUID
.segmentationId
in thespecifier
object.type
of segmentation representation.Segment-Level Visibility Control
🔄 Before:
🆕 After:
Migration Steps:
setSegmentVisibility
tosetSegmentIndexVisibility
.toolGroupId
withviewportId
.specifier
object withsegmentationId
and optionaltype
instead ofsegmentationRepresentationUID
.Locking
Retrieving Locked Segments
🔄 Before:
🆕 After:
Migration Steps:
getLockedSegments
togetLockedSegmentIndices
.Color
Viewport-Centric Approach
🔄 Before:
🆕 After:
Migration Steps:
toolGroupId
withviewportId
in function calls.segmentationRepresentationUID
withsegmentationId
.Color LUT Management
🔄 Before:
🆕 After:
Migration Steps:
addColorLUT
to handle the returned index if needed.colorLUTIndex
parameter optional in function calls.Segment Color Retrieval and Setting
🔄 Before:
🆕 After:
Migration Steps:
getColorForSegmentIndex
togetSegmentIndexColor
.setColorForSegmentIndex
tosetSegmentIndexColor
.viewportId
instead oftoolGroupId
.segmentationRepresentationUID
withsegmentationId
in function calls.Other Changes
Renaming
getToolGroupIdsWithSegmentation
🔄 Before:
🆕 After:
Migration Steps:
getToolGroupIdsWithSegmentation
withgetViewportIdsWithSegmentation
.Important
These changes reflect a significant shift from tool group-based to viewport-based operations in Cornerstone3D 2.0. Make sure to update all relevant parts of your codebase to align with this new approach.
Here's the converted version of the migration guide for the additional changes in Cornerstone3D 2.0, using GitHub Markdown format:
Segmentation Representation Management
🔄 Before:
🆕 After:
Migration Steps:
addSegmentationRepresentation
to useviewportId
instead oftoolGroupId
.getSegmentationRepresentationByUID
withgetSegmentationRepresentation
, using the new specifier object.removeSegmentationRepresentation
calls to use the new specifier object instead ofsegmentationRepresentationUID
.PolySEG
Import
🆕 After:
Options
🔄 Before:
🆕 After:
Actor UID for labelmaps
🔄 Before:
🆕 After:
New function for getting segmentation actor:
New Utilities
🆕 After:
Renaming and Nomenclature
Types
🔄 Before:
PointsManager
🆕 After:
IPointsManager
Migration:
Units
getCalibratedLengthUnitsAndScale Signature
🔄 Before:
🆕 After:
getModalityUnit -> getPixelValueUnits
BasicStatsCalculator
🔄 Before:
noPointsCollection
🆕 After:
storePointData
Renaming
getSegmentAtWorldPoint
->getSegmentIndexAtWorldPoint
getSegmentAtLabelmapBorder
->getSegmentIndexAtLabelmapBorder
Others
roundNumber
🆕 After:
pointInShapeCallback
🆕 After:
@cornerstonejs/dicom-image-loader
Initialization
🔄 Before:
🆕 After:
Decoders Update
Remove the following rule from your bundler configuration:
Always
Prescale
Note
By default, Cornerstone3D always prescales images with the modality LUT (rescale slope and intercept). You probably don't need to make any changes to your codebase.
Removal of
minAfterScale
andmaxAfterScale
onimageFrame
Use
smallestPixelValue
andlargestPixelValue
instead.DICOM Image Loader ESM default
🔄 Before:
🆕 After: Remove this alias and use the default import.
@cornerstonejs/nifti-image-volume-loader
🔄 Before:
🆕 After:
Developer Experience
Dependency Cycles
Run
yarn run format-check
to ensure correct formatting and check for dependencies.Published APIs
Run
yarn run build:update-api
and include the generated files in your PR.Karma tests
Setup and Cleanup
🔄 Before:
🆕 After:
Viewport Creation
🆕 After:
Image Id and Volume Id
🔄 Before:
🆕 After:
For volumeId:
Note
These changes represent significant updates to the Cornerstone3D library. Make sure to update your codebase accordingly and test thoroughly after migration.