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.
Files changed (103) hide show
  1. package/.vscode/settings.json +4 -0
  2. package/README.md +78 -48
  3. package/bundler/webpack.common.js +27 -0
  4. package/bundler/webpack.dev.js +23 -0
  5. package/bundler/webpack.prod.js +19 -0
  6. package/decs.d.ts +12 -0
  7. package/dist/imaging/MetaDataReadable.d.ts +39 -0
  8. package/dist/imaging/MetaDataTypes.d.ts +3488 -0
  9. package/dist/imaging/imageAnonymization.d.ts +12 -0
  10. package/dist/imaging/imageColormaps.d.ts +47 -0
  11. package/dist/imaging/imageContours.d.ts +18 -0
  12. package/dist/imaging/imageIo.d.ts +42 -0
  13. package/dist/imaging/imageLayers.d.ts +56 -0
  14. package/dist/imaging/imageLoading.d.ts +65 -0
  15. package/dist/imaging/imageParsing.d.ts +46 -0
  16. package/dist/imaging/imagePresets.d.ts +43 -0
  17. package/dist/imaging/imageRendering.d.ts +238 -0
  18. package/dist/imaging/imageReslice.d.ts +14 -0
  19. package/dist/imaging/imageStore.d.ts +121 -0
  20. package/dist/imaging/imageTags.d.ts +22 -0
  21. package/dist/imaging/imageTools.d.ts +20 -0
  22. package/dist/imaging/imageUtils.d.ts +165 -0
  23. package/dist/imaging/loaders/commonLoader.d.ts +103 -0
  24. package/dist/imaging/loaders/dicomLoader.d.ts +29 -0
  25. package/dist/imaging/loaders/fileLoader.d.ts +33 -0
  26. package/dist/imaging/loaders/multiframeLoader.d.ts +37 -0
  27. package/dist/imaging/loaders/nrrdLoader.d.ts +112 -0
  28. package/dist/imaging/loaders/resliceLoader.d.ts +15 -0
  29. package/dist/imaging/monitors/memory.d.ts +41 -0
  30. package/dist/imaging/monitors/performance.d.ts +23 -0
  31. package/dist/imaging/parsers/ecg.d.ts +15 -0
  32. package/dist/imaging/parsers/nrrd.d.ts +3 -0
  33. package/dist/imaging/tools/custom/4dSliceScrollTool.d.ts +12 -0
  34. package/dist/imaging/tools/custom/contourTool.d.ts +409 -0
  35. package/dist/imaging/tools/custom/diameterTool.d.ts +18 -0
  36. package/dist/imaging/tools/custom/editMaskTool.d.ts +22 -0
  37. package/dist/imaging/tools/custom/ellipticalRoiOverlayTool.d.ts +45 -0
  38. package/dist/imaging/tools/custom/polygonSegmentationMixin.d.ts +54 -0
  39. package/dist/imaging/tools/custom/polylineScissorsTool.d.ts +11 -0
  40. package/dist/imaging/tools/custom/rectangleRoiOverlayTool.d.ts +45 -0
  41. package/dist/imaging/tools/custom/seedTool.d.ts +0 -0
  42. package/dist/imaging/tools/custom/setLabelMap3D.d.ts +39 -0
  43. package/dist/imaging/tools/custom/thresholdsBrushTool.d.ts +19 -0
  44. package/dist/imaging/tools/default.d.ts +53 -0
  45. package/dist/imaging/tools/interaction.d.ts +30 -0
  46. package/dist/imaging/tools/io.d.ts +38 -0
  47. package/dist/imaging/tools/main.d.ts +81 -0
  48. package/dist/imaging/tools/segmentation.d.ts +125 -0
  49. package/dist/imaging/tools/state.d.ts +17 -0
  50. package/dist/imaging/tools/strategies/eraseFreehand.d.ts +16 -0
  51. package/dist/imaging/tools/strategies/fillFreehand.d.ts +16 -0
  52. package/dist/imaging/tools/strategies/index.d.ts +2 -0
  53. package/dist/index.d.ts +34 -0
  54. package/dist/larvitar.js +89801 -0
  55. package/dist/larvitar.js.map +1 -0
  56. package/imaging/MetaDataReadable.ts +40 -0
  57. package/imaging/MetaDataTypes.ts +3490 -0
  58. package/imaging/dataDictionary.json +5328 -5328
  59. package/imaging/{imageAnonymization.js → imageAnonymization.ts} +41 -13
  60. package/imaging/{imageColormaps.js → imageColormaps.ts} +48 -30
  61. package/imaging/{imageContours.js → imageContours.ts} +24 -22
  62. package/imaging/{imageIo.js → imageIo.ts} +89 -52
  63. package/imaging/{imageLayers.js → imageLayers.ts} +31 -14
  64. package/imaging/{imageLoading.js → imageLoading.ts} +108 -45
  65. package/imaging/{imageParsing.js → imageParsing.ts} +158 -80
  66. package/imaging/{imagePresets.js → imagePresets.ts} +44 -11
  67. package/imaging/imageRendering.ts +1091 -0
  68. package/imaging/{imageReslice.js → imageReslice.ts} +18 -9
  69. package/imaging/imageStore.ts +487 -0
  70. package/imaging/imageTags.ts +609 -0
  71. package/imaging/imageTools.js +2 -1
  72. package/imaging/{imageUtils.js → imageUtils.ts} +211 -701
  73. package/imaging/loaders/{commonLoader.js → commonLoader.ts} +73 -24
  74. package/imaging/loaders/{dicomLoader.js → dicomLoader.ts} +25 -5
  75. package/imaging/loaders/{fileLoader.js → fileLoader.ts} +5 -5
  76. package/imaging/loaders/{multiframeLoader.js → multiframeLoader.ts} +145 -90
  77. package/imaging/loaders/{nrrdLoader.js → nrrdLoader.ts} +230 -64
  78. package/imaging/loaders/{resliceLoader.js → resliceLoader.ts} +51 -20
  79. package/imaging/monitors/{memory.js → memory.ts} +54 -8
  80. package/imaging/monitors/performance.ts +34 -0
  81. package/imaging/parsers/ecg.ts +51 -0
  82. package/imaging/tools/README.md +27 -0
  83. package/imaging/tools/custom/4dSliceScrollTool.js +47 -46
  84. package/imaging/tools/custom/ellipticalRoiOverlayTool.js +534 -0
  85. package/imaging/tools/custom/polylineScissorsTool.js +1 -1
  86. package/imaging/tools/custom/rectangleRoiOverlayTool.js +564 -0
  87. package/imaging/tools/{setLabelMap3D.js → custom/setLabelMap3D.ts} +19 -25
  88. package/imaging/tools/{default.js → default.ts} +114 -30
  89. package/imaging/tools/{interaction.js → interaction.ts} +42 -23
  90. package/imaging/tools/{io.js → io.ts} +47 -31
  91. package/imaging/tools/{main.js → main.ts} +105 -40
  92. package/imaging/tools/{segmentation.js → segmentation.ts} +95 -68
  93. package/imaging/tools/{state.js → state.ts} +7 -12
  94. package/imaging/tools/types.d.ts +243 -0
  95. package/imaging/types.d.ts +197 -0
  96. package/{index.js → index.ts} +43 -14
  97. package/jsdoc.json +1 -1
  98. package/package.json +32 -14
  99. package/tsconfig.json +102 -0
  100. package/imaging/imageRendering.js +0 -860
  101. package/imaging/imageStore.js +0 -322
  102. package/modules/vuex/larvitar.js +0 -187
  103. /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 WadoImageLoader
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 { larvitar_store } from "./imageStore";
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 WADO web worker
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 cornerstoneDICOMImageLoader
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 wadoImageLoader fileManager
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 = numberOfFrames > 1 ? true : false;
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 || sid;
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
- allSeriesStack[id] = {
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: sid,
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
- const sortMethods = is4D
181
- ? ["imagePosition", "contentTime"]
182
- : ["imagePosition"];
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
- if (isNewInstance(allSeriesStack[id].instances, iid)) {
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
- // cornerstoneDICOMImageLoader to display the stack of images
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 += 1;
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
- // order images in stack
205
- allSeriesStack[id].imageIds = getSortedStack(
206
- allSeriesStack[id],
207
- sortMethods,
208
- true
209
- );
210
- // populate the ordered dictionary of instanceUIDs
211
- allSeriesStack[id].instanceUIDs = getSortedUIDs(allSeriesStack[id]);
212
- larvitar_store.addSeriesIds(id, allSeriesStack[id].imageIds);
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 (instances, iid) {
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
  }