larvitar 1.5.14 → 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} +105 -43
  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,51 +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
214
  // get instance number from metadata
181
215
  const instanceNumber = seriesData.metadata["x00200013"];
182
216
  const defaultMethod = instanceNumber ? "instanceNumber" : "imagePosition";
183
- const sortMethods = is4D ? [defaultMethod, "contentTime"] : [defaultMethod];
217
+ const sortMethods: Array<"imagePosition" | "contentTime" | "instanceNumber"> =
218
+ is4D ? [defaultMethod, "contentTime"] : [defaultMethod];
184
219
 
185
220
  // if the parsed file is a new series instance, keep it
186
- 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!)) {
187
227
  // generate an imageId for the file and store it
188
228
  // in allSeriesStack imageIds array, used by
189
- // cornerstoneDICOMImageLoader to display the stack of images
229
+ // DICOMImageLoader to display the stack of images
190
230
  let imageId = cornerstoneDICOMImageLoader.wadouri.fileManager.add(
191
231
  seriesData.file
192
- );
232
+ ) as string;
233
+
234
+ if (sliceIndex !== undefined) {
235
+ allSeriesStack[id].imageIds[sliceIndex] = imageId;
236
+ } else {
237
+ allSeriesStack[id].imageIds.push(imageId);
238
+ }
193
239
 
194
- allSeriesStack[id].imageIds.push(imageId);
195
240
  if (is4D === false) {
196
- allSeriesStack[id].numberOfImages += 1;
241
+ allSeriesStack[id].numberOfImages =
242
+ (allSeriesStack[id].numberOfImages || 0) + 1;
197
243
  }
244
+
198
245
  allSeriesStack[id].bytes += seriesData.file.size;
199
246
  // store needed instance tags
200
247
  allSeriesStack[id].instances[imageId] = {
@@ -202,15 +249,27 @@ export const updateLoadedStack = function (
202
249
  file: seriesData.file,
203
250
  dataSet: seriesData.dataSet
204
251
  };
205
- // order images in stack
206
- allSeriesStack[id].imageIds = getSortedStack(
207
- allSeriesStack[id],
208
- sortMethods,
209
- true
210
- );
211
- // populate the ordered dictionary of instanceUIDs
212
- allSeriesStack[id].instanceUIDs = getSortedUIDs(allSeriesStack[id]);
213
- 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
+ }
214
273
  }
215
274
  };
216
275
 
@@ -224,9 +283,12 @@ export const updateLoadedStack = function (
224
283
  * @param {String} iid - instance uid to check
225
284
  * @return {Bool} True if is new instance, false if already present
226
285
  */
227
- let isNewInstance = function (instances, iid) {
286
+ let isNewInstance = function (
287
+ instances: { [key: string]: Instance },
288
+ iid: string
289
+ ) {
228
290
  let isNewInstance = true;
229
- forEach(instances, function (instance) {
291
+ forEach(instances, function (instance: Instance) {
230
292
  if (instance.metadata.instanceUID === iid) {
231
293
  isNewInstance = false;
232
294
  }