larvitar 1.5.14 → 2.0.2
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 +40 -0
- package/dist/imaging/MetaDataTypes.d.ts +3489 -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 +113 -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/BorderMagnifyTool.d.ts +18 -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/imaging/waveforms/ecg.d.ts +39 -0
- package/dist/index.d.ts +35 -0
- package/dist/larvitar.js +90104 -0
- package/dist/larvitar.js.map +1 -0
- package/imaging/MetaDataReadable.ts +41 -0
- package/imaging/MetaDataTypes.ts +3491 -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} +107 -43
- package/imaging/{imageParsing.js → imageParsing.ts} +160 -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} +231 -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 +54 -0
- package/imaging/tools/README.md +27 -0
- package/imaging/tools/custom/4dSliceScrollTool.js +47 -46
- package/imaging/tools/custom/BorderMagnifyTool.js +99 -0
- 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} +119 -33
- 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 +200 -0
- package/imaging/waveforms/ecg.ts +191 -0
- package/{index.js → index.ts} +53 -14
- package/jsdoc.json +1 -1
- package/package.json +35 -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,82 +122,128 @@ 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;
|
|
154
|
+
let waveform = seriesData.metadata.waveform;
|
|
147
155
|
let SOPUID = seriesData.metadata["x00080016"];
|
|
148
156
|
let isPDF = SOPUID == "1.2.840.10008.5.1.4.1.1.104.1" ? true : false;
|
|
149
157
|
let anonymized = seriesData.metadata.anonymized;
|
|
150
158
|
|
|
151
159
|
let color = cornerstoneDICOMImageLoader.isColorImage(
|
|
152
160
|
seriesData.metadata["x00280004"]
|
|
153
|
-
);
|
|
154
|
-
let id = customId ||
|
|
161
|
+
) as boolean;
|
|
162
|
+
let id = customId || lid?.toString();
|
|
163
|
+
|
|
164
|
+
if (!id) {
|
|
165
|
+
throw new Error("Unique UID is not defined");
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Staged Protocol
|
|
169
|
+
// https://dicom.nema.org/dicom/2013/output/chtml/part17/sect_K.5.html
|
|
170
|
+
const numberOfStages = seriesData.metadata["x00082124"]; // Number of stages
|
|
171
|
+
const numberOfViews = seriesData.metadata["x0008212a"]; // Number of views in stage
|
|
172
|
+
const isStagedProtocol = numberOfStages ? true : false;
|
|
173
|
+
|
|
155
174
|
// initialize series stack
|
|
156
175
|
if (!allSeriesStack[id]) {
|
|
157
|
-
|
|
176
|
+
let series: Partial<Series> = {
|
|
158
177
|
currentImageIdIndex: 0,
|
|
159
178
|
imageIds: [], // (ordered)
|
|
160
179
|
instanceUIDs: {}, // instanceUID: imageId (ordered)
|
|
161
180
|
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,
|
|
181
|
+
seriesDescription: seriesDescription as string,
|
|
182
|
+
larvitarSeriesInstanceUID: lid as string,
|
|
183
|
+
seriesUID: sid as string,
|
|
184
|
+
studyUID: ssid as string,
|
|
185
|
+
numberOfImages: is4D ? (acquisitionNumberAttribute as number) : 0,
|
|
186
|
+
numberOfSlices: numberOfSlices as number,
|
|
187
|
+
numberOfFrames: numberOfFrames as number,
|
|
188
|
+
numberOfTemporalPositions: numberOfTemporalPositions as number,
|
|
170
189
|
isMultiframe: isMultiframe,
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
190
|
+
waveform: waveform as boolean,
|
|
191
|
+
is4D: is4D as boolean,
|
|
192
|
+
isPDF: isPDF as boolean,
|
|
193
|
+
anonymized: anonymized as boolean,
|
|
194
|
+
modality: modality as string,
|
|
175
195
|
color: color,
|
|
176
196
|
bytes: 0
|
|
177
197
|
};
|
|
198
|
+
if (isStagedProtocol) {
|
|
199
|
+
const stageName = seriesData.metadata["x00082120"];
|
|
200
|
+
const stageNumber = seriesData.metadata["x00082122"];
|
|
201
|
+
const viewName = seriesData.metadata["x00082127"];
|
|
202
|
+
const viewNumber = seriesData.metadata["x00082128"];
|
|
203
|
+
const stagedProtocol: StagedProtocol = {
|
|
204
|
+
numberOfStages: numberOfStages as number,
|
|
205
|
+
numberOfViews: numberOfViews as number,
|
|
206
|
+
stageName: stageName ? (stageName as string).trim() : undefined,
|
|
207
|
+
stageNumber: stageNumber as number,
|
|
208
|
+
viewName: viewName ? (viewName as string).trim() : undefined,
|
|
209
|
+
viewNumber: viewNumber as number
|
|
210
|
+
};
|
|
211
|
+
series.stagedProtocol = stagedProtocol;
|
|
212
|
+
}
|
|
213
|
+
allSeriesStack[id] = series as Series;
|
|
178
214
|
}
|
|
179
215
|
|
|
180
216
|
// get instance number from metadata
|
|
181
217
|
const instanceNumber = seriesData.metadata["x00200013"];
|
|
182
218
|
const defaultMethod = instanceNumber ? "instanceNumber" : "imagePosition";
|
|
183
|
-
const sortMethods
|
|
219
|
+
const sortMethods: Array<"imagePosition" | "contentTime" | "instanceNumber"> =
|
|
220
|
+
is4D ? [defaultMethod, "contentTime"] : [defaultMethod];
|
|
184
221
|
|
|
185
222
|
// if the parsed file is a new series instance, keep it
|
|
186
|
-
|
|
223
|
+
|
|
224
|
+
if (isMultiframe) {
|
|
225
|
+
allSeriesStack[id].bytes += seriesData.file.size;
|
|
226
|
+
allSeriesStack[id].dataSet = seriesData.dataSet;
|
|
227
|
+
allSeriesStack[id].metadata = seriesData.metadata;
|
|
228
|
+
} else if (isNewInstance(allSeriesStack[id].instances, iid!)) {
|
|
187
229
|
// generate an imageId for the file and store it
|
|
188
230
|
// in allSeriesStack imageIds array, used by
|
|
189
|
-
//
|
|
231
|
+
// DICOMImageLoader to display the stack of images
|
|
190
232
|
let imageId = cornerstoneDICOMImageLoader.wadouri.fileManager.add(
|
|
191
233
|
seriesData.file
|
|
192
|
-
);
|
|
234
|
+
) as string;
|
|
235
|
+
|
|
236
|
+
if (sliceIndex !== undefined) {
|
|
237
|
+
allSeriesStack[id].imageIds[sliceIndex] = imageId;
|
|
238
|
+
} else {
|
|
239
|
+
allSeriesStack[id].imageIds.push(imageId);
|
|
240
|
+
}
|
|
193
241
|
|
|
194
|
-
allSeriesStack[id].imageIds.push(imageId);
|
|
195
242
|
if (is4D === false) {
|
|
196
|
-
allSeriesStack[id].numberOfImages
|
|
243
|
+
allSeriesStack[id].numberOfImages =
|
|
244
|
+
(allSeriesStack[id].numberOfImages || 0) + 1;
|
|
197
245
|
}
|
|
246
|
+
|
|
198
247
|
allSeriesStack[id].bytes += seriesData.file.size;
|
|
199
248
|
// store needed instance tags
|
|
200
249
|
allSeriesStack[id].instances[imageId] = {
|
|
@@ -202,15 +251,27 @@ export const updateLoadedStack = function (
|
|
|
202
251
|
file: seriesData.file,
|
|
203
252
|
dataSet: seriesData.dataSet
|
|
204
253
|
};
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
254
|
+
|
|
255
|
+
if (isPDF === false) {
|
|
256
|
+
if (sliceIndex === undefined) {
|
|
257
|
+
// order images in stack
|
|
258
|
+
allSeriesStack[id].imageIds = getSortedStack(
|
|
259
|
+
allSeriesStack[id] as Series,
|
|
260
|
+
sortMethods,
|
|
261
|
+
true
|
|
262
|
+
);
|
|
263
|
+
// populate the ordered dictionary of instanceUIDs
|
|
264
|
+
allSeriesStack[id].instanceUIDs = getSortedUIDs(
|
|
265
|
+
allSeriesStack[id] as Series
|
|
266
|
+
);
|
|
267
|
+
} else {
|
|
268
|
+
allSeriesStack[id].instanceUIDs[iid] = imageId;
|
|
269
|
+
}
|
|
270
|
+
store.addSeriesId(id, allSeriesStack[id].imageIds);
|
|
271
|
+
} else {
|
|
272
|
+
allSeriesStack[id].instanceUIDs[iid] = imageId;
|
|
273
|
+
store.addSeriesId(id, allSeriesStack[id].imageIds);
|
|
274
|
+
}
|
|
214
275
|
}
|
|
215
276
|
};
|
|
216
277
|
|
|
@@ -224,9 +285,12 @@ export const updateLoadedStack = function (
|
|
|
224
285
|
* @param {String} iid - instance uid to check
|
|
225
286
|
* @return {Bool} True if is new instance, false if already present
|
|
226
287
|
*/
|
|
227
|
-
let isNewInstance = function (
|
|
288
|
+
let isNewInstance = function (
|
|
289
|
+
instances: { [key: string]: Instance },
|
|
290
|
+
iid: string
|
|
291
|
+
) {
|
|
228
292
|
let isNewInstance = true;
|
|
229
|
-
forEach(instances, function (instance) {
|
|
293
|
+
forEach(instances, function (instance: Instance) {
|
|
230
294
|
if (instance.metadata.instanceUID === iid) {
|
|
231
295
|
isNewInstance = false;
|
|
232
296
|
}
|