larvitar 2.0.4 → 2.0.6

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 (72) hide show
  1. package/README.md +2 -2
  2. package/dist/larvitar.js +5 -3
  3. package/dist/larvitar.js.map +1 -1
  4. package/package.json +6 -2
  5. package/.github/workflows/build-docs.yml +0 -59
  6. package/.github/workflows/codeql-analysis.yml +0 -71
  7. package/.github/workflows/deploy.yml +0 -37
  8. package/.vscode/settings.json +0 -4
  9. package/CODE_OF_CONDUCT.md +0 -76
  10. package/MIGRATION.md +0 -25
  11. package/bundler/webpack.common.js +0 -27
  12. package/bundler/webpack.dev.js +0 -23
  13. package/bundler/webpack.prod.js +0 -19
  14. package/decs.d.ts +0 -12
  15. package/imaging/MetaDataReadable.ts +0 -42
  16. package/imaging/MetaDataTypes.ts +0 -3491
  17. package/imaging/dataDictionary.json +0 -21866
  18. package/imaging/imageAnonymization.ts +0 -135
  19. package/imaging/imageColormaps.ts +0 -217
  20. package/imaging/imageContours.ts +0 -196
  21. package/imaging/imageIo.ts +0 -251
  22. package/imaging/imageLayers.ts +0 -121
  23. package/imaging/imageLoading.ts +0 -299
  24. package/imaging/imageParsing.ts +0 -444
  25. package/imaging/imagePresets.ts +0 -156
  26. package/imaging/imageRendering.ts +0 -1091
  27. package/imaging/imageReslice.ts +0 -87
  28. package/imaging/imageStore.ts +0 -487
  29. package/imaging/imageTags.ts +0 -609
  30. package/imaging/imageTools.js +0 -708
  31. package/imaging/imageUtils.ts +0 -1079
  32. package/imaging/loaders/commonLoader.ts +0 -275
  33. package/imaging/loaders/dicomLoader.ts +0 -66
  34. package/imaging/loaders/fileLoader.ts +0 -71
  35. package/imaging/loaders/multiframeLoader.ts +0 -435
  36. package/imaging/loaders/nrrdLoader.ts +0 -630
  37. package/imaging/loaders/resliceLoader.ts +0 -205
  38. package/imaging/monitors/memory.ts +0 -151
  39. package/imaging/monitors/performance.ts +0 -34
  40. package/imaging/parsers/ecg.ts +0 -54
  41. package/imaging/parsers/nrrd.js +0 -485
  42. package/imaging/tools/README.md +0 -27
  43. package/imaging/tools/custom/4dSliceScrollTool.js +0 -146
  44. package/imaging/tools/custom/BorderMagnifyTool.js +0 -99
  45. package/imaging/tools/custom/contourTool.js +0 -1884
  46. package/imaging/tools/custom/diameterTool.js +0 -141
  47. package/imaging/tools/custom/editMaskTool.js +0 -141
  48. package/imaging/tools/custom/ellipticalRoiOverlayTool.js +0 -534
  49. package/imaging/tools/custom/polygonSegmentationMixin.js +0 -245
  50. package/imaging/tools/custom/polylineScissorsTool.js +0 -59
  51. package/imaging/tools/custom/rectangleRoiOverlayTool.js +0 -564
  52. package/imaging/tools/custom/seedTool.js +0 -342
  53. package/imaging/tools/custom/setLabelMap3D.ts +0 -242
  54. package/imaging/tools/custom/thresholdsBrushTool.js +0 -161
  55. package/imaging/tools/default.ts +0 -594
  56. package/imaging/tools/interaction.ts +0 -266
  57. package/imaging/tools/io.ts +0 -229
  58. package/imaging/tools/main.ts +0 -424
  59. package/imaging/tools/segmentation.ts +0 -532
  60. package/imaging/tools/segmentations.md +0 -38
  61. package/imaging/tools/state.ts +0 -74
  62. package/imaging/tools/strategies/eraseFreehand.js +0 -76
  63. package/imaging/tools/strategies/fillFreehand.js +0 -79
  64. package/imaging/tools/strategies/index.js +0 -2
  65. package/imaging/tools/types.d.ts +0 -243
  66. package/imaging/types.d.ts +0 -200
  67. package/imaging/waveforms/ecg.ts +0 -191
  68. package/index.ts +0 -431
  69. package/jsdoc.json +0 -52
  70. package/rollup.config.js +0 -51
  71. package/template/.gitkeep +0 -0
  72. package/tsconfig.json +0 -102
