@ohif/app 3.8.0-beta.73 → 3.8.0-beta.74
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/{121.bundle.21827fec690c01ee9ab3.js → 121.bundle.bd8acf52b6a7047ae832.js} +2 -2
- package/dist/141.bundle.556b4c1e4cab770417ac.js +8620 -0
- package/dist/{191.bundle.c0ea2d031ffddeca32c9.js → 183.bundle.25293de927ef032a6695.js} +195 -122
- package/dist/{188.bundle.acfe3c0e6eb9cc90aef1.js → 188.bundle.f1b3909e55be12d37c4a.js} +2 -2
- package/dist/{987.bundle.e19408decfd59aadd118.js → 217.bundle.9631d914f170f8d7ef63.js} +31558 -39396
- package/dist/{295.bundle.3a0d5062d65296c4bf5d.js → 295.bundle.688b6bbff493cd904ae7.js} +2 -2
- package/dist/{155.bundle.64e00e96835d61e99c0e.js → 325.bundle.3d260b1a7f80cfc892a0.js} +43 -58
- package/dist/{425.bundle.f796ed1020fbed0f1e71.js → 335.bundle.ec53cc58116ef1dc5fa3.js} +132 -518
- package/dist/{342.bundle.521c0217f82380c0c2ad.js → 342.bundle.c6165579c4ac3ef0d6a8.js} +2 -2
- package/dist/{41.bundle.8b3f6e6f4bd71b85ef14.js → 41.bundle.3c9bb4e3800dcea2c043.js} +28 -29
- package/dist/{433.bundle.6f2308ab10593784778c.js → 433.bundle.1474591f213852cffcba.js} +188 -172
- package/dist/{290.bundle.952de53057f98e2c5ef0.js → 445.bundle.38c6d2af64e41cd7c614.js} +1 -1049
- package/dist/{448.bundle.19df2fef38bb0f6a272a.js → 448.bundle.e6af6868af55a353b12b.js} +16 -22
- package/dist/487.bundle.de932b440ffc809978b5.js +1875 -0
- package/dist/{530.bundle.f4b7966fb33eafb8cd5d.js → 530.bundle.7c94543955552475c56a.js} +9 -9
- package/dist/{540.bundle.32224b29bfa11d1f1cec.js → 540.bundle.31780163f7065fd4d325.js} +15 -15
- package/dist/{544.bundle.1110b24e96863d719a95.js → 544.bundle.fcb790bae53294b49b05.js} +8 -8
- package/dist/{574.bundle.2b3369042aad5d553463.js → 574.bundle.b4eb8773d7741868e84b.js} +166 -45
- package/dist/{594.bundle.61a9f0567260e9bb4480.js → 594.bundle.6c0b915507752363e82a.js} +4 -4
- package/dist/{2.bundle.a849401e1fefc0898248.js → 633.bundle.7f782a390a22d9c7ec1d.js} +35 -43
- package/dist/{699.bundle.9f4eddf87548c0d0dca3.js → 699.bundle.7642c1505c1685f63897.js} +18 -35
- package/dist/702.bundle.963481fbf871984b646f.js +8426 -0
- package/dist/722.bundle.afab1fe6bfcd569130ac.js +1083 -0
- package/dist/{724.bundle.b57096deac9649aada4b.js → 724.bundle.ad52afcbec7501305d25.js} +20 -11
- package/dist/{90.bundle.70f4752bb4ac79aef269.js → 83.bundle.ff7db010621303a71a50.js} +419 -137
- package/dist/{862.bundle.47305c27f0fb939c2f97.js → 862.bundle.f49a379497bb3b43a942.js} +3 -3
- package/dist/{889.bundle.3816444220909bd1fc78.js → 889.bundle.67ca151a5e2d653b0021.js} +8 -8
- package/dist/{595.bundle.e8ff2d0672cb195d4ab8.js → 896.bundle.ba0b4c73e2331281159f.js} +686 -57
- package/dist/{905.bundle.2dd7f62cb6e49851926b.js → 905.bundle.e67fd55073b8ff735ed5.js} +4 -4
- package/dist/{907.bundle.d22edc6203167e985ab3.js → 907.bundle.0167da9471dcfa5c862e.js} +2 -2
- package/dist/94.bundle.ccec301dfb972a375ecc.js +784 -0
- package/dist/{961.bundle.f207f1ac54a174e67d82.js → 961.bundle.711da9767a4e31ea5aef.js} +2 -2
- package/dist/{app.bundle.5e5ee16c43a68961e8c4.js → app.bundle.c0c40b901a1bf1043f08.js} +98584 -89435
- package/dist/app.bundle.css +5 -4
- package/dist/cornerstoneDICOMImageLoader.min.js +1 -1
- package/dist/cornerstoneDICOMImageLoader.min.js.map +1 -1
- package/dist/histogram-worker.bundle.829e14ec12c2b41a4323.js +359 -0
- package/dist/index.html +1 -1
- package/dist/{polySeg.bundle.fe47718e6a8414f175b1.js → polySeg.bundle.c503e9460cef894737cd.js} +3 -6
- package/dist/sw.js +1 -1
- package/package.json +20 -19
- package/dist/425.css +0 -2
- /package/dist/{164.bundle.6b98e9caf53620fbd6ca.js → 164.bundle.55df0a2c8b3569d8e1f9.js} +0 -0
- /package/dist/{155.css → 325.css} +0 -0
- /package/dist/{2.css → 633.css} +0 -0
- /package/dist/{595.css → 896.css} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
(globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[
|
|
2
|
+
(globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[335],{
|
|
3
3
|
|
|
4
|
-
/***/
|
|
4
|
+
/***/ 27335:
|
|
5
5
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
6
6
|
|
|
7
7
|
// ESM COMPAT FLAG
|
|
@@ -723,10 +723,10 @@ var react = __webpack_require__(41766);
|
|
|
723
723
|
// EXTERNAL MODULE: ../../../node_modules/prop-types/index.js
|
|
724
724
|
var prop_types = __webpack_require__(11374);
|
|
725
725
|
var prop_types_default = /*#__PURE__*/__webpack_require__.n(prop_types);
|
|
726
|
-
// EXTERNAL MODULE: ../../ui/src/index.js +
|
|
727
|
-
var src = __webpack_require__(
|
|
728
|
-
// EXTERNAL MODULE: ../../core/src/index.ts +
|
|
729
|
-
var core_src = __webpack_require__(
|
|
726
|
+
// EXTERNAL MODULE: ../../ui/src/index.js + 785 modules
|
|
727
|
+
var src = __webpack_require__(5085);
|
|
728
|
+
// EXTERNAL MODULE: ../../core/src/index.ts + 70 modules
|
|
729
|
+
var core_src = __webpack_require__(55411);
|
|
730
730
|
// EXTERNAL MODULE: ../../../node_modules/react-i18next/dist/es/index.js + 15 modules
|
|
731
731
|
var es = __webpack_require__(80619);
|
|
732
732
|
;// CONCATENATED MODULE: ../../../extensions/tmtv/src/Panels/PanelPetSUV.tsx
|
|
@@ -970,318 +970,22 @@ PanelPetSUV.propTypes = {
|
|
|
970
970
|
}).isRequired
|
|
971
971
|
}).isRequired
|
|
972
972
|
};
|
|
973
|
-
|
|
974
|
-
var default_src = __webpack_require__(54090);
|
|
975
|
-
;// CONCATENATED MODULE: ../../../extensions/tmtv/src/Panels/PanelROIThresholdSegmentation/segmentationEditHandler.tsx
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
function segmentationItemEditHandler({
|
|
979
|
-
id,
|
|
980
|
-
servicesManager
|
|
981
|
-
}) {
|
|
982
|
-
const {
|
|
983
|
-
segmentationService,
|
|
984
|
-
uiDialogService
|
|
985
|
-
} = servicesManager.services;
|
|
986
|
-
const segmentation = segmentationService.getSegmentation(id);
|
|
987
|
-
const onSubmitHandler = ({
|
|
988
|
-
action,
|
|
989
|
-
value
|
|
990
|
-
}) => {
|
|
991
|
-
switch (action.id) {
|
|
992
|
-
case 'save':
|
|
993
|
-
{
|
|
994
|
-
segmentationService.addOrUpdateSegmentation({
|
|
995
|
-
...segmentation,
|
|
996
|
-
...value
|
|
997
|
-
}, false,
|
|
998
|
-
// don't suppress event
|
|
999
|
-
true // it should update cornerstone
|
|
1000
|
-
);
|
|
1001
|
-
}
|
|
1002
|
-
}
|
|
1003
|
-
uiDialogService.dismiss({
|
|
1004
|
-
id: 'enter-annotation'
|
|
1005
|
-
});
|
|
1006
|
-
};
|
|
1007
|
-
uiDialogService.create({
|
|
1008
|
-
id: 'enter-annotation',
|
|
1009
|
-
centralize: true,
|
|
1010
|
-
isDraggable: false,
|
|
1011
|
-
showOverlay: true,
|
|
1012
|
-
content: src/* Dialog */.lG,
|
|
1013
|
-
contentProps: {
|
|
1014
|
-
title: 'Enter your Segmentation',
|
|
1015
|
-
noCloseButton: true,
|
|
1016
|
-
value: {
|
|
1017
|
-
label: segmentation.label || ''
|
|
1018
|
-
},
|
|
1019
|
-
body: ({
|
|
1020
|
-
value,
|
|
1021
|
-
setValue
|
|
1022
|
-
}) => {
|
|
1023
|
-
const onChangeHandler = event => {
|
|
1024
|
-
event.persist();
|
|
1025
|
-
setValue(value => ({
|
|
1026
|
-
...value,
|
|
1027
|
-
label: event.target.value
|
|
1028
|
-
}));
|
|
1029
|
-
};
|
|
1030
|
-
const onKeyPressHandler = event => {
|
|
1031
|
-
if (event.key === 'Enter') {
|
|
1032
|
-
onSubmitHandler({
|
|
1033
|
-
value,
|
|
1034
|
-
action: {
|
|
1035
|
-
id: 'save'
|
|
1036
|
-
}
|
|
1037
|
-
});
|
|
1038
|
-
}
|
|
1039
|
-
};
|
|
1040
|
-
return /*#__PURE__*/react.createElement(src/* Input */.pd, {
|
|
1041
|
-
autoFocus: true,
|
|
1042
|
-
className: "border-primary-main bg-black",
|
|
1043
|
-
type: "text",
|
|
1044
|
-
containerClassName: "mr-2",
|
|
1045
|
-
value: value.label,
|
|
1046
|
-
onChange: onChangeHandler,
|
|
1047
|
-
onKeyPress: onKeyPressHandler
|
|
1048
|
-
});
|
|
1049
|
-
},
|
|
1050
|
-
actions: [{
|
|
1051
|
-
id: 'cancel',
|
|
1052
|
-
text: 'Cancel',
|
|
1053
|
-
type: src/* ButtonEnums.type */.Ny.NW.secondary
|
|
1054
|
-
}, {
|
|
1055
|
-
id: 'save',
|
|
1056
|
-
text: 'Save',
|
|
1057
|
-
type: src/* ButtonEnums.type */.Ny.NW.primary
|
|
1058
|
-
}],
|
|
1059
|
-
onSubmit: onSubmitHandler
|
|
1060
|
-
}
|
|
1061
|
-
});
|
|
1062
|
-
}
|
|
1063
|
-
/* harmony default export */ const segmentationEditHandler = (segmentationItemEditHandler);
|
|
1064
|
-
;// CONCATENATED MODULE: ../../../extensions/tmtv/src/Panels/PanelROIThresholdSegmentation/ExportReports.tsx
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
function ExportReports({
|
|
1069
|
-
segmentations,
|
|
1070
|
-
tmtvValue,
|
|
1071
|
-
config,
|
|
1072
|
-
commandsManager
|
|
1073
|
-
}) {
|
|
1074
|
-
const {
|
|
1075
|
-
t
|
|
1076
|
-
} = (0,es/* useTranslation */.Bd)('PanelSUVExport');
|
|
1077
|
-
return /*#__PURE__*/react.createElement(react.Fragment, null, segmentations?.length ? /*#__PURE__*/react.createElement("div", {
|
|
1078
|
-
className: "mt-4 flex justify-center space-x-2"
|
|
1079
|
-
}, /*#__PURE__*/react.createElement(src/* LegacyButtonGroup */.xA, {
|
|
1080
|
-
color: "black",
|
|
1081
|
-
size: "inherit"
|
|
1082
|
-
}, /*#__PURE__*/react.createElement(src/* LegacyButton */._H, {
|
|
1083
|
-
className: "px-2 py-2 text-base",
|
|
1084
|
-
disabled: tmtvValue === null,
|
|
1085
|
-
onClick: () => {
|
|
1086
|
-
commandsManager.runCommand('exportTMTVReportCSV', {
|
|
1087
|
-
segmentations,
|
|
1088
|
-
tmtv: tmtvValue,
|
|
1089
|
-
config
|
|
1090
|
-
});
|
|
1091
|
-
}
|
|
1092
|
-
}, t('Export CSV'))), /*#__PURE__*/react.createElement(src/* LegacyButtonGroup */.xA, {
|
|
1093
|
-
color: "black",
|
|
1094
|
-
size: "inherit"
|
|
1095
|
-
}, /*#__PURE__*/react.createElement(src/* LegacyButton */._H, {
|
|
1096
|
-
className: "px-2 py-2 text-base",
|
|
1097
|
-
onClick: () => {
|
|
1098
|
-
commandsManager.runCommand('createTMTVRTReport');
|
|
1099
|
-
},
|
|
1100
|
-
disabled: tmtvValue === null
|
|
1101
|
-
}, t('Create RT Report')))) : null);
|
|
1102
|
-
}
|
|
1103
|
-
/* harmony default export */ const PanelROIThresholdSegmentation_ExportReports = (ExportReports);
|
|
1104
|
-
;// CONCATENATED MODULE: ../../../extensions/tmtv/src/Panels/PanelROIThresholdSegmentation/callInputDialog.tsx
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
function callInputDialog(uiDialogService, label, callback) {
|
|
1108
|
-
const dialogId = 'enter-segment-label';
|
|
1109
|
-
const onSubmitHandler = ({
|
|
1110
|
-
action,
|
|
1111
|
-
value
|
|
1112
|
-
}) => {
|
|
1113
|
-
switch (action.id) {
|
|
1114
|
-
case 'save':
|
|
1115
|
-
callback(value.label, action.id);
|
|
1116
|
-
break;
|
|
1117
|
-
case 'cancel':
|
|
1118
|
-
callback('', action.id);
|
|
1119
|
-
break;
|
|
1120
|
-
}
|
|
1121
|
-
uiDialogService.dismiss({
|
|
1122
|
-
id: dialogId
|
|
1123
|
-
});
|
|
1124
|
-
};
|
|
1125
|
-
if (uiDialogService) {
|
|
1126
|
-
uiDialogService.create({
|
|
1127
|
-
id: dialogId,
|
|
1128
|
-
centralize: true,
|
|
1129
|
-
isDraggable: false,
|
|
1130
|
-
showOverlay: true,
|
|
1131
|
-
content: src/* Dialog */.lG,
|
|
1132
|
-
contentProps: {
|
|
1133
|
-
title: 'Segment',
|
|
1134
|
-
value: {
|
|
1135
|
-
label
|
|
1136
|
-
},
|
|
1137
|
-
noCloseButton: true,
|
|
1138
|
-
onClose: () => uiDialogService.dismiss({
|
|
1139
|
-
id: dialogId
|
|
1140
|
-
}),
|
|
1141
|
-
actions: [{
|
|
1142
|
-
id: 'cancel',
|
|
1143
|
-
text: 'Cancel',
|
|
1144
|
-
type: src/* ButtonEnums.type */.Ny.NW.secondary
|
|
1145
|
-
}, {
|
|
1146
|
-
id: 'save',
|
|
1147
|
-
text: 'Confirm',
|
|
1148
|
-
type: src/* ButtonEnums.type */.Ny.NW.primary
|
|
1149
|
-
}],
|
|
1150
|
-
onSubmit: onSubmitHandler,
|
|
1151
|
-
body: ({
|
|
1152
|
-
value,
|
|
1153
|
-
setValue
|
|
1154
|
-
}) => {
|
|
1155
|
-
return /*#__PURE__*/react.createElement(src/* Input */.pd, {
|
|
1156
|
-
label: "Enter the segment label",
|
|
1157
|
-
labelClassName: "text-white text-[14px] leading-[1.2]",
|
|
1158
|
-
autoFocus: true,
|
|
1159
|
-
className: "border-primary-main bg-black",
|
|
1160
|
-
type: "text",
|
|
1161
|
-
value: value.label,
|
|
1162
|
-
onChange: event => {
|
|
1163
|
-
event.persist();
|
|
1164
|
-
setValue(value => ({
|
|
1165
|
-
...value,
|
|
1166
|
-
label: event.target.value
|
|
1167
|
-
}));
|
|
1168
|
-
},
|
|
1169
|
-
onKeyPress: event => {
|
|
1170
|
-
if (event.key === 'Enter') {
|
|
1171
|
-
onSubmitHandler({
|
|
1172
|
-
value,
|
|
1173
|
-
action: {
|
|
1174
|
-
id: 'save'
|
|
1175
|
-
}
|
|
1176
|
-
});
|
|
1177
|
-
}
|
|
1178
|
-
}
|
|
1179
|
-
});
|
|
1180
|
-
}
|
|
1181
|
-
}
|
|
1182
|
-
});
|
|
1183
|
-
}
|
|
1184
|
-
}
|
|
1185
|
-
/* harmony default export */ const PanelROIThresholdSegmentation_callInputDialog = (callInputDialog);
|
|
1186
|
-
// EXTERNAL MODULE: ../../../node_modules/react-color/es/index.js + 219 modules
|
|
1187
|
-
var react_color_es = __webpack_require__(13726);
|
|
1188
|
-
;// CONCATENATED MODULE: ../../../extensions/tmtv/src/Panels/PanelROIThresholdSegmentation/colorPickerDialog.css
|
|
1189
|
-
// extracted by mini-css-extract-plugin
|
|
1190
|
-
|
|
1191
|
-
;// CONCATENATED MODULE: ../../../extensions/tmtv/src/Panels/PanelROIThresholdSegmentation/colorPickerDialog.tsx
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
function callColorPickerDialog(uiDialogService, rgbaColor, callback) {
|
|
1197
|
-
const dialogId = 'pick-color';
|
|
1198
|
-
const onSubmitHandler = ({
|
|
1199
|
-
action,
|
|
1200
|
-
value
|
|
1201
|
-
}) => {
|
|
1202
|
-
switch (action.id) {
|
|
1203
|
-
case 'save':
|
|
1204
|
-
callback(value.rgbaColor, action.id);
|
|
1205
|
-
break;
|
|
1206
|
-
case 'cancel':
|
|
1207
|
-
callback('', action.id);
|
|
1208
|
-
break;
|
|
1209
|
-
}
|
|
1210
|
-
uiDialogService.dismiss({
|
|
1211
|
-
id: dialogId
|
|
1212
|
-
});
|
|
1213
|
-
};
|
|
1214
|
-
if (uiDialogService) {
|
|
1215
|
-
uiDialogService.create({
|
|
1216
|
-
id: dialogId,
|
|
1217
|
-
centralize: true,
|
|
1218
|
-
isDraggable: false,
|
|
1219
|
-
showOverlay: true,
|
|
1220
|
-
content: src/* Dialog */.lG,
|
|
1221
|
-
contentProps: {
|
|
1222
|
-
title: 'Segment Color',
|
|
1223
|
-
value: {
|
|
1224
|
-
rgbaColor
|
|
1225
|
-
},
|
|
1226
|
-
noCloseButton: true,
|
|
1227
|
-
onClose: () => uiDialogService.dismiss({
|
|
1228
|
-
id: dialogId
|
|
1229
|
-
}),
|
|
1230
|
-
actions: [{
|
|
1231
|
-
id: 'cancel',
|
|
1232
|
-
text: 'Cancel',
|
|
1233
|
-
type: 'primary'
|
|
1234
|
-
}, {
|
|
1235
|
-
id: 'save',
|
|
1236
|
-
text: 'Save',
|
|
1237
|
-
type: 'secondary'
|
|
1238
|
-
}],
|
|
1239
|
-
onSubmit: onSubmitHandler,
|
|
1240
|
-
body: ({
|
|
1241
|
-
value,
|
|
1242
|
-
setValue
|
|
1243
|
-
}) => {
|
|
1244
|
-
const handleChange = color => {
|
|
1245
|
-
setValue({
|
|
1246
|
-
rgbaColor: color.rgb
|
|
1247
|
-
});
|
|
1248
|
-
};
|
|
1249
|
-
return /*#__PURE__*/react.createElement(react_color_es/* ChromePicker */.xk, {
|
|
1250
|
-
color: value.rgbaColor,
|
|
1251
|
-
onChange: handleChange,
|
|
1252
|
-
presetColors: [],
|
|
1253
|
-
width: 300
|
|
1254
|
-
});
|
|
1255
|
-
}
|
|
1256
|
-
}
|
|
1257
|
-
});
|
|
1258
|
-
}
|
|
1259
|
-
}
|
|
1260
|
-
/* harmony default export */ const colorPickerDialog = (callColorPickerDialog);
|
|
1261
|
-
;// CONCATENATED MODULE: ../../../extensions/tmtv/src/Panels/PanelROIThresholdSegmentation/PanelROIThresholdSegmentation.tsx
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
973
|
+
;// CONCATENATED MODULE: ../../../extensions/tmtv/src/Panels/PanelROIThresholdSegmentation/PanelROIThresholdExport.tsx
|
|
1266
974
|
|
|
1267
975
|
|
|
1268
976
|
|
|
1269
977
|
|
|
1270
978
|
function PanelRoiThresholdSegmentation({
|
|
1271
979
|
servicesManager,
|
|
1272
|
-
commandsManager
|
|
1273
|
-
extensionManager
|
|
980
|
+
commandsManager
|
|
1274
981
|
}) {
|
|
1275
982
|
const {
|
|
1276
|
-
segmentationService
|
|
1277
|
-
viewportGridService,
|
|
1278
|
-
uiDialogService
|
|
983
|
+
segmentationService
|
|
1279
984
|
} = servicesManager.services;
|
|
1280
|
-
const
|
|
985
|
+
const {
|
|
986
|
+
t
|
|
987
|
+
} = (0,es/* useTranslation */.Bd)('PanelSUVExport');
|
|
1281
988
|
const [segmentations, setSegmentations] = (0,react.useState)(() => segmentationService.getSegmentations());
|
|
1282
|
-
const runCommand = (0,react.useCallback)((commandName, commandOptions = {}) => {
|
|
1283
|
-
return commandsManager.runCommand(commandName, commandOptions);
|
|
1284
|
-
}, [commandsManager]);
|
|
1285
989
|
|
|
1286
990
|
/**
|
|
1287
991
|
* Update UI based on segmentation changes (added, removed, updated)
|
|
@@ -1307,178 +1011,41 @@ function PanelRoiThresholdSegmentation({
|
|
|
1307
1011
|
});
|
|
1308
1012
|
};
|
|
1309
1013
|
}, []);
|
|
1310
|
-
const onSegmentationClick = segmentationId => {
|
|
1311
|
-
segmentationService.setActiveSegmentationForToolGroup(segmentationId);
|
|
1312
|
-
setSelectedSegmentationId(segmentationId);
|
|
1313
|
-
};
|
|
1314
|
-
const onSegmentationAdd = async () => {
|
|
1315
|
-
runCommand('createNewLabelmapFromPT').then(segmentationId => {
|
|
1316
|
-
setSelectedSegmentationId(segmentationId);
|
|
1317
|
-
});
|
|
1318
|
-
};
|
|
1319
|
-
const onSegmentAdd = segmentationId => {
|
|
1320
|
-
segmentationService.addSegment(segmentationId);
|
|
1321
|
-
};
|
|
1322
|
-
const getToolGroupIds = segmentationId => {
|
|
1323
|
-
const toolGroupIds = segmentationService.getToolGroupIdsWithSegmentation(segmentationId);
|
|
1324
|
-
return toolGroupIds;
|
|
1325
|
-
};
|
|
1326
|
-
const onSegmentClick = (segmentationId, segmentIndex) => {
|
|
1327
|
-
segmentationService.setActiveSegment(segmentationId, segmentIndex);
|
|
1328
|
-
const toolGroupIds = getToolGroupIds(segmentationId);
|
|
1329
|
-
toolGroupIds.forEach(toolGroupId => {
|
|
1330
|
-
// const toolGroupId =
|
|
1331
|
-
segmentationService.setActiveSegmentationForToolGroup(segmentationId, toolGroupId);
|
|
1332
|
-
segmentationService.jumpToSegmentCenter(segmentationId, segmentIndex, toolGroupId);
|
|
1333
|
-
});
|
|
1334
|
-
};
|
|
1335
|
-
const _setSegmentationConfiguration = (0,react.useCallback)((segmentationId, key, value) => {
|
|
1336
|
-
segmentationService.setConfiguration({
|
|
1337
|
-
segmentationId,
|
|
1338
|
-
[key]: value
|
|
1339
|
-
});
|
|
1340
|
-
}, [segmentationService]);
|
|
1341
|
-
const onToggleSegmentVisibility = (segmentationId, segmentIndex) => {
|
|
1342
|
-
const segmentation = segmentationService.getSegmentation(segmentationId);
|
|
1343
|
-
const segmentInfo = segmentation.segments[segmentIndex];
|
|
1344
|
-
const isVisible = !segmentInfo.isVisible;
|
|
1345
|
-
const toolGroupIds = getToolGroupIds(segmentationId);
|
|
1346
|
-
toolGroupIds.forEach(toolGroupId => {
|
|
1347
|
-
segmentationService.setSegmentVisibility(segmentationId, segmentIndex, isVisible, toolGroupId);
|
|
1348
|
-
});
|
|
1349
|
-
};
|
|
1350
|
-
const onSegmentDelete = (segmentationId, segmentIndex) => {
|
|
1351
|
-
segmentationService.removeSegment(segmentationId, segmentIndex);
|
|
1352
|
-
};
|
|
1353
|
-
const onSegmentEdit = (segmentationId, segmentIndex) => {
|
|
1354
|
-
const segmentation = segmentationService.getSegmentation(segmentationId);
|
|
1355
|
-
const segment = segmentation.segments[segmentIndex];
|
|
1356
|
-
const {
|
|
1357
|
-
label
|
|
1358
|
-
} = segment;
|
|
1359
|
-
PanelROIThresholdSegmentation_callInputDialog(uiDialogService, label, (label, actionId) => {
|
|
1360
|
-
if (label === '') {
|
|
1361
|
-
return;
|
|
1362
|
-
}
|
|
1363
|
-
segmentationService.setSegmentLabel(segmentationId, segmentIndex, label);
|
|
1364
|
-
});
|
|
1365
|
-
};
|
|
1366
|
-
const onToggleSegmentLock = (segmentationId, segmentIndex) => {
|
|
1367
|
-
segmentationService.toggleSegmentLocked(segmentationId, segmentIndex);
|
|
1368
|
-
};
|
|
1369
|
-
const onSegmentColorClick = (segmentationId, segmentIndex) => {
|
|
1370
|
-
const segmentation = segmentationService.getSegmentation(segmentationId);
|
|
1371
|
-
const segment = segmentation.segments[segmentIndex];
|
|
1372
|
-
const {
|
|
1373
|
-
color,
|
|
1374
|
-
opacity
|
|
1375
|
-
} = segment;
|
|
1376
|
-
const rgbaColor = {
|
|
1377
|
-
r: color[0],
|
|
1378
|
-
g: color[1],
|
|
1379
|
-
b: color[2],
|
|
1380
|
-
a: opacity / 255.0
|
|
1381
|
-
};
|
|
1382
|
-
colorPickerDialog(uiDialogService, rgbaColor, (newRgbaColor, actionId) => {
|
|
1383
|
-
if (actionId === 'cancel') {
|
|
1384
|
-
return;
|
|
1385
|
-
}
|
|
1386
|
-
segmentationService.setSegmentRGBAColor(segmentationId, segmentIndex, [newRgbaColor.r, newRgbaColor.g, newRgbaColor.b, newRgbaColor.a * 255.0]);
|
|
1387
|
-
});
|
|
1388
|
-
};
|
|
1389
|
-
const storeSegmentation = async segmentationId => {
|
|
1390
|
-
const datasources = extensionManager.getActiveDataSource();
|
|
1391
|
-
const displaySetInstanceUIDs = await (0,default_src.createReportAsync)({
|
|
1392
|
-
servicesManager,
|
|
1393
|
-
getReport: () => commandsManager.runCommand('storeSegmentation', {
|
|
1394
|
-
segmentationId,
|
|
1395
|
-
dataSource: datasources[0]
|
|
1396
|
-
}),
|
|
1397
|
-
reportType: 'Segmentation'
|
|
1398
|
-
});
|
|
1399
|
-
|
|
1400
|
-
// Show the exported report in the active viewport as read only (similar to SR)
|
|
1401
|
-
if (displaySetInstanceUIDs) {
|
|
1402
|
-
// clear the segmentation that we exported, similar to the storeMeasurement
|
|
1403
|
-
// where we remove the measurements and prompt again the user if they would like
|
|
1404
|
-
// to re-read the measurements in a SR read only viewport
|
|
1405
|
-
segmentationService.remove(segmentationId);
|
|
1406
|
-
viewportGridService.setDisplaySetsForViewport({
|
|
1407
|
-
viewportId: viewportGridService.getActiveViewportId(),
|
|
1408
|
-
displaySetInstanceUIDs
|
|
1409
|
-
});
|
|
1410
|
-
}
|
|
1411
|
-
};
|
|
1412
|
-
const onSegmentationDownloadRTSS = segmentationId => {
|
|
1413
|
-
commandsManager.runCommand('downloadRTSS', {
|
|
1414
|
-
segmentationId
|
|
1415
|
-
});
|
|
1416
|
-
};
|
|
1417
|
-
const onSegmentationDownload = segmentationId => {
|
|
1418
|
-
commandsManager.runCommand('downloadSegmentation', {
|
|
1419
|
-
segmentationId
|
|
1420
|
-
});
|
|
1421
|
-
};
|
|
1422
1014
|
const tmtvValue = segmentations?.[0]?.cachedStats?.tmtv?.value || null;
|
|
1423
1015
|
const config = segmentations?.[0]?.cachedStats?.tmtv?.config || {};
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
disableEditing: false,
|
|
1432
|
-
showAddSegmentation: true,
|
|
1433
|
-
showAddSegment: false,
|
|
1434
|
-
showDeleteSegment: true,
|
|
1435
|
-
segmentations: segmentations,
|
|
1436
|
-
onSegmentationAdd: onSegmentationAdd,
|
|
1437
|
-
onSegmentationClick: onSegmentationClick,
|
|
1438
|
-
onToggleSegmentationVisibility: id => {
|
|
1439
|
-
segmentationService.toggleSegmentationVisibility(id);
|
|
1440
|
-
},
|
|
1441
|
-
onToggleSegmentVisibility: onToggleSegmentVisibility,
|
|
1442
|
-
onSegmentationDelete: id => {
|
|
1443
|
-
segmentationService.remove(id);
|
|
1444
|
-
},
|
|
1445
|
-
onSegmentationEdit: id => {
|
|
1446
|
-
segmentationEditHandler({
|
|
1447
|
-
id,
|
|
1448
|
-
servicesManager
|
|
1016
|
+
const actions = [{
|
|
1017
|
+
label: 'Export CSV',
|
|
1018
|
+
onClick: () => {
|
|
1019
|
+
commandsManager.runCommand('exportTMTVReportCSV', {
|
|
1020
|
+
segmentations,
|
|
1021
|
+
tmtv: tmtvValue,
|
|
1022
|
+
config
|
|
1449
1023
|
});
|
|
1450
1024
|
},
|
|
1451
|
-
|
|
1452
|
-
|
|
1025
|
+
disabled: tmtvValue === null
|
|
1026
|
+
}, {
|
|
1027
|
+
label: 'Create RT Report',
|
|
1028
|
+
onClick: () => {
|
|
1029
|
+
commandsManager.runCommand('createTMTVRTReport');
|
|
1453
1030
|
},
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
onSegmentationDownloadRTSS: onSegmentationDownloadRTSS,
|
|
1462
|
-
onSegmentationDownload: onSegmentationDownload,
|
|
1463
|
-
setRenderOutline: value => _setSegmentationConfiguration(selectedSegmentationId, 'renderOutline', value),
|
|
1464
|
-
setOutlineOpacityActive: value => _setSegmentationConfiguration(selectedSegmentationId, 'outlineOpacity', value),
|
|
1465
|
-
setRenderFill: value => _setSegmentationConfiguration(selectedSegmentationId, 'renderFill', value),
|
|
1466
|
-
setRenderInactiveSegmentations: value => _setSegmentationConfiguration(selectedSegmentationId, 'renderInactiveSegmentations', value),
|
|
1467
|
-
setOutlineWidthActive: value => _setSegmentationConfiguration(selectedSegmentationId, 'outlineWidthActive', value),
|
|
1468
|
-
setFillAlpha: value => _setSegmentationConfiguration(selectedSegmentationId, 'fillAlpha', value),
|
|
1469
|
-
setFillAlphaInactive: value => _setSegmentationConfiguration(selectedSegmentationId, 'fillAlphaInactive', value)
|
|
1470
|
-
})), tmtvValue !== null ? /*#__PURE__*/react.createElement("div", {
|
|
1031
|
+
disabled: tmtvValue === null
|
|
1032
|
+
}];
|
|
1033
|
+
return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
|
|
1034
|
+
className: "mt-1 flex flex-col"
|
|
1035
|
+
}, /*#__PURE__*/react.createElement("div", {
|
|
1036
|
+
className: "invisible-scrollbar overflow-y-auto overflow-x-hidden"
|
|
1037
|
+
}, tmtvValue !== null ? /*#__PURE__*/react.createElement("div", {
|
|
1471
1038
|
className: "bg-secondary-dark mt-1 flex items-baseline justify-between px-2 py-1"
|
|
1472
1039
|
}, /*#__PURE__*/react.createElement("span", {
|
|
1473
1040
|
className: "text-base font-bold uppercase tracking-widest text-white"
|
|
1474
1041
|
}, 'TMTV:'), /*#__PURE__*/react.createElement("div", {
|
|
1475
1042
|
className: "text-white"
|
|
1476
|
-
}, `${tmtvValue} mL`)) : null, /*#__PURE__*/react.createElement(
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
}))), /*#__PURE__*/react.createElement("div", {
|
|
1043
|
+
}, `${tmtvValue} mL`)) : null, /*#__PURE__*/react.createElement("div", {
|
|
1044
|
+
className: "mt-1 flex justify-center"
|
|
1045
|
+
}, /*#__PURE__*/react.createElement(src/* ActionButtons */.wr, {
|
|
1046
|
+
actions: actions,
|
|
1047
|
+
t: t
|
|
1048
|
+
})))), /*#__PURE__*/react.createElement("div", {
|
|
1482
1049
|
className: "absolute bottom-1 flex cursor-pointer items-center justify-center text-blue-400 opacity-50 hover:opacity-80",
|
|
1483
1050
|
onClick: () => {
|
|
1484
1051
|
// navigate to a url in a new tab
|
|
@@ -1535,17 +1102,19 @@ function getPanelModule({
|
|
|
1535
1102
|
servicesManager: servicesManager
|
|
1536
1103
|
});
|
|
1537
1104
|
};
|
|
1538
|
-
const
|
|
1105
|
+
const wrappedROIThresholdToolbox = () => {
|
|
1539
1106
|
return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement(src/* Toolbox */.OO, {
|
|
1540
1107
|
commandsManager: commandsManager,
|
|
1541
1108
|
servicesManager: servicesManager,
|
|
1542
1109
|
extensionManager: extensionManager,
|
|
1543
|
-
buttonSectionId: "
|
|
1110
|
+
buttonSectionId: "ROIThresholdToolbox",
|
|
1544
1111
|
title: "Threshold Tools"
|
|
1545
|
-
})
|
|
1112
|
+
}));
|
|
1113
|
+
};
|
|
1114
|
+
const wrappedROIThresholdExport = () => {
|
|
1115
|
+
return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement(PanelROIThresholdSegmentation, {
|
|
1546
1116
|
commandsManager: commandsManager,
|
|
1547
|
-
servicesManager: servicesManager
|
|
1548
|
-
extensionManager: extensionManager
|
|
1117
|
+
servicesManager: servicesManager
|
|
1549
1118
|
}));
|
|
1550
1119
|
};
|
|
1551
1120
|
return [{
|
|
@@ -1555,20 +1124,26 @@ function getPanelModule({
|
|
|
1555
1124
|
label: 'Patient Info',
|
|
1556
1125
|
component: wrappedPanelPetSuv
|
|
1557
1126
|
}, {
|
|
1558
|
-
name: '
|
|
1127
|
+
name: 'tmtvBox',
|
|
1128
|
+
iconName: 'tab-segmentation',
|
|
1129
|
+
iconLabel: 'Segmentation',
|
|
1130
|
+
label: 'Segmentation Toolbox',
|
|
1131
|
+
component: wrappedROIThresholdToolbox
|
|
1132
|
+
}, {
|
|
1133
|
+
name: 'tmtvExport',
|
|
1559
1134
|
iconName: 'tab-segmentation',
|
|
1560
1135
|
iconLabel: 'Segmentation',
|
|
1561
|
-
label: 'Segmentation',
|
|
1562
|
-
component:
|
|
1136
|
+
label: 'Segmentation Export',
|
|
1137
|
+
component: wrappedROIThresholdExport
|
|
1563
1138
|
}];
|
|
1564
1139
|
}
|
|
1565
1140
|
/* harmony default export */ const src_getPanelModule = (getPanelModule);
|
|
1566
|
-
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/index.js +
|
|
1567
|
-
var esm = __webpack_require__(
|
|
1141
|
+
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/index.js + 18 modules
|
|
1142
|
+
var esm = __webpack_require__(24542);
|
|
1568
1143
|
;// CONCATENATED MODULE: ../../../extensions/tmtv/src/utils/measurementServiceMappings/constants/supportedTools.js
|
|
1569
1144
|
/* harmony default export */ const supportedTools = (['RectangleROIStartEndThreshold']);
|
|
1570
|
-
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/index.js +
|
|
1571
|
-
var dist_esm = __webpack_require__(
|
|
1145
|
+
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/index.js + 327 modules
|
|
1146
|
+
var dist_esm = __webpack_require__(44656);
|
|
1572
1147
|
;// CONCATENATED MODULE: ../../../extensions/tmtv/src/utils/measurementServiceMappings/utils/getSOPInstanceAttributes.js
|
|
1573
1148
|
|
|
1574
1149
|
function getSOPInstanceAttributes(imageId) {
|
|
@@ -1687,8 +1262,8 @@ function init({
|
|
|
1687
1262
|
const csTools3DVer1MeasurementSource = measurementService.getSource(CORNERSTONE_3D_TOOLS_SOURCE_NAME, CORNERSTONE_3D_TOOLS_SOURCE_VERSION);
|
|
1688
1263
|
measurementService.addMapping(csTools3DVer1MeasurementSource, 'RectangleROIStartEndThreshold', RectangleROIStartEndThreshold.matchingCriteria, RectangleROIStartEndThreshold.toAnnotation, RectangleROIStartEndThreshold.toMeasurement);
|
|
1689
1264
|
}
|
|
1690
|
-
// EXTERNAL MODULE: ../../../node_modules/gl-matrix/esm/index.js +
|
|
1691
|
-
var gl_matrix_esm = __webpack_require__(
|
|
1265
|
+
// EXTERNAL MODULE: ../../../node_modules/gl-matrix/esm/index.js + 1 modules
|
|
1266
|
+
var gl_matrix_esm = __webpack_require__(44753);
|
|
1692
1267
|
;// CONCATENATED MODULE: ../../../extensions/tmtv/src/utils/getThresholdValue.ts
|
|
1693
1268
|
|
|
1694
1269
|
function getRoiStats(referencedVolume, annotations) {
|
|
@@ -1770,21 +1345,21 @@ function calculateSuvPeak(labelmap, referenceVolume, annotations, segmentIndex =
|
|
|
1770
1345
|
if (referenceVolume.metadata.Modality !== 'PT') {
|
|
1771
1346
|
return;
|
|
1772
1347
|
}
|
|
1773
|
-
|
|
1348
|
+
const labelmapData = labelmap.getScalarData();
|
|
1349
|
+
const referenceVolumeData = referenceVolume.getScalarData();
|
|
1350
|
+
if (labelmapData.length !== referenceVolumeData.length) {
|
|
1774
1351
|
throw new Error('labelmap and referenceVolume must have the same number of pixels');
|
|
1775
1352
|
}
|
|
1776
1353
|
const {
|
|
1777
|
-
scalarData: labelmapData,
|
|
1778
1354
|
dimensions,
|
|
1779
1355
|
imageData: labelmapImageData
|
|
1780
1356
|
} = labelmap;
|
|
1781
1357
|
const {
|
|
1782
|
-
scalarData: referenceVolumeData,
|
|
1783
1358
|
imageData: referenceVolumeImageData
|
|
1784
1359
|
} = referenceVolume;
|
|
1785
1360
|
let boundsIJK;
|
|
1786
1361
|
// Todo: using the first annotation for now
|
|
1787
|
-
if (annotations && annotations[0].data?.cachedStats) {
|
|
1362
|
+
if (annotations?.length && annotations[0].data?.cachedStats) {
|
|
1788
1363
|
const {
|
|
1789
1364
|
projectionPoints
|
|
1790
1365
|
} = annotations[0].data.cachedStats;
|
|
@@ -1889,7 +1464,7 @@ function calculateTMTV(labelmaps, segmentIndex = 1) {
|
|
|
1889
1464
|
}
|
|
1890
1465
|
/* harmony default export */ const utils_calculateTMTV = (calculateTMTV);
|
|
1891
1466
|
;// CONCATENATED MODULE: ../../../extensions/tmtv/src/utils/createAndDownloadTMTVReport.js
|
|
1892
|
-
function createAndDownloadTMTVReport(segReport, additionalReportRows) {
|
|
1467
|
+
function createAndDownloadTMTVReport(segReport, additionalReportRows, options = {}) {
|
|
1893
1468
|
const firstReport = segReport[Object.keys(segReport)[0]];
|
|
1894
1469
|
const columns = Object.keys(firstReport);
|
|
1895
1470
|
const csv = [columns.join(',')];
|
|
@@ -1925,7 +1500,7 @@ function createAndDownloadTMTVReport(segReport, additionalReportRows) {
|
|
|
1925
1500
|
const url = URL.createObjectURL(blob);
|
|
1926
1501
|
const a = document.createElement('a');
|
|
1927
1502
|
a.href = url;
|
|
1928
|
-
a.download = `${firstReport.PatientID}_tmtv.csv`;
|
|
1503
|
+
a.download = options.filename ?? `${firstReport.PatientID}_tmtv.csv`;
|
|
1929
1504
|
a.click();
|
|
1930
1505
|
}
|
|
1931
1506
|
// EXTERNAL MODULE: ../../../node_modules/dcmjs/build/dcmjs.es.js
|
|
@@ -1963,7 +1538,7 @@ function dicomRTAnnotationExport(annotations) {
|
|
|
1963
1538
|
|
|
1964
1539
|
|
|
1965
1540
|
const commandsModule_metadataProvider = core_src.classes.MetadataProvider;
|
|
1966
|
-
const
|
|
1541
|
+
const RECTANGLE_ROI_THRESHOLD_MANUAL_TOOL_IDS = ['RectangleROIStartEndThreshold', 'RectangleROIThreshold'];
|
|
1967
1542
|
const LABELMAP = esm.Enums.SegmentationRepresentations.Labelmap;
|
|
1968
1543
|
const commandsModule = ({
|
|
1969
1544
|
servicesManager,
|
|
@@ -2011,6 +1586,12 @@ const commandsModule = ({
|
|
|
2011
1586
|
});
|
|
2012
1587
|
return toolGroupIds;
|
|
2013
1588
|
}
|
|
1589
|
+
function _getAnnotationsSelectedByToolNames(toolNames) {
|
|
1590
|
+
return toolNames.reduce((allAnnotationUIDs, toolName) => {
|
|
1591
|
+
const annotationUIDs = esm.annotation.selection.getAnnotationsSelectedByToolName(toolName);
|
|
1592
|
+
return allAnnotationUIDs.concat(annotationUIDs);
|
|
1593
|
+
}, []);
|
|
1594
|
+
}
|
|
2014
1595
|
const actions = {
|
|
2015
1596
|
getMatchingPTDisplaySet: ({
|
|
2016
1597
|
viewportMatchDetails
|
|
@@ -2062,7 +1643,9 @@ const commandsModule = ({
|
|
|
2062
1643
|
};
|
|
2063
1644
|
return metadata;
|
|
2064
1645
|
},
|
|
2065
|
-
createNewLabelmapFromPT: async (
|
|
1646
|
+
createNewLabelmapFromPT: async ({
|
|
1647
|
+
label
|
|
1648
|
+
}) => {
|
|
2066
1649
|
// Create a segmentation of the same resolution as the source data
|
|
2067
1650
|
// using volumeLoader.createAndCacheDerivedVolume.
|
|
2068
1651
|
const {
|
|
@@ -2127,23 +1710,52 @@ const commandsModule = ({
|
|
|
2127
1710
|
const {
|
|
2128
1711
|
referencedVolumeId
|
|
2129
1712
|
} = dist_esm.cache.getVolume(segVolumeId);
|
|
1713
|
+
const annotationUIDs = _getAnnotationsSelectedByToolNames(RECTANGLE_ROI_THRESHOLD_MANUAL_TOOL_IDS);
|
|
1714
|
+
if (annotationUIDs.length === 0) {
|
|
1715
|
+
uiNotificationService.show({
|
|
1716
|
+
title: 'Commands Module',
|
|
1717
|
+
message: 'No ROIThreshold Tool is Selected',
|
|
1718
|
+
type: 'error'
|
|
1719
|
+
});
|
|
1720
|
+
return;
|
|
1721
|
+
}
|
|
2130
1722
|
const labelmapVolume = dist_esm.cache.getVolume(segmentationId);
|
|
2131
|
-
|
|
1723
|
+
let referencedVolume = dist_esm.cache.getVolume(referencedVolumeId);
|
|
2132
1724
|
const ctReferencedVolume = dist_esm.cache.getVolume(ctVolumeId);
|
|
1725
|
+
|
|
1726
|
+
// check if viewport is
|
|
1727
|
+
|
|
2133
1728
|
if (!referencedVolume) {
|
|
2134
1729
|
throw new Error('No Reference volume found');
|
|
2135
1730
|
}
|
|
2136
1731
|
if (!labelmapVolume) {
|
|
2137
1732
|
throw new Error('No Reference labelmap found');
|
|
2138
1733
|
}
|
|
2139
|
-
const
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
1734
|
+
const annotation = esm.annotation.state.getAnnotation(annotationUIDs[0]);
|
|
1735
|
+
const {
|
|
1736
|
+
metadata: {
|
|
1737
|
+
enabledElement: {
|
|
1738
|
+
viewport
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
} = annotation;
|
|
1742
|
+
const showingReferenceVolume = viewport.hasVolumeId(referencedVolumeId);
|
|
1743
|
+
if (!showingReferenceVolume) {
|
|
1744
|
+
// if the reference volume is not being displayed, we can't
|
|
1745
|
+
// rely on it for thresholding, we have couple of options here
|
|
1746
|
+
// 1. We choose whatever volume is being displayed
|
|
1747
|
+
// 2. We check if it is a fusion viewport, we pick the volume
|
|
1748
|
+
// that matches the size and dimensions of the labelmap. This might
|
|
1749
|
+
// happen if the 4D PT is converted to a computed volume and displayed
|
|
1750
|
+
// and wants to threshold the labelmap
|
|
1751
|
+
// 3. We throw an error
|
|
1752
|
+
const displaySetInstanceUIDs = viewportGridService.getDisplaySetsUIDsForViewport(viewport.id);
|
|
1753
|
+
displaySetInstanceUIDs.forEach(displaySetInstanceUID => {
|
|
1754
|
+
const volume = dist_esm.cache.getVolumes().find(volume => volume.volumeId.includes(displaySetInstanceUID));
|
|
1755
|
+
if (dist_esm.utilities.isEqual(volume.dimensions, labelmapVolume.dimensions) && dist_esm.utilities.isEqual(volume.spacing, labelmapVolume.spacing)) {
|
|
1756
|
+
referencedVolume = volume;
|
|
1757
|
+
}
|
|
2145
1758
|
});
|
|
2146
|
-
return;
|
|
2147
1759
|
}
|
|
2148
1760
|
const {
|
|
2149
1761
|
ptLower,
|
|
@@ -2172,7 +1784,7 @@ const commandsModule = ({
|
|
|
2172
1784
|
referencedVolumeId
|
|
2173
1785
|
} = labelmap;
|
|
2174
1786
|
const referencedVolume = dist_esm.cache.getVolume(referencedVolumeId);
|
|
2175
|
-
const annotationUIDs =
|
|
1787
|
+
const annotationUIDs = _getAnnotationsSelectedByToolNames(RECTANGLE_ROI_THRESHOLD_MANUAL_TOOL_IDS);
|
|
2176
1788
|
const annotations = annotationUIDs.map(annotationUID => esm.annotation.state.getAnnotation(annotationUID));
|
|
2177
1789
|
const suvPeak = calculateSUVPeak(labelmap, referencedVolume, annotations, segmentIndex);
|
|
2178
1790
|
return {
|
|
@@ -2190,9 +1802,7 @@ const commandsModule = ({
|
|
|
2190
1802
|
scalarData,
|
|
2191
1803
|
spacing
|
|
2192
1804
|
} = labelmap;
|
|
2193
|
-
const
|
|
2194
|
-
scalarData: referencedScalarData
|
|
2195
|
-
} = dist_esm.cache.getVolume(labelmap.referencedVolumeId);
|
|
1805
|
+
const referencedScalarData = dist_esm.cache.getVolume(labelmap.referencedVolumeId).getScalarData();
|
|
2196
1806
|
let segmentationMax = -Infinity;
|
|
2197
1807
|
let segmentationMin = Infinity;
|
|
2198
1808
|
let segmentationValues = [];
|
|
@@ -2242,7 +1852,8 @@ const commandsModule = ({
|
|
|
2242
1852
|
exportTMTVReportCSV: ({
|
|
2243
1853
|
segmentations,
|
|
2244
1854
|
tmtv,
|
|
2245
|
-
config
|
|
1855
|
+
config,
|
|
1856
|
+
options
|
|
2246
1857
|
}) => {
|
|
2247
1858
|
const segReport = commandsManager.runCommand('getSegmentationCSVReport', {
|
|
2248
1859
|
segmentations
|
|
@@ -2251,11 +1862,6 @@ const commandsModule = ({
|
|
|
2251
1862
|
segmentations
|
|
2252
1863
|
});
|
|
2253
1864
|
const additionalReportRows = [{
|
|
2254
|
-
key: 'Total Metabolic Tumor Volume',
|
|
2255
|
-
value: {
|
|
2256
|
-
tmtv
|
|
2257
|
-
}
|
|
2258
|
-
}, {
|
|
2259
1865
|
key: 'Total Lesion Glycolysis',
|
|
2260
1866
|
value: {
|
|
2261
1867
|
tlg: tlg.toFixed(4)
|
|
@@ -2266,7 +1872,15 @@ const commandsModule = ({
|
|
|
2266
1872
|
...config
|
|
2267
1873
|
}
|
|
2268
1874
|
}];
|
|
2269
|
-
|
|
1875
|
+
if (tmtv !== undefined) {
|
|
1876
|
+
additionalReportRows.unshift({
|
|
1877
|
+
key: 'Total Metabolic Tumor Volume',
|
|
1878
|
+
value: {
|
|
1879
|
+
tmtv
|
|
1880
|
+
}
|
|
1881
|
+
});
|
|
1882
|
+
}
|
|
1883
|
+
createAndDownloadTMTVReport(segReport, additionalReportRows, options);
|
|
2270
1884
|
},
|
|
2271
1885
|
getTotalLesionGlycolysis: ({
|
|
2272
1886
|
segmentations
|
|
@@ -2291,8 +1905,8 @@ const commandsModule = ({
|
|
|
2291
1905
|
console.error('commandsModule::getTotalLesionGlycolysis:No referencedVolumeId found');
|
|
2292
1906
|
}
|
|
2293
1907
|
const ptVolume = dist_esm.cache.getVolume(referencedVolumeId);
|
|
2294
|
-
const mergedLabelData = mergedLabelmap.
|
|
2295
|
-
if (mergedLabelData.length !== ptVolume.
|
|
1908
|
+
const mergedLabelData = mergedLabelmap.getScalarData();
|
|
1909
|
+
if (mergedLabelData.length !== ptVolume.getScalarData().length) {
|
|
2296
1910
|
console.error('commandsModule::getTotalLesionGlycolysis:Labelmap and ptVolume are not the same size');
|
|
2297
1911
|
}
|
|
2298
1912
|
let suv = 0;
|
|
@@ -2300,7 +1914,7 @@ const commandsModule = ({
|
|
|
2300
1914
|
for (let i = 0; i < mergedLabelData.length; i++) {
|
|
2301
1915
|
// if not background
|
|
2302
1916
|
if (mergedLabelData[i] !== 0) {
|
|
2303
|
-
suv += ptVolume.
|
|
1917
|
+
suv += ptVolume.getScalarData()[i];
|
|
2304
1918
|
totalLesionVoxelCount += 1;
|
|
2305
1919
|
}
|
|
2306
1920
|
}
|
|
@@ -2319,7 +1933,7 @@ const commandsModule = ({
|
|
|
2319
1933
|
focalPoint,
|
|
2320
1934
|
viewPlaneNormal
|
|
2321
1935
|
} = viewport.getCamera();
|
|
2322
|
-
const selectedAnnotationUIDs =
|
|
1936
|
+
const selectedAnnotationUIDs = _getAnnotationsSelectedByToolNames(RECTANGLE_ROI_THRESHOLD_MANUAL_TOOL_IDS);
|
|
2323
1937
|
const annotationUID = selectedAnnotationUIDs[0];
|
|
2324
1938
|
const annotation = esm.annotation.state.getAnnotation(annotationUID);
|
|
2325
1939
|
const {
|
|
@@ -2355,7 +1969,7 @@ const commandsModule = ({
|
|
|
2355
1969
|
const {
|
|
2356
1970
|
viewport
|
|
2357
1971
|
} = _getActiveViewportsEnabledElement();
|
|
2358
|
-
const selectedAnnotationUIDs =
|
|
1972
|
+
const selectedAnnotationUIDs = _getAnnotationsSelectedByToolNames(RECTANGLE_ROI_THRESHOLD_MANUAL_TOOL_IDS);
|
|
2359
1973
|
const annotationUID = selectedAnnotationUIDs[0];
|
|
2360
1974
|
const annotation = esm.annotation.state.getAnnotation(annotationUID);
|
|
2361
1975
|
|
|
@@ -2374,7 +1988,7 @@ const commandsModule = ({
|
|
|
2374
1988
|
const annotations = [];
|
|
2375
1989
|
Object.keys(stateManager.annotations).forEach(frameOfReferenceUID => {
|
|
2376
1990
|
const forAnnotations = stateManager.annotations[frameOfReferenceUID];
|
|
2377
|
-
const ROIAnnotations = forAnnotations[
|
|
1991
|
+
const ROIAnnotations = RECTANGLE_ROI_THRESHOLD_MANUAL_TOOL_IDS.reduce((annotations, toolName) => [...annotations, ...(forAnnotations[toolName] ?? [])], []);
|
|
2378
1992
|
annotations.push(...ROIAnnotations);
|
|
2379
1993
|
});
|
|
2380
1994
|
commandsManager.runCommand('exportRTReportForAnnotations', {
|
|
@@ -2436,7 +2050,7 @@ const commandsModule = ({
|
|
|
2436
2050
|
}
|
|
2437
2051
|
report[id] = {
|
|
2438
2052
|
...segReport,
|
|
2439
|
-
PatientID: instance.PatientID,
|
|
2053
|
+
PatientID: instance.PatientID ?? '000000',
|
|
2440
2054
|
PatientName: instance.PatientName.Alphabetic,
|
|
2441
2055
|
StudyInstanceUID: instance.StudyInstanceUID,
|
|
2442
2056
|
SeriesInstanceUID: instance.SeriesInstanceUID,
|