larvitar 2.0.5 → 2.0.7
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/README.md +2 -2
- package/dist/imaging/imageRendering.d.ts +1 -71
- package/dist/imaging/imageStore.d.ts +5 -0
- package/dist/imaging/loaders/commonLoader.d.ts +4 -4
- package/dist/imaging/loaders/nrrdLoader.d.ts +1 -51
- package/dist/larvitar.js +13 -1
- package/dist/larvitar.js.map +1 -1
- package/imaging/tools/types.d.ts +19 -19
- package/imaging/types.d.ts +110 -2
- package/package.json +7 -2
- package/.github/workflows/build-docs.yml +0 -59
- package/.github/workflows/codeql-analysis.yml +0 -71
- package/.github/workflows/deploy.yml +0 -37
- package/.vscode/settings.json +0 -4
- package/CODE_OF_CONDUCT.md +0 -76
- package/MIGRATION.md +0 -25
- package/bundler/webpack.common.js +0 -27
- package/bundler/webpack.dev.js +0 -23
- package/bundler/webpack.prod.js +0 -19
- package/decs.d.ts +0 -12
- package/dist/imaging/MetaDataReadable.d.ts +0 -41
- package/dist/imaging/MetaDataTypes.d.ts +0 -3489
- package/imaging/dataDictionary.json +0 -21866
- package/imaging/imageAnonymization.ts +0 -135
- package/imaging/imageColormaps.ts +0 -217
- package/imaging/imageContours.ts +0 -196
- package/imaging/imageIo.ts +0 -251
- package/imaging/imageLayers.ts +0 -121
- package/imaging/imageLoading.ts +0 -299
- package/imaging/imageParsing.ts +0 -444
- package/imaging/imagePresets.ts +0 -156
- package/imaging/imageRendering.ts +0 -1091
- package/imaging/imageReslice.ts +0 -87
- package/imaging/imageStore.ts +0 -487
- package/imaging/imageTags.ts +0 -609
- package/imaging/imageTools.js +0 -708
- package/imaging/imageUtils.ts +0 -1079
- package/imaging/loaders/commonLoader.ts +0 -275
- package/imaging/loaders/dicomLoader.ts +0 -66
- package/imaging/loaders/fileLoader.ts +0 -71
- package/imaging/loaders/multiframeLoader.ts +0 -435
- package/imaging/loaders/nrrdLoader.ts +0 -630
- package/imaging/loaders/resliceLoader.ts +0 -205
- package/imaging/monitors/memory.ts +0 -151
- package/imaging/monitors/performance.ts +0 -34
- package/imaging/parsers/ecg.ts +0 -54
- package/imaging/parsers/nrrd.js +0 -485
- package/imaging/tools/custom/4dSliceScrollTool.js +0 -146
- package/imaging/tools/custom/BorderMagnifyTool.js +0 -99
- package/imaging/tools/custom/contourTool.js +0 -1884
- package/imaging/tools/custom/diameterTool.js +0 -141
- package/imaging/tools/custom/editMaskTool.js +0 -141
- package/imaging/tools/custom/ellipticalRoiOverlayTool.js +0 -534
- package/imaging/tools/custom/polygonSegmentationMixin.js +0 -245
- package/imaging/tools/custom/polylineScissorsTool.js +0 -59
- package/imaging/tools/custom/rectangleRoiOverlayTool.js +0 -564
- package/imaging/tools/custom/seedTool.js +0 -342
- package/imaging/tools/custom/setLabelMap3D.ts +0 -242
- package/imaging/tools/custom/thresholdsBrushTool.js +0 -161
- package/imaging/tools/default.ts +0 -594
- package/imaging/tools/interaction.ts +0 -266
- package/imaging/tools/io.ts +0 -229
- package/imaging/tools/main.ts +0 -427
- package/imaging/tools/segmentation.ts +0 -532
- package/imaging/tools/segmentations.md +0 -38
- package/imaging/tools/state.ts +0 -74
- package/imaging/tools/strategies/eraseFreehand.js +0 -76
- package/imaging/tools/strategies/fillFreehand.js +0 -79
- package/imaging/tools/strategies/index.js +0 -2
- package/imaging/waveforms/ecg.ts +0 -191
- package/index.ts +0 -431
- package/jsdoc.json +0 -52
- package/rollup.config.js +0 -51
- package/template/.gitkeep +0 -0
- package/tsconfig.json +0 -102
- /package/imaging/{MetaDataReadable.ts → MetaDataReadable.d.ts} +0 -0
- /package/imaging/{MetaDataTypes.ts → MetaDataTypes.d.ts} +0 -0
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
/** @module imaging/strategies/eraseFreehand
|
|
2
|
-
* @desc This file provides functionalities for
|
|
3
|
-
* erasing pixels
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
// external libraries
|
|
7
|
-
import cornerstoneTools from "cornerstone-tools";
|
|
8
|
-
const { getBoundingBoxAroundPolygon, eraseInsideShape, eraseOutsideShape } =
|
|
9
|
-
cornerstoneTools.importInternal("util/segmentationUtils");
|
|
10
|
-
const isPointInPolygon = cornerstoneTools.importInternal(
|
|
11
|
-
"util/isPointInPolygon"
|
|
12
|
-
);
|
|
13
|
-
const getLogger = cornerstoneTools.importInternal("util/getLogger");
|
|
14
|
-
const logger = getLogger("util:segmentation:operations:eraseInsideFreehand");
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Erase all pixels labeled with the activeSegmentIndex,
|
|
18
|
-
* in the region defined by evt.operationData.points.
|
|
19
|
-
* @param {} evt The Cornerstone event.
|
|
20
|
-
* @param {} operationData An object containing the `pixelData` to
|
|
21
|
-
* modify, the `segmentIndex` and the `points` array.
|
|
22
|
-
* @returns {null}
|
|
23
|
-
*/
|
|
24
|
-
function eraseFreehand(evt, operationData, inside = true) {
|
|
25
|
-
const { points, segmentationMixinType } = operationData;
|
|
26
|
-
|
|
27
|
-
if (segmentationMixinType !== `freehandSegmentationMixin`) {
|
|
28
|
-
logger.error(
|
|
29
|
-
`eraseInsideFreehand operation requires freehandSegmentationMixin operationData, recieved ${segmentationMixinType}`
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const { image } = evt.detail;
|
|
36
|
-
const vertices = points.map(a => [a.x, a.y]);
|
|
37
|
-
const [topLeft, bottomRight] = getBoundingBoxAroundPolygon(vertices, image);
|
|
38
|
-
|
|
39
|
-
inside
|
|
40
|
-
? eraseInsideShape(
|
|
41
|
-
evt,
|
|
42
|
-
operationData,
|
|
43
|
-
point => isPointInPolygon([point.x, point.y], vertices),
|
|
44
|
-
topLeft,
|
|
45
|
-
bottomRight
|
|
46
|
-
)
|
|
47
|
-
: eraseOutsideShape(
|
|
48
|
-
evt,
|
|
49
|
-
operationData,
|
|
50
|
-
point => isPointInPolygon([point.x, point.y], vertices),
|
|
51
|
-
topLeft,
|
|
52
|
-
bottomRight
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Erase all pixels inside/outside the region defined by `operationData.points`.
|
|
58
|
-
* @param {} evt The Cornerstone event.
|
|
59
|
-
* @param {} operationData An object containing the `pixelData` to
|
|
60
|
-
* modify, the `segmentIndex` and the `points` array.
|
|
61
|
-
* @returns {null}
|
|
62
|
-
*/
|
|
63
|
-
export function eraseInsideFreehand(evt, operationData) {
|
|
64
|
-
eraseFreehand(evt, operationData, true);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Erase all pixels outside the region defined by `operationData.points`.
|
|
69
|
-
* @param {} evt The Cornerstone event.
|
|
70
|
-
* @param {} operationData An object containing the `pixelData` to
|
|
71
|
-
* modify, the `segmentIndex` and the `points` array.
|
|
72
|
-
* @returns {null}
|
|
73
|
-
*/
|
|
74
|
-
export function eraseOutsideFreehand(evt, operationData) {
|
|
75
|
-
eraseFreehand(evt, operationData, false);
|
|
76
|
-
}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
/** @module imaging/strategies/fillFreehand
|
|
2
|
-
* @desc This file provides functionalities for
|
|
3
|
-
* filling pixels
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
// external libraries
|
|
7
|
-
import cornerstoneTools from "cornerstone-tools";
|
|
8
|
-
const { getBoundingBoxAroundPolygon, fillInsideShape, fillOutsideShape } =
|
|
9
|
-
cornerstoneTools.importInternal("util/segmentationUtils");
|
|
10
|
-
const isPointInPolygon = cornerstoneTools.importInternal(
|
|
11
|
-
"util/isPointInPolygon"
|
|
12
|
-
);
|
|
13
|
-
const getLogger = cornerstoneTools.importInternal("util/getLogger");
|
|
14
|
-
const logger = getLogger("util:segmentation:operations:fillInsideFreehand");
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Fill all pixels inside/outside the region defined by
|
|
18
|
-
* `operationData.points` with the `activeSegmentIndex` value.
|
|
19
|
-
* @param {} evt The Cornerstone event.
|
|
20
|
-
* @param {} operationData An object containing the `pixelData` to
|
|
21
|
-
* modify, the `segmentIndex` and the `points` array.
|
|
22
|
-
* @returns {null}
|
|
23
|
-
*/
|
|
24
|
-
function fillFreehand(evt, operationData, inside = true) {
|
|
25
|
-
const { points, segmentationMixinType } = operationData;
|
|
26
|
-
|
|
27
|
-
if (segmentationMixinType !== `freehandSegmentationMixin`) {
|
|
28
|
-
logger.error(
|
|
29
|
-
`eraseInsideFreehand operation requires freehandSegmentationMixin operationData, recieved ${segmentationMixinType}`
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Obtain the bounding box of the entire drawing so that
|
|
36
|
-
// we can subset our search. Outside of the bounding box,
|
|
37
|
-
// everything is outside of the polygon.
|
|
38
|
-
const { image } = evt.detail;
|
|
39
|
-
const vertices = points.map(a => [a.x, a.y]);
|
|
40
|
-
const [topLeft, bottomRight] = getBoundingBoxAroundPolygon(vertices, image);
|
|
41
|
-
|
|
42
|
-
inside
|
|
43
|
-
? fillInsideShape(
|
|
44
|
-
evt,
|
|
45
|
-
operationData,
|
|
46
|
-
point => isPointInPolygon([point.x, point.y], vertices),
|
|
47
|
-
topLeft,
|
|
48
|
-
bottomRight
|
|
49
|
-
)
|
|
50
|
-
: fillOutsideShape(
|
|
51
|
-
evt,
|
|
52
|
-
operationData,
|
|
53
|
-
point => isPointInPolygon([point.x, point.y], vertices),
|
|
54
|
-
topLeft,
|
|
55
|
-
bottomRight
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Fill all pixels inside/outside the region defined by `operationData.points`.
|
|
61
|
-
* @param {} evt The Cornerstone event.
|
|
62
|
-
* @param {} operationData An object containing the `pixelData` to
|
|
63
|
-
* modify, the `segmentIndex` and the `points` array.
|
|
64
|
-
* @returns {null}
|
|
65
|
-
*/
|
|
66
|
-
export function fillInsideFreehand(evt, operationData) {
|
|
67
|
-
fillFreehand(evt, operationData, true);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Fill all pixels outside the region defined by `operationData.points`.
|
|
72
|
-
* @param {} evt The Cornerstone event.
|
|
73
|
-
* @param {} operationData An object containing the `pixelData` to
|
|
74
|
-
* modify, the `segmentIndex` and the `points` array.
|
|
75
|
-
* @returns {null}
|
|
76
|
-
*/
|
|
77
|
-
export function fillOutsideFreehand(evt, operationData) {
|
|
78
|
-
fillFreehand(evt, operationData, false);
|
|
79
|
-
}
|
package/imaging/waveforms/ecg.ts
DELETED
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
/** @module waveforms/ecg
|
|
2
|
-
* @desc This file provides utility functions for
|
|
3
|
-
* rendering ecg waveforms using plotly.js
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
// external libraries
|
|
7
|
-
import Plotly, { Datum } from "plotly.js-dist-min";
|
|
8
|
-
|
|
9
|
-
// internal libraries
|
|
10
|
-
import { Series } from "../types";
|
|
11
|
-
import { NrrdSeries } from "../loaders/nrrdLoader";
|
|
12
|
-
import { updateImage } from "../imageRendering";
|
|
13
|
-
import store from "../imageStore";
|
|
14
|
-
import { getSeriesDataFromLarvitarManager } from "../loaders/commonLoader";
|
|
15
|
-
import { updateStackToolState } from "../imageTools";
|
|
16
|
-
|
|
17
|
-
/*
|
|
18
|
-
* This module provides the following functions to be exported:
|
|
19
|
-
* renderECG(data, divId, colorMarker, numberOfFrames, frameTime, frameId)
|
|
20
|
-
* syncECGFrame(traceData, seriesId, canvasId, numberOfFrames, divId)
|
|
21
|
-
* updateECGFrame(traceData, frameId, numberOfFrames, divId)
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
const LAYOUT: Partial<Plotly.Layout> = {
|
|
25
|
-
xaxis: {
|
|
26
|
-
rangemode: "tozero",
|
|
27
|
-
showgrid: true,
|
|
28
|
-
gridcolor: "rgba(238,135,51,0.5)",
|
|
29
|
-
dtick: 1,
|
|
30
|
-
tickwidth: 2,
|
|
31
|
-
tickcolor: "#f5f5f5",
|
|
32
|
-
tickformat: ".2f",
|
|
33
|
-
tickfont: {
|
|
34
|
-
color: "#f5f5f5"
|
|
35
|
-
}
|
|
36
|
-
},
|
|
37
|
-
yaxis: {
|
|
38
|
-
rangemode: "nonnegative",
|
|
39
|
-
showgrid: true,
|
|
40
|
-
gridcolor: "rgba(238,135,51,0.5)",
|
|
41
|
-
dtick: 20,
|
|
42
|
-
tick0: 0,
|
|
43
|
-
tickwidth: 2,
|
|
44
|
-
tickcolor: "#f5f5f5",
|
|
45
|
-
tickfont: {
|
|
46
|
-
color: "#f5f5f5"
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
showlegend: false,
|
|
50
|
-
paper_bgcolor: "#000000",
|
|
51
|
-
plot_bgcolor: "#000000"
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Render ECG waveform in a div
|
|
56
|
-
* @instance
|
|
57
|
-
* @function renderECG
|
|
58
|
-
* @param {number[]} data - ECG waveform data
|
|
59
|
-
* @param {string} divId - DivId to render waveform in
|
|
60
|
-
* @param {string} colorMarker - Color of the marker
|
|
61
|
-
* @param {number} numberOfframes - Number of frames in the image
|
|
62
|
-
* @param {number} frameTime - Time interval of each frame in the image
|
|
63
|
-
* @param {number} frameId - FrameId of the image to be rendered
|
|
64
|
-
* @returns {Object} traceData - Plotly trace data
|
|
65
|
-
*/
|
|
66
|
-
export const renderECG = function (
|
|
67
|
-
data: number[],
|
|
68
|
-
divId: string,
|
|
69
|
-
colorMarker: string,
|
|
70
|
-
numberOfFrames: number,
|
|
71
|
-
frameTime: number,
|
|
72
|
-
frameId: number = 0
|
|
73
|
-
): Partial<Plotly.PlotData>[] {
|
|
74
|
-
// convert info using frameTime and numberOfFrames
|
|
75
|
-
const totalTime = (numberOfFrames - 1) * (frameTime * 1e-3);
|
|
76
|
-
const dotX: number = Math.floor((frameId * data.length) / numberOfFrames);
|
|
77
|
-
// build the trace data
|
|
78
|
-
const trace: Partial<Plotly.PlotData> = {
|
|
79
|
-
x: data.map((_, i) => (i * totalTime) / data.length),
|
|
80
|
-
y: data,
|
|
81
|
-
mode: "lines",
|
|
82
|
-
type: "scattergl",
|
|
83
|
-
line: {
|
|
84
|
-
width: 1.5,
|
|
85
|
-
shape: "linear"
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
// build the marker data
|
|
90
|
-
const marker: Partial<Plotly.PlotData> = {
|
|
91
|
-
x: [dotX],
|
|
92
|
-
y: [data[dotX]],
|
|
93
|
-
mode: "markers",
|
|
94
|
-
type: "scattergl",
|
|
95
|
-
marker: {
|
|
96
|
-
size: 12,
|
|
97
|
-
color: colorMarker,
|
|
98
|
-
symbol: "line-ns-open",
|
|
99
|
-
line: {
|
|
100
|
-
width: 3
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
// render data and update ranges
|
|
105
|
-
const traceData: Partial<Plotly.PlotData>[] = [trace, marker];
|
|
106
|
-
// fix the range of the x-axis
|
|
107
|
-
LAYOUT.xaxis!.range = [0, totalTime];
|
|
108
|
-
// fix the grid of x-axis using a line for each frame
|
|
109
|
-
LAYOUT.xaxis!.dtick = LAYOUT.xaxis!.dtick = totalTime / (numberOfFrames - 1);
|
|
110
|
-
Plotly.newPlot(divId, traceData, LAYOUT, {
|
|
111
|
-
responsive: true,
|
|
112
|
-
displayModeBar: false
|
|
113
|
-
});
|
|
114
|
-
return traceData;
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Sync ECG waveform with rendered image on click
|
|
119
|
-
* @instance
|
|
120
|
-
* @function syncECGFrame
|
|
121
|
-
* @param {Object} traceData - Plotly trace data
|
|
122
|
-
* @param {string} seriesId - SeriesId of the image
|
|
123
|
-
* @param {string} canvasId - CanvasId of the image
|
|
124
|
-
* @param {number} numberOfFrames - Number of frames in the image
|
|
125
|
-
* @param {string} divId - DivId to render waveform in
|
|
126
|
-
*/
|
|
127
|
-
export const syncECGFrame = function (
|
|
128
|
-
traceData: Partial<Plotly.PlotData>[],
|
|
129
|
-
seriesId: string,
|
|
130
|
-
canvasId: string,
|
|
131
|
-
numberOfFrames: number,
|
|
132
|
-
divId: string
|
|
133
|
-
) {
|
|
134
|
-
// document.getElementById('myDiv') return HTMLElement. This type doesn't
|
|
135
|
-
// contain method 'on' because this method is added within plotly-latest.min.js.
|
|
136
|
-
const domElement: any = document.getElementById(divId);
|
|
137
|
-
if (domElement) {
|
|
138
|
-
domElement.on("plotly_click", function (data: Plotly.PlotMouseEvent) {
|
|
139
|
-
traceData[1].x = [data.points[0].x];
|
|
140
|
-
traceData[1].y = [data.points[0].y];
|
|
141
|
-
Plotly.extendTraces(divId, {}, [0]);
|
|
142
|
-
const totalTime: number = (traceData[0].x as number[])[
|
|
143
|
-
(traceData[0].x as number[]).length - 1
|
|
144
|
-
];
|
|
145
|
-
const frameId: number = Math.floor(
|
|
146
|
-
((data.points[0].x as number) * numberOfFrames - 1) / totalTime
|
|
147
|
-
);
|
|
148
|
-
const series: Series | NrrdSeries | null =
|
|
149
|
-
getSeriesDataFromLarvitarManager(seriesId);
|
|
150
|
-
if (series) {
|
|
151
|
-
updateImage(series as Series, canvasId, frameId, false);
|
|
152
|
-
updateStackToolState(canvasId, frameId);
|
|
153
|
-
}
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
const canvasElement: any = document.getElementById(canvasId);
|
|
158
|
-
canvasElement.addEventListener("wheel", function (e: WheelEvent) {
|
|
159
|
-
const viewport = store.get(["viewports", canvasId]);
|
|
160
|
-
updateECGFrame(traceData, viewport.sliceId, numberOfFrames, divId);
|
|
161
|
-
updateStackToolState(canvasId, viewport.sliceId);
|
|
162
|
-
});
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Sync ECG waveform with rendered image on click
|
|
167
|
-
* @instance
|
|
168
|
-
* @function updateECGFrame
|
|
169
|
-
* @param {Object} traceData - Plotly trace data
|
|
170
|
-
* @param {number} frameId - FrameId of the image
|
|
171
|
-
* @param {number} numberOfFrames - Number of frames in the image
|
|
172
|
-
* @param {string} divId - DivId to render waveform in
|
|
173
|
-
*/
|
|
174
|
-
export const updateECGFrame = function (
|
|
175
|
-
traceData: Partial<Plotly.PlotData>[],
|
|
176
|
-
frameId: number,
|
|
177
|
-
numberOfFrames: number,
|
|
178
|
-
divId: string
|
|
179
|
-
) {
|
|
180
|
-
const totalTime: number = (traceData[0].x as number[])[
|
|
181
|
-
(traceData[0].x as number[]).length - 1
|
|
182
|
-
];
|
|
183
|
-
const dotX: number = (frameId * totalTime) / (numberOfFrames - 1);
|
|
184
|
-
const index: number = (traceData[0].x as number[]).findIndex(
|
|
185
|
-
(x: number) => x >= dotX
|
|
186
|
-
);
|
|
187
|
-
const dotY: Datum | Datum[] = traceData[0].y![index];
|
|
188
|
-
traceData[1].x = [dotX];
|
|
189
|
-
traceData[1].y = Array.isArray(dotY) ? dotY : [dotY];
|
|
190
|
-
Plotly.extendTraces(divId, {}, [0]);
|
|
191
|
-
};
|