@cornerstonejs/labelmap-interpolation 3.0.0-beta.3 → 3.0.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ import interpolate from './utilities/interpolateLabelmap';
2
+ export { interpolate };
@@ -0,0 +1,2 @@
1
+ import interpolate from './utilities/interpolateLabelmap';
2
+ export { interpolate };
@@ -0,0 +1 @@
1
+ export declare function registerInterpolationWorker(): void;
@@ -0,0 +1,23 @@
1
+ import { getWebWorkerManager } from '@cornerstonejs/core';
2
+ let registered = false;
3
+ export function registerInterpolationWorker() {
4
+ if (registered) {
5
+ return;
6
+ }
7
+ registered = true;
8
+ const workerFn = () => {
9
+ return new Worker(new URL('./workers/interpolationWorker.js', import.meta.url), {
10
+ name: 'interpolation',
11
+ type: 'module',
12
+ });
13
+ };
14
+ const workerManager = getWebWorkerManager();
15
+ const options = {
16
+ maxWorkerInstances: 1,
17
+ autoTerminateOnIdle: {
18
+ enabled: true,
19
+ idleTimeThreshold: 2000,
20
+ },
21
+ };
22
+ workerManager.registerWorker('interpolation', workerFn, options);
23
+ }
@@ -0,0 +1,15 @@
1
+ type MorphologicalContourInterpolationOptions = {
2
+ label?: number;
3
+ axis?: number;
4
+ noHeuristicAlignment?: boolean;
5
+ noUseDistanceTransform?: boolean;
6
+ useCustomSlicePositions?: boolean;
7
+ };
8
+ declare function interpolateLabelmap({ segmentationId, segmentIndex, configuration, }: {
9
+ segmentationId: string;
10
+ segmentIndex: number;
11
+ configuration?: MorphologicalContourInterpolationOptions & {
12
+ preview: boolean;
13
+ };
14
+ }): Promise<void>;
15
+ export default interpolateLabelmap;
@@ -0,0 +1,44 @@
1
+ import { getWebWorkerManager, eventTarget, Enums, triggerEvent, } from '@cornerstonejs/core';
2
+ import { segmentation, Enums as csToolsEnums, utilities, } from '@cornerstonejs/tools';
3
+ import { registerInterpolationWorker } from '../registerWorker';
4
+ const { triggerSegmentationEvents } = segmentation;
5
+ const { getOrCreateSegmentationVolume } = utilities.segmentation;
6
+ const { triggerSegmentationDataModified } = triggerSegmentationEvents;
7
+ const { WorkerTypes } = csToolsEnums;
8
+ const workerManager = getWebWorkerManager();
9
+ const triggerWorkerProgress = (eventTarget, progress) => {
10
+ triggerEvent(eventTarget, Enums.Events.WEB_WORKER_PROGRESS, {
11
+ progress,
12
+ type: WorkerTypes.INTERPOLATE_LABELMAP,
13
+ });
14
+ };
15
+ async function interpolateLabelmap({ segmentationId, segmentIndex, configuration = { preview: false }, }) {
16
+ registerInterpolationWorker();
17
+ triggerWorkerProgress(eventTarget, 0);
18
+ const segVolume = getOrCreateSegmentationVolume(segmentationId);
19
+ const { voxelManager: segmentationVoxelManager, imageData: segmentationImageData, } = segVolume;
20
+ const segmentationInfo = {
21
+ scalarData: segmentationVoxelManager.getCompleteScalarDataArray(),
22
+ dimensions: segmentationImageData.getDimensions(),
23
+ spacing: segmentationImageData.getSpacing(),
24
+ origin: segmentationImageData.getOrigin(),
25
+ direction: segmentationImageData.getDirection(),
26
+ };
27
+ try {
28
+ const { data: outputScalarData } = await workerManager.executeTask('interpolation', 'interpolateLabelmap', {
29
+ segmentationInfo,
30
+ configuration: {
31
+ ...configuration,
32
+ label: segmentIndex,
33
+ },
34
+ });
35
+ segmentationVoxelManager.setCompleteScalarDataArray(outputScalarData);
36
+ triggerSegmentationDataModified(segmentationId, segmentationVoxelManager.getArrayOfModifiedSlices(), segmentIndex);
37
+ triggerWorkerProgress(eventTarget, 100);
38
+ }
39
+ catch (error) {
40
+ console.warn('Warning: Failed to perform morphological contour interpolation', error);
41
+ triggerWorkerProgress(eventTarget, 100);
42
+ }
43
+ }
44
+ export default interpolateLabelmap;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,129 @@
1
+ import { expose } from 'comlink';
2
+ import vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';
3
+ import vtkDataArray from '@kitware/vtk.js/Common/Core/DataArray';
4
+ async function peerImport(moduleId) {
5
+ try {
6
+ switch (moduleId) {
7
+ case 'itk-wasm':
8
+ return import('itk-wasm');
9
+ case '@itk-wasm/morphological-contour-interpolation':
10
+ return import('@itk-wasm/morphological-contour-interpolation');
11
+ default:
12
+ throw new Error(`Unknown module ID: ${moduleId}`);
13
+ }
14
+ }
15
+ catch (error) {
16
+ console.warn(`Error importing ${moduleId}:`, error);
17
+ return null;
18
+ }
19
+ }
20
+ const computeWorker = {
21
+ getITKImage: async (args) => {
22
+ const { imageData, options } = args;
23
+ const { imageName, scalarData } = options;
24
+ let Image, ImageType, IntTypes, FloatTypes, PixelTypes;
25
+ try {
26
+ const itkModule = await peerImport('itk-wasm');
27
+ if (!itkModule) {
28
+ throw new Error('Module not found');
29
+ }
30
+ ({ Image, ImageType, IntTypes, FloatTypes, PixelTypes } = itkModule);
31
+ }
32
+ catch (error) {
33
+ console.warn("Warning: 'itk-wasm' module not found. Please install it separately.");
34
+ return null;
35
+ }
36
+ const dataTypesMap = {
37
+ Int8: IntTypes.Int8,
38
+ UInt8: IntTypes.UInt8,
39
+ Int16: IntTypes.Int16,
40
+ UInt16: IntTypes.UInt16,
41
+ Int32: IntTypes.Int32,
42
+ UInt32: IntTypes.UInt32,
43
+ Int64: IntTypes.Int64,
44
+ UInt64: IntTypes.UInt64,
45
+ Float32: FloatTypes.Float32,
46
+ Float64: FloatTypes.Float64,
47
+ };
48
+ const { numberOfComponents } = imageData.get('numberOfComponents');
49
+ const dimensions = imageData.getDimensions();
50
+ const origin = imageData.getOrigin();
51
+ const spacing = imageData.getSpacing();
52
+ const directionArray = imageData.getDirection();
53
+ const direction = new Float64Array(directionArray);
54
+ const dataType = scalarData.constructor.name
55
+ .replace(/^Ui/, 'UI')
56
+ .replace(/Array$/, '');
57
+ const metadata = undefined;
58
+ const imageType = new ImageType(dimensions.length, dataTypesMap[dataType], PixelTypes.Scalar, numberOfComponents);
59
+ const image = new Image(imageType);
60
+ image.name = imageName;
61
+ image.origin = origin;
62
+ image.spacing = spacing;
63
+ image.direction = direction;
64
+ image.size = dimensions;
65
+ image.metadata = metadata;
66
+ image.data = scalarData;
67
+ return image;
68
+ },
69
+ interpolateLabelmap: async (args) => {
70
+ const { segmentationInfo, configuration } = args;
71
+ const { scalarData, dimensions, spacing, origin, direction } = segmentationInfo;
72
+ let itkModule;
73
+ try {
74
+ itkModule = await peerImport('@itk-wasm/morphological-contour-interpolation');
75
+ if (!itkModule) {
76
+ throw new Error('Module not found');
77
+ }
78
+ }
79
+ catch (error) {
80
+ console.warn("Warning: '@itk-wasm/morphological-contour-interpolation' module not found. Please install it separately.");
81
+ return { data: scalarData };
82
+ }
83
+ const imageData = vtkImageData.newInstance();
84
+ imageData.setDimensions(dimensions);
85
+ imageData.setOrigin(origin);
86
+ imageData.setDirection(direction || [1, 0, 0, 0, 1, 0, 0, 0, 1]);
87
+ imageData.setSpacing(spacing);
88
+ const scalarArray = vtkDataArray.newInstance({
89
+ name: 'Pixels',
90
+ numberOfComponents: 1,
91
+ values: scalarData,
92
+ });
93
+ imageData.getPointData().setScalars(scalarArray);
94
+ imageData.modified();
95
+ try {
96
+ const inputImage = await computeWorker.getITKImage({
97
+ imageData,
98
+ options: {
99
+ imageName: 'interpolation',
100
+ scalarData: scalarData,
101
+ },
102
+ });
103
+ if (!inputImage) {
104
+ throw new Error('Failed to get ITK image');
105
+ }
106
+ const { outputImage } = await itkModule.morphologicalContourInterpolation(inputImage, {
107
+ ...configuration,
108
+ webWorker: false,
109
+ });
110
+ const outputScalarData = outputImage.data;
111
+ const modifiedScalarData = new Uint16Array(scalarData.length);
112
+ modifiedScalarData.set(scalarData);
113
+ for (let i = 0; i < outputScalarData.length; i++) {
114
+ const newValue = outputScalarData[i];
115
+ const originalValue = scalarData[i];
116
+ if (newValue !== originalValue) {
117
+ modifiedScalarData[i] = newValue;
118
+ }
119
+ }
120
+ return { data: modifiedScalarData };
121
+ }
122
+ catch (error) {
123
+ console.error(error);
124
+ console.warn('Warning: Failed to perform morphological contour interpolation');
125
+ return { data: scalarData };
126
+ }
127
+ },
128
+ };
129
+ expose(computeWorker);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cornerstonejs/labelmap-interpolation",
3
- "version": "3.0.0-beta.3",
3
+ "version": "3.0.0-beta.4",
4
4
  "description": "Labelmap Interpolation utility for Cornerstone3D",
