larvitar 1.5.13 → 2.0.0
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.
- package/.vscode/settings.json +4 -0
- package/README.md +78 -48
- package/bundler/webpack.common.js +27 -0
- package/bundler/webpack.dev.js +23 -0
- package/bundler/webpack.prod.js +19 -0
- package/decs.d.ts +12 -0
- package/dist/imaging/MetaDataReadable.d.ts +39 -0
- package/dist/imaging/MetaDataTypes.d.ts +3488 -0
- package/dist/imaging/imageAnonymization.d.ts +12 -0
- package/dist/imaging/imageColormaps.d.ts +47 -0
- package/dist/imaging/imageContours.d.ts +18 -0
- package/dist/imaging/imageIo.d.ts +42 -0
- package/dist/imaging/imageLayers.d.ts +56 -0
- package/dist/imaging/imageLoading.d.ts +65 -0
- package/dist/imaging/imageParsing.d.ts +46 -0
- package/dist/imaging/imagePresets.d.ts +43 -0
- package/dist/imaging/imageRendering.d.ts +238 -0
- package/dist/imaging/imageReslice.d.ts +14 -0
- package/dist/imaging/imageStore.d.ts +121 -0
- package/dist/imaging/imageTags.d.ts +22 -0
- package/dist/imaging/imageTools.d.ts +20 -0
- package/dist/imaging/imageUtils.d.ts +165 -0
- package/dist/imaging/loaders/commonLoader.d.ts +103 -0
- package/dist/imaging/loaders/dicomLoader.d.ts +29 -0
- package/dist/imaging/loaders/fileLoader.d.ts +33 -0
- package/dist/imaging/loaders/multiframeLoader.d.ts +37 -0
- package/dist/imaging/loaders/nrrdLoader.d.ts +112 -0
- package/dist/imaging/loaders/resliceLoader.d.ts +15 -0
- package/dist/imaging/monitors/memory.d.ts +41 -0
- package/dist/imaging/monitors/performance.d.ts +23 -0
- package/dist/imaging/parsers/ecg.d.ts +15 -0
- package/dist/imaging/parsers/nrrd.d.ts +3 -0
- package/dist/imaging/tools/custom/4dSliceScrollTool.d.ts +12 -0
- package/dist/imaging/tools/custom/contourTool.d.ts +409 -0
- package/dist/imaging/tools/custom/diameterTool.d.ts +18 -0
- package/dist/imaging/tools/custom/editMaskTool.d.ts +22 -0
- package/dist/imaging/tools/custom/ellipticalRoiOverlayTool.d.ts +45 -0
- package/dist/imaging/tools/custom/polygonSegmentationMixin.d.ts +54 -0
- package/dist/imaging/tools/custom/polylineScissorsTool.d.ts +11 -0
- package/dist/imaging/tools/custom/rectangleRoiOverlayTool.d.ts +45 -0
- package/dist/imaging/tools/custom/seedTool.d.ts +0 -0
- package/dist/imaging/tools/custom/setLabelMap3D.d.ts +39 -0
- package/dist/imaging/tools/custom/thresholdsBrushTool.d.ts +19 -0
- package/dist/imaging/tools/default.d.ts +53 -0
- package/dist/imaging/tools/interaction.d.ts +30 -0
- package/dist/imaging/tools/io.d.ts +38 -0
- package/dist/imaging/tools/main.d.ts +81 -0
- package/dist/imaging/tools/segmentation.d.ts +125 -0
- package/dist/imaging/tools/state.d.ts +17 -0
- package/dist/imaging/tools/strategies/eraseFreehand.d.ts +16 -0
- package/dist/imaging/tools/strategies/fillFreehand.d.ts +16 -0
- package/dist/imaging/tools/strategies/index.d.ts +2 -0
- package/dist/index.d.ts +34 -0
- package/dist/larvitar.js +89801 -0
- package/dist/larvitar.js.map +1 -0
- package/imaging/MetaDataReadable.ts +40 -0
- package/imaging/MetaDataTypes.ts +3490 -0
- package/imaging/dataDictionary.json +5328 -5328
- package/imaging/{imageAnonymization.js → imageAnonymization.ts} +41 -13
- package/imaging/{imageColormaps.js → imageColormaps.ts} +48 -30
- package/imaging/{imageContours.js → imageContours.ts} +24 -22
- package/imaging/{imageIo.js → imageIo.ts} +89 -52
- package/imaging/{imageLayers.js → imageLayers.ts} +31 -14
- package/imaging/{imageLoading.js → imageLoading.ts} +108 -45
- package/imaging/{imageParsing.js → imageParsing.ts} +158 -80
- package/imaging/{imagePresets.js → imagePresets.ts} +44 -11
- package/imaging/imageRendering.ts +1091 -0
- package/imaging/{imageReslice.js → imageReslice.ts} +18 -9
- package/imaging/imageStore.ts +487 -0
- package/imaging/imageTags.ts +609 -0
- package/imaging/imageTools.js +2 -1
- package/imaging/{imageUtils.js → imageUtils.ts} +211 -701
- package/imaging/loaders/{commonLoader.js → commonLoader.ts} +73 -24
- package/imaging/loaders/{dicomLoader.js → dicomLoader.ts} +25 -5
- package/imaging/loaders/{fileLoader.js → fileLoader.ts} +5 -5
- package/imaging/loaders/{multiframeLoader.js → multiframeLoader.ts} +145 -90
- package/imaging/loaders/{nrrdLoader.js → nrrdLoader.ts} +230 -64
- package/imaging/loaders/{resliceLoader.js → resliceLoader.ts} +51 -20
- package/imaging/monitors/{memory.js → memory.ts} +54 -8
- package/imaging/monitors/performance.ts +34 -0
- package/imaging/parsers/ecg.ts +51 -0
- package/imaging/tools/README.md +27 -0
- package/imaging/tools/custom/4dSliceScrollTool.js +47 -46
- package/imaging/tools/custom/ellipticalRoiOverlayTool.js +534 -0
- package/imaging/tools/custom/polylineScissorsTool.js +1 -1
- package/imaging/tools/custom/rectangleRoiOverlayTool.js +564 -0
- package/imaging/tools/{setLabelMap3D.js → custom/setLabelMap3D.ts} +19 -25
- package/imaging/tools/{default.js → default.ts} +114 -30
- package/imaging/tools/{interaction.js → interaction.ts} +42 -23
- package/imaging/tools/{io.js → io.ts} +47 -31
- package/imaging/tools/{main.js → main.ts} +105 -40
- package/imaging/tools/{segmentation.js → segmentation.ts} +95 -68
- package/imaging/tools/{state.js → state.ts} +7 -12
- package/imaging/tools/types.d.ts +243 -0
- package/imaging/types.d.ts +197 -0
- package/{index.js → index.ts} +43 -14
- package/jsdoc.json +1 -1
- package/package.json +32 -14
- package/tsconfig.json +102 -0
- package/imaging/imageRendering.js +0 -860
- package/imaging/imageStore.js +0 -322
- package/modules/vuex/larvitar.js +0 -187
- /package/imaging/tools/{polygonSegmentationMixin.js → custom/polygonSegmentationMixin.js} +0 -0
|
@@ -1,29 +1,32 @@
|
|
|
1
1
|
/** @module imaging/imageLoading
|
|
2
2
|
* @desc This file provides functionalities for
|
|
3
|
-
* initialize, configure and update
|
|
3
|
+
* initialize, configure and update DICOMImageLoader
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
// external libraries
|
|
7
7
|
import cornerstone from "cornerstone-core";
|
|
8
8
|
import dicomParser from "dicom-parser";
|
|
9
|
+
// import cornerstoneDICOMImageLoader from "@cornerstonejs/dicom-image-loader/dist/cornerstoneDICOMImageLoader.bundle.min.js";
|
|
9
10
|
import { default as cornerstoneDICOMImageLoader } from "cornerstone-wado-image-loader";
|
|
10
11
|
import cornerstoneWebImageLoader from "cornerstone-web-image-loader";
|
|
11
12
|
import cornerstoneFileImageLoader from "cornerstone-file-image-loader";
|
|
12
13
|
import { forEach } from "lodash";
|
|
13
14
|
|
|
14
15
|
// internal libraries
|
|
15
|
-
import
|
|
16
|
+
import store from "./imageStore";
|
|
16
17
|
import { getSortedStack, getSortedUIDs } from "./imageUtils";
|
|
17
18
|
import { loadNrrdImage } from "./loaders/nrrdLoader";
|
|
18
19
|
import { loadReslicedImage } from "./loaders/resliceLoader";
|
|
19
20
|
import { loadMultiFrameImage } from "./loaders/multiframeLoader";
|
|
21
|
+
import { ImageObject, Instance, Series, StagedProtocol } from "./types";
|
|
22
|
+
import { getLarvitarManager } from "./loaders/commonLoader";
|
|
20
23
|
|
|
21
24
|
/**
|
|
22
25
|
* Global standard configuration
|
|
23
26
|
* @inner
|
|
24
27
|
* @var {Object} globalConfig
|
|
25
28
|
* @property {Number} maxWebWorkers - number of maximum web workers
|
|
26
|
-
* @property {String} webWorkerPath - path to default
|
|
29
|
+
* @property {String} webWorkerPath - path to default DICOM web worker
|
|
27
30
|
* @property {} - see https://github.com/cornerstonejs/cornerstoneDICOMImageLoader/blob/master/docs/WebWorkers.md
|
|
28
31
|
*/
|
|
29
32
|
|
|
@@ -54,12 +57,12 @@ const globalConfig = {
|
|
|
54
57
|
*/
|
|
55
58
|
|
|
56
59
|
/**
|
|
57
|
-
* Configure
|
|
60
|
+
* Configure DICOMImageLoader
|
|
58
61
|
* @instance
|
|
59
62
|
* @function initializeImageLoader
|
|
60
63
|
* @param {Object} config - Custom config @default globalConfig
|
|
61
64
|
*/
|
|
62
|
-
export const initializeImageLoader = function (config) {
|
|
65
|
+
export const initializeImageLoader = function (config?: typeof globalConfig) {
|
|
63
66
|
let imageLoaderConfig = config ? config : globalConfig;
|
|
64
67
|
cornerstoneDICOMImageLoader.external.cornerstone = cornerstone;
|
|
65
68
|
cornerstoneDICOMImageLoader.external.dicomParser = dicomParser;
|
|
@@ -119,28 +122,32 @@ export const registerMultiFrameImageLoader = function () {
|
|
|
119
122
|
};
|
|
120
123
|
|
|
121
124
|
/**
|
|
122
|
-
* Update the allSeriesStack object using
|
|
125
|
+
* Update the allSeriesStack object using DICOMImageLoader fileManager
|
|
123
126
|
* @instance
|
|
124
127
|
* @function updateLoadedStack
|
|
125
128
|
* @param {Object} seriesData - Cornerstone series object
|
|
126
129
|
* @param {Object} allSeriesStack - Dict containing all series objects
|
|
127
130
|
* @param {String} customId - Optional custom id to overwrite seriesUID as default one
|
|
131
|
+
* @param {number} sliceIndex - Optional custom index to overwrite slice index as default one
|
|
128
132
|
*/
|
|
129
133
|
export const updateLoadedStack = function (
|
|
130
|
-
seriesData,
|
|
131
|
-
allSeriesStack
|
|
132
|
-
customId
|
|
134
|
+
seriesData: ImageObject,
|
|
135
|
+
allSeriesStack: ReturnType<typeof getLarvitarManager>,
|
|
136
|
+
customId?: string,
|
|
137
|
+
sliceIndex?: number
|
|
133
138
|
) {
|
|
139
|
+
let lid = seriesData.metadata.larvitarSeriesInstanceUID;
|
|
134
140
|
let sid = seriesData.metadata.seriesUID;
|
|
135
141
|
let ssid = seriesData.metadata.studyUID;
|
|
136
|
-
let iid = seriesData.metadata.instanceUID;
|
|
142
|
+
let iid = seriesData.metadata.instanceUID as string;
|
|
137
143
|
let seriesDescription = seriesData.metadata.seriesDescription;
|
|
138
144
|
let numberOfSlices = seriesData.metadata["x00540081"]
|
|
139
145
|
? seriesData.metadata["x00540081"]
|
|
140
146
|
: seriesData.metadata["x00201002"];
|
|
141
147
|
let numberOfFrames = seriesData.metadata["x00280008"];
|
|
142
148
|
let modality = seriesData.metadata["x00080060"];
|
|
143
|
-
let isMultiframe =
|
|
149
|
+
let isMultiframe =
|
|
150
|
+
numberOfFrames && (numberOfFrames as number) > 1 ? true : false;
|
|
144
151
|
let numberOfTemporalPositions = seriesData.metadata["x00200105"];
|
|
145
152
|
let acquisitionNumberAttribute = seriesData.metadata["x00200012"];
|
|
146
153
|
let is4D = seriesData.metadata.is4D;
|
|
@@ -150,50 +157,91 @@ export const updateLoadedStack = function (
|
|
|
150
157
|
|
|
151
158
|
let color = cornerstoneDICOMImageLoader.isColorImage(
|
|
152
159
|
seriesData.metadata["x00280004"]
|
|
153
|
-
);
|
|
154
|
-
let id = customId ||
|
|
160
|
+
) as boolean;
|
|
161
|
+
let id = customId || lid?.toString();
|
|
162
|
+
|
|
163
|
+
if (!id) {
|
|
164
|
+
throw new Error("Unique UID is not defined");
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Staged Protocol
|
|
168
|
+
// https://dicom.nema.org/dicom/2013/output/chtml/part17/sect_K.5.html
|
|
169
|
+
const numberOfStages = seriesData.metadata["x00082124"]; // Number of stages
|
|
170
|
+
const numberOfViews = seriesData.metadata["x0008212a"]; // Number of views in stage
|
|
171
|
+
const isStagedProtocol = numberOfStages ? true : false;
|
|
172
|
+
|
|
155
173
|
// initialize series stack
|
|
156
174
|
if (!allSeriesStack[id]) {
|
|
157
|
-
|
|
175
|
+
let series: Partial<Series> = {
|
|
158
176
|
currentImageIdIndex: 0,
|
|
159
177
|
imageIds: [], // (ordered)
|
|
160
178
|
instanceUIDs: {}, // instanceUID: imageId (ordered)
|
|
161
179
|
instances: {},
|
|
162
|
-
seriesDescription: seriesDescription,
|
|
163
|
-
larvitarSeriesInstanceUID:
|
|
164
|
-
seriesUID: sid,
|
|
165
|
-
studyUID: ssid,
|
|
166
|
-
numberOfImages: is4D ? acquisitionNumberAttribute : 0,
|
|
167
|
-
numberOfSlices: numberOfSlices,
|
|
168
|
-
numberOfFrames: numberOfFrames,
|
|
169
|
-
numberOfTemporalPositions: numberOfTemporalPositions,
|
|
180
|
+
seriesDescription: seriesDescription as string,
|
|
181
|
+
larvitarSeriesInstanceUID: lid as string,
|
|
182
|
+
seriesUID: sid as string,
|
|
183
|
+
studyUID: ssid as string,
|
|
184
|
+
numberOfImages: is4D ? (acquisitionNumberAttribute as number) : 0,
|
|
185
|
+
numberOfSlices: numberOfSlices as number,
|
|
186
|
+
numberOfFrames: numberOfFrames as number,
|
|
187
|
+
numberOfTemporalPositions: numberOfTemporalPositions as number,
|
|
170
188
|
isMultiframe: isMultiframe,
|
|
171
|
-
is4D: is4D,
|
|
172
|
-
isPDF: isPDF,
|
|
173
|
-
anonymized: anonymized,
|
|
174
|
-
modality: modality,
|
|
189
|
+
is4D: is4D as boolean,
|
|
190
|
+
isPDF: isPDF as boolean,
|
|
191
|
+
anonymized: anonymized as boolean,
|
|
192
|
+
modality: modality as string,
|
|
175
193
|
color: color,
|
|
176
194
|
bytes: 0
|
|
177
195
|
};
|
|
196
|
+
if (isStagedProtocol) {
|
|
197
|
+
const stageName = seriesData.metadata["x00082120"];
|
|
198
|
+
const stageNumber = seriesData.metadata["x00082122"];
|
|
199
|
+
const viewName = seriesData.metadata["x00082127"];
|
|
200
|
+
const viewNumber = seriesData.metadata["x00082128"];
|
|
201
|
+
const stagedProtocol: StagedProtocol = {
|
|
202
|
+
numberOfStages: numberOfStages as number,
|
|
203
|
+
numberOfViews: numberOfViews as number,
|
|
204
|
+
stageName: stageName ? (stageName as string).trim() : undefined,
|
|
205
|
+
stageNumber: stageNumber as number,
|
|
206
|
+
viewName: viewName ? (viewName as string).trim() : undefined,
|
|
207
|
+
viewNumber: viewNumber as number
|
|
208
|
+
};
|
|
209
|
+
series.stagedProtocol = stagedProtocol;
|
|
210
|
+
}
|
|
211
|
+
allSeriesStack[id] = series as Series;
|
|
178
212
|
}
|
|
179
213
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
214
|
+
// get instance number from metadata
|
|
215
|
+
const instanceNumber = seriesData.metadata["x00200013"];
|
|
216
|
+
const defaultMethod = instanceNumber ? "instanceNumber" : "imagePosition";
|
|
217
|
+
const sortMethods: Array<"imagePosition" | "contentTime" | "instanceNumber"> =
|
|
218
|
+
is4D ? [defaultMethod, "contentTime"] : [defaultMethod];
|
|
183
219
|
|
|
184
220
|
// if the parsed file is a new series instance, keep it
|
|
185
|
-
|
|
221
|
+
|
|
222
|
+
if (isMultiframe) {
|
|
223
|
+
allSeriesStack[id].bytes += seriesData.file.size;
|
|
224
|
+
allSeriesStack[id].dataSet = seriesData.dataSet;
|
|
225
|
+
allSeriesStack[id].metadata = seriesData.metadata;
|
|
226
|
+
} else if (isNewInstance(allSeriesStack[id].instances, iid!)) {
|
|
186
227
|
// generate an imageId for the file and store it
|
|
187
228
|
// in allSeriesStack imageIds array, used by
|
|
188
|
-
//
|
|
229
|
+
// DICOMImageLoader to display the stack of images
|
|
189
230
|
let imageId = cornerstoneDICOMImageLoader.wadouri.fileManager.add(
|
|
190
231
|
seriesData.file
|
|
191
|
-
);
|
|
232
|
+
) as string;
|
|
233
|
+
|
|
234
|
+
if (sliceIndex !== undefined) {
|
|
235
|
+
allSeriesStack[id].imageIds[sliceIndex] = imageId;
|
|
236
|
+
} else {
|
|
237
|
+
allSeriesStack[id].imageIds.push(imageId);
|
|
238
|
+
}
|
|
192
239
|
|
|
193
|
-
allSeriesStack[id].imageIds.push(imageId);
|
|
194
240
|
if (is4D === false) {
|
|
195
|
-
allSeriesStack[id].numberOfImages
|
|
241
|
+
allSeriesStack[id].numberOfImages =
|
|
242
|
+
(allSeriesStack[id].numberOfImages || 0) + 1;
|
|
196
243
|
}
|
|
244
|
+
|
|
197
245
|
allSeriesStack[id].bytes += seriesData.file.size;
|
|
198
246
|
// store needed instance tags
|
|
199
247
|
allSeriesStack[id].instances[imageId] = {
|
|
@@ -201,15 +249,27 @@ export const updateLoadedStack = function (
|
|
|
201
249
|
file: seriesData.file,
|
|
202
250
|
dataSet: seriesData.dataSet
|
|
203
251
|
};
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
252
|
+
|
|
253
|
+
if (isPDF === false) {
|
|
254
|
+
if (sliceIndex === undefined) {
|
|
255
|
+
// order images in stack
|
|
256
|
+
allSeriesStack[id].imageIds = getSortedStack(
|
|
257
|
+
allSeriesStack[id] as Series,
|
|
258
|
+
sortMethods,
|
|
259
|
+
true
|
|
260
|
+
);
|
|
261
|
+
// populate the ordered dictionary of instanceUIDs
|
|
262
|
+
allSeriesStack[id].instanceUIDs = getSortedUIDs(
|
|
263
|
+
allSeriesStack[id] as Series
|
|
264
|
+
);
|
|
265
|
+
} else {
|
|
266
|
+
allSeriesStack[id].instanceUIDs[iid] = imageId;
|
|
267
|
+
}
|
|
268
|
+
store.addSeriesId(id, allSeriesStack[id].imageIds);
|
|
269
|
+
} else {
|
|
270
|
+
allSeriesStack[id].instanceUIDs[iid] = imageId;
|
|
271
|
+
store.addSeriesId(id, allSeriesStack[id].imageIds);
|
|
272
|
+
}
|
|
213
273
|
}
|
|
214
274
|
};
|
|
215
275
|
|
|
@@ -223,9 +283,12 @@ export const updateLoadedStack = function (
|
|
|
223
283
|
* @param {String} iid - instance uid to check
|
|
224
284
|
* @return {Bool} True if is new instance, false if already present
|
|
225
285
|
*/
|
|
226
|
-
let isNewInstance = function (
|
|
286
|
+
let isNewInstance = function (
|
|
287
|
+
instances: { [key: string]: Instance },
|
|
288
|
+
iid: string
|
|
289
|
+
) {
|
|
227
290
|
let isNewInstance = true;
|
|
228
|
-
forEach(instances, function (instance) {
|
|
291
|
+
forEach(instances, function (instance: Instance) {
|
|
229
292
|
if (instance.metadata.instanceUID === iid) {
|
|
230
293
|
isNewInstance = false;
|
|
231
294
|
}
|