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.
Files changed (107) 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 +40 -0
  8. package/dist/imaging/MetaDataTypes.d.ts +3489 -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 +113 -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/BorderMagnifyTool.d.ts +18 -0
  35. package/dist/imaging/tools/custom/contourTool.d.ts +409 -0
  36. package/dist/imaging/tools/custom/diameterTool.d.ts +18 -0
  37. package/dist/imaging/tools/custom/editMaskTool.d.ts +22 -0
  38. package/dist/imaging/tools/custom/ellipticalRoiOverlayTool.d.ts +45 -0
  39. package/dist/imaging/tools/custom/polygonSegmentationMixin.d.ts +54 -0
  40. package/dist/imaging/tools/custom/polylineScissorsTool.d.ts +11 -0
  41. package/dist/imaging/tools/custom/rectangleRoiOverlayTool.d.ts +45 -0
  42. package/dist/imaging/tools/custom/seedTool.d.ts +0 -0
  43. package/dist/imaging/tools/custom/setLabelMap3D.d.ts +39 -0
  44. package/dist/imaging/tools/custom/thresholdsBrushTool.d.ts +19 -0
  45. package/dist/imaging/tools/default.d.ts +53 -0
  46. package/dist/imaging/tools/interaction.d.ts +30 -0
  47. package/dist/imaging/tools/io.d.ts +38 -0
  48. package/dist/imaging/tools/main.d.ts +81 -0
  49. package/dist/imaging/tools/segmentation.d.ts +125 -0
  50. package/dist/imaging/tools/state.d.ts +17 -0
  51. package/dist/imaging/tools/strategies/eraseFreehand.d.ts +16 -0
  52. package/dist/imaging/tools/strategies/fillFreehand.d.ts +16 -0
  53. package/dist/imaging/tools/strategies/index.d.ts +2 -0
  54. package/dist/imaging/waveforms/ecg.d.ts +39 -0
  55. package/dist/index.d.ts +35 -0
  56. package/dist/larvitar.js +90104 -0
  57. package/dist/larvitar.js.map +1 -0
  58. package/imaging/MetaDataReadable.ts +41 -0
  59. package/imaging/MetaDataTypes.ts +3491 -0
  60. package/imaging/dataDictionary.json +5328 -5328
  61. package/imaging/{imageAnonymization.js → imageAnonymization.ts} +41 -13
  62. package/imaging/{imageColormaps.js → imageColormaps.ts} +48 -30
  63. package/imaging/{imageContours.js → imageContours.ts} +24 -22
  64. package/imaging/{imageIo.js → imageIo.ts} +89 -52
  65. package/imaging/{imageLayers.js → imageLayers.ts} +31 -14
  66. package/imaging/{imageLoading.js → imageLoading.ts} +107 -43
  67. package/imaging/{imageParsing.js → imageParsing.ts} +160 -80
  68. package/imaging/{imagePresets.js → imagePresets.ts} +44 -11
  69. package/imaging/imageRendering.ts +1091 -0
  70. package/imaging/{imageReslice.js → imageReslice.ts} +18 -9
  71. package/imaging/imageStore.ts +487 -0
  72. package/imaging/imageTags.ts +609 -0
  73. package/imaging/imageTools.js +2 -1
  74. package/imaging/{imageUtils.js → imageUtils.ts} +211 -701
  75. package/imaging/loaders/{commonLoader.js → commonLoader.ts} +73 -24
  76. package/imaging/loaders/{dicomLoader.js → dicomLoader.ts} +25 -5
  77. package/imaging/loaders/{fileLoader.js → fileLoader.ts} +5 -5
  78. package/imaging/loaders/{multiframeLoader.js → multiframeLoader.ts} +145 -90
  79. package/imaging/loaders/{nrrdLoader.js → nrrdLoader.ts} +231 -64
  80. package/imaging/loaders/{resliceLoader.js → resliceLoader.ts} +51 -20
  81. package/imaging/monitors/{memory.js → memory.ts} +54 -8
  82. package/imaging/monitors/performance.ts +34 -0
  83. package/imaging/parsers/ecg.ts +54 -0
  84. package/imaging/tools/README.md +27 -0
  85. package/imaging/tools/custom/4dSliceScrollTool.js +47 -46
  86. package/imaging/tools/custom/BorderMagnifyTool.js +99 -0
  87. package/imaging/tools/custom/ellipticalRoiOverlayTool.js +534 -0
  88. package/imaging/tools/custom/polylineScissorsTool.js +1 -1
  89. package/imaging/tools/custom/rectangleRoiOverlayTool.js +564 -0
  90. package/imaging/tools/{setLabelMap3D.js → custom/setLabelMap3D.ts} +19 -25
  91. package/imaging/tools/{default.js → default.ts} +119 -33
  92. package/imaging/tools/{interaction.js → interaction.ts} +42 -23
  93. package/imaging/tools/{io.js → io.ts} +47 -31
  94. package/imaging/tools/{main.js → main.ts} +105 -40
  95. package/imaging/tools/{segmentation.js → segmentation.ts} +95 -68
  96. package/imaging/tools/{state.js → state.ts} +7 -12
  97. package/imaging/tools/types.d.ts +243 -0
  98. package/imaging/types.d.ts +200 -0
  99. package/imaging/waveforms/ecg.ts +191 -0
  100. package/{index.js → index.ts} +53 -14
  101. package/jsdoc.json +1 -1
  102. package/package.json +35 -14
  103. package/tsconfig.json +102 -0
  104. package/imaging/imageRendering.js +0 -860
  105. package/imaging/imageStore.js +0 -322
  106. package/modules/vuex/larvitar.js +0 -187
  107. /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,82 +122,128 @@ 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;
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 || sid;
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
- allSeriesStack[id] = {
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: sid,
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
- is4D: is4D,
172
- isPDF: isPDF,
173
- anonymized: anonymized,
174
- modality: modality,
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 = is4D ? [defaultMethod, "contentTime"] : [defaultMethod];
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
- if (isNewInstance(allSeriesStack[id].instances, iid)) {
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
- // cornerstoneDICOMImageLoader to display the stack of images
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 += 1;
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
- // 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);
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 (instances, iid) {
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
  }