@cornerstonejs/adapters 2.0.0-beta.2 → 2.0.0-beta.3
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/adapters.es.js +747 -21
- package/dist/adapters.es.js.map +1 -1
- package/dist/types/adapters/Cornerstone3D/RTStruct/RTSS.d.ts +27 -0
- package/dist/types/adapters/Cornerstone3D/RTStruct/index.d.ts +3 -0
- package/dist/types/adapters/Cornerstone3D/index.d.ts +5 -1
- package/dist/types/adapters/index.d.ts +6 -1
- package/dist/types/index.d.ts +2 -2
- package/package.json +5 -5
package/dist/adapters.es.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { data, utilities, derivations, normalizers, log } from 'dcmjs';
|
|
1
|
+
import dcmjs, { data, utilities, derivations, normalizers, log } from 'dcmjs';
|
|
2
2
|
import { Buffer } from 'buffer';
|
|
3
3
|
import ndarray from 'ndarray';
|
|
4
4
|
import cloneDeep from 'lodash.clonedeep';
|
|
@@ -583,7 +583,7 @@ var StructuredReport$1 = derivations.StructuredReport;
|
|
|
583
583
|
var Normalizer$4 = normalizers.Normalizer;
|
|
584
584
|
var TID1500MeasurementReport$1 = TID1500$1.TID1500MeasurementReport,
|
|
585
585
|
TID1501MeasurementGroup$1 = TID1500$1.TID1501MeasurementGroup;
|
|
586
|
-
var DicomMetaDictionary$
|
|
586
|
+
var DicomMetaDictionary$4 = data.DicomMetaDictionary;
|
|
587
587
|
var FINDING$2 = {
|
|
588
588
|
CodingSchemeDesignator: "DCM",
|
|
589
589
|
CodeValue: "121071"
|
|
@@ -754,7 +754,7 @@ var MeasurementReport$1 = /*#__PURE__*/function () {
|
|
|
754
754
|
vr: "UI"
|
|
755
755
|
},
|
|
756
756
|
ImplementationClassUID: {
|
|
757
|
-
Value: [DicomMetaDictionary$
|
|
757
|
+
Value: [DicomMetaDictionary$4.uid()],
|
|
758
758
|
// TODO: could be git hash or other valid id
|
|
759
759
|
vr: "UI"
|
|
760
760
|
},
|
|
@@ -1827,7 +1827,7 @@ var _utilities$orientatio$1 = utilities.orientation,
|
|
|
1827
1827
|
var datasetToBlob = utilities.datasetToBlob,
|
|
1828
1828
|
BitArray$2 = utilities.BitArray,
|
|
1829
1829
|
DicomMessage$1 = utilities.DicomMessage,
|
|
1830
|
-
DicomMetaDictionary$
|
|
1830
|
+
DicomMetaDictionary$3 = utilities.DicomMetaDictionary;
|
|
1831
1831
|
var Normalizer$3 = normalizers.Normalizer;
|
|
1832
1832
|
var SegmentationDerivation$2 = derivations.Segmentation;
|
|
1833
1833
|
var Segmentation$5 = {
|
|
@@ -1957,16 +1957,16 @@ function _createSegFromImages$1(images, isMultiframe, options) {
|
|
|
1957
1957
|
var image = images[0];
|
|
1958
1958
|
var arrayBuffer = image.data.byteArray.buffer;
|
|
1959
1959
|
var dicomData = DicomMessage$1.readFile(arrayBuffer);
|
|
1960
|
-
var dataset = DicomMetaDictionary$
|
|
1961
|
-
dataset._meta = DicomMetaDictionary$
|
|
1960
|
+
var dataset = DicomMetaDictionary$3.naturalizeDataset(dicomData.dict);
|
|
1961
|
+
dataset._meta = DicomMetaDictionary$3.namifyDataset(dicomData.meta);
|
|
1962
1962
|
datasets.push(dataset);
|
|
1963
1963
|
} else {
|
|
1964
1964
|
for (var i = 0; i < images.length; i++) {
|
|
1965
1965
|
var _image = images[i];
|
|
1966
1966
|
var _arrayBuffer = _image.data.byteArray.buffer;
|
|
1967
1967
|
var _dicomData = DicomMessage$1.readFile(_arrayBuffer);
|
|
1968
|
-
var _dataset = DicomMetaDictionary$
|
|
1969
|
-
_dataset._meta = DicomMetaDictionary$
|
|
1968
|
+
var _dataset = DicomMetaDictionary$3.naturalizeDataset(_dicomData.dict);
|
|
1969
|
+
_dataset._meta = DicomMetaDictionary$3.namifyDataset(_dicomData.meta);
|
|
1970
1970
|
datasets.push(_dataset);
|
|
1971
1971
|
}
|
|
1972
1972
|
}
|
|
@@ -1986,8 +1986,8 @@ function _createSegFromImages$1(images, isMultiframe, options) {
|
|
|
1986
1986
|
*/
|
|
1987
1987
|
function generateToolState$3(imageIds, arrayBuffer, metadataProvider) {
|
|
1988
1988
|
var dicomData = DicomMessage$1.readFile(arrayBuffer);
|
|
1989
|
-
var dataset = DicomMetaDictionary$
|
|
1990
|
-
dataset._meta = DicomMetaDictionary$
|
|
1989
|
+
var dataset = DicomMetaDictionary$3.naturalizeDataset(dicomData.dict);
|
|
1990
|
+
dataset._meta = DicomMetaDictionary$3.namifyDataset(dicomData.meta);
|
|
1991
1991
|
var multiframe = Normalizer$3.normalizeToDataset([dataset]);
|
|
1992
1992
|
var imagePlaneModule = metadataProvider.get("imagePlaneModule", imageIds[0]);
|
|
1993
1993
|
if (!imagePlaneModule) {
|
|
@@ -2267,7 +2267,7 @@ var _utilities$orientatio = utilities.orientation,
|
|
|
2267
2267
|
nearlyEqual = _utilities$orientatio.nearlyEqual;
|
|
2268
2268
|
var BitArray$1 = data.BitArray,
|
|
2269
2269
|
DicomMessage = data.DicomMessage,
|
|
2270
|
-
DicomMetaDictionary$
|
|
2270
|
+
DicomMetaDictionary$2 = data.DicomMetaDictionary;
|
|
2271
2271
|
var Normalizer$2 = normalizers.Normalizer;
|
|
2272
2272
|
var SegmentationDerivation$1 = derivations.Segmentation;
|
|
2273
2273
|
var _utilities$compressio = utilities.compression,
|
|
@@ -2417,16 +2417,16 @@ function _createSegFromImages(images, isMultiframe, options) {
|
|
|
2417
2417
|
var image = images[0];
|
|
2418
2418
|
var arrayBuffer = image.data.byteArray.buffer;
|
|
2419
2419
|
var dicomData = DicomMessage.readFile(arrayBuffer);
|
|
2420
|
-
var dataset = DicomMetaDictionary$
|
|
2421
|
-
dataset._meta = DicomMetaDictionary$
|
|
2420
|
+
var dataset = DicomMetaDictionary$2.naturalizeDataset(dicomData.dict);
|
|
2421
|
+
dataset._meta = DicomMetaDictionary$2.namifyDataset(dicomData.meta);
|
|
2422
2422
|
datasets.push(dataset);
|
|
2423
2423
|
} else {
|
|
2424
2424
|
for (var i = 0; i < images.length; i++) {
|
|
2425
2425
|
var _image = images[i];
|
|
2426
2426
|
var _arrayBuffer = _image.data.byteArray.buffer;
|
|
2427
2427
|
var _dicomData = DicomMessage.readFile(_arrayBuffer);
|
|
2428
|
-
var _dataset = DicomMetaDictionary$
|
|
2429
|
-
_dataset._meta = DicomMetaDictionary$
|
|
2428
|
+
var _dataset = DicomMetaDictionary$2.naturalizeDataset(_dicomData.dict);
|
|
2429
|
+
_dataset._meta = DicomMetaDictionary$2.namifyDataset(_dicomData.meta);
|
|
2430
2430
|
datasets.push(_dataset);
|
|
2431
2431
|
}
|
|
2432
2432
|
}
|
|
@@ -2610,8 +2610,8 @@ function _generateToolState() {
|
|
|
2610
2610
|
case 0:
|
|
2611
2611
|
_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;
|
|
2612
2612
|
dicomData = DicomMessage.readFile(arrayBuffer);
|
|
2613
|
-
dataset = DicomMetaDictionary$
|
|
2614
|
-
dataset._meta = DicomMetaDictionary$
|
|
2613
|
+
dataset = DicomMetaDictionary$2.naturalizeDataset(dicomData.dict);
|
|
2614
|
+
dataset._meta = DicomMetaDictionary$2.namifyDataset(dicomData.meta);
|
|
2615
2615
|
multiframe = Normalizer$2.normalizeToDataset([dataset]);
|
|
2616
2616
|
imagePlaneModule = metadataProvider.get("imagePlaneModule", imageIds[0]);
|
|
2617
2617
|
generalSeriesModule = metadataProvider.get("generalSeriesModule", imageIds[0]);
|
|
@@ -3587,7 +3587,7 @@ var TID1500 = utilities.TID1500, addAccessors = utilities.addAccessors;
|
|
|
3587
3587
|
var StructuredReport = derivations.StructuredReport;
|
|
3588
3588
|
var Normalizer$1 = normalizers.Normalizer;
|
|
3589
3589
|
var TID1500MeasurementReport = TID1500.TID1500MeasurementReport, TID1501MeasurementGroup = TID1500.TID1501MeasurementGroup;
|
|
3590
|
-
var DicomMetaDictionary = data.DicomMetaDictionary;
|
|
3590
|
+
var DicomMetaDictionary$1 = data.DicomMetaDictionary;
|
|
3591
3591
|
var FINDING = { CodingSchemeDesignator: "DCM", CodeValue: "121071" };
|
|
3592
3592
|
var FINDING_SITE = { CodingSchemeDesignator: "SCT", CodeValue: "363698007" };
|
|
3593
3593
|
var FINDING_SITE_OLD = { CodingSchemeDesignator: "SRT", CodeValue: "G-C0E3" };
|
|
@@ -3656,7 +3656,7 @@ var MeasurementReport = /** @class */ (function () {
|
|
|
3656
3656
|
vr: "UI"
|
|
3657
3657
|
},
|
|
3658
3658
|
ImplementationClassUID: {
|
|
3659
|
-
Value: [DicomMetaDictionary.uid()],
|
|
3659
|
+
Value: [DicomMetaDictionary$1.uid()],
|
|
3660
3660
|
vr: "UI"
|
|
3661
3661
|
},
|
|
3662
3662
|
ImplementationVersionName: {
|
|
@@ -3691,7 +3691,7 @@ var MeasurementReport = /** @class */ (function () {
|
|
|
3691
3691
|
description: undefined,
|
|
3692
3692
|
sopInstanceUid: ReferencedSOPInstanceUID,
|
|
3693
3693
|
annotation: {
|
|
3694
|
-
annotationUID: DicomMetaDictionary.uid(),
|
|
3694
|
+
annotationUID: DicomMetaDictionary$1.uid(),
|
|
3695
3695
|
metadata: {
|
|
3696
3696
|
toolName: toolType,
|
|
3697
3697
|
referencedImageId: referencedImageId,
|
|
@@ -4974,6 +4974,726 @@ var Segmentation$1 = /*#__PURE__*/Object.freeze({
|
|
|
4974
4974
|
generateToolState: generateToolState
|
|
4975
4975
|
});
|
|
4976
4976
|
|
|
4977
|
+
/**
|
|
4978
|
+
* Checks if point is within array
|
|
4979
|
+
* @param {*} array
|
|
4980
|
+
* @param {*} pt
|
|
4981
|
+
* @returns
|
|
4982
|
+
*/
|
|
4983
|
+
function ptInArray(array, pt) {
|
|
4984
|
+
var index = -1;
|
|
4985
|
+
for (var i = 0; i < array.length; i++) {
|
|
4986
|
+
if (isSamePoint(pt, array[i])) {
|
|
4987
|
+
index = i;
|
|
4988
|
+
}
|
|
4989
|
+
}
|
|
4990
|
+
return index;
|
|
4991
|
+
}
|
|
4992
|
+
|
|
4993
|
+
/**
|
|
4994
|
+
* Checks if point A and point B contain same values
|
|
4995
|
+
* @param {*} ptA
|
|
4996
|
+
* @param {*} ptB
|
|
4997
|
+
* @returns
|
|
4998
|
+
*/
|
|
4999
|
+
function isSamePoint(ptA, ptB) {
|
|
5000
|
+
if (ptA[0] == ptB[0] && ptA[1] == ptB[1] && ptA[2] == ptB[2]) {
|
|
5001
|
+
return true;
|
|
5002
|
+
} else {
|
|
5003
|
+
return false;
|
|
5004
|
+
}
|
|
5005
|
+
}
|
|
5006
|
+
|
|
5007
|
+
/**
|
|
5008
|
+
* Goes through linesArray and replaces all references of old index with new index
|
|
5009
|
+
* @param {*} linesArray
|
|
5010
|
+
* @param {*} oldIndex
|
|
5011
|
+
* @param {*} newIndex
|
|
5012
|
+
*/
|
|
5013
|
+
function replacePointIndexReferences(linesArray, oldIndex, newIndex) {
|
|
5014
|
+
for (var i = 0; i < linesArray.length; i++) {
|
|
5015
|
+
var line = linesArray[i];
|
|
5016
|
+
if (line.a == oldIndex) {
|
|
5017
|
+
line.a = newIndex;
|
|
5018
|
+
} else if (line.b == oldIndex) {
|
|
5019
|
+
line.b = newIndex;
|
|
5020
|
+
}
|
|
5021
|
+
}
|
|
5022
|
+
}
|
|
5023
|
+
|
|
5024
|
+
/**
|
|
5025
|
+
* Iterate through polyData from vtkjs and merge any points that are the same
|
|
5026
|
+
* then update merged point references within lines array
|
|
5027
|
+
* @param {*} polyData
|
|
5028
|
+
* @param {*} bypass
|
|
5029
|
+
* @returns
|
|
5030
|
+
*/
|
|
5031
|
+
function removeDuplicatePoints(polyData, bypass) {
|
|
5032
|
+
var points = polyData.getPoints();
|
|
5033
|
+
var lines = polyData.getLines();
|
|
5034
|
+
var pointsArray = [];
|
|
5035
|
+
for (var i = 0; i < points.getNumberOfPoints(); i++) {
|
|
5036
|
+
var pt = points.getPoint(i).slice();
|
|
5037
|
+
pointsArray.push(pt);
|
|
5038
|
+
}
|
|
5039
|
+
var linesArray = [];
|
|
5040
|
+
for (var _i = 0; _i < lines.getNumberOfCells(); _i++) {
|
|
5041
|
+
var cell = lines.getCell(_i * 3).slice();
|
|
5042
|
+
//console.log(JSON.stringify(cell));
|
|
5043
|
+
var a = cell[0];
|
|
5044
|
+
var b = cell[1];
|
|
5045
|
+
var line = {
|
|
5046
|
+
a: a,
|
|
5047
|
+
b: b
|
|
5048
|
+
};
|
|
5049
|
+
linesArray.push(line);
|
|
5050
|
+
}
|
|
5051
|
+
if (bypass) {
|
|
5052
|
+
return {
|
|
5053
|
+
points: pointsArray,
|
|
5054
|
+
lines: linesArray
|
|
5055
|
+
};
|
|
5056
|
+
}
|
|
5057
|
+
|
|
5058
|
+
// Iterate through points and replace any duplicates
|
|
5059
|
+
var newPoints = [];
|
|
5060
|
+
for (var _i2 = 0; _i2 < pointsArray.length; _i2++) {
|
|
5061
|
+
var _pt = pointsArray[_i2];
|
|
5062
|
+
var index = ptInArray(newPoints, _pt);
|
|
5063
|
+
if (index >= 0) {
|
|
5064
|
+
// Duplicate Point -> replace references in lines
|
|
5065
|
+
replacePointIndexReferences(linesArray, _i2, index);
|
|
5066
|
+
} else {
|
|
5067
|
+
index = newPoints.length;
|
|
5068
|
+
newPoints.push(_pt);
|
|
5069
|
+
replacePointIndexReferences(linesArray, _i2, index);
|
|
5070
|
+
}
|
|
5071
|
+
}
|
|
5072
|
+
|
|
5073
|
+
// Final pass through lines, remove any that refer to exact same point
|
|
5074
|
+
var newLines = [];
|
|
5075
|
+
linesArray.forEach(function (line) {
|
|
5076
|
+
if (line.a != line.b) {
|
|
5077
|
+
newLines.push(line);
|
|
5078
|
+
}
|
|
5079
|
+
});
|
|
5080
|
+
return {
|
|
5081
|
+
points: newPoints,
|
|
5082
|
+
lines: newLines
|
|
5083
|
+
};
|
|
5084
|
+
}
|
|
5085
|
+
|
|
5086
|
+
function findNextLink(line, lines, contourPoints) {
|
|
5087
|
+
var index = -1;
|
|
5088
|
+
lines.forEach(function (cell, i) {
|
|
5089
|
+
if (index >= 0) {
|
|
5090
|
+
return;
|
|
5091
|
+
}
|
|
5092
|
+
if (cell.a == line.b) {
|
|
5093
|
+
index = i;
|
|
5094
|
+
}
|
|
5095
|
+
});
|
|
5096
|
+
if (index >= 0) {
|
|
5097
|
+
var nextLine = lines[index];
|
|
5098
|
+
lines.splice(index, 1);
|
|
5099
|
+
contourPoints.push(nextLine.b);
|
|
5100
|
+
if (contourPoints[0] == nextLine.b) {
|
|
5101
|
+
return {
|
|
5102
|
+
remainingLines: lines,
|
|
5103
|
+
contourPoints: contourPoints,
|
|
5104
|
+
type: "CLOSED_PLANAR"
|
|
5105
|
+
//type: 'CLOSEDPLANAR_XOR',
|
|
5106
|
+
};
|
|
5107
|
+
}
|
|
5108
|
+
|
|
5109
|
+
return findNextLink(nextLine, lines, contourPoints);
|
|
5110
|
+
}
|
|
5111
|
+
return {
|
|
5112
|
+
remainingLines: lines,
|
|
5113
|
+
contourPoints: contourPoints,
|
|
5114
|
+
type: "OPEN_PLANAR"
|
|
5115
|
+
};
|
|
5116
|
+
}
|
|
5117
|
+
|
|
5118
|
+
/**
|
|
5119
|
+
*
|
|
5120
|
+
* @param {*} lines
|
|
5121
|
+
*/
|
|
5122
|
+
function findContours(lines) {
|
|
5123
|
+
if (lines.length == 0) {
|
|
5124
|
+
return [];
|
|
5125
|
+
}
|
|
5126
|
+
var contourPoints = [];
|
|
5127
|
+
var firstCell = lines.shift();
|
|
5128
|
+
contourPoints.push(firstCell.a);
|
|
5129
|
+
contourPoints.push(firstCell.b);
|
|
5130
|
+
var result = findNextLink(firstCell, lines, contourPoints);
|
|
5131
|
+
if (result.remainingLines.length == 0) {
|
|
5132
|
+
return [{
|
|
5133
|
+
type: result.type,
|
|
5134
|
+
contourPoints: result.contourPoints
|
|
5135
|
+
}];
|
|
5136
|
+
} else {
|
|
5137
|
+
var extraContours = findContours(result.remainingLines);
|
|
5138
|
+
extraContours.push({
|
|
5139
|
+
type: result.type,
|
|
5140
|
+
contourPoints: result.contourPoints
|
|
5141
|
+
});
|
|
5142
|
+
return extraContours;
|
|
5143
|
+
}
|
|
5144
|
+
}
|
|
5145
|
+
function findContoursFromReducedSet(lines, points) {
|
|
5146
|
+
return findContours(lines);
|
|
5147
|
+
}
|
|
5148
|
+
|
|
5149
|
+
function generateContourSetsFromLabelmap(_ref) {
|
|
5150
|
+
var segmentations = _ref.segmentations,
|
|
5151
|
+
cornerstoneCache = _ref.cornerstoneCache,
|
|
5152
|
+
cornerstoneToolsEnums = _ref.cornerstoneToolsEnums,
|
|
5153
|
+
vtkUtils = _ref.vtkUtils;
|
|
5154
|
+
var LABELMAP = cornerstoneToolsEnums.SegmentationRepresentations.Labelmap;
|
|
5155
|
+
var representationData = segmentations.representationData,
|
|
5156
|
+
segments = segmentations.segments;
|
|
5157
|
+
var segVolumeId = representationData[LABELMAP].volumeId;
|
|
5158
|
+
|
|
5159
|
+
// Get segmentation volume
|
|
5160
|
+
var vol = cornerstoneCache.getVolume(segVolumeId);
|
|
5161
|
+
if (!vol) {
|
|
5162
|
+
console.warn("No volume found for ".concat(segVolumeId));
|
|
5163
|
+
return;
|
|
5164
|
+
}
|
|
5165
|
+
var numSlices = vol.dimensions[2];
|
|
5166
|
+
|
|
5167
|
+
// Get image volume segmentation references
|
|
5168
|
+
var imageVol = cornerstoneCache.getVolume(vol.referencedVolumeId);
|
|
5169
|
+
if (!imageVol) {
|
|
5170
|
+
console.warn("No volume found for ".concat(vol.referencedVolumeId));
|
|
5171
|
+
return;
|
|
5172
|
+
}
|
|
5173
|
+
|
|
5174
|
+
// NOTE: Workaround for marching squares not finding closed contours at
|
|
5175
|
+
// boundary of image volume, clear pixels along x-y border of volume
|
|
5176
|
+
var segData = vol.imageData.getPointData().getScalars().getData();
|
|
5177
|
+
var pixelsPerSlice = vol.dimensions[0] * vol.dimensions[1];
|
|
5178
|
+
for (var z = 0; z < numSlices; z++) {
|
|
5179
|
+
for (var y = 0; y < vol.dimensions[1]; y++) {
|
|
5180
|
+
for (var x = 0; x < vol.dimensions[0]; x++) {
|
|
5181
|
+
var index = x + y * vol.dimensions[0] + z * pixelsPerSlice;
|
|
5182
|
+
if (x === 0 || y === 0 || x === vol.dimensions[0] - 1 || y === vol.dimensions[1] - 1) {
|
|
5183
|
+
segData[index] = 0;
|
|
5184
|
+
}
|
|
5185
|
+
}
|
|
5186
|
+
}
|
|
5187
|
+
}
|
|
5188
|
+
|
|
5189
|
+
// end workaround
|
|
5190
|
+
//
|
|
5191
|
+
//
|
|
5192
|
+
var ContourSets = [];
|
|
5193
|
+
|
|
5194
|
+
// Iterate through all segments in current segmentation set
|
|
5195
|
+
var numSegments = segments.length;
|
|
5196
|
+
for (var segIndex = 0; segIndex < numSegments; segIndex++) {
|
|
5197
|
+
var segment = segments[segIndex];
|
|
5198
|
+
|
|
5199
|
+
// Skip empty segments
|
|
5200
|
+
if (!segment) {
|
|
5201
|
+
continue;
|
|
5202
|
+
}
|
|
5203
|
+
var contourSequence = [];
|
|
5204
|
+
for (var sliceIndex = 0; sliceIndex < numSlices; sliceIndex++) {
|
|
5205
|
+
// Check if the slice is empty before running marching cube
|
|
5206
|
+
if (isSliceEmptyForSegment(sliceIndex, segData, pixelsPerSlice, segIndex)) {
|
|
5207
|
+
continue;
|
|
5208
|
+
}
|
|
5209
|
+
try {
|
|
5210
|
+
var _reducedSet$points;
|
|
5211
|
+
var scalars = vtkUtils.vtkDataArray.newInstance({
|
|
5212
|
+
name: "Scalars",
|
|
5213
|
+
values: Array.from(segData),
|
|
5214
|
+
numberOfComponents: 1
|
|
5215
|
+
});
|
|
5216
|
+
|
|
5217
|
+
// Modify segData for this specific segment directly
|
|
5218
|
+
var segmentIndexFound = false;
|
|
5219
|
+
for (var i = 0; i < segData.length; i++) {
|
|
5220
|
+
var value = segData[i];
|
|
5221
|
+
if (value === segIndex) {
|
|
5222
|
+
segmentIndexFound = true;
|
|
5223
|
+
scalars.setValue(i, 1);
|
|
5224
|
+
} else {
|
|
5225
|
+
scalars.setValue(i, 0);
|
|
5226
|
+
}
|
|
5227
|
+
}
|
|
5228
|
+
if (!segmentIndexFound) {
|
|
5229
|
+
continue;
|
|
5230
|
+
}
|
|
5231
|
+
var mSquares = vtkUtils.vtkImageMarchingSquares.newInstance({
|
|
5232
|
+
slice: sliceIndex
|
|
5233
|
+
});
|
|
5234
|
+
|
|
5235
|
+
// filter out the scalar data so that only it has background and
|
|
5236
|
+
// the current segment index
|
|
5237
|
+
var imageDataCopy = vtkUtils.vtkImageData.newInstance();
|
|
5238
|
+
imageDataCopy.shallowCopy(vol.imageData);
|
|
5239
|
+
imageDataCopy.getPointData().setScalars(scalars);
|
|
5240
|
+
|
|
5241
|
+
// Connect pipeline
|
|
5242
|
+
mSquares.setInputData(imageDataCopy);
|
|
5243
|
+
var cValues = [];
|
|
5244
|
+
cValues[0] = 1;
|
|
5245
|
+
mSquares.setContourValues(cValues);
|
|
5246
|
+
mSquares.setMergePoints(false);
|
|
5247
|
+
|
|
5248
|
+
// Perform marching squares
|
|
5249
|
+
var msOutput = mSquares.getOutputData();
|
|
5250
|
+
|
|
5251
|
+
// Clean up output from marching squares
|
|
5252
|
+
var reducedSet = removeDuplicatePoints(msOutput);
|
|
5253
|
+
if ((_reducedSet$points = reducedSet.points) !== null && _reducedSet$points !== void 0 && _reducedSet$points.length) {
|
|
5254
|
+
var contours = findContoursFromReducedSet(reducedSet.lines, reducedSet.points);
|
|
5255
|
+
contourSequence.push({
|
|
5256
|
+
referencedImageId: imageVol.imageIds[sliceIndex],
|
|
5257
|
+
contours: contours,
|
|
5258
|
+
polyData: reducedSet
|
|
5259
|
+
});
|
|
5260
|
+
}
|
|
5261
|
+
} catch (e) {
|
|
5262
|
+
console.warn(sliceIndex);
|
|
5263
|
+
console.warn(e);
|
|
5264
|
+
}
|
|
5265
|
+
}
|
|
5266
|
+
var metadata = {
|
|
5267
|
+
referencedImageId: imageVol.imageIds[0],
|
|
5268
|
+
// just use 0
|
|
5269
|
+
FrameOfReferenceUID: imageVol.metadata.FrameOfReferenceUID
|
|
5270
|
+
};
|
|
5271
|
+
var ContourSet = {
|
|
5272
|
+
label: segment.label,
|
|
5273
|
+
color: segment.color,
|
|
5274
|
+
metadata: metadata,
|
|
5275
|
+
sliceContours: contourSequence
|
|
5276
|
+
};
|
|
5277
|
+
ContourSets.push(ContourSet);
|
|
5278
|
+
}
|
|
5279
|
+
return ContourSets;
|
|
5280
|
+
}
|
|
5281
|
+
function isSliceEmptyForSegment(sliceIndex, segData, pixelsPerSlice, segIndex) {
|
|
5282
|
+
var startIdx = sliceIndex * pixelsPerSlice;
|
|
5283
|
+
var endIdx = startIdx + pixelsPerSlice;
|
|
5284
|
+
for (var i = startIdx; i < endIdx; i++) {
|
|
5285
|
+
if (segData[i] === segIndex) {
|
|
5286
|
+
return false;
|
|
5287
|
+
}
|
|
5288
|
+
}
|
|
5289
|
+
return true;
|
|
5290
|
+
}
|
|
5291
|
+
|
|
5292
|
+
// comment
|
|
5293
|
+
var RectangleROIStartEndThreshold = /*#__PURE__*/function () {
|
|
5294
|
+
function RectangleROIStartEndThreshold() {
|
|
5295
|
+
_classCallCheck(this, RectangleROIStartEndThreshold);
|
|
5296
|
+
} // empty
|
|
5297
|
+
_createClass(RectangleROIStartEndThreshold, null, [{
|
|
5298
|
+
key: "getContourSequence",
|
|
5299
|
+
value: function getContourSequence(toolData, metadataProvider) {
|
|
5300
|
+
var data = toolData.data;
|
|
5301
|
+
var _data$cachedStats = data.cachedStats,
|
|
5302
|
+
projectionPoints = _data$cachedStats.projectionPoints,
|
|
5303
|
+
projectionPointsImageIds = _data$cachedStats.projectionPointsImageIds;
|
|
5304
|
+
return projectionPoints.map(function (point, index) {
|
|
5305
|
+
var ContourData = getPointData(point);
|
|
5306
|
+
var ContourImageSequence = getContourImageSequence(projectionPointsImageIds[index], metadataProvider);
|
|
5307
|
+
return {
|
|
5308
|
+
NumberOfContourPoints: ContourData.length / 3,
|
|
5309
|
+
ContourImageSequence: ContourImageSequence,
|
|
5310
|
+
ContourGeometricType: "CLOSED_PLANAR",
|
|
5311
|
+
ContourData: ContourData
|
|
5312
|
+
};
|
|
5313
|
+
});
|
|
5314
|
+
}
|
|
5315
|
+
}]);
|
|
5316
|
+
return RectangleROIStartEndThreshold;
|
|
5317
|
+
}();
|
|
5318
|
+
RectangleROIStartEndThreshold.toolName = "RectangleROIStartEndThreshold";
|
|
5319
|
+
function getPointData(points) {
|
|
5320
|
+
// Since this is a closed contour, the order of the points is important.
|
|
5321
|
+
// re-order the points to be in the correct order clockwise
|
|
5322
|
+
// Spread to make sure Float32Arrays are converted to arrays
|
|
5323
|
+
var orderedPoints = [].concat(_toConsumableArray(points[0]), _toConsumableArray(points[1]), _toConsumableArray(points[3]), _toConsumableArray(points[2]));
|
|
5324
|
+
var pointsArray = orderedPoints.flat();
|
|
5325
|
+
|
|
5326
|
+
// reduce the precision of the points to 2 decimal places
|
|
5327
|
+
var pointsArrayWithPrecision = pointsArray.map(function (point) {
|
|
5328
|
+
return point.toFixed(2);
|
|
5329
|
+
});
|
|
5330
|
+
return pointsArrayWithPrecision;
|
|
5331
|
+
}
|
|
5332
|
+
function getContourImageSequence(imageId, metadataProvider) {
|
|
5333
|
+
var sopCommon = metadataProvider.get("sopCommonModule", imageId);
|
|
5334
|
+
return {
|
|
5335
|
+
ReferencedSOPClassUID: sopCommon.sopClassUID,
|
|
5336
|
+
ReferencedSOPInstanceUID: sopCommon.sopInstanceUID
|
|
5337
|
+
};
|
|
5338
|
+
}
|
|
5339
|
+
|
|
5340
|
+
function validateAnnotation(annotation) {
|
|
5341
|
+
if (!(annotation !== null && annotation !== void 0 && annotation.data)) {
|
|
5342
|
+
throw new Error("Tool data is empty");
|
|
5343
|
+
}
|
|
5344
|
+
if (!annotation.metadata || annotation.metadata.referenceImageId) {
|
|
5345
|
+
throw new Error("Tool data is not associated with any imageId");
|
|
5346
|
+
}
|
|
5347
|
+
}
|
|
5348
|
+
var AnnotationToPointData = /*#__PURE__*/function () {
|
|
5349
|
+
function AnnotationToPointData() {
|
|
5350
|
+
_classCallCheck(this, AnnotationToPointData);
|
|
5351
|
+
} // empty
|
|
5352
|
+
_createClass(AnnotationToPointData, null, [{
|
|
5353
|
+
key: "convert",
|
|
5354
|
+
value: function convert(annotation, index, metadataProvider) {
|
|
5355
|
+
validateAnnotation(annotation);
|
|
5356
|
+
var toolName = annotation.metadata.toolName;
|
|
5357
|
+
var toolClass = AnnotationToPointData.TOOL_NAMES[toolName];
|
|
5358
|
+
if (!toolClass) {
|
|
5359
|
+
throw new Error("Unknown tool type: ".concat(toolName, ", cannot convert to RTSSReport"));
|
|
5360
|
+
}
|
|
5361
|
+
|
|
5362
|
+
// Each toolData should become a list of contours, ContourSequence
|
|
5363
|
+
// contains a list of contours with their pointData, their geometry
|
|
5364
|
+
// type and their length.
|
|
5365
|
+
var ContourSequence = toolClass.getContourSequence(annotation, metadataProvider);
|
|
5366
|
+
|
|
5367
|
+
// Todo: random rgb color for now, options should be passed in
|
|
5368
|
+
var color = [Math.floor(Math.random() * 255), Math.floor(Math.random() * 255), Math.floor(Math.random() * 255)];
|
|
5369
|
+
return {
|
|
5370
|
+
ReferencedROINumber: index + 1,
|
|
5371
|
+
ROIDisplayColor: color,
|
|
5372
|
+
ContourSequence: ContourSequence
|
|
5373
|
+
};
|
|
5374
|
+
}
|
|
5375
|
+
}, {
|
|
5376
|
+
key: "register",
|
|
5377
|
+
value: function register(toolClass) {
|
|
5378
|
+
AnnotationToPointData.TOOL_NAMES[toolClass.toolName] = toolClass;
|
|
5379
|
+
}
|
|
5380
|
+
}]);
|
|
5381
|
+
return AnnotationToPointData;
|
|
5382
|
+
}();
|
|
5383
|
+
AnnotationToPointData.TOOL_NAMES = {};
|
|
5384
|
+
AnnotationToPointData.register(RectangleROIStartEndThreshold);
|
|
5385
|
+
|
|
5386
|
+
function getPatientModule(imageId, metadataProvider) {
|
|
5387
|
+
var generalSeriesModule = metadataProvider.get("generalSeriesModule", imageId);
|
|
5388
|
+
var generalStudyModule = metadataProvider.get("generalStudyModule", imageId);
|
|
5389
|
+
var patientStudyModule = metadataProvider.get("patientStudyModule", imageId);
|
|
5390
|
+
var patientModule = metadataProvider.get("patientModule", imageId);
|
|
5391
|
+
var patientDemographicModule = metadataProvider.get("patientDemographicModule", imageId);
|
|
5392
|
+
return {
|
|
5393
|
+
Modality: generalSeriesModule.modality,
|
|
5394
|
+
PatientID: patientModule.patientId,
|
|
5395
|
+
PatientName: patientModule.patientName,
|
|
5396
|
+
PatientBirthDate: "",
|
|
5397
|
+
PatientAge: patientStudyModule.patientAge,
|
|
5398
|
+
PatientSex: patientDemographicModule.patientSex,
|
|
5399
|
+
PatientWeight: patientStudyModule.patientWeight,
|
|
5400
|
+
StudyDate: generalStudyModule.studyDate,
|
|
5401
|
+
StudyTime: generalStudyModule.studyTime,
|
|
5402
|
+
StudyID: "ToDo",
|
|
5403
|
+
AccessionNumber: generalStudyModule.accessionNumber
|
|
5404
|
+
};
|
|
5405
|
+
}
|
|
5406
|
+
|
|
5407
|
+
function getReferencedFrameOfReferenceSequence(metadata, metadataProvider, dataset) {
|
|
5408
|
+
var imageId = metadata.referencedImageId,
|
|
5409
|
+
FrameOfReferenceUID = metadata.FrameOfReferenceUID;
|
|
5410
|
+
var instance = metadataProvider.get("instance", imageId);
|
|
5411
|
+
var SeriesInstanceUID = instance.SeriesInstanceUID;
|
|
5412
|
+
var ReferencedSeriesSequence = dataset.ReferencedSeriesSequence;
|
|
5413
|
+
return [{
|
|
5414
|
+
FrameOfReferenceUID: FrameOfReferenceUID,
|
|
5415
|
+
RTReferencedStudySequence: [{
|
|
5416
|
+
ReferencedSOPClassUID: dataset.SOPClassUID,
|
|
5417
|
+
ReferencedSOPInstanceUID: dataset.SOPInstanceUID,
|
|
5418
|
+
RTReferencedSeriesSequence: [{
|
|
5419
|
+
SeriesInstanceUID: SeriesInstanceUID,
|
|
5420
|
+
ContourImageSequence: _toConsumableArray(ReferencedSeriesSequence[0].ReferencedInstanceSequence)
|
|
5421
|
+
}]
|
|
5422
|
+
}]
|
|
5423
|
+
}];
|
|
5424
|
+
}
|
|
5425
|
+
|
|
5426
|
+
function getReferencedSeriesSequence(metadata, _index, metadataProvider, DicomMetadataStore) {
|
|
5427
|
+
// grab imageId from toolData
|
|
5428
|
+
var imageId = metadata.referencedImageId;
|
|
5429
|
+
var instance = metadataProvider.get("instance", imageId);
|
|
5430
|
+
var SeriesInstanceUID = instance.SeriesInstanceUID,
|
|
5431
|
+
StudyInstanceUID = instance.StudyInstanceUID;
|
|
5432
|
+
var ReferencedSeriesSequence = [];
|
|
5433
|
+
if (SeriesInstanceUID) {
|
|
5434
|
+
var series = DicomMetadataStore.getSeries(StudyInstanceUID, SeriesInstanceUID);
|
|
5435
|
+
var ReferencedSeries = {
|
|
5436
|
+
SeriesInstanceUID: SeriesInstanceUID,
|
|
5437
|
+
ReferencedInstanceSequence: []
|
|
5438
|
+
};
|
|
5439
|
+
series.instances.forEach(function (instance) {
|
|
5440
|
+
var SOPInstanceUID = instance.SOPInstanceUID,
|
|
5441
|
+
SOPClassUID = instance.SOPClassUID;
|
|
5442
|
+
ReferencedSeries.ReferencedInstanceSequence.push({
|
|
5443
|
+
ReferencedSOPClassUID: SOPClassUID,
|
|
5444
|
+
ReferencedSOPInstanceUID: SOPInstanceUID
|
|
5445
|
+
});
|
|
5446
|
+
});
|
|
5447
|
+
ReferencedSeriesSequence.push(ReferencedSeries);
|
|
5448
|
+
}
|
|
5449
|
+
return ReferencedSeriesSequence;
|
|
5450
|
+
}
|
|
5451
|
+
|
|
5452
|
+
function getRTROIObservationsSequence(toolData, index) {
|
|
5453
|
+
return {
|
|
5454
|
+
ObservationNumber: index + 1,
|
|
5455
|
+
ReferencedROINumber: index + 1,
|
|
5456
|
+
RTROIInterpretedType: "Todo: type",
|
|
5457
|
+
ROIInterpreter: "Todo: interpreter"
|
|
5458
|
+
};
|
|
5459
|
+
}
|
|
5460
|
+
|
|
5461
|
+
function getRTSeriesModule(DicomMetaDictionary) {
|
|
5462
|
+
return {
|
|
5463
|
+
SeriesInstanceUID: DicomMetaDictionary.uid(),
|
|
5464
|
+
// generate a new series instance uid
|
|
5465
|
+
SeriesNumber: "99" // Todo:: what should be the series number?
|
|
5466
|
+
};
|
|
5467
|
+
}
|
|
5468
|
+
|
|
5469
|
+
function getStructureSetModule(contour, index) {
|
|
5470
|
+
var FrameOfReferenceUID = contour.metadata.FrameOfReferenceUID;
|
|
5471
|
+
return {
|
|
5472
|
+
ROINumber: index + 1,
|
|
5473
|
+
ROIName: contour.name || "Todo: name ".concat(index + 1),
|
|
5474
|
+
ROIDescription: "Todo: description ".concat(index + 1),
|
|
5475
|
+
ROIGenerationAlgorithm: "Todo: algorithm",
|
|
5476
|
+
ReferencedFrameOfReferenceUID: FrameOfReferenceUID
|
|
5477
|
+
};
|
|
5478
|
+
}
|
|
5479
|
+
|
|
5480
|
+
var DicomMetaDictionary = dcmjs.data.DicomMetaDictionary;
|
|
5481
|
+
/**
|
|
5482
|
+
* Convert handles to RTSS report containing the dcmjs dicom dataset.
|
|
5483
|
+
*
|
|
5484
|
+
* Note: current WIP and using segmentation to contour conversion,
|
|
5485
|
+
* routine that is not fully tested
|
|
5486
|
+
*
|
|
5487
|
+
* @param segmentations - Cornerstone tool segmentations data
|
|
5488
|
+
* @param metadataProvider - Metadata provider
|
|
5489
|
+
* @param DicomMetadataStore - metadata store instance
|
|
5490
|
+
* @param cs - cornerstone instance
|
|
5491
|
+
* @param csTools - cornerstone tool instance
|
|
5492
|
+
* @returns Report object containing the dataset
|
|
5493
|
+
*/
|
|
5494
|
+
function generateRTSSFromSegmentations(segmentations, metadataProvider, DicomMetadataStore, cornerstoneCache, cornerstoneToolsEnums, vtkUtils) {
|
|
5495
|
+
// Convert segmentations to ROIContours
|
|
5496
|
+
var roiContours = [];
|
|
5497
|
+
var contourSets = generateContourSetsFromLabelmap({
|
|
5498
|
+
segmentations: segmentations,
|
|
5499
|
+
cornerstoneCache: cornerstoneCache,
|
|
5500
|
+
cornerstoneToolsEnums: cornerstoneToolsEnums,
|
|
5501
|
+
vtkUtils: vtkUtils
|
|
5502
|
+
});
|
|
5503
|
+
contourSets.forEach(function (contourSet, segIndex) {
|
|
5504
|
+
// Check contour set isn't undefined
|
|
5505
|
+
if (contourSet) {
|
|
5506
|
+
var contourSequence_1 = [];
|
|
5507
|
+
contourSet.sliceContours.forEach(function (sliceContour) {
|
|
5508
|
+
/**
|
|
5509
|
+
* addContour - Adds a new ROI with related contours to ROIContourSequence
|
|
5510
|
+
*
|
|
5511
|
+
* @param newContour - cornerstoneTools `ROIContour` object
|
|
5512
|
+
*
|
|
5513
|
+
* newContour = {
|
|
5514
|
+
* name: string,
|
|
5515
|
+
* description: string,
|
|
5516
|
+
* contourSequence: array[contour]
|
|
5517
|
+
* color: array[number],
|
|
5518
|
+
* metadata: {
|
|
5519
|
+
* referencedImageId: string,
|
|
5520
|
+
* FrameOfReferenceUID: string
|
|
5521
|
+
* }
|
|
5522
|
+
* }
|
|
5523
|
+
*
|
|
5524
|
+
* contour = {
|
|
5525
|
+
* ContourImageSequence: array[
|
|
5526
|
+
* { ReferencedSOPClassUID: string, ReferencedSOPInstanceUID: string}
|
|
5527
|
+
* ]
|
|
5528
|
+
* ContourGeometricType: string,
|
|
5529
|
+
* NumberOfContourPoints: number,
|
|
5530
|
+
* ContourData: array[number]
|
|
5531
|
+
* }
|
|
5532
|
+
*/
|
|
5533
|
+
// Note: change needed if support non-planar contour representation is needed
|
|
5534
|
+
var sopCommon = metadataProvider.get("sopCommonModule", sliceContour.referencedImageId);
|
|
5535
|
+
var ReferencedSOPClassUID = sopCommon.sopClassUID;
|
|
5536
|
+
var ReferencedSOPInstanceUID = sopCommon.sopInstanceUID;
|
|
5537
|
+
var ContourImageSequence = [
|
|
5538
|
+
{ ReferencedSOPClassUID: ReferencedSOPClassUID, ReferencedSOPInstanceUID: ReferencedSOPInstanceUID } // NOTE: replace in dcmjs?
|
|
5539
|
+
];
|
|
5540
|
+
var sliceContourPolyData = sliceContour.polyData;
|
|
5541
|
+
sliceContour.contours.forEach(function (contour, index) {
|
|
5542
|
+
var ContourGeometricType = contour.type;
|
|
5543
|
+
var NumberOfContourPoints = contour.contourPoints.length;
|
|
5544
|
+
var ContourData = [];
|
|
5545
|
+
contour.contourPoints.forEach(function (point) {
|
|
5546
|
+
var pointData = sliceContourPolyData.points[point];
|
|
5547
|
+
pointData[0] = +pointData[0].toFixed(2);
|
|
5548
|
+
pointData[1] = +pointData[1].toFixed(2);
|
|
5549
|
+
pointData[2] = +pointData[2].toFixed(2);
|
|
5550
|
+
ContourData.push(pointData[0]);
|
|
5551
|
+
ContourData.push(pointData[1]);
|
|
5552
|
+
ContourData.push(pointData[2]);
|
|
5553
|
+
});
|
|
5554
|
+
contourSequence_1.push({
|
|
5555
|
+
ContourImageSequence: ContourImageSequence,
|
|
5556
|
+
ContourGeometricType: ContourGeometricType,
|
|
5557
|
+
NumberOfContourPoints: NumberOfContourPoints,
|
|
5558
|
+
ContourNumber: index + 1,
|
|
5559
|
+
ContourData: ContourData
|
|
5560
|
+
});
|
|
5561
|
+
});
|
|
5562
|
+
});
|
|
5563
|
+
var segLabel = contourSet.label || "Segment ".concat(segIndex + 1);
|
|
5564
|
+
var ROIContour = {
|
|
5565
|
+
name: segLabel,
|
|
5566
|
+
description: segLabel,
|
|
5567
|
+
contourSequence: contourSequence_1,
|
|
5568
|
+
color: contourSet.color,
|
|
5569
|
+
metadata: contourSet.metadata
|
|
5570
|
+
};
|
|
5571
|
+
roiContours.push(ROIContour);
|
|
5572
|
+
}
|
|
5573
|
+
});
|
|
5574
|
+
var rtMetadata = {
|
|
5575
|
+
name: segmentations.label,
|
|
5576
|
+
label: segmentations.label
|
|
5577
|
+
};
|
|
5578
|
+
var dataset = _initializeDataset(rtMetadata, roiContours[0].metadata, metadataProvider);
|
|
5579
|
+
roiContours.forEach(function (contour, index) {
|
|
5580
|
+
var roiContour = {
|
|
5581
|
+
ROIDisplayColor: contour.color || [255, 0, 0],
|
|
5582
|
+
ContourSequence: contour.contourSequence,
|
|
5583
|
+
ReferencedROINumber: index + 1
|
|
5584
|
+
};
|
|
5585
|
+
dataset.StructureSetROISequence.push(getStructureSetModule(contour, index));
|
|
5586
|
+
dataset.ROIContourSequence.push(roiContour);
|
|
5587
|
+
// ReferencedSeriesSequence
|
|
5588
|
+
dataset.ReferencedSeriesSequence = getReferencedSeriesSequence(contour.metadata, index, metadataProvider, DicomMetadataStore);
|
|
5589
|
+
// ReferencedFrameOfReferenceSequence
|
|
5590
|
+
dataset.ReferencedFrameOfReferenceSequence =
|
|
5591
|
+
getReferencedFrameOfReferenceSequence(contour.metadata, metadataProvider, dataset);
|
|
5592
|
+
});
|
|
5593
|
+
var fileMetaInformationVersionArray = new Uint8Array(2);
|
|
5594
|
+
fileMetaInformationVersionArray[1] = 1;
|
|
5595
|
+
var _meta = {
|
|
5596
|
+
FileMetaInformationVersion: {
|
|
5597
|
+
Value: [fileMetaInformationVersionArray.buffer],
|
|
5598
|
+
vr: "OB"
|
|
5599
|
+
},
|
|
5600
|
+
TransferSyntaxUID: {
|
|
5601
|
+
Value: ["1.2.840.10008.1.2.1"],
|
|
5602
|
+
vr: "UI"
|
|
5603
|
+
},
|
|
5604
|
+
ImplementationClassUID: {
|
|
5605
|
+
Value: [DicomMetaDictionary.uid()],
|
|
5606
|
+
vr: "UI"
|
|
5607
|
+
},
|
|
5608
|
+
ImplementationVersionName: {
|
|
5609
|
+
Value: ["dcmjs"],
|
|
5610
|
+
vr: "SH"
|
|
5611
|
+
}
|
|
5612
|
+
};
|
|
5613
|
+
dataset._meta = _meta;
|
|
5614
|
+
return dataset;
|
|
5615
|
+
}
|
|
5616
|
+
/**
|
|
5617
|
+
* Convert handles to RTSSReport report object containing the dcmjs dicom dataset.
|
|
5618
|
+
*
|
|
5619
|
+
* Note: The tool data needs to be formatted in a specific way, and currently
|
|
5620
|
+
* it is limited to the RectangleROIStartEndTool in the Cornerstone.
|
|
5621
|
+
*
|
|
5622
|
+
* @param annotations Array of Cornerstone tool annotation data
|
|
5623
|
+
* @param metadataProvider Metadata provider
|
|
5624
|
+
* @param options report generation options
|
|
5625
|
+
* @returns Report object containing the dataset
|
|
5626
|
+
*/
|
|
5627
|
+
function generateRTSSFromAnnotations(annotations, metadataProvider, DicomMetadataStore, options) {
|
|
5628
|
+
var rtMetadata = {
|
|
5629
|
+
name: "RTSS from Annotations",
|
|
5630
|
+
label: "RTSS from Annotations"
|
|
5631
|
+
};
|
|
5632
|
+
var dataset = _initializeDataset(rtMetadata, annotations[0].metadata, metadataProvider);
|
|
5633
|
+
annotations.forEach(function (annotation, index) {
|
|
5634
|
+
var ContourSequence = AnnotationToPointData.convert(annotation, index, metadataProvider, options);
|
|
5635
|
+
dataset.StructureSetROISequence.push(getStructureSetModule(annotation, index));
|
|
5636
|
+
dataset.ROIContourSequence.push(ContourSequence);
|
|
5637
|
+
dataset.RTROIObservationsSequence.push(getRTROIObservationsSequence(annotation, index));
|
|
5638
|
+
// ReferencedSeriesSequence
|
|
5639
|
+
// Todo: handle more than one series
|
|
5640
|
+
dataset.ReferencedSeriesSequence = getReferencedSeriesSequence(annotation.metadata, index, metadataProvider, DicomMetadataStore);
|
|
5641
|
+
// ReferencedFrameOfReferenceSequence
|
|
5642
|
+
dataset.ReferencedFrameOfReferenceSequence =
|
|
5643
|
+
getReferencedFrameOfReferenceSequence(annotation.metadata, metadataProvider, dataset);
|
|
5644
|
+
});
|
|
5645
|
+
var fileMetaInformationVersionArray = new Uint8Array(2);
|
|
5646
|
+
fileMetaInformationVersionArray[1] = 1;
|
|
5647
|
+
var _meta = {
|
|
5648
|
+
FileMetaInformationVersion: {
|
|
5649
|
+
Value: [fileMetaInformationVersionArray.buffer],
|
|
5650
|
+
vr: "OB"
|
|
5651
|
+
},
|
|
5652
|
+
TransferSyntaxUID: {
|
|
5653
|
+
Value: ["1.2.840.10008.1.2.1"],
|
|
5654
|
+
vr: "UI"
|
|
5655
|
+
},
|
|
5656
|
+
ImplementationClassUID: {
|
|
5657
|
+
Value: [DicomMetaDictionary.uid()],
|
|
5658
|
+
vr: "UI"
|
|
5659
|
+
},
|
|
5660
|
+
ImplementationVersionName: {
|
|
5661
|
+
Value: ["dcmjs"],
|
|
5662
|
+
vr: "SH"
|
|
5663
|
+
}
|
|
5664
|
+
};
|
|
5665
|
+
dataset._meta = _meta;
|
|
5666
|
+
return dataset;
|
|
5667
|
+
}
|
|
5668
|
+
// /**
|
|
5669
|
+
// * Generate Cornerstone tool state from dataset
|
|
5670
|
+
// * @param {object} dataset dataset
|
|
5671
|
+
// * @param {object} hooks
|
|
5672
|
+
// * @param {function} hooks.getToolClass Function to map dataset to a tool class
|
|
5673
|
+
// * @returns
|
|
5674
|
+
// */
|
|
5675
|
+
// //static generateToolState(_dataset, _hooks = {}) {
|
|
5676
|
+
// function generateToolState() {
|
|
5677
|
+
// // Todo
|
|
5678
|
+
// console.warn("RTSS.generateToolState not implemented");
|
|
5679
|
+
// }
|
|
5680
|
+
function _initializeDataset(rtMetadata, imgMetadata, metadataProvider) {
|
|
5681
|
+
var rtSOPInstanceUID = DicomMetaDictionary.uid();
|
|
5682
|
+
// get the first annotation data
|
|
5683
|
+
var imageId = imgMetadata.referencedImageId, FrameOfReferenceUID = imgMetadata.FrameOfReferenceUID;
|
|
5684
|
+
var studyInstanceUID = metadataProvider.get("generalSeriesModule", imageId).studyInstanceUID;
|
|
5685
|
+
var patientModule = getPatientModule(imageId, metadataProvider);
|
|
5686
|
+
var rtSeriesModule = getRTSeriesModule(DicomMetaDictionary);
|
|
5687
|
+
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() });
|
|
5688
|
+
}
|
|
5689
|
+
|
|
5690
|
+
var RTSS = /*#__PURE__*/Object.freeze({
|
|
5691
|
+
__proto__: null,
|
|
5692
|
+
generateContourSetsFromLabelmap: generateContourSetsFromLabelmap,
|
|
5693
|
+
generateRTSSFromAnnotations: generateRTSSFromAnnotations,
|
|
5694
|
+
generateRTSSFromSegmentations: generateRTSSFromSegmentations
|
|
5695
|
+
});
|
|
5696
|
+
|
|
4977
5697
|
var Cornerstone3DSR = {
|
|
4978
5698
|
Bidirectional: Bidirectional,
|
|
4979
5699
|
CobbAngle: CobbAngle,
|
|
@@ -4992,6 +5712,9 @@ var Cornerstone3DSR = {
|
|
|
4992
5712
|
var Cornerstone3DSEG = {
|
|
4993
5713
|
Segmentation: Segmentation$1
|
|
4994
5714
|
};
|
|
5715
|
+
var Cornerstone3DRT = {
|
|
5716
|
+
RTSS: RTSS
|
|
5717
|
+
};
|
|
4995
5718
|
|
|
4996
5719
|
var Colors = data.Colors,
|
|
4997
5720
|
BitArray = data.BitArray;
|
|
@@ -5189,6 +5912,9 @@ var adaptersSEG = {
|
|
|
5189
5912
|
Cornerstone3D: Cornerstone3DSEG,
|
|
5190
5913
|
VTKjs: VTKjsSEG
|
|
5191
5914
|
};
|
|
5915
|
+
var adaptersRT = {
|
|
5916
|
+
Cornerstone3D: Cornerstone3DRT
|
|
5917
|
+
};
|
|
5192
5918
|
|
|
5193
|
-
export { index as Enums, adaptersSEG, adaptersSR, index$1 as helpers };
|
|
5919
|
+
export { index as Enums, adaptersRT, adaptersSEG, adaptersSR, index$1 as helpers };
|
|
5194
5920
|
//# sourceMappingURL=adapters.es.js.map
|