@@ -1,135 +0,0 @@
1
- /** @module imaging/imageAnonymization
2
- * @desc This file provides anonymization functionalities on DICOM images
3
- */
4
-
5
- // internal libraries
6
- import { MetaDataTypes } from "./MetaDataTypes";
7
- import { MetaData, Series } from "./types";
8
-
9
- /*
10
- * This module provides the following functions to be exported:
11
- * anonymize(series: Series): Series
12
- */
13
-
14
- /**
15
- * Anonymize a series by replacing all metadata with random values
16
- * @function anonymize
17
- * @param {Series} series - series to anonymize
18
- * @returns {Series} anonymized series
19
- */
20
- export const anonymize = function (series: Series): Series {
21
- // anonymize series bytearray
22
- for (const id in series.imageIds) {
23
- const imageId = series.imageIds[id];
24
- let image = series.instances[imageId];
25
- if (image.dataSet) {
26
- for (const tag in image.dataSet.elements) {
27
- let element = image.dataSet.elements[tag];
28
- let text = "";
29
- const vr = element.vr;
30
- if (element !== undefined) {
31
- let str = image.dataSet.string(tag);
32
- if (str !== undefined) {
33
- text = str;
34
- }
35
- }
36
- if (vr) {
37
- const deIdentifiedValue = makeDeIdentifiedValue(text.length, vr);
38
- if (deIdentifiedValue !== undefined) {
39
- for (let i: number = 0; i < element.length; i++) {
40
- const char =
41
- deIdentifiedValue.length > i
42
- ? deIdentifiedValue.charCodeAt(i)
43
- : 32;
44
- image.dataSet.byteArray[element.dataOffset + i] = char;
45
- }
46
- // @ts-ignore always string
47
- image.metadata[tag] = deIdentifiedValue;
48
- }
49
- }
50
- }
51
- image.metadata.seriesUID = image.metadata["x0020000e"];
52
- image.metadata.instanceUID = image.metadata["x00080018"];
53
- image.metadata.studyUID = image.metadata["x0020000d"];
54
- image.metadata.accessionNumber = image.metadata["x00080050"];
55
- image.metadata.studyDescription = image.metadata["x00081030"];
56
- image.metadata.patientName = image.metadata["x00100010"] as string;
57
- image.metadata.patientBirthdate = image.metadata["x00100030"];
58
- image.metadata.seriesDescription = image.metadata["x0008103e"] as string;
59
- image.metadata.anonymized = true;
60
- } else {
61
- console.warn(`No dataset found for image ${imageId}`);
62
- }
63
- }
64
-
65
- // update parsed metadata
66
- series.anonymized = true;
67
- series.seriesDescription = series.instances[series.imageIds[0]].metadata[
68
- "x0008103e"
69
- ] as string;
70
-
71
- return series;
72
- };
73
-
74
- // Internal functions
75
-
76
- /**
77
- * Generate a random string of a given length
78
- * @function makeRandomString
79
- * @param {number} length - length of the string to generate
80
- * @returns {string} random string
81
- */
82
- const makeRandomString = function (length: number): string {
83
- let text: string = "";
84
- const possible: string =
85
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
86
- for (let i: number = 0; i < length; i++) {
87
- text += possible.charAt(Math.floor(Math.random() * possible.length));
88
- }
89
- return text;
90
- };
91
-
92
- /**
93
- * Pad a number with 0s to a given size
94
- * @function pad
95
- * @param {number} num - number to pad
96
- * @param {number} size - size of the padded number
97
- * @returns {string} padded number
98
- */
99
- const pad = function (num: number, size: number): string {
100
- var s: string = num + "";
101
- while (s.length < size) s = "0" + s;
102
- return s;
103
- };
104
-
105
- /**
106
- * Make a de-identified value for a given length and VR
107
- * @function makeDeIdentifiedValue
108
- * @param {number} length - length of the value to generate
109
- * @param {string} vr - VR of the value to generate
110
- * @returns {string} de-identified value
111
- */
112
- const makeDeIdentifiedValue = function (
113
- length: number,
114
- vr: string
115
- ): string | undefined {
116
- if (vr === "LO" || vr === "SH" || vr === "PN") {
117
- return makeRandomString(length);
118
- } else if (vr === "DA") {
119
- let oldDate = new Date(1900, 0, 1);
120
- return (
121
- oldDate.getFullYear() +
122
- pad(oldDate.getMonth() + 1, 2) +
123
- pad(oldDate.getDate(), 2)
124
- );
125
- } else if (vr === "TM") {
126
- var now = new Date();
127
- return (
128
- pad(now.getHours(), 2) +
129
- pad(now.getMinutes(), 2) +
130
- pad(now.getSeconds(), 2)
131
- );
132
- } else {
133
- return undefined;
134
- }
135
- };
@@ -1,217 +0,0 @@
1
- /** @module imaging/imageColormaps
2
- * @desc This file provides functionalities for
3
- * handling colormaps
4
- */
5
-
6
- import cornerstone from "cornerstone-core";
7
- import { EnabledElementLayer } from "cornerstone-core";
8
- import { each } from "lodash";
9
-
10
- /*
11
- * This module provides the following functions to be exported:
12
- * getColormapsList()
13
- * addColorMap(colormapId, colormapName, colors)
14
- * fillPixelData(canvas, colormapId)
15
- * applyColorMap(colormapId)
16
- * HSVToRGB(hue, sat, val)
17
- */
18
-
19
- /**
20
- * Fill a canvas with pixelData representing the colormap
21
- * @instance
22
- * @function getColormapsList
23
- * @returns {Array} A list of cornerstone colormaps
24
- */
25
- export function getColormapsList() {
26
- return cornerstone.colors.getColormapsList();
27
- }
28
-
29
- /**
30
- * Add a custom color map to cornerstone list
31
- * @instance
32
- * @function addColorMap
33
- * @param {String} colormapId - the new colormap id
34
- * @param {String} colormapName - the new colormap name
35
- * @param {Array} colors - array containing 255 rgb colors (ie [[r,g,b], [r,g,b], ...])
36
- */
37
- export function addColorMap(
38
- colormapId: string,
39
- colormapName: string,
40
- colors: Array<Array<number>>
41
- ) {
42
- const colormap = cornerstone.colors.getColormap(colormapId, null);
43
- colormap.setColorSchemeName(colormapName);
44
- let noc = colors.length;
45
- colormap.setNumberOfColors(noc);
46
-
47
- for (let i = 0; i < noc; i++) {
48
- let rgb = colors[i];
49
- colormap.insertColor(i, rgb);
50
- }
51
-
52
- return colormap;
53
- }
54
-
55
- /**
56
- * Fill a canvas with pixelData representing the colormap
57
- * @instance
58
- * @function fillPixelData
59
- * @param {HTMLCanvasElement} canvas - target canvas
60
- * @param {String} colormapId - the colormap name
61
- */
62
- export function fillPixelData(canvas: HTMLCanvasElement, colormapId: string) {
63
- const ctx = canvas.getContext("2d");
64
- const height = canvas.height;
65
- const width = canvas.width;
66
- if (ctx) {
67
- const colorbar = ctx.createImageData(width, height);
68
- const colormap = cornerstone.colors.getColormap(colormapId, {});
69
- const lookupTable = colormap.createLookupTable();
70
-
71
- // Set the min and max values then the lookup table
72
- // will be able to return the right color for this range
73
- lookupTable.setTableRange(0, width);
74
-
75
- // Update the colorbar pixel by pixel
76
- for (let col = 0; col < width; col++) {
77
- const color = lookupTable.mapValue(col);
78
-
79
- for (let row = 0; row < height; row++) {
80
- const pixel = (col + row * width) * 4;
81
- colorbar.data[pixel] = color[0];
82
- colorbar.data[pixel + 1] = color[1];
83
- colorbar.data[pixel + 2] = color[2];
84
- colorbar.data[pixel + 3] = color[3];
85
- }
86
- }
87
- ctx.putImageData(colorbar, 0, 0);
88
- } else {
89
- console.error("No context found for canvas", canvas);
90
- }
91
- }
92
-
93
- /**
94
- * Apply a color map on a viewport
95
- * @instance
96
- * @function applyColorMap
97
- * @param {String} colormapId - the colormap name
98
- * @param {Array} viewportNames - List of viewports where to apply preset
99
- */
100
- export function applyColorMap(
101
- colormapId: string,
102
- viewportNames?: Array<string>
103
- ) {
104
- // for retro-compatibility
105
- if (!viewportNames) {
106
- viewportNames = cornerstone.getEnabledElements().map(e => e.element.id);
107
- }
108
- let colormap = cornerstone.colors.getColormap(colormapId, {});
109
-
110
- each(viewportNames, viewportName => {
111
- let element = document.getElementById(viewportName);
112
-
113
- if (!element) {
114
- console.error("No element with id:", viewportName);
115
- return;
116
- }
117
-
118
- let enabledElement: EnabledElementLayer;
119
-
120
- try {
121
- enabledElement = cornerstone.getEnabledElement(element);
122
- } catch {
123
- console.error("No enabledElement with id", viewportName);
124
- return;
125
- }
126
-
127
- enabledElement.options = {}; // HACK to bypass cornerstone bug
128
-
129
- if (!enabledElement) {
130
- }
131
-
132
- const viewport = cornerstone.getViewport(element);
133
- if (viewport) {
134
- viewport.colormap = colormap;
135
- cornerstone.setViewport(element, viewport);
136
- cornerstone.updateImage(element, true);
137
- }
138
- });
139
-
140
- return colormap;
141
- }
142
-
143
- /**
144
- * Converts an HSV (Hue, Saturation, Value) color to RGB (Red, Green, Blue) color value
145
- * @param {Number} hue A number representing the hue color value
146
- * @param {Number} sat A number representing the saturation color value
147
- * @param {Number} val A number representing the value color value
148
- * @returns {Number[]} An RGB color array
149
- */
150
- export function HSVToRGB(hue: number, sat: number, val: number) {
151
- if (hue > 1) {
152
- throw new Error("HSVToRGB expects hue < 1");
153
- }
154
-
155
- const rgb = [];
156
-
157
- if (sat === 0) {
158
- rgb[0] = val;
159
- rgb[1] = val;
160
- rgb[2] = val;
161
-
162
- return rgb;
163
- }
164
-
165
- const hueCase = Math.floor(hue * 6);
166
- const frac = 6 * hue - hueCase;
167
- const lx = val * (1 - sat);
168
- const ly = val * (1 - sat * frac);
169
- const lz = val * (1 - sat * (1 - frac));
170
-
171
- switch (hueCase) {
172
- /* 0<hue<1/6 */
173
- case 0:
174
- case 6:
175
- rgb[0] = val;
176
- rgb[1] = lz;
177
- rgb[2] = lx;
178
- break;
179
-
180
- /* 1/6<hue<2/6 */
181
- case 1:
182
- rgb[0] = ly;
183
- rgb[1] = val;
184
- rgb[2] = lx;
185
- break;
186
-
187
- /* 2/6<hue<3/6 */
188
- case 2:
189
- rgb[0] = lx;
190
- rgb[1] = val;
191
- rgb[2] = lz;
192
- break;
193
-
194
- /* 3/6<hue/4/6 */
195
- case 3:
196
- rgb[0] = lx;
197
- rgb[1] = ly;
198
- rgb[2] = val;
199
- break;
200
-
201
- /* 4/6<hue<5/6 */
202
- case 4:
203
- rgb[0] = lz;
204
- rgb[1] = lx;
205
- rgb[2] = val;
206
- break;
207
-
208
- /* 5/6<hue<1 */
209
- case 5:
210
- rgb[0] = val;
211
- rgb[1] = lx;
212
- rgb[2] = ly;
213
- break;
214
- }
215
-
216
- return rgb;
217
- }
@@ -1,196 +0,0 @@
1
- /** @module imaging/imageContours
2
- * @desc This file provides functionalities to render a set of points on a canvas.
3
- * Use this in order to render image contours (e.g. from binary masks).
4
- */
5
-
6
- // external libraries
7
- import { each, range } from "lodash";
8
- import { vec2 } from "cornerstone-core";
9
- import { Contours } from "./types";
10
-
11
- /*
12
- * This module provides the following functions to be exported:
13
- * parseContours(contoursData,pointBatchSize,segmentationName, viewports)
14
- */
15
-
16
- /**
17
- * Parse raw data to contours object for each viewport
18
- * @export
19
- * @function parseContours
20
- * @param {Array} contoursData - Raw data
21
- * @param {Number} pointBatchSize - Number of points that defines a contour segment (default to 2)
22
- * @param {String} segmentationName - Mask object name
23
- * @param {Array} viewports - Viewport array ids
24
- * @returns {Number} Number of array elements consumed
25
- */
26
- export const parseContours = function (
27
- contoursData: { [key: string]: Uint8Array }, // TODO-ts: check if this is correct @mronzoni
28
- pointBatchSize: number,
29
- segmentationName: string,
30
- viewports: Array<string>
31
- ) {
32
- let contours: Contours = {};
33
- each(viewports, viewport => {
34
- contours[viewport] = {};
35
- contours[viewport][segmentationName] = [];
36
- let points = contoursData[viewport];
37
-
38
- if (!points) {
39
- return;
40
- }
41
-
42
- let numberOfSlices = points[0];
43
- points = points.slice(1);
44
-
45
- each(range(numberOfSlices), function () {
46
- let sliceSize = extractSlicePoints(
47
- contours,
48
- pointBatchSize,
49
- points,
50
- segmentationName,
51
- viewport
52
- );
53
- points = points.slice(sliceSize);
54
- });
55
- });
56
-
57
- return contours;
58
- };
59
-
60
- /* Internal module functions */
61
-
62
- /**
63
- * From raw data, fill cornerstone tool data structure for ContoursTool for a single slice
64
- * @instance
65
- * @function populateContoursObject
66
- * @param {Number} pointBatchSize - Number of points that defines a contour segment
67
- * @param {Object} contours - Main contour tool object dict (to be filled)
68
- * @param {Number} lineNumber - Number of line to be rendered (a contour is made of n lines)
69
- * @param {Number} sliceNumber - Number of the slice in which the contour should be rendered
70
- * @param {String} segmentationName - Mask object name
71
- * @param {String} viewport - Viewport id
72
- * @param {Array} data - Raw data (array of pixel values)
73
- */
74
- const populateContoursObject = function (
75
- pointBatchSize: number,
76
- contours: Contours,
77
- lineNumber: number,
78
- sliceNumber: number,
79
- segmentationName: string,
80
- viewport: string,
81
- data: Uint8Array
82
- ) {
83
- let coords: Array<{ x: number; y: number; lines: Array<vec2> }> = [];
84
-
85
- for (let i = 0; i < data.length; i += pointBatchSize) {
86
- let xy = data.slice(i, pointBatchSize + i);
87
-
88
- // always add the first item
89
- if (!coords.length) {
90
- coords.push({
91
- x: xy[0],
92
- y: xy[1],
93
- lines: []
94
- });
95
- }
96
-
97
- // add new items if different from the previous one
98
- else {
99
- //if (coords[coords.length - 1].x !== xy[0] &&
100
- // coords[coords.length - 1].y !== xy[1]) {
101
- coords.push({
102
- x: xy[0],
103
- y: xy[1],
104
- lines: [
105
- {
106
- x: coords[coords.length - 1].x,
107
- y: coords[coords.length - 1].y
108
- }
109
- ]
110
- });
111
- }
112
- }
113
-
114
- // add line element to the first item
115
- if (coords[0]) {
116
- coords[0].lines = [
117
- {
118
- x: coords[coords.length - 1].x,
119
- y: coords[coords.length - 1].y
120
- }
121
- ];
122
- }
123
-
124
- contours[viewport][segmentationName][sliceNumber].lines[lineNumber] = coords;
125
- };
126
-
127
- /**
128
- * Extract each slice points from raw data array
129
- * @instance
130
- * @function extractSlicePoints
131
- * @param {Object} contours - Main contour tool object dict (to be filled)
132
- * @param {Number} pointBatchSize - Number of points that defines a contour segment (default to 2)
133
- * @param {Number} slicePoints - Number of contour points on a slice
134
- * @param {String} segmentationName - Mask object name
135
- * @param {String} viewport - Viewport id
136
- * @returns {Number} Number of array elements consumed
137
- */
138
- const extractSlicePoints = function (
139
- contours: Contours,
140
- pointBatchSize: number,
141
- slicePoints: Uint8Array, // TODO-ts: check if this is correct @mronzoni
142
- segmentationName: string,
143
- viewport: string
144
- ) {
145
- // read slice number and number of lines for current slice, then remove from array
146
- let sliceNumber = slicePoints[0];
147
- let numberOfLines = slicePoints[1];
148
-
149
- try {
150
- slicePoints = slicePoints.subarray(2);
151
- } catch (err) {
152
- slicePoints = slicePoints.slice(2);
153
- }
154
-
155
- let numberOfPoints = 0;
156
- contours[viewport][segmentationName][sliceNumber] = {
157
- lines: [] as vec2[][]
158
- };
159
-
160
- if (numberOfLines) {
161
- // for each line
162
- each(range(numberOfLines), function (l: number) {
163
- // get number of points for current line
164
- let numberOfPointsPerLine = slicePoints[0];
165
- // compute coordinates size
166
- let lineCoordSize = numberOfPointsPerLine * pointBatchSize;
167
-
168
- // remove numberOfPointsPerLine and the coordinates for this line
169
- let subCoords;
170
- try {
171
- subCoords = slicePoints.subarray(1, lineCoordSize + 1);
172
- } catch (err) {
173
- subCoords = slicePoints.slice(1, lineCoordSize + 1);
174
- }
175
- populateContoursObject(
176
- pointBatchSize,
177
- contours,
178
- l,
179
- sliceNumber,
180
- segmentationName,
181
- viewport,
182
- subCoords
183
- );
184
-
185
- let lineSize = 1 + lineCoordSize;
186
- numberOfPoints += lineSize;
187
- try {
188
- slicePoints = slicePoints.subarray(lineSize);
189
- } catch (err) {
190
- slicePoints = slicePoints.slice(lineSize);
191
- }
192
- });
193
- }
194
-
195
- return 2 + numberOfPoints;
196
- };