5
5
  "files": [
6
6
  "dist"
@@ -22,15 +22,19 @@
22
22
  "scripts": {
23
23
  "test": "jest --testTimeout 60000",
24
24
  "clean": "rimraf dist",
25
+ "clean:deep": "yarn run clean && shx rm -rf node_modules",
25
26
  "build": "yarn run build:esm",
26
27
  "build:esm": "tsc --project ./tsconfig.json",
27
28
  "build:esm:watch": "tsc --project ./tsconfig.json --watch",
28
29
  "dev": "tsc --project ./tsconfig.json --watch",
29
30
  "build:all": "yarn run build:esm",
30
- "build:update-api": "yarn run build:esm && api-extractor run --local",
31
31
  "start": "tsc --project ./tsconfig.json --watch",
32
32
  "format": "prettier --write 'src/**/*.js' 'test/**/*.js'",
33
- "lint": "eslint --fix ."
33
+ "lint": "eslint --fix .",
34
+ "format-check": "npx eslint ./src --quiet",
35
+ "api-check": "api-extractor --debug run ",
36
+ "build:update-api": "yarn run build:esm && api-extractor run --local",
37
+ "prepublishOnly": "yarn clean && yarn build"
34
38
  },
35
39
  "repository": {
36
40
  "type": "git",
@@ -47,9 +51,9 @@
47
51
  "itk-wasm": "1.0.0-b.165"
48
52
  },
49
53
  "peerDependencies": {
50
- "@cornerstonejs/core": "^3.0.0-beta.3",
51
- "@cornerstonejs/tools": "^3.0.0-beta.3",
54
+ "@cornerstonejs/core": "^3.0.0-beta.4",
55
+ "@cornerstonejs/tools": "^3.0.0-beta.4",
52
56
  "@kitware/vtk.js": "^32.9.0"
53
57
  },
54
- "gitHead": "d2b29db96b3ecf98c9e9f0591978423dc9f6cb3f"
58
+ "gitHead": "93464de8c8c6f01ca4ca35140c8f910b4a226582"
55
59
  }