@ohif/app 3.7.0-beta.99 → 3.8.0-beta.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.
- package/dist/{202.bundle.96bbb4547a346fe3921f.js → 202.bundle.d3490836f71e001dd30f.js} +746 -19
- package/dist/{221.bundle.8d4059312a771ac53a19.js → 221.bundle.a331e2a9a29f9599fd40.js} +70 -14
- package/dist/{342.bundle.095cc16d795ac02a7b78.js → 342.bundle.0496ac7497a393d0a21b.js} +40 -22
- package/dist/{359.bundle.d32d3e78569b6717a2fb.js → 359.bundle.aa2adce78c3935aa19c1.js} +1 -3
- package/dist/{370.bundle.a275a49f7b72669bce3f.js → 370.bundle.31f3d861d96bdd540dc7.js} +4 -4
- package/dist/{743.bundle.4bfe6e562ffb2c22708f.js → 743.bundle.489f7df3a089d4d374e1.js} +13 -0
- package/dist/{831.bundle.83658f62fcc769043605.js → 757.bundle.ec8301d8e70d2b990f65.js} +368 -1
- package/dist/{782.bundle.f6d16bde1ecbb30f1693.js → 788.bundle.b9dabaea41cb029360b1.js} +5 -305
- package/dist/{82.bundle.e83d670b0199d1bc717c.js → 82.bundle.77c6092b1e5209f1a172.js} +62 -42
- package/dist/{957.bundle.71558794566041f37a92.js → 957.bundle.9ea4506963ef8b2d84ba.js} +44 -41
- package/dist/{app.bundle.85c4172c936ff45dd5ae.js → app.bundle.75f3f246ad5bd7bf197e.js} +143 -99
- package/dist/app.bundle.css +1 -1
- package/dist/index.html +1 -1
- package/dist/sw.js +1 -1
- package/package.json +19 -18
- /package/dist/{12.bundle.c149229c3721197734b9.js → 12.bundle.b965cc54108a0b38a022.js} +0 -0
- /package/dist/{181.bundle.169383e9b1a0358b44e8.js → 181.bundle.ceb057236403bcb630ac.js} +0 -0
- /package/dist/{19.bundle.d1a02a9b42c17df51f39.js → 19.bundle.d961845411cf4e95d27c.js} +0 -0
- /package/dist/{236.bundle.004ffd1d05a9f69d6812.js → 236.bundle.b09ef6a3c16be7ad1d05.js} +0 -0
- /package/dist/{281.bundle.2faa52a55643723e80a3.js → 281.bundle.4f7c49673b5861436311.js} +0 -0
- /package/dist/{410.bundle.998289ecc010615b6088.js → 410.bundle.12c1bc7cb765ef74d275.js} +0 -0
- /package/dist/{506.bundle.f12d11057236d3e4cf05.js → 506.bundle.311783d53e8d64b84280.js} +0 -0
- /package/dist/{613.bundle.9d7c11a0ceefc2d954b5.js → 613.bundle.4359bc30c68b8f567140.js} +0 -0
- /package/dist/{663.bundle.7c704397c496dd476e11.js → 663.bundle.87300c41b902228496ec.js} +0 -0
- /package/dist/{687.bundle.93b66d44a4f83a1921db.js → 687.bundle.a3caefcf2e55897bad75.js} +0 -0
- /package/dist/{774.bundle.7528cba56a1407357144.js → 774.bundle.4b2dc46a35012b898e1a.js} +0 -0
- /package/dist/{814.bundle.9b3900d3b98f009990f9.js → 814.bundle.a3d1fbc03a4a3ea3f23d.js} +0 -0
- /package/dist/{822.bundle.0545d6dbb49515aa04ee.js → 822.bundle.891f2e57b1b7bc2f4cb4.js} +0 -0
- /package/dist/{99.bundle.bf2efcee897944d8a14b.js → 99.bundle.d77c8c0a957274c827da.js} +0 -0
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
"use strict";
|
|
7
7
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
8
8
|
/* harmony export */ Y: () => (/* binding */ index),
|
|
9
|
+
/* harmony export */ adaptersRT: () => (/* binding */ adaptersRT),
|
|
9
10
|
/* harmony export */ adaptersSEG: () => (/* binding */ adaptersSEG),
|
|
10
11
|
/* harmony export */ adaptersSR: () => (/* binding */ adaptersSR),
|
|
11
12
|
/* harmony export */ helpers: () => (/* binding */ index$1)
|
|
@@ -602,7 +603,7 @@ var StructuredReport$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .derivations */ .U
|
|
|
602
603
|
var Normalizer$4 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .normalizers */ .oq.Normalizer;
|
|
603
604
|
var TID1500MeasurementReport$1 = TID1500$1.TID1500MeasurementReport,
|
|
604
605
|
TID1501MeasurementGroup$1 = TID1500$1.TID1501MeasurementGroup;
|
|
605
|
-
var DicomMetaDictionary$
|
|
606
|
+
var DicomMetaDictionary$4 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.DicomMetaDictionary;
|
|
606
607
|
var FINDING$2 = {
|
|
607
608
|
CodingSchemeDesignator: "DCM",
|
|
608
609
|
CodeValue: "121071"
|
|
@@ -773,7 +774,7 @@ var MeasurementReport$1 = /*#__PURE__*/function () {
|
|
|
773
774
|
vr: "UI"
|
|
774
775
|
},
|
|
775
776
|
ImplementationClassUID: {
|
|
776
|
-
Value: [DicomMetaDictionary$
|
|
777
|
+
Value: [DicomMetaDictionary$4.uid()],
|
|
777
778
|
// TODO: could be git hash or other valid id
|
|
778
779
|
vr: "UI"
|
|
779
780
|
},
|
|
@@ -1846,7 +1847,7 @@ var _utilities$orientatio$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */
|
|
|
1846
1847
|
var datasetToBlob = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.datasetToBlob,
|
|
1847
1848
|
BitArray$2 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.BitArray,
|
|
1848
1849
|
DicomMessage$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.DicomMessage,
|
|
1849
|
-
DicomMetaDictionary$
|
|
1850
|
+
DicomMetaDictionary$3 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.DicomMetaDictionary;
|
|
1850
1851
|
var Normalizer$3 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .normalizers */ .oq.Normalizer;
|
|
1851
1852
|
var SegmentationDerivation$2 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .derivations */ .U7.Segmentation;
|
|
1852
1853
|
var Segmentation$5 = {
|
|
@@ -1976,16 +1977,16 @@ function _createSegFromImages$1(images, isMultiframe, options) {
|
|
|
1976
1977
|
var image = images[0];
|
|
1977
1978
|
var arrayBuffer = image.data.byteArray.buffer;
|
|
1978
1979
|
var dicomData = DicomMessage$1.readFile(arrayBuffer);
|
|
1979
|
-
var dataset = DicomMetaDictionary$
|
|
1980
|
-
dataset._meta = DicomMetaDictionary$
|
|
1980
|
+
var dataset = DicomMetaDictionary$3.naturalizeDataset(dicomData.dict);
|
|
1981
|
+
dataset._meta = DicomMetaDictionary$3.namifyDataset(dicomData.meta);
|
|
1981
1982
|
datasets.push(dataset);
|
|
1982
1983
|
} else {
|
|
1983
1984
|
for (var i = 0; i < images.length; i++) {
|
|
1984
1985
|
var _image = images[i];
|
|
1985
1986
|
var _arrayBuffer = _image.data.byteArray.buffer;
|
|
1986
1987
|
var _dicomData = DicomMessage$1.readFile(_arrayBuffer);
|
|
1987
|
-
var _dataset = DicomMetaDictionary$
|
|
1988
|
-
_dataset._meta = DicomMetaDictionary$
|
|
1988
|
+
var _dataset = DicomMetaDictionary$3.naturalizeDataset(_dicomData.dict);
|
|
1989
|
+
_dataset._meta = DicomMetaDictionary$3.namifyDataset(_dicomData.meta);
|
|
1989
1990
|
datasets.push(_dataset);
|
|
1990
1991
|
}
|
|
1991
1992
|
}
|
|
@@ -2005,8 +2006,8 @@ function _createSegFromImages$1(images, isMultiframe, options) {
|
|
|
2005
2006
|
*/
|
|
2006
2007
|
function generateToolState$3(imageIds, arrayBuffer, metadataProvider) {
|
|
2007
2008
|
var dicomData = DicomMessage$1.readFile(arrayBuffer);
|
|
2008
|
-
var dataset = DicomMetaDictionary$
|
|
2009
|
-
dataset._meta = DicomMetaDictionary$
|
|
2009
|
+
var dataset = DicomMetaDictionary$3.naturalizeDataset(dicomData.dict);
|
|
2010
|
+
dataset._meta = DicomMetaDictionary$3.namifyDataset(dicomData.meta);
|
|
2010
2011
|
var multiframe = Normalizer$3.normalizeToDataset([dataset]);
|
|
2011
2012
|
var imagePlaneModule = metadataProvider.get("imagePlaneModule", imageIds[0]);
|
|
2012
2013
|
if (!imagePlaneModule) {
|
|
@@ -2286,7 +2287,7 @@ var _utilities$orientatio = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .
|
|
|
2286
2287
|
nearlyEqual = _utilities$orientatio.nearlyEqual;
|
|
2287
2288
|
var BitArray$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.BitArray,
|
|
2288
2289
|
DicomMessage = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.DicomMessage,
|
|
2289
|
-
DicomMetaDictionary$
|
|
2290
|
+
DicomMetaDictionary$2 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.DicomMetaDictionary;
|
|
2290
2291
|
var Normalizer$2 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .normalizers */ .oq.Normalizer;
|
|
2291
2292
|
var SegmentationDerivation$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .derivations */ .U7.Segmentation;
|
|
2292
2293
|
var _utilities$compressio = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.compression,
|
|
@@ -2436,16 +2437,16 @@ function _createSegFromImages(images, isMultiframe, options) {
|
|
|
2436
2437
|
var image = images[0];
|
|
2437
2438
|
var arrayBuffer = image.data.byteArray.buffer;
|
|
2438
2439
|
var dicomData = DicomMessage.readFile(arrayBuffer);
|
|
2439
|
-
var dataset = DicomMetaDictionary$
|
|
2440
|
-
dataset._meta = DicomMetaDictionary$
|
|
2440
|
+
var dataset = DicomMetaDictionary$2.naturalizeDataset(dicomData.dict);
|
|
2441
|
+
dataset._meta = DicomMetaDictionary$2.namifyDataset(dicomData.meta);
|
|
2441
2442
|
datasets.push(dataset);
|
|
2442
2443
|
} else {
|
|
2443
2444
|
for (var i = 0; i < images.length; i++) {
|
|
2444
2445
|
var _image = images[i];
|
|
2445
2446
|
var _arrayBuffer = _image.data.byteArray.buffer;
|
|
2446
2447
|
var _dicomData = DicomMessage.readFile(_arrayBuffer);
|
|
2447
|
-
var _dataset = DicomMetaDictionary$
|
|
2448
|
-
_dataset._meta = DicomMetaDictionary$
|
|
2448
|
+
var _dataset = DicomMetaDictionary$2.naturalizeDataset(_dicomData.dict);
|
|
2449
|
+
_dataset._meta = DicomMetaDictionary$2.namifyDataset(_dicomData.meta);
|
|
2449
2450
|
datasets.push(_dataset);
|
|
2450
2451
|
}
|
|
2451
2452
|
}
|
|
@@ -2629,8 +2630,8 @@ function _generateToolState() {
|
|
|
2629
2630
|
case 0:
|
|
2630
2631
|
_options$skipOverlapp = options.skipOverlapping, skipOverlapping = _options$skipOverlapp === void 0 ? false : _options$skipOverlapp, _options$tolerance = options.tolerance, tolerance = _options$tolerance === void 0 ? 1e-3 : _options$tolerance, _options$TypedArrayCo = options.TypedArrayConstructor, TypedArrayConstructor = _options$TypedArrayCo === void 0 ? Uint8Array : _options$TypedArrayCo, _options$maxBytesPerC = options.maxBytesPerChunk, maxBytesPerChunk = _options$maxBytesPerC === void 0 ? 199000000 : _options$maxBytesPerC, eventTarget = options.eventTarget, triggerEvent = options.triggerEvent;
|
|
2631
2632
|
dicomData = DicomMessage.readFile(arrayBuffer);
|
|
2632
|
-
dataset = DicomMetaDictionary$
|
|
2633
|
-
dataset._meta = DicomMetaDictionary$
|
|
2633
|
+
dataset = DicomMetaDictionary$2.naturalizeDataset(dicomData.dict);
|
|
2634
|
+
dataset._meta = DicomMetaDictionary$2.namifyDataset(dicomData.meta);
|
|
2634
2635
|
multiframe = Normalizer$2.normalizeToDataset([dataset]);
|
|
2635
2636
|
imagePlaneModule = metadataProvider.get("imagePlaneModule", imageIds[0]);
|
|
2636
2637
|
generalSeriesModule = metadataProvider.get("generalSeriesModule", imageIds[0]);
|
|
@@ -3606,7 +3607,7 @@ var TID1500 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.TID1500, ad
|
|
|
3606
3607
|
var StructuredReport = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .derivations */ .U7.StructuredReport;
|
|
3607
3608
|
var Normalizer$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .normalizers */ .oq.Normalizer;
|
|
3608
3609
|
var TID1500MeasurementReport = TID1500.TID1500MeasurementReport, TID1501MeasurementGroup = TID1500.TID1501MeasurementGroup;
|
|
3609
|
-
var DicomMetaDictionary = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.DicomMetaDictionary;
|
|
3610
|
+
var DicomMetaDictionary$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.DicomMetaDictionary;
|
|
3610
3611
|
var FINDING = { CodingSchemeDesignator: "DCM", CodeValue: "121071" };
|
|
3611
3612
|
var FINDING_SITE = { CodingSchemeDesignator: "SCT", CodeValue: "363698007" };
|
|
3612
3613
|
var FINDING_SITE_OLD = { CodingSchemeDesignator: "SRT", CodeValue: "G-C0E3" };
|
|
@@ -3675,7 +3676,7 @@ var MeasurementReport = /** @class */ (function () {
|
|
|
3675
3676
|
vr: "UI"
|
|
3676
3677
|
},
|
|
3677
3678
|
ImplementationClassUID: {
|
|
3678
|
-
Value: [DicomMetaDictionary.uid()],
|
|
3679
|
+
Value: [DicomMetaDictionary$1.uid()],
|
|
3679
3680
|
vr: "UI"
|
|
3680
3681
|
},
|
|
3681
3682
|
ImplementationVersionName: {
|
|
@@ -3710,7 +3711,7 @@ var MeasurementReport = /** @class */ (function () {
|
|
|
3710
3711
|
description: undefined,
|
|
3711
3712
|
sopInstanceUid: ReferencedSOPInstanceUID,
|
|
3712
3713
|
annotation: {
|
|
3713
|
-
annotationUID: DicomMetaDictionary.uid(),
|
|
3714
|
+
annotationUID: DicomMetaDictionary$1.uid(),
|
|
3714
3715
|
metadata: {
|
|
3715
3716
|
toolName: toolType,
|
|
3716
3717
|
referencedImageId: referencedImageId,
|
|
@@ -4993,6 +4994,726 @@ var Segmentation$1 = /*#__PURE__*/Object.freeze({
|
|
|
4993
4994
|
generateToolState: generateToolState
|
|
4994
4995
|
});
|
|
4995
4996
|
|
|
4997
|
+
/**
|
|
4998
|
+
* Checks if point is within array
|
|
4999
|
+
* @param {*} array
|
|
5000
|
+
* @param {*} pt
|
|
5001
|
+
* @returns
|
|
5002
|
+
*/
|
|
5003
|
+
function ptInArray(array, pt) {
|
|
5004
|
+
var index = -1;
|
|
5005
|
+
for (var i = 0; i < array.length; i++) {
|
|
5006
|
+
if (isSamePoint(pt, array[i])) {
|
|
5007
|
+
index = i;
|
|
5008
|
+
}
|
|
5009
|
+
}
|
|
5010
|
+
return index;
|
|
5011
|
+
}
|
|
5012
|
+
|
|
5013
|
+
/**
|
|
5014
|
+
* Checks if point A and point B contain same values
|
|
5015
|
+
* @param {*} ptA
|
|
5016
|
+
* @param {*} ptB
|
|
5017
|
+
* @returns
|
|
5018
|
+
*/
|
|
5019
|
+
function isSamePoint(ptA, ptB) {
|
|
5020
|
+
if (ptA[0] == ptB[0] && ptA[1] == ptB[1] && ptA[2] == ptB[2]) {
|
|
5021
|
+
return true;
|
|
5022
|
+
} else {
|
|
5023
|
+
return false;
|
|
5024
|
+
}
|
|
5025
|
+
}
|
|
5026
|
+
|
|
5027
|
+
/**
|
|
5028
|
+
* Goes through linesArray and replaces all references of old index with new index
|
|
5029
|
+
* @param {*} linesArray
|
|
5030
|
+
* @param {*} oldIndex
|
|
5031
|
+
* @param {*} newIndex
|
|
5032
|
+
*/
|
|
5033
|
+
function replacePointIndexReferences(linesArray, oldIndex, newIndex) {
|
|
5034
|
+
for (var i = 0; i < linesArray.length; i++) {
|
|
5035
|
+
var line = linesArray[i];
|
|
5036
|
+
if (line.a == oldIndex) {
|
|
5037
|
+
line.a = newIndex;
|
|
5038
|
+
} else if (line.b == oldIndex) {
|
|
5039
|
+
line.b = newIndex;
|
|
5040
|
+
}
|
|
5041
|
+
}
|
|
5042
|
+
}
|
|
5043
|
+
|
|
5044
|
+
/**
|
|
5045
|
+
* Iterate through polyData from vtkjs and merge any points that are the same
|
|
5046
|
+
* then update merged point references within lines array
|
|
5047
|
+
* @param {*} polyData
|
|
5048
|
+
* @param {*} bypass
|
|
5049
|
+
* @returns
|
|
5050
|
+
*/
|
|
5051
|
+
function removeDuplicatePoints(polyData, bypass) {
|
|
5052
|
+
var points = polyData.getPoints();
|
|
5053
|
+
var lines = polyData.getLines();
|
|
5054
|
+
var pointsArray = [];
|
|
5055
|
+
for (var i = 0; i < points.getNumberOfPoints(); i++) {
|
|
5056
|
+
var pt = points.getPoint(i).slice();
|
|
5057
|
+
pointsArray.push(pt);
|
|
5058
|
+
}
|
|
5059
|
+
var linesArray = [];
|
|
5060
|
+
for (var _i = 0; _i < lines.getNumberOfCells(); _i++) {
|
|
5061
|
+
var cell = lines.getCell(_i * 3).slice();
|
|
5062
|
+
//console.log(JSON.stringify(cell));
|
|
5063
|
+
var a = cell[0];
|
|
5064
|
+
var b = cell[1];
|
|
5065
|
+
var line = {
|
|
5066
|
+
a: a,
|
|
5067
|
+
b: b
|
|
5068
|
+
};
|
|
5069
|
+
linesArray.push(line);
|
|
5070
|
+
}
|
|
5071
|
+
if (bypass) {
|
|
5072
|
+
return {
|
|
5073
|
+
points: pointsArray,
|
|
5074
|
+
lines: linesArray
|
|
5075
|
+
};
|
|
5076
|
+
}
|
|
5077
|
+
|
|
5078
|
+
// Iterate through points and replace any duplicates
|
|
5079
|
+
var newPoints = [];
|
|
5080
|
+
for (var _i2 = 0; _i2 < pointsArray.length; _i2++) {
|
|
5081
|
+
var _pt = pointsArray[_i2];
|
|
5082
|
+
var index = ptInArray(newPoints, _pt);
|
|
5083
|
+
if (index >= 0) {
|
|
5084
|
+
// Duplicate Point -> replace references in lines
|
|
5085
|
+
replacePointIndexReferences(linesArray, _i2, index);
|
|
5086
|
+
} else {
|
|
5087
|
+
index = newPoints.length;
|
|
5088
|
+
newPoints.push(_pt);
|
|
5089
|
+
replacePointIndexReferences(linesArray, _i2, index);
|
|
5090
|
+
}
|
|
5091
|
+
}
|
|
5092
|
+
|
|
5093
|
+
// Final pass through lines, remove any that refer to exact same point
|
|
5094
|
+
var newLines = [];
|
|
5095
|
+
linesArray.forEach(function (line) {
|
|
5096
|
+
if (line.a != line.b) {
|
|
5097
|
+
newLines.push(line);
|
|
5098
|
+
}
|
|
5099
|
+
});
|
|
5100
|
+
return {
|
|
5101
|
+
points: newPoints,
|
|
5102
|
+
lines: newLines
|
|
5103
|
+
};
|
|
5104
|
+
}
|
|
5105
|
+
|
|
5106
|
+
function findNextLink(line, lines, contourPoints) {
|
|
5107
|
+
var index = -1;
|
|
5108
|
+
lines.forEach(function (cell, i) {
|
|
5109
|
+
if (index >= 0) {
|
|
5110
|
+
return;
|
|
5111
|
+
}
|
|
5112
|
+
if (cell.a == line.b) {
|
|
5113
|
+
index = i;
|
|
5114
|
+
}
|
|
5115
|
+
});
|
|
5116
|
+
if (index >= 0) {
|
|
5117
|
+
var nextLine = lines[index];
|
|
5118
|
+
lines.splice(index, 1);
|
|
5119
|
+
contourPoints.push(nextLine.b);
|
|
5120
|
+
if (contourPoints[0] == nextLine.b) {
|
|
5121
|
+
return {
|
|
5122
|
+
remainingLines: lines,
|
|
5123
|
+
contourPoints: contourPoints,
|
|
5124
|
+
type: "CLOSED_PLANAR"
|
|
5125
|
+
//type: 'CLOSEDPLANAR_XOR',
|
|
5126
|
+
};
|
|
5127
|
+
}
|
|
5128
|
+
|
|
5129
|
+
return findNextLink(nextLine, lines, contourPoints);
|
|
5130
|
+
}
|
|
5131
|
+
return {
|
|
5132
|
+
remainingLines: lines,
|
|
5133
|
+
contourPoints: contourPoints,
|
|
5134
|
+
type: "OPEN_PLANAR"
|
|
5135
|
+
};
|
|
5136
|
+
}
|
|
5137
|
+
|
|
5138
|
+
/**
|
|
5139
|
+
*
|
|
5140
|
+
* @param {*} lines
|
|
5141
|
+
*/
|
|
5142
|
+
function findContours(lines) {
|
|
5143
|
+
if (lines.length == 0) {
|
|
5144
|
+
return [];
|
|
5145
|
+
}
|
|
5146
|
+
var contourPoints = [];
|
|
5147
|
+
var firstCell = lines.shift();
|
|
5148
|
+
contourPoints.push(firstCell.a);
|
|
5149
|
+
contourPoints.push(firstCell.b);
|
|
5150
|
+
var result = findNextLink(firstCell, lines, contourPoints);
|
|
5151
|
+
if (result.remainingLines.length == 0) {
|
|
5152
|
+
return [{
|
|
5153
|
+
type: result.type,
|
|
5154
|
+
contourPoints: result.contourPoints
|
|
5155
|
+
}];
|
|
5156
|
+
} else {
|
|
5157
|
+
var extraContours = findContours(result.remainingLines);
|
|
5158
|
+
extraContours.push({
|
|
5159
|
+
type: result.type,
|
|
5160
|
+
contourPoints: result.contourPoints
|
|
5161
|
+
});
|
|
5162
|
+
return extraContours;
|
|
5163
|
+
}
|
|
5164
|
+
}
|
|
5165
|
+
function findContoursFromReducedSet(lines, points) {
|
|
5166
|
+
return findContours(lines);
|
|
5167
|
+
}
|
|
5168
|
+
|
|
5169
|
+
function generateContourSetsFromLabelmap(_ref) {
|
|
5170
|
+
var segmentations = _ref.segmentations,
|
|
5171
|
+
cornerstoneCache = _ref.cornerstoneCache,
|
|
5172
|
+
cornerstoneToolsEnums = _ref.cornerstoneToolsEnums,
|
|
5173
|
+
vtkUtils = _ref.vtkUtils;
|
|
5174
|
+
var LABELMAP = cornerstoneToolsEnums.SegmentationRepresentations.Labelmap;
|
|
5175
|
+
var representationData = segmentations.representationData,
|
|
5176
|
+
segments = segmentations.segments;
|
|
5177
|
+
var segVolumeId = representationData[LABELMAP].volumeId;
|
|
5178
|
+
|
|
5179
|
+
// Get segmentation volume
|
|
5180
|
+
var vol = cornerstoneCache.getVolume(segVolumeId);
|
|
5181
|
+
if (!vol) {
|
|
5182
|
+
console.warn("No volume found for ".concat(segVolumeId));
|
|
5183
|
+
return;
|
|
5184
|
+
}
|
|
5185
|
+
var numSlices = vol.dimensions[2];
|
|
5186
|
+
|
|
5187
|
+
// Get image volume segmentation references
|
|
5188
|
+
var imageVol = cornerstoneCache.getVolume(vol.referencedVolumeId);
|
|
5189
|
+
if (!imageVol) {
|
|
5190
|
+
console.warn("No volume found for ".concat(vol.referencedVolumeId));
|
|
5191
|
+
return;
|
|
5192
|
+
}
|
|
5193
|
+
|
|
5194
|
+
// NOTE: Workaround for marching squares not finding closed contours at
|
|
5195
|
+
// boundary of image volume, clear pixels along x-y border of volume
|
|
5196
|
+
var segData = vol.imageData.getPointData().getScalars().getData();
|
|
5197
|
+
var pixelsPerSlice = vol.dimensions[0] * vol.dimensions[1];
|
|
5198
|
+
for (var z = 0; z < numSlices; z++) {
|
|
5199
|
+
for (var y = 0; y < vol.dimensions[1]; y++) {
|
|
5200
|
+
for (var x = 0; x < vol.dimensions[0]; x++) {
|
|
5201
|
+
var index = x + y * vol.dimensions[0] + z * pixelsPerSlice;
|
|
5202
|
+
if (x === 0 || y === 0 || x === vol.dimensions[0] - 1 || y === vol.dimensions[1] - 1) {
|
|
5203
|
+
segData[index] = 0;
|
|
5204
|
+
}
|
|
5205
|
+
}
|
|
5206
|
+
}
|
|
5207
|
+
}
|
|
5208
|
+
|
|
5209
|
+
// end workaround
|
|
5210
|
+
//
|
|
5211
|
+
//
|
|
5212
|
+
var ContourSets = [];
|
|
5213
|
+
|
|
5214
|
+
// Iterate through all segments in current segmentation set
|
|
5215
|
+
var numSegments = segments.length;
|
|
5216
|
+
for (var segIndex = 0; segIndex < numSegments; segIndex++) {
|
|
5217
|
+
var segment = segments[segIndex];
|
|
5218
|
+
|
|
5219
|
+
// Skip empty segments
|
|
5220
|
+
if (!segment) {
|
|
5221
|
+
continue;
|
|
5222
|
+
}
|
|
5223
|
+
var contourSequence = [];
|
|
5224
|
+
for (var sliceIndex = 0; sliceIndex < numSlices; sliceIndex++) {
|
|
5225
|
+
// Check if the slice is empty before running marching cube
|
|
5226
|
+
if (isSliceEmptyForSegment(sliceIndex, segData, pixelsPerSlice, segIndex)) {
|
|
5227
|
+
continue;
|
|
5228
|
+
}
|
|
5229
|
+
try {
|
|
5230
|
+
var _reducedSet$points;
|
|
5231
|
+
var scalars = vtkUtils.vtkDataArray.newInstance({
|
|
5232
|
+
name: "Scalars",
|
|
5233
|
+
values: Array.from(segData),
|
|
5234
|
+
numberOfComponents: 1
|
|
5235
|
+
});
|
|
5236
|
+
|
|
5237
|
+
// Modify segData for this specific segment directly
|
|
5238
|
+
var segmentIndexFound = false;
|
|
5239
|
+
for (var i = 0; i < segData.length; i++) {
|
|
5240
|
+
var value = segData[i];
|
|
5241
|
+
if (value === segIndex) {
|
|
5242
|
+
segmentIndexFound = true;
|
|
5243
|
+
scalars.setValue(i, 1);
|
|
5244
|
+
} else {
|
|
5245
|
+
scalars.setValue(i, 0);
|
|
5246
|
+
}
|
|
5247
|
+
}
|
|
5248
|
+
if (!segmentIndexFound) {
|
|
5249
|
+
continue;
|
|
5250
|
+
}
|
|
5251
|
+
var mSquares = vtkUtils.vtkImageMarchingSquares.newInstance({
|
|
5252
|
+
slice: sliceIndex
|
|
5253
|
+
});
|
|
5254
|
+
|
|
5255
|
+
// filter out the scalar data so that only it has background and
|
|
5256
|
+
// the current segment index
|
|
5257
|
+
var imageDataCopy = vtkUtils.vtkImageData.newInstance();
|
|
5258
|
+
imageDataCopy.shallowCopy(vol.imageData);
|
|
5259
|
+
imageDataCopy.getPointData().setScalars(scalars);
|
|
5260
|
+
|
|
5261
|
+
// Connect pipeline
|
|
5262
|
+
mSquares.setInputData(imageDataCopy);
|
|
5263
|
+
var cValues = [];
|
|
5264
|
+
cValues[0] = 1;
|
|
5265
|
+
mSquares.setContourValues(cValues);
|
|
5266
|
+
mSquares.setMergePoints(false);
|
|
5267
|
+
|
|
5268
|
+
// Perform marching squares
|
|
5269
|
+
var msOutput = mSquares.getOutputData();
|
|
5270
|
+
|
|
5271
|
+
// Clean up output from marching squares
|
|
5272
|
+
var reducedSet = removeDuplicatePoints(msOutput);
|
|
5273
|
+
if ((_reducedSet$points = reducedSet.points) !== null && _reducedSet$points !== void 0 && _reducedSet$points.length) {
|
|
5274
|
+
var contours = findContoursFromReducedSet(reducedSet.lines, reducedSet.points);
|
|
5275
|
+
contourSequence.push({
|
|
5276
|
+
referencedImageId: imageVol.imageIds[sliceIndex],
|
|
5277
|
+
contours: contours,
|
|
5278
|
+
polyData: reducedSet
|
|
5279
|
+
});
|
|
5280
|
+
}
|
|
5281
|
+
} catch (e) {
|
|
5282
|
+
console.warn(sliceIndex);
|
|
5283
|
+
console.warn(e);
|
|
5284
|
+
}
|
|
5285
|
+
}
|
|
5286
|
+
var metadata = {
|
|
5287
|
+
referencedImageId: imageVol.imageIds[0],
|
|
5288
|
+
// just use 0
|
|
5289
|
+
FrameOfReferenceUID: imageVol.metadata.FrameOfReferenceUID
|
|
5290
|
+
};
|
|
5291
|
+
var ContourSet = {
|
|
5292
|
+
label: segment.label,
|
|
5293
|
+
color: segment.color,
|
|
5294
|
+
metadata: metadata,
|
|
5295
|
+
sliceContours: contourSequence
|
|
5296
|
+
};
|
|
5297
|
+
ContourSets.push(ContourSet);
|
|
5298
|
+
}
|
|
5299
|
+
return ContourSets;
|
|
5300
|
+
}
|
|
5301
|
+
function isSliceEmptyForSegment(sliceIndex, segData, pixelsPerSlice, segIndex) {
|
|
5302
|
+
var startIdx = sliceIndex * pixelsPerSlice;
|
|
5303
|
+
var endIdx = startIdx + pixelsPerSlice;
|
|
5304
|
+
for (var i = startIdx; i < endIdx; i++) {
|
|
5305
|
+
if (segData[i] === segIndex) {
|
|
5306
|
+
return false;
|
|
5307
|
+
}
|
|
5308
|
+
}
|
|
5309
|
+
return true;
|
|
5310
|
+
}
|
|
5311
|
+
|
|
5312
|
+
// comment
|
|
5313
|
+
var RectangleROIStartEndThreshold = /*#__PURE__*/function () {
|
|
5314
|
+
function RectangleROIStartEndThreshold() {
|
|
5315
|
+
_classCallCheck(this, RectangleROIStartEndThreshold);
|
|
5316
|
+
} // empty
|
|
5317
|
+
_createClass(RectangleROIStartEndThreshold, null, [{
|
|
5318
|
+
key: "getContourSequence",
|
|
5319
|
+
value: function getContourSequence(toolData, metadataProvider) {
|
|
5320
|
+
var data = toolData.data;
|
|
5321
|
+
var _data$cachedStats = data.cachedStats,
|
|
5322
|
+
projectionPoints = _data$cachedStats.projectionPoints,
|
|
5323
|
+
projectionPointsImageIds = _data$cachedStats.projectionPointsImageIds;
|
|
5324
|
+
return projectionPoints.map(function (point, index) {
|
|
5325
|
+
var ContourData = getPointData(point);
|
|
5326
|
+
var ContourImageSequence = getContourImageSequence(projectionPointsImageIds[index], metadataProvider);
|
|
5327
|
+
return {
|
|
5328
|
+
NumberOfContourPoints: ContourData.length / 3,
|
|
5329
|
+
ContourImageSequence: ContourImageSequence,
|
|
5330
|
+
ContourGeometricType: "CLOSED_PLANAR",
|
|
5331
|
+
ContourData: ContourData
|
|
5332
|
+
};
|
|
5333
|
+
});
|
|
5334
|
+
}
|
|
5335
|
+
}]);
|
|
5336
|
+
return RectangleROIStartEndThreshold;
|
|
5337
|
+
}();
|
|
5338
|
+
RectangleROIStartEndThreshold.toolName = "RectangleROIStartEndThreshold";
|
|
5339
|
+
function getPointData(points) {
|
|
5340
|
+
// Since this is a closed contour, the order of the points is important.
|
|
5341
|
+
// re-order the points to be in the correct order clockwise
|
|
5342
|
+
// Spread to make sure Float32Arrays are converted to arrays
|
|
5343
|
+
var orderedPoints = [].concat(_toConsumableArray(points[0]), _toConsumableArray(points[1]), _toConsumableArray(points[3]), _toConsumableArray(points[2]));
|
|
5344
|
+
var pointsArray = orderedPoints.flat();
|
|
5345
|
+
|
|
5346
|
+
// reduce the precision of the points to 2 decimal places
|
|
5347
|
+
var pointsArrayWithPrecision = pointsArray.map(function (point) {
|
|
5348
|
+
return point.toFixed(2);
|
|
5349
|
+
});
|
|
5350
|
+
return pointsArrayWithPrecision;
|
|
5351
|
+
}
|
|
5352
|
+
function getContourImageSequence(imageId, metadataProvider) {
|
|
5353
|
+
var sopCommon = metadataProvider.get("sopCommonModule", imageId);
|
|
5354
|
+
return {
|
|
5355
|
+
ReferencedSOPClassUID: sopCommon.sopClassUID,
|
|
5356
|
+
ReferencedSOPInstanceUID: sopCommon.sopInstanceUID
|
|
5357
|
+
};
|
|
5358
|
+
}
|
|
5359
|
+
|
|
5360
|
+
function validateAnnotation(annotation) {
|
|
5361
|
+
if (!(annotation !== null && annotation !== void 0 && annotation.data)) {
|
|
5362
|
+
throw new Error("Tool data is empty");
|
|
5363
|
+
}
|
|
5364
|
+
if (!annotation.metadata || annotation.metadata.referenceImageId) {
|
|
5365
|
+
throw new Error("Tool data is not associated with any imageId");
|
|
5366
|
+
}
|
|
5367
|
+
}
|
|
5368
|
+
var AnnotationToPointData = /*#__PURE__*/function () {
|
|
5369
|
+
function AnnotationToPointData() {
|
|
5370
|
+
_classCallCheck(this, AnnotationToPointData);
|
|
5371
|
+
} // empty
|
|
5372
|
+
_createClass(AnnotationToPointData, null, [{
|
|
5373
|
+
key: "convert",
|
|
5374
|
+
value: function convert(annotation, index, metadataProvider) {
|
|
5375
|
+
validateAnnotation(annotation);
|
|
5376
|
+
var toolName = annotation.metadata.toolName;
|
|
5377
|
+
var toolClass = AnnotationToPointData.TOOL_NAMES[toolName];
|
|
5378
|
+
if (!toolClass) {
|
|
5379
|
+
throw new Error("Unknown tool type: ".concat(toolName, ", cannot convert to RTSSReport"));
|
|
5380
|
+
}
|
|
5381
|
+
|
|
5382
|
+
// Each toolData should become a list of contours, ContourSequence
|
|
5383
|
+
// contains a list of contours with their pointData, their geometry
|
|
5384
|
+
// type and their length.
|
|
5385
|
+
var ContourSequence = toolClass.getContourSequence(annotation, metadataProvider);
|
|
5386
|
+
|
|
5387
|
+
// Todo: random rgb color for now, options should be passed in
|
|
5388
|
+
var color = [Math.floor(Math.random() * 255), Math.floor(Math.random() * 255), Math.floor(Math.random() * 255)];
|
|
5389
|
+
return {
|
|
5390
|
+
ReferencedROINumber: index + 1,
|
|
5391
|
+
ROIDisplayColor: color,
|
|
5392
|
+
ContourSequence: ContourSequence
|
|
5393
|
+
};
|
|
5394
|
+
}
|
|
5395
|
+
}, {
|
|
5396
|
+
key: "register",
|
|
5397
|
+
value: function register(toolClass) {
|
|
5398
|
+
AnnotationToPointData.TOOL_NAMES[toolClass.toolName] = toolClass;
|
|
5399
|
+
}
|
|
5400
|
+
}]);
|
|
5401
|
+
return AnnotationToPointData;
|
|
5402
|
+
}();
|
|
5403
|
+
AnnotationToPointData.TOOL_NAMES = {};
|
|
5404
|
+
AnnotationToPointData.register(RectangleROIStartEndThreshold);
|
|
5405
|
+
|
|
5406
|
+
function getPatientModule(imageId, metadataProvider) {
|
|
5407
|
+
var generalSeriesModule = metadataProvider.get("generalSeriesModule", imageId);
|
|
5408
|
+
var generalStudyModule = metadataProvider.get("generalStudyModule", imageId);
|
|
5409
|
+
var patientStudyModule = metadataProvider.get("patientStudyModule", imageId);
|
|
5410
|
+
var patientModule = metadataProvider.get("patientModule", imageId);
|
|
5411
|
+
var patientDemographicModule = metadataProvider.get("patientDemographicModule", imageId);
|
|
5412
|
+
return {
|
|
5413
|
+
Modality: generalSeriesModule.modality,
|
|
5414
|
+
PatientID: patientModule.patientId,
|
|
5415
|
+
PatientName: patientModule.patientName,
|
|
5416
|
+
PatientBirthDate: "",
|
|
5417
|
+
PatientAge: patientStudyModule.patientAge,
|
|
5418
|
+
PatientSex: patientDemographicModule.patientSex,
|
|
5419
|
+
PatientWeight: patientStudyModule.patientWeight,
|
|
5420
|
+
StudyDate: generalStudyModule.studyDate,
|
|
5421
|
+
StudyTime: generalStudyModule.studyTime,
|
|
5422
|
+
StudyID: "ToDo",
|
|
5423
|
+
AccessionNumber: generalStudyModule.accessionNumber
|
|
5424
|
+
};
|
|
5425
|
+
}
|
|
5426
|
+
|
|
5427
|
+
function getReferencedFrameOfReferenceSequence(metadata, metadataProvider, dataset) {
|
|
5428
|
+
var imageId = metadata.referencedImageId,
|
|
5429
|
+
FrameOfReferenceUID = metadata.FrameOfReferenceUID;
|
|
5430
|
+
var instance = metadataProvider.get("instance", imageId);
|
|
5431
|
+
var SeriesInstanceUID = instance.SeriesInstanceUID;
|
|
5432
|
+
var ReferencedSeriesSequence = dataset.ReferencedSeriesSequence;
|
|
5433
|
+
return [{
|
|
5434
|
+
FrameOfReferenceUID: FrameOfReferenceUID,
|
|
5435
|
+
RTReferencedStudySequence: [{
|
|
5436
|
+
ReferencedSOPClassUID: dataset.SOPClassUID,
|
|
5437
|
+
ReferencedSOPInstanceUID: dataset.SOPInstanceUID,
|
|
5438
|
+
RTReferencedSeriesSequence: [{
|
|
5439
|
+
SeriesInstanceUID: SeriesInstanceUID,
|
|
5440
|
+
ContourImageSequence: _toConsumableArray(ReferencedSeriesSequence[0].ReferencedInstanceSequence)
|
|
5441
|
+
}]
|
|
5442
|
+
}]
|
|
5443
|
+
}];
|
|
5444
|
+
}
|
|
5445
|
+
|
|
5446
|
+
function getReferencedSeriesSequence(metadata, _index, metadataProvider, DicomMetadataStore) {
|
|
5447
|
+
// grab imageId from toolData
|
|
5448
|
+
var imageId = metadata.referencedImageId;
|
|
5449
|
+
var instance = metadataProvider.get("instance", imageId);
|
|
5450
|
+
var SeriesInstanceUID = instance.SeriesInstanceUID,
|
|
5451
|
+
StudyInstanceUID = instance.StudyInstanceUID;
|
|
5452
|
+
var ReferencedSeriesSequence = [];
|
|
5453
|
+
if (SeriesInstanceUID) {
|
|
5454
|
+
var series = DicomMetadataStore.getSeries(StudyInstanceUID, SeriesInstanceUID);
|
|
5455
|
+
var ReferencedSeries = {
|
|
5456
|
+
SeriesInstanceUID: SeriesInstanceUID,
|
|
5457
|
+
ReferencedInstanceSequence: []
|
|
5458
|
+
};
|
|
5459
|
+
series.instances.forEach(function (instance) {
|
|
5460
|
+
var SOPInstanceUID = instance.SOPInstanceUID,
|
|
5461
|
+
SOPClassUID = instance.SOPClassUID;
|
|
5462
|
+
ReferencedSeries.ReferencedInstanceSequence.push({
|
|
5463
|
+
ReferencedSOPClassUID: SOPClassUID,
|
|
5464
|
+
ReferencedSOPInstanceUID: SOPInstanceUID
|
|
5465
|
+
});
|
|
5466
|
+
});
|
|
5467
|
+
ReferencedSeriesSequence.push(ReferencedSeries);
|
|
5468
|
+
}
|
|
5469
|
+
return ReferencedSeriesSequence;
|
|
5470
|
+
}
|
|
5471
|
+
|
|
5472
|
+
function getRTROIObservationsSequence(toolData, index) {
|
|
5473
|
+
return {
|
|
5474
|
+
ObservationNumber: index + 1,
|
|
5475
|
+
ReferencedROINumber: index + 1,
|
|
5476
|
+
RTROIInterpretedType: "Todo: type",
|
|
5477
|
+
ROIInterpreter: "Todo: interpreter"
|
|
5478
|
+
};
|
|
5479
|
+
}
|
|
5480
|
+
|
|
5481
|
+
function getRTSeriesModule(DicomMetaDictionary) {
|
|
5482
|
+
return {
|
|
5483
|
+
SeriesInstanceUID: DicomMetaDictionary.uid(),
|
|
5484
|
+
// generate a new series instance uid
|
|
5485
|
+
SeriesNumber: "99" // Todo:: what should be the series number?
|
|
5486
|
+
};
|
|
5487
|
+
}
|
|
5488
|
+
|
|
5489
|
+
function getStructureSetModule(contour, index) {
|
|
5490
|
+
var FrameOfReferenceUID = contour.metadata.FrameOfReferenceUID;
|
|
5491
|
+
return {
|
|
5492
|
+
ROINumber: index + 1,
|
|
5493
|
+
ROIName: contour.name || "Todo: name ".concat(index + 1),
|
|
5494
|
+
ROIDescription: "Todo: description ".concat(index + 1),
|
|
5495
|
+
ROIGenerationAlgorithm: "Todo: algorithm",
|
|
5496
|
+
ReferencedFrameOfReferenceUID: FrameOfReferenceUID
|
|
5497
|
+
};
|
|
5498
|
+
}
|
|
5499
|
+
|
|
5500
|
+
var DicomMetaDictionary = dcmjs__WEBPACK_IMPORTED_MODULE_0__["default"].data.DicomMetaDictionary;
|
|
5501
|
+
/**
|
|
5502
|
+
* Convert handles to RTSS report containing the dcmjs dicom dataset.
|
|
5503
|
+
*
|
|
5504
|
+
* Note: current WIP and using segmentation to contour conversion,
|
|
5505
|
+
* routine that is not fully tested
|
|
5506
|
+
*
|
|
5507
|
+
* @param segmentations - Cornerstone tool segmentations data
|
|
5508
|
+
* @param metadataProvider - Metadata provider
|
|
5509
|
+
* @param DicomMetadataStore - metadata store instance
|
|
5510
|
+
* @param cs - cornerstone instance
|
|
5511
|
+
* @param csTools - cornerstone tool instance
|
|
5512
|
+
* @returns Report object containing the dataset
|
|
5513
|
+
*/
|
|
5514
|
+
function generateRTSSFromSegmentations(segmentations, metadataProvider, DicomMetadataStore, cornerstoneCache, cornerstoneToolsEnums, vtkUtils) {
|
|
5515
|
+
// Convert segmentations to ROIContours
|
|
5516
|
+
var roiContours = [];
|
|
5517
|
+
var contourSets = generateContourSetsFromLabelmap({
|
|
5518
|
+
segmentations: segmentations,
|
|
5519
|
+
cornerstoneCache: cornerstoneCache,
|
|
5520
|
+
cornerstoneToolsEnums: cornerstoneToolsEnums,
|
|
5521
|
+
vtkUtils: vtkUtils
|
|
5522
|
+
});
|
|
5523
|
+
contourSets.forEach(function (contourSet, segIndex) {
|
|
5524
|
+
// Check contour set isn't undefined
|
|
5525
|
+
if (contourSet) {
|
|
5526
|
+
var contourSequence_1 = [];
|
|
5527
|
+
contourSet.sliceContours.forEach(function (sliceContour) {
|
|
5528
|
+
/**
|
|
5529
|
+
* addContour - Adds a new ROI with related contours to ROIContourSequence
|
|
5530
|
+
*
|
|
5531
|
+
* @param newContour - cornerstoneTools `ROIContour` object
|
|
5532
|
+
*
|
|
5533
|
+
* newContour = {
|
|
5534
|
+
* name: string,
|
|
5535
|
+
* description: string,
|
|
5536
|
+
* contourSequence: array[contour]
|
|
5537
|
+
* color: array[number],
|
|
5538
|
+
* metadata: {
|
|
5539
|
+
* referencedImageId: string,
|
|
5540
|
+
* FrameOfReferenceUID: string
|
|
5541
|
+
* }
|
|
5542
|
+
* }
|
|
5543
|
+
*
|
|
5544
|
+
* contour = {
|
|
5545
|
+
* ContourImageSequence: array[
|
|
5546
|
+
* { ReferencedSOPClassUID: string, ReferencedSOPInstanceUID: string}
|
|
5547
|
+
* ]
|
|
5548
|
+
* ContourGeometricType: string,
|
|
5549
|
+
* NumberOfContourPoints: number,
|
|
5550
|
+
* ContourData: array[number]
|
|
5551
|
+
* }
|
|
5552
|
+
*/
|
|
5553
|
+
// Note: change needed if support non-planar contour representation is needed
|
|
5554
|
+
var sopCommon = metadataProvider.get("sopCommonModule", sliceContour.referencedImageId);
|
|
5555
|
+
var ReferencedSOPClassUID = sopCommon.sopClassUID;
|
|
5556
|
+
var ReferencedSOPInstanceUID = sopCommon.sopInstanceUID;
|
|
5557
|
+
var ContourImageSequence = [
|
|
5558
|
+
{ ReferencedSOPClassUID: ReferencedSOPClassUID, ReferencedSOPInstanceUID: ReferencedSOPInstanceUID } // NOTE: replace in dcmjs?
|
|
5559
|
+
];
|
|
5560
|
+
var sliceContourPolyData = sliceContour.polyData;
|
|
5561
|
+
sliceContour.contours.forEach(function (contour, index) {
|
|
5562
|
+
var ContourGeometricType = contour.type;
|
|
5563
|
+
var NumberOfContourPoints = contour.contourPoints.length;
|
|
5564
|
+
var ContourData = [];
|
|
5565
|
+
contour.contourPoints.forEach(function (point) {
|
|
5566
|
+
var pointData = sliceContourPolyData.points[point];
|
|
5567
|
+
pointData[0] = +pointData[0].toFixed(2);
|
|
5568
|
+
pointData[1] = +pointData[1].toFixed(2);
|
|
5569
|
+
pointData[2] = +pointData[2].toFixed(2);
|
|
5570
|
+
ContourData.push(pointData[0]);
|
|
5571
|
+
ContourData.push(pointData[1]);
|
|
5572
|
+
ContourData.push(pointData[2]);
|
|
5573
|
+
});
|
|
5574
|
+
contourSequence_1.push({
|
|
5575
|
+
ContourImageSequence: ContourImageSequence,
|
|
5576
|
+
ContourGeometricType: ContourGeometricType,
|
|
5577
|
+
NumberOfContourPoints: NumberOfContourPoints,
|
|
5578
|
+
ContourNumber: index + 1,
|
|
5579
|
+
ContourData: ContourData
|
|
5580
|
+
});
|
|
5581
|
+
});
|
|
5582
|
+
});
|
|
5583
|
+
var segLabel = contourSet.label || "Segment ".concat(segIndex + 1);
|
|
5584
|
+
var ROIContour = {
|
|
5585
|
+
name: segLabel,
|
|
5586
|
+
description: segLabel,
|
|
5587
|
+
contourSequence: contourSequence_1,
|
|
5588
|
+
color: contourSet.color,
|
|
5589
|
+
metadata: contourSet.metadata
|
|
5590
|
+
};
|
|
5591
|
+
roiContours.push(ROIContour);
|
|
5592
|
+
}
|
|
5593
|
+
});
|
|
5594
|
+
var rtMetadata = {
|
|
5595
|
+
name: segmentations.label,
|
|
5596
|
+
label: segmentations.label
|
|
5597
|
+
};
|
|
5598
|
+
var dataset = _initializeDataset(rtMetadata, roiContours[0].metadata, metadataProvider);
|
|
5599
|
+
roiContours.forEach(function (contour, index) {
|
|
5600
|
+
var roiContour = {
|
|
5601
|
+
ROIDisplayColor: contour.color || [255, 0, 0],
|
|
5602
|
+
ContourSequence: contour.contourSequence,
|
|
5603
|
+
ReferencedROINumber: index + 1
|
|
5604
|
+
};
|
|
5605
|
+
dataset.StructureSetROISequence.push(getStructureSetModule(contour, index));
|
|
5606
|
+
dataset.ROIContourSequence.push(roiContour);
|
|
5607
|
+
// ReferencedSeriesSequence
|
|
5608
|
+
dataset.ReferencedSeriesSequence = getReferencedSeriesSequence(contour.metadata, index, metadataProvider, DicomMetadataStore);
|
|
5609
|
+
// ReferencedFrameOfReferenceSequence
|
|
5610
|
+
dataset.ReferencedFrameOfReferenceSequence =
|
|
5611
|
+
getReferencedFrameOfReferenceSequence(contour.metadata, metadataProvider, dataset);
|
|
5612
|
+
});
|
|
5613
|
+
var fileMetaInformationVersionArray = new Uint8Array(2);
|
|
5614
|
+
fileMetaInformationVersionArray[1] = 1;
|
|
5615
|
+
var _meta = {
|
|
5616
|
+
FileMetaInformationVersion: {
|
|
5617
|
+
Value: [fileMetaInformationVersionArray.buffer],
|
|
5618
|
+
vr: "OB"
|
|
5619
|
+
},
|
|
5620
|
+
TransferSyntaxUID: {
|
|
5621
|
+
Value: ["1.2.840.10008.1.2.1"],
|
|
5622
|
+
vr: "UI"
|
|
5623
|
+
},
|
|
5624
|
+
ImplementationClassUID: {
|
|
5625
|
+
Value: [DicomMetaDictionary.uid()],
|
|
5626
|
+
vr: "UI"
|
|
5627
|
+
},
|
|
5628
|
+
ImplementationVersionName: {
|
|
5629
|
+
Value: ["dcmjs"],
|
|
5630
|
+
vr: "SH"
|
|
5631
|
+
}
|
|
5632
|
+
};
|
|
5633
|
+
dataset._meta = _meta;
|
|
5634
|
+
return dataset;
|
|
5635
|
+
}
|
|
5636
|
+
/**
|
|
5637
|
+
* Convert handles to RTSSReport report object containing the dcmjs dicom dataset.
|
|
5638
|
+
*
|
|
5639
|
+
* Note: The tool data needs to be formatted in a specific way, and currently
|
|
5640
|
+
* it is limited to the RectangleROIStartEndTool in the Cornerstone.
|
|
5641
|
+
*
|
|
5642
|
+
* @param annotations Array of Cornerstone tool annotation data
|
|
5643
|
+
* @param metadataProvider Metadata provider
|
|
5644
|
+
* @param options report generation options
|
|
5645
|
+
* @returns Report object containing the dataset
|
|
5646
|
+
*/
|
|
5647
|
+
function generateRTSSFromAnnotations(annotations, metadataProvider, DicomMetadataStore, options) {
|
|
5648
|
+
var rtMetadata = {
|
|
5649
|
+
name: "RTSS from Annotations",
|
|
5650
|
+
label: "RTSS from Annotations"
|
|
5651
|
+
};
|
|
5652
|
+
var dataset = _initializeDataset(rtMetadata, annotations[0].metadata, metadataProvider);
|
|
5653
|
+
annotations.forEach(function (annotation, index) {
|
|
5654
|
+
var ContourSequence = AnnotationToPointData.convert(annotation, index, metadataProvider, options);
|
|
5655
|
+
dataset.StructureSetROISequence.push(getStructureSetModule(annotation, index));
|
|
5656
|
+
dataset.ROIContourSequence.push(ContourSequence);
|
|
5657
|
+
dataset.RTROIObservationsSequence.push(getRTROIObservationsSequence(annotation, index));
|
|
5658
|
+
// ReferencedSeriesSequence
|
|
5659
|
+
// Todo: handle more than one series
|
|
5660
|
+
dataset.ReferencedSeriesSequence = getReferencedSeriesSequence(annotation.metadata, index, metadataProvider, DicomMetadataStore);
|
|
5661
|
+
// ReferencedFrameOfReferenceSequence
|
|
5662
|
+
dataset.ReferencedFrameOfReferenceSequence =
|
|
5663
|
+
getReferencedFrameOfReferenceSequence(annotation.metadata, metadataProvider, dataset);
|
|
5664
|
+
});
|
|
5665
|
+
var fileMetaInformationVersionArray = new Uint8Array(2);
|
|
5666
|
+
fileMetaInformationVersionArray[1] = 1;
|
|
5667
|
+
var _meta = {
|
|
5668
|
+
FileMetaInformationVersion: {
|
|
5669
|
+
Value: [fileMetaInformationVersionArray.buffer],
|
|
5670
|
+
vr: "OB"
|
|
5671
|
+
},
|
|
5672
|
+
TransferSyntaxUID: {
|
|
5673
|
+
Value: ["1.2.840.10008.1.2.1"],
|
|
5674
|
+
vr: "UI"
|
|
5675
|
+
},
|
|
5676
|
+
ImplementationClassUID: {
|
|
5677
|
+
Value: [DicomMetaDictionary.uid()],
|
|
5678
|
+
vr: "UI"
|
|
5679
|
+
},
|
|
5680
|
+
ImplementationVersionName: {
|
|
5681
|
+
Value: ["dcmjs"],
|
|
5682
|
+
vr: "SH"
|
|
5683
|
+
}
|
|
5684
|
+
};
|
|
5685
|
+
dataset._meta = _meta;
|
|
5686
|
+
return dataset;
|
|
5687
|
+
}
|
|
5688
|
+
// /**
|
|
5689
|
+
// * Generate Cornerstone tool state from dataset
|
|
5690
|
+
// * @param {object} dataset dataset
|
|
5691
|
+
// * @param {object} hooks
|
|
5692
|
+
// * @param {function} hooks.getToolClass Function to map dataset to a tool class
|
|
5693
|
+
// * @returns
|
|
5694
|
+
// */
|
|
5695
|
+
// //static generateToolState(_dataset, _hooks = {}) {
|
|
5696
|
+
// function generateToolState() {
|
|
5697
|
+
// // Todo
|
|
5698
|
+
// console.warn("RTSS.generateToolState not implemented");
|
|
5699
|
+
// }
|
|
5700
|
+
function _initializeDataset(rtMetadata, imgMetadata, metadataProvider) {
|
|
5701
|
+
var rtSOPInstanceUID = DicomMetaDictionary.uid();
|
|
5702
|
+
// get the first annotation data
|
|
5703
|
+
var imageId = imgMetadata.referencedImageId, FrameOfReferenceUID = imgMetadata.FrameOfReferenceUID;
|
|
5704
|
+
var studyInstanceUID = metadataProvider.get("generalSeriesModule", imageId).studyInstanceUID;
|
|
5705
|
+
var patientModule = getPatientModule(imageId, metadataProvider);
|
|
5706
|
+
var rtSeriesModule = getRTSeriesModule(DicomMetaDictionary);
|
|
5707
|
+
return __assign(__assign(__assign({ StructureSetROISequence: [], ROIContourSequence: [], RTROIObservationsSequence: [], ReferencedSeriesSequence: [], ReferencedFrameOfReferenceSequence: [] }, patientModule), rtSeriesModule), { StudyInstanceUID: studyInstanceUID, SOPClassUID: "1.2.840.10008.5.1.4.1.1.481.3", SOPInstanceUID: rtSOPInstanceUID, Manufacturer: "dcmjs", Modality: "RTSTRUCT", FrameOfReferenceUID: FrameOfReferenceUID, PositionReferenceIndicator: "", StructureSetLabel: rtMetadata.label || "", StructureSetName: rtMetadata.name || "", ReferringPhysicianName: "", OperatorsName: "", StructureSetDate: DicomMetaDictionary.date(), StructureSetTime: DicomMetaDictionary.time() });
|
|
5708
|
+
}
|
|
5709
|
+
|
|
5710
|
+
var RTSS = /*#__PURE__*/Object.freeze({
|
|
5711
|
+
__proto__: null,
|
|
5712
|
+
generateContourSetsFromLabelmap: generateContourSetsFromLabelmap,
|
|
5713
|
+
generateRTSSFromAnnotations: generateRTSSFromAnnotations,
|
|
5714
|
+
generateRTSSFromSegmentations: generateRTSSFromSegmentations
|
|
5715
|
+
});
|
|
5716
|
+
|
|
4996
5717
|
var Cornerstone3DSR = {
|
|
4997
5718
|
Bidirectional: Bidirectional,
|
|
4998
5719
|
CobbAngle: CobbAngle,
|
|
@@ -5011,6 +5732,9 @@ var Cornerstone3DSR = {
|
|
|
5011
5732
|
var Cornerstone3DSEG = {
|
|
5012
5733
|
Segmentation: Segmentation$1
|
|
5013
5734
|
};
|
|
5735
|
+
var Cornerstone3DRT = {
|
|
5736
|
+
RTSS: RTSS
|
|
5737
|
+
};
|
|
5014
5738
|
|
|
5015
5739
|
var Colors = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.Colors,
|
|
5016
5740
|
BitArray = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.BitArray;
|
|
@@ -5208,6 +5932,9 @@ var adaptersSEG = {
|
|
|
5208
5932
|
Cornerstone3D: Cornerstone3DSEG,
|
|
5209
5933
|
VTKjs: VTKjsSEG
|
|
5210
5934
|
};
|
|
5935
|
+
var adaptersRT = {
|
|
5936
|
+
Cornerstone3D: Cornerstone3DRT
|
|
5937
|
+
};
|
|
5211
5938
|
|
|
5212
5939
|
|
|
5213
5940
|
|