@ohif/app 3.7.0-beta.11 → 3.7.0-beta.110
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/{917.bundle.b9983325adf849bff6fd.js → 12.bundle.5ea15cb6633d8028e47d.js} +6 -6
- package/dist/{295.bundle.957b1159fec14b9199a1.js → 125.bundle.253395f320b72180da63.js} +6 -6
- package/dist/{351.bundle.0742237651aef9694a65.js → 181.bundle.ceb057236403bcb630ac.js} +226 -204
- package/dist/{351.css → 181.css} +1 -1
- package/dist/{744.bundle.4c4b884f90eb70482821.js → 19.bundle.03f809886c36c388d05c.js} +240 -381
- package/dist/{606.bundle.5d876f5f3dd8287f0a28.js → 202.bundle.d3490836f71e001dd30f.js} +2089 -692
- package/dist/{926.bundle.dbc9d0e591cb9217fda2.js → 220.bundle.f7e1c96c94245e70f2be.js} +990 -400
- package/dist/221.bundle.dc6dac346d724d6baeae.js +1779 -0
- package/dist/221.css +2 -0
- package/dist/{664.bundle.09abae984223969d1bde.js → 23.bundle.e008ad788170f2ed5569.js} +5 -6
- package/dist/{976.bundle.9cc2382162214ea0af2b.js → 236.bundle.7b906cd27864d65f32c0.js} +89 -105
- package/dist/{55.bundle.550a823e75eb608e8d5e.js → 250.bundle.8084960e3318cda37317.js} +52 -36
- package/dist/{973.bundle.4584df05b320b94cace5.js → 281.bundle.c9854cc25c839e49c2c8.js} +18 -14
- package/dist/{82.bundle.9a0e7f08d4bce18d302f.js → 342.bundle.7d6c1e6bda1c67d729a7.js} +1802 -489
- package/dist/{404.bundle.3d65ff813eead20462d3.js → 359.bundle.72d017719489ff11057b.js} +47 -134
- package/dist/{192.bundle.950e5380ea63c6d635d5.js → 370.bundle.e55d75ff1bdccee16cde.js} +117 -103
- package/dist/{790.bundle.7327fec7833ceea2784b.js → 410.bundle.5b41c68cb0f210a83f13.js} +11 -9
- package/dist/{151.bundle.31ea35044218837bf73f.js → 417.bundle.af0a207c29b109f84159.js} +49 -17
- package/dist/{569.bundle.c8e771a8d28e237b32be.js → 451.bundle.9fd36f52ff69594f0669.js} +86 -106
- package/dist/{581.bundle.dc6197189f7c88c27d4c.js → 471.bundle.b3d77b83b1593c09a504.js} +78 -99
- package/dist/{199.bundle.f50ffd85a4334de2f5c1.js → 506.bundle.468dc6db2a9bfa96bb44.js} +11 -9
- package/dist/{531.bundle.2a82fb1d69e5b57cc72b.js → 530.bundle.a03b6f942ace3e1baa1e.js} +726 -447
- package/dist/579.css +1 -0
- package/dist/{935.bundle.deeffff0e4f7b528e3c3.js → 604.bundle.a51f83e64004bca5f497.js} +2 -3
- package/dist/613.bundle.74d59dec1983ef3efcdc.js +532 -0
- package/dist/{984.bundle.119557c018e6371b4628.js → 663.bundle.a6196baf5853e7d3f7c7.js} +68 -38
- package/dist/{205.bundle.b5a473c200dcf2bbcdb4.js → 686.bundle.dccef1f36e4bc79bcc48.js} +6 -6
- package/dist/{50.bundle.65ff60818862eda39d12.js → 687.bundle.e2c9c42ad3989a14d513.js} +218 -9
- package/dist/{331.bundle.bd0c13931a21d53086c9.js → 743.bundle.489f7df3a089d4d374e1.js} +26294 -21326
- package/dist/757.bundle.ec8301d8e70d2b990f65.js +17067 -0
- package/dist/{728.bundle.d13856835357400fef82.js → 774.bundle.4b2dc46a35012b898e1a.js} +95 -64
- package/dist/{381.bundle.0905e683605fcbc0895f.js → 775.bundle.2285e7e0e67878948c0d.js} +16 -16
- package/dist/{283.bundle.1015e87c3a47b1f1379c.js → 788.bundle.f4493409508bdffa7af8.js} +120 -370
- package/dist/{642.bundle.8905e515ce593e57ceb1.js → 814.bundle.10a2cbf02b044387e68b.js} +6 -6
- package/dist/{707.bundle.f774f3e4a687ddd60a32.js → 82.bundle.9c6461625afd2e38b997.js} +1203 -804
- package/dist/{799.bundle.758558e64147e5aad612.js → 822.bundle.891f2e57b1b7bc2f4cb4.js} +81 -34
- package/dist/{953.bundle.3b0189ebc11cf0946f18.js → 886.bundle.4b3a7f2079d085fdbcb3.js} +34 -29
- package/dist/945.min.worker.js +1 -1
- package/dist/945.min.worker.js.map +1 -1
- package/dist/{270.bundle.4564621556b0f963a004.js → 957.bundle.9ea4506963ef8b2d84ba.js} +7095 -979
- package/dist/{208.bundle.7f610a302dc54c4924da.js → 99.bundle.334c4bd4e4e81aaf45ad.js} +86 -105
- package/dist/_redirects +1 -1
- package/dist/app-config.js +35 -17
- package/dist/app.bundle.css +13 -12
- package/dist/{app.bundle.3d598a4738bdc22950d3.js → app.bundle.fd6ac18b8874825722a0.js} +72771 -67313
- package/dist/assets/yandex-browser-manifest.json +1 -1
- package/dist/cornerstoneDICOMImageLoader.min.js +1 -1
- package/dist/cornerstoneDICOMImageLoader.min.js.map +1 -1
- package/dist/{dicom-microscopy-viewer.bundle.aa60bdf008c32c39cfd7.js → dicom-microscopy-viewer.bundle.2c146384eb9466d02ff8.js} +5 -4
- package/dist/es6-shim.min.js +3569 -2
- package/dist/google.js +8 -7
- package/dist/index.html +2 -1
- package/dist/{index.worker.1c69152d710fa7b84bce.worker.js → index.worker.e62ecca63f1a2e124230.worker.js} +2 -2
- package/dist/index.worker.e62ecca63f1a2e124230.worker.js.map +1 -0
- package/dist/init-service-worker.js +3 -5
- package/dist/oidc-client.min.js +10857 -39
- package/dist/polyfill.min.js +184 -1
- package/dist/silent-refresh.html +18 -9
- package/dist/sw.js +1 -1
- package/package.json +21 -22
- package/dist/616.bundle.de530ae226dfa5573f6e.js +0 -685
- package/dist/780.bundle.fd0f13dc92e9caa0581e.js +0 -4769
- package/dist/index.worker.1c69152d710fa7b84bce.worker.js.map +0 -1
- /package/dist/{806.css → 19.css} +0 -0
- /package/dist/{55.css → 250.css} +0 -0
- /package/dist/{707.css → 82.css} +0 -0
|
@@ -1,19 +1,24 @@
|
|
|
1
|
-
(
|
|
1
|
+
(self["webpackChunk"] = self["webpackChunk"] || []).push([[202],{
|
|
2
2
|
|
|
3
|
-
/***/
|
|
3
|
+
/***/ 91202:
|
|
4
4
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
5
5
|
|
|
6
6
|
"use strict";
|
|
7
7
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
8
|
-
/* harmony export */
|
|
8
|
+
/* harmony export */ Y: () => (/* binding */ index),
|
|
9
|
+
/* harmony export */ adaptersRT: () => (/* binding */ adaptersRT),
|
|
10
|
+
/* harmony export */ adaptersSEG: () => (/* binding */ adaptersSEG),
|
|
11
|
+
/* harmony export */ adaptersSR: () => (/* binding */ adaptersSR),
|
|
12
|
+
/* harmony export */ helpers: () => (/* binding */ index$1)
|
|
9
13
|
/* harmony export */ });
|
|
10
|
-
/*
|
|
11
|
-
/* harmony import */ var
|
|
12
|
-
/* harmony import */ var
|
|
13
|
-
/* harmony import */ var
|
|
14
|
-
/* harmony import */ var
|
|
15
|
-
/* harmony import */ var
|
|
16
|
-
/* harmony import */ var
|
|
14
|
+
/* harmony import */ var dcmjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(67540);
|
|
15
|
+
/* harmony import */ var buffer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(58955);
|
|
16
|
+
/* harmony import */ var ndarray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(87513);
|
|
17
|
+
/* harmony import */ var ndarray__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(ndarray__WEBPACK_IMPORTED_MODULE_2__);
|
|
18
|
+
/* harmony import */ var lodash_clonedeep__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(11677);
|
|
19
|
+
/* harmony import */ var lodash_clonedeep__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(lodash_clonedeep__WEBPACK_IMPORTED_MODULE_3__);
|
|
20
|
+
/* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(45451);
|
|
21
|
+
|
|
17
22
|
|
|
18
23
|
|
|
19
24
|
|
|
@@ -67,6 +72,337 @@ function _objectSpread2(target) {
|
|
|
67
72
|
}
|
|
68
73
|
return target;
|
|
69
74
|
}
|
|
75
|
+
function _regeneratorRuntime() {
|
|
76
|
+
_regeneratorRuntime = function () {
|
|
77
|
+
return exports;
|
|
78
|
+
};
|
|
79
|
+
var exports = {},
|
|
80
|
+
Op = Object.prototype,
|
|
81
|
+
hasOwn = Op.hasOwnProperty,
|
|
82
|
+
defineProperty = Object.defineProperty || function (obj, key, desc) {
|
|
83
|
+
obj[key] = desc.value;
|
|
84
|
+
},
|
|
85
|
+
$Symbol = "function" == typeof Symbol ? Symbol : {},
|
|
86
|
+
iteratorSymbol = $Symbol.iterator || "@@iterator",
|
|
87
|
+
asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator",
|
|
88
|
+
toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
|
|
89
|
+
function define(obj, key, value) {
|
|
90
|
+
return Object.defineProperty(obj, key, {
|
|
91
|
+
value: value,
|
|
92
|
+
enumerable: !0,
|
|
93
|
+
configurable: !0,
|
|
94
|
+
writable: !0
|
|
95
|
+
}), obj[key];
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
define({}, "");
|
|
99
|
+
} catch (err) {
|
|
100
|
+
define = function (obj, key, value) {
|
|
101
|
+
return obj[key] = value;
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function wrap(innerFn, outerFn, self, tryLocsList) {
|
|
105
|
+
var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator,
|
|
106
|
+
generator = Object.create(protoGenerator.prototype),
|
|
107
|
+
context = new Context(tryLocsList || []);
|
|
108
|
+
return defineProperty(generator, "_invoke", {
|
|
109
|
+
value: makeInvokeMethod(innerFn, self, context)
|
|
110
|
+
}), generator;
|
|
111
|
+
}
|
|
112
|
+
function tryCatch(fn, obj, arg) {
|
|
113
|
+
try {
|
|
114
|
+
return {
|
|
115
|
+
type: "normal",
|
|
116
|
+
arg: fn.call(obj, arg)
|
|
117
|
+
};
|
|
118
|
+
} catch (err) {
|
|
119
|
+
return {
|
|
120
|
+
type: "throw",
|
|
121
|
+
arg: err
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
exports.wrap = wrap;
|
|
126
|
+
var ContinueSentinel = {};
|
|
127
|
+
function Generator() {}
|
|
128
|
+
function GeneratorFunction() {}
|
|
129
|
+
function GeneratorFunctionPrototype() {}
|
|
130
|
+
var IteratorPrototype = {};
|
|
131
|
+
define(IteratorPrototype, iteratorSymbol, function () {
|
|
132
|
+
return this;
|
|
133
|
+
});
|
|
134
|
+
var getProto = Object.getPrototypeOf,
|
|
135
|
+
NativeIteratorPrototype = getProto && getProto(getProto(values([])));
|
|
136
|
+
NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype);
|
|
137
|
+
var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype);
|
|
138
|
+
function defineIteratorMethods(prototype) {
|
|
139
|
+
["next", "throw", "return"].forEach(function (method) {
|
|
140
|
+
define(prototype, method, function (arg) {
|
|
141
|
+
return this._invoke(method, arg);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
function AsyncIterator(generator, PromiseImpl) {
|
|
146
|
+
function invoke(method, arg, resolve, reject) {
|
|
147
|
+
var record = tryCatch(generator[method], generator, arg);
|
|
148
|
+
if ("throw" !== record.type) {
|
|
149
|
+
var result = record.arg,
|
|
150
|
+
value = result.value;
|
|
151
|
+
return value && "object" == typeof value && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) {
|
|
152
|
+
invoke("next", value, resolve, reject);
|
|
153
|
+
}, function (err) {
|
|
154
|
+
invoke("throw", err, resolve, reject);
|
|
155
|
+
}) : PromiseImpl.resolve(value).then(function (unwrapped) {
|
|
156
|
+
result.value = unwrapped, resolve(result);
|
|
157
|
+
}, function (error) {
|
|
158
|
+
return invoke("throw", error, resolve, reject);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
reject(record.arg);
|
|
162
|
+
}
|
|
163
|
+
var previousPromise;
|
|
164
|
+
defineProperty(this, "_invoke", {
|
|
165
|
+
value: function (method, arg) {
|
|
166
|
+
function callInvokeWithMethodAndArg() {
|
|
167
|
+
return new PromiseImpl(function (resolve, reject) {
|
|
168
|
+
invoke(method, arg, resolve, reject);
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
function makeInvokeMethod(innerFn, self, context) {
|
|
176
|
+
var state = "suspendedStart";
|
|
177
|
+
return function (method, arg) {
|
|
178
|
+
if ("executing" === state) throw new Error("Generator is already running");
|
|
179
|
+
if ("completed" === state) {
|
|
180
|
+
if ("throw" === method) throw arg;
|
|
181
|
+
return doneResult();
|
|
182
|
+
}
|
|
183
|
+
for (context.method = method, context.arg = arg;;) {
|
|
184
|
+
var delegate = context.delegate;
|
|
185
|
+
if (delegate) {
|
|
186
|
+
var delegateResult = maybeInvokeDelegate(delegate, context);
|
|
187
|
+
if (delegateResult) {
|
|
188
|
+
if (delegateResult === ContinueSentinel) continue;
|
|
189
|
+
return delegateResult;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) {
|
|
193
|
+
if ("suspendedStart" === state) throw state = "completed", context.arg;
|
|
194
|
+
context.dispatchException(context.arg);
|
|
195
|
+
} else "return" === context.method && context.abrupt("return", context.arg);
|
|
196
|
+
state = "executing";
|
|
197
|
+
var record = tryCatch(innerFn, self, context);
|
|
198
|
+
if ("normal" === record.type) {
|
|
199
|
+
if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue;
|
|
200
|
+
return {
|
|
201
|
+
value: record.arg,
|
|
202
|
+
done: context.done
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
"throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg);
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
function maybeInvokeDelegate(delegate, context) {
|
|
210
|
+
var methodName = context.method,
|
|
211
|
+
method = delegate.iterator[methodName];
|
|
212
|
+
if (undefined === method) return context.delegate = null, "throw" === methodName && delegate.iterator.return && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method) || "return" !== methodName && (context.method = "throw", context.arg = new TypeError("The iterator does not provide a '" + methodName + "' method")), ContinueSentinel;
|
|
213
|
+
var record = tryCatch(method, delegate.iterator, context.arg);
|
|
214
|
+
if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel;
|
|
215
|
+
var info = record.arg;
|
|
216
|
+
return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel);
|
|
217
|
+
}
|
|
218
|
+
function pushTryEntry(locs) {
|
|
219
|
+
var entry = {
|
|
220
|
+
tryLoc: locs[0]
|
|
221
|
+
};
|
|
222
|
+
1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry);
|
|
223
|
+
}
|
|
224
|
+
function resetTryEntry(entry) {
|
|
225
|
+
var record = entry.completion || {};
|
|
226
|
+
record.type = "normal", delete record.arg, entry.completion = record;
|
|
227
|
+
}
|
|
228
|
+
function Context(tryLocsList) {
|
|
229
|
+
this.tryEntries = [{
|
|
230
|
+
tryLoc: "root"
|
|
231
|
+
}], tryLocsList.forEach(pushTryEntry, this), this.reset(!0);
|
|
232
|
+
}
|
|
233
|
+
function values(iterable) {
|
|
234
|
+
if (iterable) {
|
|
235
|
+
var iteratorMethod = iterable[iteratorSymbol];
|
|
236
|
+
if (iteratorMethod) return iteratorMethod.call(iterable);
|
|
237
|
+
if ("function" == typeof iterable.next) return iterable;
|
|
238
|
+
if (!isNaN(iterable.length)) {
|
|
239
|
+
var i = -1,
|
|
240
|
+
next = function next() {
|
|
241
|
+
for (; ++i < iterable.length;) if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next;
|
|
242
|
+
return next.value = undefined, next.done = !0, next;
|
|
243
|
+
};
|
|
244
|
+
return next.next = next;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return {
|
|
248
|
+
next: doneResult
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
function doneResult() {
|
|
252
|
+
return {
|
|
253
|
+
value: undefined,
|
|
254
|
+
done: !0
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
return GeneratorFunction.prototype = GeneratorFunctionPrototype, defineProperty(Gp, "constructor", {
|
|
258
|
+
value: GeneratorFunctionPrototype,
|
|
259
|
+
configurable: !0
|
|
260
|
+
}), defineProperty(GeneratorFunctionPrototype, "constructor", {
|
|
261
|
+
value: GeneratorFunction,
|
|
262
|
+
configurable: !0
|
|
263
|
+
}), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) {
|
|
264
|
+
var ctor = "function" == typeof genFun && genFun.constructor;
|
|
265
|
+
return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name));
|
|
266
|
+
}, exports.mark = function (genFun) {
|
|
267
|
+
return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun;
|
|
268
|
+
}, exports.awrap = function (arg) {
|
|
269
|
+
return {
|
|
270
|
+
__await: arg
|
|
271
|
+
};
|
|
272
|
+
}, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () {
|
|
273
|
+
return this;
|
|
274
|
+
}), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) {
|
|
275
|
+
void 0 === PromiseImpl && (PromiseImpl = Promise);
|
|
276
|
+
var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl);
|
|
277
|
+
return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) {
|
|
278
|
+
return result.done ? result.value : iter.next();
|
|
279
|
+
});
|
|
280
|
+
}, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () {
|
|
281
|
+
return this;
|
|
282
|
+
}), define(Gp, "toString", function () {
|
|
283
|
+
return "[object Generator]";
|
|
284
|
+
}), exports.keys = function (val) {
|
|
285
|
+
var object = Object(val),
|
|
286
|
+
keys = [];
|
|
287
|
+
for (var key in object) keys.push(key);
|
|
288
|
+
return keys.reverse(), function next() {
|
|
289
|
+
for (; keys.length;) {
|
|
290
|
+
var key = keys.pop();
|
|
291
|
+
if (key in object) return next.value = key, next.done = !1, next;
|
|
292
|
+
}
|
|
293
|
+
return next.done = !0, next;
|
|
294
|
+
};
|
|
295
|
+
}, exports.values = values, Context.prototype = {
|
|
296
|
+
constructor: Context,
|
|
297
|
+
reset: function (skipTempReset) {
|
|
298
|
+
if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined);
|
|
299
|
+
},
|
|
300
|
+
stop: function () {
|
|
301
|
+
this.done = !0;
|
|
302
|
+
var rootRecord = this.tryEntries[0].completion;
|
|
303
|
+
if ("throw" === rootRecord.type) throw rootRecord.arg;
|
|
304
|
+
return this.rval;
|
|
305
|
+
},
|
|
306
|
+
dispatchException: function (exception) {
|
|
307
|
+
if (this.done) throw exception;
|
|
308
|
+
var context = this;
|
|
309
|
+
function handle(loc, caught) {
|
|
310
|
+
return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught;
|
|
311
|
+
}
|
|
312
|
+
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
|
|
313
|
+
var entry = this.tryEntries[i],
|
|
314
|
+
record = entry.completion;
|
|
315
|
+
if ("root" === entry.tryLoc) return handle("end");
|
|
316
|
+
if (entry.tryLoc <= this.prev) {
|
|
317
|
+
var hasCatch = hasOwn.call(entry, "catchLoc"),
|
|
318
|
+
hasFinally = hasOwn.call(entry, "finallyLoc");
|
|
319
|
+
if (hasCatch && hasFinally) {
|
|
320
|
+
if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
|
|
321
|
+
if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
|
|
322
|
+
} else if (hasCatch) {
|
|
323
|
+
if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
|
|
324
|
+
} else {
|
|
325
|
+
if (!hasFinally) throw new Error("try statement without catch or finally");
|
|
326
|
+
if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
},
|
|
331
|
+
abrupt: function (type, arg) {
|
|
332
|
+
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
|
|
333
|
+
var entry = this.tryEntries[i];
|
|
334
|
+
if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) {
|
|
335
|
+
var finallyEntry = entry;
|
|
336
|
+
break;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null);
|
|
340
|
+
var record = finallyEntry ? finallyEntry.completion : {};
|
|
341
|
+
return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record);
|
|
342
|
+
},
|
|
343
|
+
complete: function (record, afterLoc) {
|
|
344
|
+
if ("throw" === record.type) throw record.arg;
|
|
345
|
+
return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel;
|
|
346
|
+
},
|
|
347
|
+
finish: function (finallyLoc) {
|
|
348
|
+
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
|
|
349
|
+
var entry = this.tryEntries[i];
|
|
350
|
+
if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel;
|
|
351
|
+
}
|
|
352
|
+
},
|
|
353
|
+
catch: function (tryLoc) {
|
|
354
|
+
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
|
|
355
|
+
var entry = this.tryEntries[i];
|
|
356
|
+
if (entry.tryLoc === tryLoc) {
|
|
357
|
+
var record = entry.completion;
|
|
358
|
+
if ("throw" === record.type) {
|
|
359
|
+
var thrown = record.arg;
|
|
360
|
+
resetTryEntry(entry);
|
|
361
|
+
}
|
|
362
|
+
return thrown;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
throw new Error("illegal catch attempt");
|
|
366
|
+
},
|
|
367
|
+
delegateYield: function (iterable, resultName, nextLoc) {
|
|
368
|
+
return this.delegate = {
|
|
369
|
+
iterator: values(iterable),
|
|
370
|
+
resultName: resultName,
|
|
371
|
+
nextLoc: nextLoc
|
|
372
|
+
}, "next" === this.method && (this.arg = undefined), ContinueSentinel;
|
|
373
|
+
}
|
|
374
|
+
}, exports;
|
|
375
|
+
}
|
|
376
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
377
|
+
try {
|
|
378
|
+
var info = gen[key](arg);
|
|
379
|
+
var value = info.value;
|
|
380
|
+
} catch (error) {
|
|
381
|
+
reject(error);
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
if (info.done) {
|
|
385
|
+
resolve(value);
|
|
386
|
+
} else {
|
|
387
|
+
Promise.resolve(value).then(_next, _throw);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
function _asyncToGenerator(fn) {
|
|
391
|
+
return function () {
|
|
392
|
+
var self = this,
|
|
393
|
+
args = arguments;
|
|
394
|
+
return new Promise(function (resolve, reject) {
|
|
395
|
+
var gen = fn.apply(self, args);
|
|
396
|
+
function _next(value) {
|
|
397
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
|
|
398
|
+
}
|
|
399
|
+
function _throw(err) {
|
|
400
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
|
|
401
|
+
}
|
|
402
|
+
_next(undefined);
|
|
403
|
+
});
|
|
404
|
+
};
|
|
405
|
+
}
|
|
70
406
|
function _classCallCheck(instance, Constructor) {
|
|
71
407
|
if (!(instance instanceof Constructor)) {
|
|
72
408
|
throw new TypeError("Cannot call a class as a function");
|
|
@@ -203,22 +539,71 @@ function _toPropertyKey(arg) {
|
|
|
203
539
|
return typeof key === "symbol" ? key : String(key);
|
|
204
540
|
}
|
|
205
541
|
|
|
206
|
-
var toArray = function
|
|
207
|
-
|
|
542
|
+
var toArray = function (x) { return (Array.isArray(x) ? x : [x]); };
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Returns a function that checks if a given content item's ConceptNameCodeSequence.CodeMeaning
|
|
546
|
+
* matches the provided codeMeaningName.
|
|
547
|
+
* @param codeMeaningName - The CodeMeaning to match against.
|
|
548
|
+
* @returns A function that takes a content item and returns a boolean indicating whether the
|
|
549
|
+
* content item's CodeMeaning matches the provided codeMeaningName.
|
|
550
|
+
*/
|
|
551
|
+
var codeMeaningEquals = function (codeMeaningName) {
|
|
552
|
+
return function (contentItem) {
|
|
553
|
+
return (contentItem.ConceptNameCodeSequence.CodeMeaning === codeMeaningName);
|
|
554
|
+
};
|
|
208
555
|
};
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Checks if a given content item's GraphicType property matches a specified value.
|
|
559
|
+
* @param {string} graphicType - The value to compare the content item's GraphicType property to.
|
|
560
|
+
* @returns {function} A function that takes a content item and returns a boolean indicating whether its GraphicType property matches the specified value.
|
|
561
|
+
*/
|
|
562
|
+
var graphicTypeEquals = function (graphicType) {
|
|
563
|
+
return function (contentItem) {
|
|
564
|
+
return contentItem && contentItem.GraphicType === graphicType;
|
|
565
|
+
};
|
|
213
566
|
};
|
|
214
567
|
|
|
568
|
+
var datasetToDict = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.datasetToDict;
|
|
569
|
+
/**
|
|
570
|
+
* Trigger file download from an array buffer
|
|
571
|
+
* @param bufferOrDataset - ArrayBuffer or DicomDataset
|
|
572
|
+
* @param filename - name of the file to download
|
|
573
|
+
*/
|
|
574
|
+
function downloadDICOMData(bufferOrDataset, filename) {
|
|
575
|
+
var blob;
|
|
576
|
+
if (bufferOrDataset instanceof ArrayBuffer) {
|
|
577
|
+
blob = new Blob([bufferOrDataset], { type: "application/dicom" });
|
|
578
|
+
}
|
|
579
|
+
else {
|
|
580
|
+
if (!bufferOrDataset._meta) {
|
|
581
|
+
throw new Error("Dataset must have a _meta property");
|
|
582
|
+
}
|
|
583
|
+
var buffer = buffer__WEBPACK_IMPORTED_MODULE_1__/* .Buffer */ .lW.from(datasetToDict(bufferOrDataset).write());
|
|
584
|
+
blob = new Blob([buffer], { type: "application/dicom" });
|
|
585
|
+
}
|
|
586
|
+
var link = document.createElement("a");
|
|
587
|
+
link.href = window.URL.createObjectURL(blob);
|
|
588
|
+
link.download = filename;
|
|
589
|
+
link.click();
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
var index$1 = /*#__PURE__*/Object.freeze({
|
|
593
|
+
__proto__: null,
|
|
594
|
+
codeMeaningEquals: codeMeaningEquals,
|
|
595
|
+
downloadDICOMData: downloadDICOMData,
|
|
596
|
+
graphicTypeEquals: graphicTypeEquals,
|
|
597
|
+
toArray: toArray
|
|
598
|
+
});
|
|
599
|
+
|
|
215
600
|
var TID1500$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.TID1500,
|
|
216
601
|
addAccessors$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.addAccessors;
|
|
217
602
|
var StructuredReport$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .derivations */ .U7.StructuredReport;
|
|
218
|
-
var Normalizer$
|
|
603
|
+
var Normalizer$4 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .normalizers */ .oq.Normalizer;
|
|
219
604
|
var TID1500MeasurementReport$1 = TID1500$1.TID1500MeasurementReport,
|
|
220
605
|
TID1501MeasurementGroup$1 = TID1500$1.TID1501MeasurementGroup;
|
|
221
|
-
var DicomMetaDictionary$
|
|
606
|
+
var DicomMetaDictionary$4 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.DicomMetaDictionary;
|
|
222
607
|
var FINDING$2 = {
|
|
223
608
|
CodingSchemeDesignator: "DCM",
|
|
224
609
|
CodeValue: "121071"
|
|
@@ -347,7 +732,7 @@ var MeasurementReport$1 = /*#__PURE__*/function () {
|
|
|
347
732
|
ReferencedSOPClassUID: sopCommonModule.sopClassUID,
|
|
348
733
|
ReferencedSOPInstanceUID: sopCommonModule.sopInstanceUID
|
|
349
734
|
};
|
|
350
|
-
if (Normalizer$
|
|
735
|
+
if (Normalizer$4.isMultiframeSOPClassUID(sopCommonModule.sopClassUID)) {
|
|
351
736
|
ReferencedSOPSequence.ReferencedFrameNumber = frameNumber;
|
|
352
737
|
}
|
|
353
738
|
|
|
@@ -389,7 +774,7 @@ var MeasurementReport$1 = /*#__PURE__*/function () {
|
|
|
389
774
|
vr: "UI"
|
|
390
775
|
},
|
|
391
776
|
ImplementationClassUID: {
|
|
392
|
-
Value: [DicomMetaDictionary$
|
|
777
|
+
Value: [DicomMetaDictionary$4.uid()],
|
|
393
778
|
// TODO: could be git hash or other valid id
|
|
394
779
|
vr: "UI"
|
|
395
780
|
},
|
|
@@ -1181,80 +1566,353 @@ ArrowAnnotate$1.isValidCornerstoneTrackingIdentifier = function (TrackingIdentif
|
|
|
1181
1566
|
};
|
|
1182
1567
|
MeasurementReport$1.registerTool(ArrowAnnotate$1);
|
|
1183
1568
|
|
|
1184
|
-
var
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
var datasetToBlob$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.datasetToBlob,
|
|
1190
|
-
BitArray$2 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.BitArray,
|
|
1191
|
-
DicomMessage$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.DicomMessage,
|
|
1192
|
-
DicomMetaDictionary$2 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.DicomMetaDictionary;
|
|
1193
|
-
var Normalizer$2 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .normalizers */ .oq.Normalizer;
|
|
1194
|
-
var SegmentationDerivation$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .derivations */ .U7.Segmentation;
|
|
1195
|
-
var Segmentation$3 = {
|
|
1196
|
-
generateSegmentation: generateSegmentation$2,
|
|
1197
|
-
generateToolState: generateToolState$2
|
|
1198
|
-
};
|
|
1199
|
-
|
|
1200
|
-
/**
|
|
1201
|
-
*
|
|
1202
|
-
* @typedef {Object} BrushData
|
|
1203
|
-
* @property {Object} toolState - The cornerstoneTools global toolState.
|
|
1204
|
-
* @property {Object[]} segments - The cornerstoneTools segment metadata that corresponds to the
|
|
1205
|
-
* seriesInstanceUid.
|
|
1206
|
-
*/
|
|
1207
|
-
|
|
1208
|
-
/**
|
|
1209
|
-
* generateSegmentation - Generates cornerstoneTools brush data, given a stack of
|
|
1210
|
-
* imageIds, images and the cornerstoneTools brushData.
|
|
1211
|
-
*
|
|
1212
|
-
* @param {object[]} images An array of the cornerstone image objects.
|
|
1213
|
-
* @param {BrushData} brushData and object containing the brushData.
|
|
1214
|
-
* @returns {type} description
|
|
1215
|
-
*/
|
|
1216
|
-
function generateSegmentation$2(images, brushData) {
|
|
1217
|
-
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
|
|
1218
|
-
includeSliceSpacing: true
|
|
1219
|
-
};
|
|
1220
|
-
var toolState = brushData.toolState,
|
|
1221
|
-
segments = brushData.segments;
|
|
1222
|
-
|
|
1223
|
-
// Calculate the dimensions of the data cube.
|
|
1224
|
-
var image0 = images[0];
|
|
1225
|
-
var dims = {
|
|
1226
|
-
x: image0.columns,
|
|
1227
|
-
y: image0.rows,
|
|
1228
|
-
z: images.length
|
|
1229
|
-
};
|
|
1230
|
-
dims.xy = dims.x * dims.y;
|
|
1231
|
-
var numSegments = _getSegCount(seg, segments);
|
|
1232
|
-
if (!numSegments) {
|
|
1233
|
-
throw new Error("No segments to export!");
|
|
1569
|
+
var TID300CobbAngle$2 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.TID300.CobbAngle;
|
|
1570
|
+
var COBB_ANGLE = "CobbAngle";
|
|
1571
|
+
var CobbAngle$1 = /*#__PURE__*/function () {
|
|
1572
|
+
function CobbAngle() {
|
|
1573
|
+
_classCallCheck(this, CobbAngle);
|
|
1234
1574
|
}
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1575
|
+
_createClass(CobbAngle, null, [{
|
|
1576
|
+
key: "getMeasurementData",
|
|
1577
|
+
value:
|
|
1578
|
+
// TODO: this function is required for all Cornerstone Tool Adapters, since it is called by MeasurementReport.
|
|
1579
|
+
function getMeasurementData(MeasurementGroup) {
|
|
1580
|
+
var _MeasurementReport$ge = MeasurementReport$1.getSetupMeasurementData(MeasurementGroup),
|
|
1581
|
+
defaultState = _MeasurementReport$ge.defaultState,
|
|
1582
|
+
NUMGroup = _MeasurementReport$ge.NUMGroup,
|
|
1583
|
+
SCOORDGroup = _MeasurementReport$ge.SCOORDGroup;
|
|
1584
|
+
var state = _objectSpread2(_objectSpread2({}, defaultState), {}, {
|
|
1585
|
+
rAngle: NUMGroup.MeasuredValueSequence.NumericValue,
|
|
1586
|
+
toolType: CobbAngle.toolType,
|
|
1587
|
+
handles: {
|
|
1588
|
+
start: {},
|
|
1589
|
+
end: {},
|
|
1590
|
+
start2: {
|
|
1591
|
+
highlight: true,
|
|
1592
|
+
drawnIndependently: true
|
|
1593
|
+
},
|
|
1594
|
+
end2: {
|
|
1595
|
+
highlight: true,
|
|
1596
|
+
drawnIndependently: true
|
|
1597
|
+
},
|
|
1598
|
+
textBox: {
|
|
1599
|
+
hasMoved: false,
|
|
1600
|
+
movesIndependently: false,
|
|
1601
|
+
drawnIndependently: true,
|
|
1602
|
+
allowedOutsideImage: true,
|
|
1603
|
+
hasBoundingBox: true
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
});
|
|
1607
|
+
var _SCOORDGroup$GraphicD = _slicedToArray(SCOORDGroup.GraphicData, 8);
|
|
1608
|
+
state.handles.start.x = _SCOORDGroup$GraphicD[0];
|
|
1609
|
+
state.handles.start.y = _SCOORDGroup$GraphicD[1];
|
|
1610
|
+
state.handles.end.x = _SCOORDGroup$GraphicD[2];
|
|
1611
|
+
state.handles.end.y = _SCOORDGroup$GraphicD[3];
|
|
1612
|
+
state.handles.start2.x = _SCOORDGroup$GraphicD[4];
|
|
1613
|
+
state.handles.start2.y = _SCOORDGroup$GraphicD[5];
|
|
1614
|
+
state.handles.end2.x = _SCOORDGroup$GraphicD[6];
|
|
1615
|
+
state.handles.end2.y = _SCOORDGroup$GraphicD[7];
|
|
1616
|
+
return state;
|
|
1617
|
+
}
|
|
1618
|
+
}, {
|
|
1619
|
+
key: "getTID300RepresentationArguments",
|
|
1620
|
+
value: function getTID300RepresentationArguments(tool) {
|
|
1621
|
+
var handles = tool.handles,
|
|
1622
|
+
finding = tool.finding,
|
|
1623
|
+
findingSites = tool.findingSites;
|
|
1624
|
+
var point1 = handles.start;
|
|
1625
|
+
var point2 = handles.end;
|
|
1626
|
+
var point3 = handles.start2;
|
|
1627
|
+
var point4 = handles.end2;
|
|
1628
|
+
var rAngle = tool.rAngle;
|
|
1629
|
+
var trackingIdentifierTextValue = "cornerstoneTools@^4.0.0:CobbAngle";
|
|
1630
|
+
return {
|
|
1631
|
+
point1: point1,
|
|
1632
|
+
point2: point2,
|
|
1633
|
+
point3: point3,
|
|
1634
|
+
point4: point4,
|
|
1635
|
+
rAngle: rAngle,
|
|
1636
|
+
trackingIdentifierTextValue: trackingIdentifierTextValue,
|
|
1637
|
+
finding: finding,
|
|
1638
|
+
findingSites: findingSites || []
|
|
1639
|
+
};
|
|
1640
|
+
}
|
|
1641
|
+
}]);
|
|
1642
|
+
return CobbAngle;
|
|
1643
|
+
}();
|
|
1644
|
+
CobbAngle$1.toolType = COBB_ANGLE;
|
|
1645
|
+
CobbAngle$1.utilityToolType = COBB_ANGLE;
|
|
1646
|
+
CobbAngle$1.TID300Representation = TID300CobbAngle$2;
|
|
1647
|
+
CobbAngle$1.isValidCornerstoneTrackingIdentifier = function (TrackingIdentifier) {
|
|
1648
|
+
if (!TrackingIdentifier.includes(":")) {
|
|
1649
|
+
return false;
|
|
1243
1650
|
}
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
var referencedFrameNumbers = referencedFrameIndicies.map(function (element) {
|
|
1251
|
-
return element + 1;
|
|
1252
|
-
});
|
|
1253
|
-
var segment = segments[segmentIndex];
|
|
1254
|
-
seg.addSegment(segment, _extractCornerstoneToolsPixelData(segmentIndex, referencedFrameIndicies, toolState, images, dims), referencedFrameNumbers);
|
|
1651
|
+
var _TrackingIdentifier$s = TrackingIdentifier.split(":"),
|
|
1652
|
+
_TrackingIdentifier$s2 = _slicedToArray(_TrackingIdentifier$s, 2),
|
|
1653
|
+
cornerstone4Tag = _TrackingIdentifier$s2[0],
|
|
1654
|
+
toolType = _TrackingIdentifier$s2[1];
|
|
1655
|
+
if (cornerstone4Tag !== CORNERSTONE_4_TAG) {
|
|
1656
|
+
return false;
|
|
1255
1657
|
}
|
|
1256
|
-
|
|
1257
|
-
|
|
1658
|
+
return toolType === COBB_ANGLE;
|
|
1659
|
+
};
|
|
1660
|
+
MeasurementReport$1.registerTool(CobbAngle$1);
|
|
1661
|
+
|
|
1662
|
+
var TID300Angle = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.TID300.Angle;
|
|
1663
|
+
var ANGLE = "Angle";
|
|
1664
|
+
var Angle$1 = /*#__PURE__*/function () {
|
|
1665
|
+
function Angle() {
|
|
1666
|
+
_classCallCheck(this, Angle);
|
|
1667
|
+
}
|
|
1668
|
+
_createClass(Angle, null, [{
|
|
1669
|
+
key: "getMeasurementData",
|
|
1670
|
+
value:
|
|
1671
|
+
/**
|
|
1672
|
+
* Generate TID300 measurement data for a plane angle measurement - use a Angle, but label it as Angle
|
|
1673
|
+
*/
|
|
1674
|
+
function getMeasurementData(MeasurementGroup) {
|
|
1675
|
+
var _MeasurementReport$ge = MeasurementReport$1.getSetupMeasurementData(MeasurementGroup),
|
|
1676
|
+
defaultState = _MeasurementReport$ge.defaultState,
|
|
1677
|
+
NUMGroup = _MeasurementReport$ge.NUMGroup,
|
|
1678
|
+
SCOORDGroup = _MeasurementReport$ge.SCOORDGroup;
|
|
1679
|
+
var state = _objectSpread2(_objectSpread2({}, defaultState), {}, {
|
|
1680
|
+
rAngle: NUMGroup.MeasuredValueSequence.NumericValue,
|
|
1681
|
+
toolType: Angle.toolType,
|
|
1682
|
+
handles: {
|
|
1683
|
+
start: {},
|
|
1684
|
+
middle: {},
|
|
1685
|
+
end: {},
|
|
1686
|
+
textBox: {
|
|
1687
|
+
hasMoved: false,
|
|
1688
|
+
movesIndependently: false,
|
|
1689
|
+
drawnIndependently: true,
|
|
1690
|
+
allowedOutsideImage: true,
|
|
1691
|
+
hasBoundingBox: true
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1694
|
+
});
|
|
1695
|
+
var _SCOORDGroup$GraphicD = _slicedToArray(SCOORDGroup.GraphicData, 8);
|
|
1696
|
+
state.handles.start.x = _SCOORDGroup$GraphicD[0];
|
|
1697
|
+
state.handles.start.y = _SCOORDGroup$GraphicD[1];
|
|
1698
|
+
state.handles.middle.x = _SCOORDGroup$GraphicD[2];
|
|
1699
|
+
state.handles.middle.y = _SCOORDGroup$GraphicD[3];
|
|
1700
|
+
state.handles.middle.x = _SCOORDGroup$GraphicD[4];
|
|
1701
|
+
state.handles.middle.y = _SCOORDGroup$GraphicD[5];
|
|
1702
|
+
state.handles.end.x = _SCOORDGroup$GraphicD[6];
|
|
1703
|
+
state.handles.end.y = _SCOORDGroup$GraphicD[7];
|
|
1704
|
+
return state;
|
|
1705
|
+
}
|
|
1706
|
+
}, {
|
|
1707
|
+
key: "getTID300RepresentationArguments",
|
|
1708
|
+
value: function getTID300RepresentationArguments(tool) {
|
|
1709
|
+
var handles = tool.handles,
|
|
1710
|
+
finding = tool.finding,
|
|
1711
|
+
findingSites = tool.findingSites;
|
|
1712
|
+
var point1 = handles.start;
|
|
1713
|
+
var point2 = handles.middle;
|
|
1714
|
+
var point3 = handles.middle;
|
|
1715
|
+
var point4 = handles.end;
|
|
1716
|
+
var rAngle = tool.rAngle;
|
|
1717
|
+
var trackingIdentifierTextValue = "cornerstoneTools@^4.0.0:Angle";
|
|
1718
|
+
return {
|
|
1719
|
+
point1: point1,
|
|
1720
|
+
point2: point2,
|
|
1721
|
+
point3: point3,
|
|
1722
|
+
point4: point4,
|
|
1723
|
+
rAngle: rAngle,
|
|
1724
|
+
trackingIdentifierTextValue: trackingIdentifierTextValue,
|
|
1725
|
+
finding: finding,
|
|
1726
|
+
findingSites: findingSites || []
|
|
1727
|
+
};
|
|
1728
|
+
}
|
|
1729
|
+
}]);
|
|
1730
|
+
return Angle;
|
|
1731
|
+
}();
|
|
1732
|
+
Angle$1.toolType = ANGLE;
|
|
1733
|
+
Angle$1.utilityToolType = ANGLE;
|
|
1734
|
+
Angle$1.TID300Representation = TID300Angle;
|
|
1735
|
+
Angle$1.isValidCornerstoneTrackingIdentifier = function (TrackingIdentifier) {
|
|
1736
|
+
if (!TrackingIdentifier.includes(":")) {
|
|
1737
|
+
return false;
|
|
1738
|
+
}
|
|
1739
|
+
var _TrackingIdentifier$s = TrackingIdentifier.split(":"),
|
|
1740
|
+
_TrackingIdentifier$s2 = _slicedToArray(_TrackingIdentifier$s, 2),
|
|
1741
|
+
cornerstone4Tag = _TrackingIdentifier$s2[0],
|
|
1742
|
+
toolType = _TrackingIdentifier$s2[1];
|
|
1743
|
+
if (cornerstone4Tag !== CORNERSTONE_4_TAG) {
|
|
1744
|
+
return false;
|
|
1745
|
+
}
|
|
1746
|
+
return toolType === ANGLE;
|
|
1747
|
+
};
|
|
1748
|
+
MeasurementReport$1.registerTool(Angle$1);
|
|
1749
|
+
|
|
1750
|
+
var TID300Polyline$2 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.TID300.Polyline;
|
|
1751
|
+
var RectangleRoi = /*#__PURE__*/function () {
|
|
1752
|
+
function RectangleRoi() {
|
|
1753
|
+
_classCallCheck(this, RectangleRoi);
|
|
1754
|
+
}
|
|
1755
|
+
_createClass(RectangleRoi, null, [{
|
|
1756
|
+
key: "getMeasurementData",
|
|
1757
|
+
value: function getMeasurementData(MeasurementGroup) {
|
|
1758
|
+
var _MeasurementReport$ge = MeasurementReport$1.getSetupMeasurementData(MeasurementGroup),
|
|
1759
|
+
defaultState = _MeasurementReport$ge.defaultState,
|
|
1760
|
+
SCOORDGroup = _MeasurementReport$ge.SCOORDGroup,
|
|
1761
|
+
NUMGroup = _MeasurementReport$ge.NUMGroup;
|
|
1762
|
+
var state = _objectSpread2(_objectSpread2({}, defaultState), {}, {
|
|
1763
|
+
toolType: RectangleRoi.toolType,
|
|
1764
|
+
handles: {
|
|
1765
|
+
start: {},
|
|
1766
|
+
end: {},
|
|
1767
|
+
textBox: {
|
|
1768
|
+
active: false,
|
|
1769
|
+
hasMoved: false,
|
|
1770
|
+
movesIndependently: false,
|
|
1771
|
+
drawnIndependently: true,
|
|
1772
|
+
allowedOutsideImage: true,
|
|
1773
|
+
hasBoundingBox: true
|
|
1774
|
+
},
|
|
1775
|
+
initialRotation: 0
|
|
1776
|
+
},
|
|
1777
|
+
cachedStats: {
|
|
1778
|
+
area: NUMGroup ? NUMGroup.MeasuredValueSequence.NumericValue : 0
|
|
1779
|
+
},
|
|
1780
|
+
color: undefined,
|
|
1781
|
+
invalidated: true
|
|
1782
|
+
});
|
|
1783
|
+
var _SCOORDGroup$GraphicD = _slicedToArray(SCOORDGroup.GraphicData, 6);
|
|
1784
|
+
state.handles.start.x = _SCOORDGroup$GraphicD[0];
|
|
1785
|
+
state.handles.start.y = _SCOORDGroup$GraphicD[1];
|
|
1786
|
+
_SCOORDGroup$GraphicD[2];
|
|
1787
|
+
_SCOORDGroup$GraphicD[3];
|
|
1788
|
+
state.handles.end.x = _SCOORDGroup$GraphicD[4];
|
|
1789
|
+
state.handles.end.y = _SCOORDGroup$GraphicD[5];
|
|
1790
|
+
return state;
|
|
1791
|
+
}
|
|
1792
|
+
}, {
|
|
1793
|
+
key: "getTID300RepresentationArguments",
|
|
1794
|
+
value: function getTID300RepresentationArguments(tool) {
|
|
1795
|
+
var finding = tool.finding,
|
|
1796
|
+
findingSites = tool.findingSites,
|
|
1797
|
+
_tool$cachedStats = tool.cachedStats,
|
|
1798
|
+
cachedStats = _tool$cachedStats === void 0 ? {} : _tool$cachedStats,
|
|
1799
|
+
handles = tool.handles;
|
|
1800
|
+
var start = handles.start,
|
|
1801
|
+
end = handles.end;
|
|
1802
|
+
var points = [start, {
|
|
1803
|
+
x: start.x,
|
|
1804
|
+
y: end.y
|
|
1805
|
+
}, end, {
|
|
1806
|
+
x: end.x,
|
|
1807
|
+
y: start.y
|
|
1808
|
+
}];
|
|
1809
|
+
var area = cachedStats.area,
|
|
1810
|
+
perimeter = cachedStats.perimeter;
|
|
1811
|
+
var trackingIdentifierTextValue = "cornerstoneTools@^4.0.0:RectangleRoi";
|
|
1812
|
+
return {
|
|
1813
|
+
points: points,
|
|
1814
|
+
area: area,
|
|
1815
|
+
perimeter: perimeter,
|
|
1816
|
+
trackingIdentifierTextValue: trackingIdentifierTextValue,
|
|
1817
|
+
finding: finding,
|
|
1818
|
+
findingSites: findingSites || []
|
|
1819
|
+
};
|
|
1820
|
+
}
|
|
1821
|
+
}]);
|
|
1822
|
+
return RectangleRoi;
|
|
1823
|
+
}();
|
|
1824
|
+
RectangleRoi.toolType = "RectangleRoi";
|
|
1825
|
+
RectangleRoi.utilityToolType = "RectangleRoi";
|
|
1826
|
+
RectangleRoi.TID300Representation = TID300Polyline$2;
|
|
1827
|
+
RectangleRoi.isValidCornerstoneTrackingIdentifier = function (TrackingIdentifier) {
|
|
1828
|
+
if (!TrackingIdentifier.includes(":")) {
|
|
1829
|
+
return false;
|
|
1830
|
+
}
|
|
1831
|
+
var _TrackingIdentifier$s = TrackingIdentifier.split(":"),
|
|
1832
|
+
_TrackingIdentifier$s2 = _slicedToArray(_TrackingIdentifier$s, 2),
|
|
1833
|
+
cornerstone4Tag = _TrackingIdentifier$s2[0],
|
|
1834
|
+
toolType = _TrackingIdentifier$s2[1];
|
|
1835
|
+
if (cornerstone4Tag !== CORNERSTONE_4_TAG) {
|
|
1836
|
+
return false;
|
|
1837
|
+
}
|
|
1838
|
+
return toolType === RectangleRoi.toolType;
|
|
1839
|
+
};
|
|
1840
|
+
MeasurementReport$1.registerTool(RectangleRoi);
|
|
1841
|
+
|
|
1842
|
+
var _utilities$orientatio$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.orientation,
|
|
1843
|
+
rotateDirectionCosinesInPlane$1 = _utilities$orientatio$1.rotateDirectionCosinesInPlane,
|
|
1844
|
+
flipIOP$1 = _utilities$orientatio$1.flipImageOrientationPatient,
|
|
1845
|
+
flipMatrix2D$1 = _utilities$orientatio$1.flipMatrix2D,
|
|
1846
|
+
rotateMatrix902D$1 = _utilities$orientatio$1.rotateMatrix902D;
|
|
1847
|
+
var datasetToBlob = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.datasetToBlob,
|
|
1848
|
+
BitArray$2 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.BitArray,
|
|
1849
|
+
DicomMessage$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.DicomMessage,
|
|
1850
|
+
DicomMetaDictionary$3 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.DicomMetaDictionary;
|
|
1851
|
+
var Normalizer$3 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .normalizers */ .oq.Normalizer;
|
|
1852
|
+
var SegmentationDerivation$2 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .derivations */ .U7.Segmentation;
|
|
1853
|
+
var Segmentation$5 = {
|
|
1854
|
+
generateSegmentation: generateSegmentation$3,
|
|
1855
|
+
generateToolState: generateToolState$3
|
|
1856
|
+
};
|
|
1857
|
+
|
|
1858
|
+
/**
|
|
1859
|
+
*
|
|
1860
|
+
* @typedef {Object} BrushData
|
|
1861
|
+
* @property {Object} toolState - The cornerstoneTools global toolState.
|
|
1862
|
+
* @property {Object[]} segments - The cornerstoneTools segment metadata that corresponds to the
|
|
1863
|
+
* seriesInstanceUid.
|
|
1864
|
+
*/
|
|
1865
|
+
|
|
1866
|
+
/**
|
|
1867
|
+
* generateSegmentation - Generates cornerstoneTools brush data, given a stack of
|
|
1868
|
+
* imageIds, images and the cornerstoneTools brushData.
|
|
1869
|
+
*
|
|
1870
|
+
* @param {object[]} images An array of the cornerstone image objects.
|
|
1871
|
+
* @param {BrushData} brushData and object containing the brushData.
|
|
1872
|
+
* @returns {type} description
|
|
1873
|
+
*/
|
|
1874
|
+
function generateSegmentation$3(images, brushData) {
|
|
1875
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
|
|
1876
|
+
includeSliceSpacing: true
|
|
1877
|
+
};
|
|
1878
|
+
var toolState = brushData.toolState,
|
|
1879
|
+
segments = brushData.segments;
|
|
1880
|
+
|
|
1881
|
+
// Calculate the dimensions of the data cube.
|
|
1882
|
+
var image0 = images[0];
|
|
1883
|
+
var dims = {
|
|
1884
|
+
x: image0.columns,
|
|
1885
|
+
y: image0.rows,
|
|
1886
|
+
z: images.length
|
|
1887
|
+
};
|
|
1888
|
+
dims.xy = dims.x * dims.y;
|
|
1889
|
+
var numSegments = _getSegCount(seg, segments);
|
|
1890
|
+
if (!numSegments) {
|
|
1891
|
+
throw new Error("No segments to export!");
|
|
1892
|
+
}
|
|
1893
|
+
var isMultiframe = image0.imageId.includes("?frame");
|
|
1894
|
+
var seg = _createSegFromImages$1(images, isMultiframe, options);
|
|
1895
|
+
var _getNumberOfFramesPer = _getNumberOfFramesPerSegment(toolState, images, segments),
|
|
1896
|
+
referencedFramesPerSegment = _getNumberOfFramesPer.referencedFramesPerSegment,
|
|
1897
|
+
segmentIndicies = _getNumberOfFramesPer.segmentIndicies;
|
|
1898
|
+
var NumberOfFrames = 0;
|
|
1899
|
+
for (var i = 0; i < referencedFramesPerSegment.length; i++) {
|
|
1900
|
+
NumberOfFrames += referencedFramesPerSegment[i].length;
|
|
1901
|
+
}
|
|
1902
|
+
seg.setNumberOfFrames(NumberOfFrames);
|
|
1903
|
+
for (var _i = 0; _i < segmentIndicies.length; _i++) {
|
|
1904
|
+
var segmentIndex = segmentIndicies[_i];
|
|
1905
|
+
var referencedFrameIndicies = referencedFramesPerSegment[_i];
|
|
1906
|
+
|
|
1907
|
+
// Frame numbers start from 1.
|
|
1908
|
+
var referencedFrameNumbers = referencedFrameIndicies.map(function (element) {
|
|
1909
|
+
return element + 1;
|
|
1910
|
+
});
|
|
1911
|
+
var segment = segments[segmentIndex];
|
|
1912
|
+
seg.addSegment(segment, _extractCornerstoneToolsPixelData(segmentIndex, referencedFrameIndicies, toolState, images, dims), referencedFrameNumbers);
|
|
1913
|
+
}
|
|
1914
|
+
seg.bitPackPixelData();
|
|
1915
|
+
var segBlob = datasetToBlob(seg.dataset);
|
|
1258
1916
|
return segBlob;
|
|
1259
1917
|
}
|
|
1260
1918
|
function _extractCornerstoneToolsPixelData(segmentIndex, referencedFrames, toolState, images, dims) {
|
|
@@ -1319,21 +1977,21 @@ function _createSegFromImages$1(images, isMultiframe, options) {
|
|
|
1319
1977
|
var image = images[0];
|
|
1320
1978
|
var arrayBuffer = image.data.byteArray.buffer;
|
|
1321
1979
|
var dicomData = DicomMessage$1.readFile(arrayBuffer);
|
|
1322
|
-
var dataset = DicomMetaDictionary$
|
|
1323
|
-
dataset._meta = DicomMetaDictionary$
|
|
1980
|
+
var dataset = DicomMetaDictionary$3.naturalizeDataset(dicomData.dict);
|
|
1981
|
+
dataset._meta = DicomMetaDictionary$3.namifyDataset(dicomData.meta);
|
|
1324
1982
|
datasets.push(dataset);
|
|
1325
1983
|
} else {
|
|
1326
1984
|
for (var i = 0; i < images.length; i++) {
|
|
1327
1985
|
var _image = images[i];
|
|
1328
1986
|
var _arrayBuffer = _image.data.byteArray.buffer;
|
|
1329
1987
|
var _dicomData = DicomMessage$1.readFile(_arrayBuffer);
|
|
1330
|
-
var _dataset = DicomMetaDictionary$
|
|
1331
|
-
_dataset._meta = DicomMetaDictionary$
|
|
1988
|
+
var _dataset = DicomMetaDictionary$3.naturalizeDataset(_dicomData.dict);
|
|
1989
|
+
_dataset._meta = DicomMetaDictionary$3.namifyDataset(_dicomData.meta);
|
|
1332
1990
|
datasets.push(_dataset);
|
|
1333
1991
|
}
|
|
1334
1992
|
}
|
|
1335
|
-
var multiframe = Normalizer$
|
|
1336
|
-
return new SegmentationDerivation$
|
|
1993
|
+
var multiframe = Normalizer$3.normalizeToDataset(datasets);
|
|
1994
|
+
return new SegmentationDerivation$2([multiframe], options);
|
|
1337
1995
|
}
|
|
1338
1996
|
|
|
1339
1997
|
/**
|
|
@@ -1346,11 +2004,11 @@ function _createSegFromImages$1(images, isMultiframe, options) {
|
|
|
1346
2004
|
* @returns {Object} The toolState and an object from which the
|
|
1347
2005
|
* segment metadata can be derived.
|
|
1348
2006
|
*/
|
|
1349
|
-
function generateToolState$
|
|
2007
|
+
function generateToolState$3(imageIds, arrayBuffer, metadataProvider) {
|
|
1350
2008
|
var dicomData = DicomMessage$1.readFile(arrayBuffer);
|
|
1351
|
-
var dataset = DicomMetaDictionary$
|
|
1352
|
-
dataset._meta = DicomMetaDictionary$
|
|
1353
|
-
var multiframe = Normalizer$
|
|
2009
|
+
var dataset = DicomMetaDictionary$3.naturalizeDataset(dicomData.dict);
|
|
2010
|
+
dataset._meta = DicomMetaDictionary$3.namifyDataset(dicomData.meta);
|
|
2011
|
+
var multiframe = Normalizer$3.normalizeToDataset([dataset]);
|
|
1354
2012
|
var imagePlaneModule = metadataProvider.get("imagePlaneModule", imageIds[0]);
|
|
1355
2013
|
if (!imagePlaneModule) {
|
|
1356
2014
|
console.warn("Insufficient metadata, imagePlaneModule missing.");
|
|
@@ -1370,7 +2028,7 @@ function generateToolState$2(imageIds, arrayBuffer, metadataProvider) {
|
|
|
1370
2028
|
for (var i = 0; i < PerFrameFunctionalGroupsSequence.length; i++) {
|
|
1371
2029
|
var PerFrameFunctionalGroups = PerFrameFunctionalGroupsSequence[i];
|
|
1372
2030
|
var ImageOrientationPatientI = sharedImageOrientationPatient || PerFrameFunctionalGroups.PlaneOrientationSequence.ImageOrientationPatient;
|
|
1373
|
-
var pixelDataI2D =
|
|
2031
|
+
var pixelDataI2D = ndarray__WEBPACK_IMPORTED_MODULE_2___default()(new Uint8Array(pixelData.buffer, i * sliceLength, sliceLength), [multiframe.Rows, multiframe.Columns]);
|
|
1374
2032
|
var alignedPixelDataI = alignPixelDataWithSourceData$1(pixelDataI2D, ImageOrientationPatientI, validOrientations);
|
|
1375
2033
|
if (!alignedPixelDataI) {
|
|
1376
2034
|
console.warn("This segmentation object is not in-plane with the source data. Bailing out of IO. It'd be better to render this with vtkjs. ");
|
|
@@ -1465,7 +2123,7 @@ function addImageIdSpecificBrushToolState(toolState, imageId, segmentIndex, pixe
|
|
|
1465
2123
|
function getImageIdOfSourceImage(SourceImageSequence, imageIds, metadataProvider) {
|
|
1466
2124
|
var ReferencedSOPInstanceUID = SourceImageSequence.ReferencedSOPInstanceUID,
|
|
1467
2125
|
ReferencedFrameNumber = SourceImageSequence.ReferencedFrameNumber;
|
|
1468
|
-
return ReferencedFrameNumber ? getImageIdOfReferencedFrame$1(ReferencedSOPInstanceUID, ReferencedFrameNumber, imageIds, metadataProvider) : getImageIdOfReferencedSingleFramedSOPInstance
|
|
2126
|
+
return ReferencedFrameNumber ? getImageIdOfReferencedFrame$1(ReferencedSOPInstanceUID, ReferencedFrameNumber, imageIds, metadataProvider) : getImageIdOfReferencedSingleFramedSOPInstance(ReferencedSOPInstanceUID, imageIds, metadataProvider);
|
|
1469
2127
|
}
|
|
1470
2128
|
|
|
1471
2129
|
/**
|
|
@@ -1478,7 +2136,7 @@ function getImageIdOfSourceImage(SourceImageSequence, imageIds, metadataProvider
|
|
|
1478
2136
|
* from the cornerstone imageIds.
|
|
1479
2137
|
* @return {String} The imageId that corresponds to the sopInstanceUid.
|
|
1480
2138
|
*/
|
|
1481
|
-
function getImageIdOfReferencedSingleFramedSOPInstance
|
|
2139
|
+
function getImageIdOfReferencedSingleFramedSOPInstance(sopInstanceUid, imageIds, metadataProvider) {
|
|
1482
2140
|
return imageIds.find(function (imageId) {
|
|
1483
2141
|
var sopCommonModule = metadataProvider.get("sopCommonModule", imageId);
|
|
1484
2142
|
if (!sopCommonModule) {
|
|
@@ -1604,26 +2262,37 @@ function getSegmentMetadata$1(multiframe) {
|
|
|
1604
2262
|
};
|
|
1605
2263
|
}
|
|
1606
2264
|
|
|
2265
|
+
/**
|
|
2266
|
+
* Cornerstone adapters events
|
|
2267
|
+
*/
|
|
2268
|
+
var Events;
|
|
2269
|
+
(function (Events) {
|
|
2270
|
+
/**
|
|
2271
|
+
* Cornerstone segmentation load progress event
|
|
2272
|
+
*/
|
|
2273
|
+
Events["SEGMENTATION_LOAD_PROGRESS"] = "CORNERSTONE_ADAPTER_SEGMENTATION_LOAD_PROGRESS";
|
|
2274
|
+
})(Events || (Events = {}));
|
|
2275
|
+
var Events$1 = Events;
|
|
2276
|
+
|
|
2277
|
+
var index = /*#__PURE__*/Object.freeze({
|
|
2278
|
+
__proto__: null,
|
|
2279
|
+
Events: Events$1
|
|
2280
|
+
});
|
|
2281
|
+
|
|
1607
2282
|
var _utilities$orientatio = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.orientation,
|
|
1608
2283
|
rotateDirectionCosinesInPlane = _utilities$orientatio.rotateDirectionCosinesInPlane,
|
|
1609
2284
|
flipIOP = _utilities$orientatio.flipImageOrientationPatient,
|
|
1610
2285
|
flipMatrix2D = _utilities$orientatio.flipMatrix2D,
|
|
1611
2286
|
rotateMatrix902D = _utilities$orientatio.rotateMatrix902D,
|
|
1612
2287
|
nearlyEqual = _utilities$orientatio.nearlyEqual;
|
|
1613
|
-
var
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
var
|
|
1618
|
-
var SegmentationDerivation = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .derivations */ .U7.Segmentation;
|
|
2288
|
+
var BitArray$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.BitArray,
|
|
2289
|
+
DicomMessage = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.DicomMessage,
|
|
2290
|
+
DicomMetaDictionary$2 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.DicomMetaDictionary;
|
|
2291
|
+
var Normalizer$2 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .normalizers */ .oq.Normalizer;
|
|
2292
|
+
var SegmentationDerivation$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .derivations */ .U7.Segmentation;
|
|
1619
2293
|
var _utilities$compressio = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.compression,
|
|
1620
2294
|
encode = _utilities$compressio.encode,
|
|
1621
2295
|
decode = _utilities$compressio.decode;
|
|
1622
|
-
var Segmentation$2 = {
|
|
1623
|
-
generateSegmentation: generateSegmentation$1,
|
|
1624
|
-
generateToolState: generateToolState$1,
|
|
1625
|
-
fillSegmentation: fillSegmentation$1
|
|
1626
|
-
};
|
|
1627
2296
|
|
|
1628
2297
|
/**
|
|
1629
2298
|
*
|
|
@@ -1632,10 +2301,9 @@ var Segmentation$2 = {
|
|
|
1632
2301
|
* @property {Object[]} segments - The cornerstoneTools segment metadata that corresponds to the
|
|
1633
2302
|
* seriesInstanceUid.
|
|
1634
2303
|
*/
|
|
1635
|
-
|
|
1636
2304
|
var generateSegmentationDefaultOptions = {
|
|
1637
2305
|
includeSliceSpacing: true,
|
|
1638
|
-
rleEncode:
|
|
2306
|
+
rleEncode: false
|
|
1639
2307
|
};
|
|
1640
2308
|
|
|
1641
2309
|
/**
|
|
@@ -1648,7 +2316,7 @@ var generateSegmentationDefaultOptions = {
|
|
|
1648
2316
|
* @param {Object} userOptions Options to pass to the segmentation derivation and `fillSegmentation`.
|
|
1649
2317
|
* @returns {Blob}
|
|
1650
2318
|
*/
|
|
1651
|
-
function generateSegmentation$
|
|
2319
|
+
function generateSegmentation$2(images, inputLabelmaps3D) {
|
|
1652
2320
|
var userOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
1653
2321
|
var isMultiframe = images[0].imageId.includes("?frame");
|
|
1654
2322
|
var segmentation = _createSegFromImages(images, isMultiframe, userOptions);
|
|
@@ -1656,12 +2324,13 @@ function generateSegmentation$1(images, inputLabelmaps3D) {
|
|
|
1656
2324
|
}
|
|
1657
2325
|
|
|
1658
2326
|
/**
|
|
1659
|
-
*
|
|
2327
|
+
* Fills a given segmentation object with data from the input labelmaps3D
|
|
1660
2328
|
*
|
|
1661
|
-
* @param
|
|
1662
|
-
* @param
|
|
1663
|
-
* @param
|
|
1664
|
-
*
|
|
2329
|
+
* @param segmentation - The segmentation object to be filled.
|
|
2330
|
+
* @param inputLabelmaps3D - An array of 3D labelmaps, or a single 3D labelmap.
|
|
2331
|
+
* @param userOptions - Optional configuration settings. Will override the default options.
|
|
2332
|
+
*
|
|
2333
|
+
* @returns {object} The filled segmentation object.
|
|
1665
2334
|
*/
|
|
1666
2335
|
function fillSegmentation$1(segmentation, inputLabelmaps3D) {
|
|
1667
2336
|
var userOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
@@ -1714,7 +2383,7 @@ function fillSegmentation$1(segmentation, inputLabelmaps3D) {
|
|
|
1714
2383
|
return element + 1;
|
|
1715
2384
|
});
|
|
1716
2385
|
var segmentMetadata = metadata[segmentIndex];
|
|
1717
|
-
var labelmaps =
|
|
2386
|
+
var labelmaps = _getLabelmapsFromReferencedFrameIndicies(labelmap3D, referencedFrameIndicies);
|
|
1718
2387
|
segmentation.addSegmentFromLabelmap(segmentMetadata, labelmaps, segmentIndex, referencedFrameNumbers);
|
|
1719
2388
|
}
|
|
1720
2389
|
}
|
|
@@ -1743,10 +2412,9 @@ function fillSegmentation$1(segmentation, inputLabelmaps3D) {
|
|
|
1743
2412
|
// If no rleEncoding, at least bitpack the data.
|
|
1744
2413
|
segmentation.bitPackPixelData();
|
|
1745
2414
|
}
|
|
1746
|
-
|
|
1747
|
-
return segBlob;
|
|
2415
|
+
return segmentation;
|
|
1748
2416
|
}
|
|
1749
|
-
function
|
|
2417
|
+
function _getLabelmapsFromReferencedFrameIndicies(labelmap3D, referencedFrameIndicies) {
|
|
1750
2418
|
var labelmaps2D = labelmap3D.labelmaps2D;
|
|
1751
2419
|
var labelmaps = [];
|
|
1752
2420
|
for (var i = 0; i < referencedFrameIndicies.length; i++) {
|
|
@@ -1769,21 +2437,21 @@ function _createSegFromImages(images, isMultiframe, options) {
|
|
|
1769
2437
|
var image = images[0];
|
|
1770
2438
|
var arrayBuffer = image.data.byteArray.buffer;
|
|
1771
2439
|
var dicomData = DicomMessage.readFile(arrayBuffer);
|
|
1772
|
-
var dataset = DicomMetaDictionary$
|
|
1773
|
-
dataset._meta = DicomMetaDictionary$
|
|
2440
|
+
var dataset = DicomMetaDictionary$2.naturalizeDataset(dicomData.dict);
|
|
2441
|
+
dataset._meta = DicomMetaDictionary$2.namifyDataset(dicomData.meta);
|
|
1774
2442
|
datasets.push(dataset);
|
|
1775
2443
|
} else {
|
|
1776
2444
|
for (var i = 0; i < images.length; i++) {
|
|
1777
2445
|
var _image = images[i];
|
|
1778
2446
|
var _arrayBuffer = _image.data.byteArray.buffer;
|
|
1779
2447
|
var _dicomData = DicomMessage.readFile(_arrayBuffer);
|
|
1780
|
-
var _dataset = DicomMetaDictionary$
|
|
1781
|
-
_dataset._meta = DicomMetaDictionary$
|
|
2448
|
+
var _dataset = DicomMetaDictionary$2.naturalizeDataset(_dicomData.dict);
|
|
2449
|
+
_dataset._meta = DicomMetaDictionary$2.namifyDataset(_dicomData.meta);
|
|
1782
2450
|
datasets.push(_dataset);
|
|
1783
2451
|
}
|
|
1784
2452
|
}
|
|
1785
|
-
var multiframe = Normalizer$
|
|
1786
|
-
return new SegmentationDerivation([multiframe], options);
|
|
2453
|
+
var multiframe = Normalizer$2.normalizeToDataset(datasets);
|
|
2454
|
+
return new SegmentationDerivation$1([multiframe], options);
|
|
1787
2455
|
}
|
|
1788
2456
|
|
|
1789
2457
|
/**
|
|
@@ -1793,8 +2461,7 @@ function _createSegFromImages(images, isMultiframe, options) {
|
|
|
1793
2461
|
* @param {string[]} imageIds - An array of the imageIds.
|
|
1794
2462
|
* @param {ArrayBuffer} arrayBuffer - The SEG arrayBuffer.
|
|
1795
2463
|
* @param {*} metadataProvider.
|
|
1796
|
-
* @param {
|
|
1797
|
-
* @param {number} tolerance - default value 1.e-3.
|
|
2464
|
+
* @param {obj} options - Options object.
|
|
1798
2465
|
*
|
|
1799
2466
|
* @return {[]ArrayBuffer}a list of array buffer for each labelMap
|
|
1800
2467
|
* @return {Object} an object from which the segment metadata can be derived
|
|
@@ -1802,83 +2469,9 @@ function _createSegFromImages(images, isMultiframe, options) {
|
|
|
1802
2469
|
* @return {[][][]} 3D list containing the track of segments per frame for each labelMap
|
|
1803
2470
|
* (available only for the overlapping case).
|
|
1804
2471
|
*/
|
|
1805
|
-
function generateToolState$
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
var dicomData = DicomMessage.readFile(arrayBuffer);
|
|
1809
|
-
var dataset = DicomMetaDictionary$1.naturalizeDataset(dicomData.dict);
|
|
1810
|
-
dataset._meta = DicomMetaDictionary$1.namifyDataset(dicomData.meta);
|
|
1811
|
-
var multiframe = Normalizer$1.normalizeToDataset([dataset]);
|
|
1812
|
-
var imagePlaneModule = metadataProvider.get("imagePlaneModule", imageIds[0]);
|
|
1813
|
-
var generalSeriesModule = metadataProvider.get("generalSeriesModule", imageIds[0]);
|
|
1814
|
-
var SeriesInstanceUID = generalSeriesModule.seriesInstanceUID;
|
|
1815
|
-
if (!imagePlaneModule) {
|
|
1816
|
-
console.warn("Insufficient metadata, imagePlaneModule missing.");
|
|
1817
|
-
}
|
|
1818
|
-
var ImageOrientationPatient = Array.isArray(imagePlaneModule.rowCosines) ? [].concat(_toConsumableArray(imagePlaneModule.rowCosines), _toConsumableArray(imagePlaneModule.columnCosines)) : [imagePlaneModule.rowCosines.x, imagePlaneModule.rowCosines.y, imagePlaneModule.rowCosines.z, imagePlaneModule.columnCosines.x, imagePlaneModule.columnCosines.y, imagePlaneModule.columnCosines.z];
|
|
1819
|
-
|
|
1820
|
-
// Get IOP from ref series, compute supported orientations:
|
|
1821
|
-
var validOrientations = getValidOrientations(ImageOrientationPatient);
|
|
1822
|
-
var sliceLength = multiframe.Columns * multiframe.Rows;
|
|
1823
|
-
var segMetadata = getSegmentMetadata(multiframe, SeriesInstanceUID);
|
|
1824
|
-
var TransferSyntaxUID = multiframe._meta.TransferSyntaxUID.Value[0];
|
|
1825
|
-
var pixelData;
|
|
1826
|
-
if (TransferSyntaxUID === "1.2.840.10008.1.2.5") {
|
|
1827
|
-
var rleEncodedFrames = Array.isArray(multiframe.PixelData) ? multiframe.PixelData : [multiframe.PixelData];
|
|
1828
|
-
pixelData = decode(rleEncodedFrames, multiframe.Rows, multiframe.Columns);
|
|
1829
|
-
if (multiframe.BitsStored === 1) {
|
|
1830
|
-
console.warn("No implementation for rle + bitbacking.");
|
|
1831
|
-
return;
|
|
1832
|
-
}
|
|
1833
|
-
} else {
|
|
1834
|
-
pixelData = unpackPixelData(multiframe);
|
|
1835
|
-
if (!pixelData) {
|
|
1836
|
-
throw new Error("Fractional segmentations are not yet supported");
|
|
1837
|
-
}
|
|
1838
|
-
}
|
|
1839
|
-
var orientation = checkOrientation(multiframe, validOrientations, [imagePlaneModule.rows, imagePlaneModule.columns, imageIds.length], tolerance);
|
|
1840
|
-
var overlapping = false;
|
|
1841
|
-
if (!skipOverlapping) {
|
|
1842
|
-
overlapping = checkSEGsOverlapping(pixelData, multiframe, imageIds, validOrientations, metadataProvider, tolerance);
|
|
1843
|
-
}
|
|
1844
|
-
var insertFunction;
|
|
1845
|
-
switch (orientation) {
|
|
1846
|
-
case "Planar":
|
|
1847
|
-
if (overlapping) {
|
|
1848
|
-
insertFunction = insertOverlappingPixelDataPlanar;
|
|
1849
|
-
} else {
|
|
1850
|
-
insertFunction = insertPixelDataPlanar;
|
|
1851
|
-
}
|
|
1852
|
-
break;
|
|
1853
|
-
case "Perpendicular":
|
|
1854
|
-
//insertFunction = insertPixelDataPerpendicular;
|
|
1855
|
-
throw new Error("Segmentations orthogonal to the acquisition plane of the source data are not yet supported.");
|
|
1856
|
-
case "Oblique":
|
|
1857
|
-
throw new Error("Segmentations oblique to the acquisition plane of the source data are not yet supported.");
|
|
1858
|
-
}
|
|
1859
|
-
|
|
1860
|
-
/* if SEGs are overlapping:
|
|
1861
|
-
1) the labelmapBuffer will contain M volumes which have non-overlapping segments;
|
|
1862
|
-
2) segmentsOnFrame will have M * numberOfFrames values to track in which labelMap are the segments;
|
|
1863
|
-
3) insertFunction will return the number of LabelMaps
|
|
1864
|
-
4) generateToolState return is an array*/
|
|
1865
|
-
|
|
1866
|
-
var segmentsOnFrameArray = [];
|
|
1867
|
-
segmentsOnFrameArray[0] = [];
|
|
1868
|
-
var segmentsOnFrame = [];
|
|
1869
|
-
var arrayBufferLength = sliceLength * imageIds.length * 2; // 2 bytes per label voxel in cst4.
|
|
1870
|
-
var labelmapBufferArray = [];
|
|
1871
|
-
labelmapBufferArray[0] = new ArrayBuffer(arrayBufferLength);
|
|
1872
|
-
insertFunction(segmentsOnFrame, segmentsOnFrameArray, labelmapBufferArray, pixelData, multiframe, imageIds, validOrientations, metadataProvider, tolerance);
|
|
1873
|
-
return {
|
|
1874
|
-
labelmapBufferArray: labelmapBufferArray,
|
|
1875
|
-
segMetadata: segMetadata,
|
|
1876
|
-
segmentsOnFrame: segmentsOnFrame,
|
|
1877
|
-
segmentsOnFrameArray: segmentsOnFrameArray
|
|
1878
|
-
};
|
|
1879
|
-
}
|
|
1880
|
-
|
|
1881
|
-
// function insertPixelDataPerpendicular(
|
|
2472
|
+
function generateToolState$2(_x, _x2, _x3, _x4) {
|
|
2473
|
+
return _generateToolState.apply(this, arguments);
|
|
2474
|
+
} // function insertPixelDataPerpendicular(
|
|
1882
2475
|
// segmentsOnFrame,
|
|
1883
2476
|
// labelmapBuffer,
|
|
1884
2477
|
// pixelData,
|
|
@@ -1893,30 +2486,23 @@ function generateToolState$1(imageIds, arrayBuffer, metadataProvider) {
|
|
|
1893
2486
|
// Rows,
|
|
1894
2487
|
// Columns
|
|
1895
2488
|
// } = multiframe;
|
|
1896
|
-
|
|
1897
2489
|
// const firstImagePlaneModule = metadataProvider.get(
|
|
1898
2490
|
// "imagePlaneModule",
|
|
1899
2491
|
// imageIds[0]
|
|
1900
2492
|
// );
|
|
1901
|
-
|
|
1902
2493
|
// const lastImagePlaneModule = metadataProvider.get(
|
|
1903
2494
|
// "imagePlaneModule",
|
|
1904
2495
|
// imageIds[imageIds.length - 1]
|
|
1905
2496
|
// );
|
|
1906
|
-
|
|
1907
2497
|
// console.log(firstImagePlaneModule);
|
|
1908
2498
|
// console.log(lastImagePlaneModule);
|
|
1909
|
-
|
|
1910
2499
|
// const corners = [
|
|
1911
2500
|
// ...getCorners(firstImagePlaneModule),
|
|
1912
2501
|
// ...getCorners(lastImagePlaneModule)
|
|
1913
2502
|
// ];
|
|
1914
|
-
|
|
1915
2503
|
// console.log(`corners:`);
|
|
1916
2504
|
// console.log(corners);
|
|
1917
|
-
|
|
1918
2505
|
// const indexToWorld = mat4.create();
|
|
1919
|
-
|
|
1920
2506
|
// const ippFirstFrame = firstImagePlaneModule.imagePositionPatient;
|
|
1921
2507
|
// const rowCosines = Array.isArray(firstImagePlaneModule.rowCosines)
|
|
1922
2508
|
// ? [...firstImagePlaneModule.rowCosines]
|
|
@@ -1925,7 +2511,6 @@ function generateToolState$1(imageIds, arrayBuffer, metadataProvider) {
|
|
|
1925
2511
|
// firstImagePlaneModule.rowCosines.y,
|
|
1926
2512
|
// firstImagePlaneModule.rowCosines.z
|
|
1927
2513
|
// ];
|
|
1928
|
-
|
|
1929
2514
|
// const columnCosines = Array.isArray(firstImagePlaneModule.columnCosines)
|
|
1930
2515
|
// ? [...firstImagePlaneModule.columnCosines]
|
|
1931
2516
|
// : [
|
|
@@ -1933,9 +2518,7 @@ function generateToolState$1(imageIds, arrayBuffer, metadataProvider) {
|
|
|
1933
2518
|
// firstImagePlaneModule.columnCosines.y,
|
|
1934
2519
|
// firstImagePlaneModule.columnCosines.z
|
|
1935
2520
|
// ];
|
|
1936
|
-
|
|
1937
2521
|
// const { pixelSpacing } = firstImagePlaneModule;
|
|
1938
|
-
|
|
1939
2522
|
// mat4.set(
|
|
1940
2523
|
// indexToWorld,
|
|
1941
2524
|
// // Column 1
|
|
@@ -1959,50 +2542,36 @@ function generateToolState$1(imageIds, arrayBuffer, metadataProvider) {
|
|
|
1959
2542
|
// 0,
|
|
1960
2543
|
// 1
|
|
1961
2544
|
// );
|
|
1962
|
-
|
|
1963
2545
|
// // TODO -> Get origin and (x,y,z) increments to build a translation matrix:
|
|
1964
2546
|
// // TODO -> Equation C.7.6.2.1-1
|
|
1965
|
-
|
|
1966
2547
|
// // | cx*di rx* Xx 0 | |x|
|
|
1967
2548
|
// // | cy*di ry Xy 0 | |y|
|
|
1968
2549
|
// // | cz*di rz Xz 0 | |z|
|
|
1969
2550
|
// // | tx ty tz 1 | |1|
|
|
1970
|
-
|
|
1971
2551
|
// // const [
|
|
1972
2552
|
// // 0, 0 , 0 , 0,
|
|
1973
2553
|
// // 0, 0 , 0 , 0,
|
|
1974
2554
|
// // 0, 0 , 0 , 0,
|
|
1975
2555
|
// // ipp[0], ipp[1] , ipp[2] , 1,
|
|
1976
2556
|
// // ]
|
|
1977
|
-
|
|
1978
2557
|
// // Each frame:
|
|
1979
|
-
|
|
1980
2558
|
// // Find which corner the first voxel lines up with (one of 8 corners.)
|
|
1981
|
-
|
|
1982
2559
|
// // Find how i,j,k orient with respect to source volume.
|
|
1983
2560
|
// // Go through each frame, find location in source to start, and whether to increment +/ix,+/-y,+/-z
|
|
1984
2561
|
// // through each voxel.
|
|
1985
|
-
|
|
1986
2562
|
// // [1,0,0,0,1,0]
|
|
1987
|
-
|
|
1988
2563
|
// // const [
|
|
1989
|
-
|
|
1990
2564
|
// // ]
|
|
1991
|
-
|
|
1992
2565
|
// // Invert transformation matrix to get worldToIndex
|
|
1993
|
-
|
|
1994
2566
|
// // Apply world to index on each point to fill up the matrix.
|
|
1995
|
-
|
|
1996
2567
|
// // const sharedImageOrientationPatient = SharedFunctionalGroupsSequence.PlaneOrientationSequence
|
|
1997
2568
|
// // ? SharedFunctionalGroupsSequence.PlaneOrientationSequence
|
|
1998
2569
|
// // .ImageOrientationPatient
|
|
1999
2570
|
// // : undefined;
|
|
2000
2571
|
// // const sliceLength = Columns * Rows;
|
|
2001
2572
|
// }
|
|
2002
|
-
|
|
2003
2573
|
// function getCorners(imagePlaneModule) {
|
|
2004
2574
|
// // console.log(imagePlaneModule);
|
|
2005
|
-
|
|
2006
2575
|
// const {
|
|
2007
2576
|
// rows,
|
|
2008
2577
|
// columns,
|
|
@@ -2012,22 +2581,18 @@ function generateToolState$1(imageIds, arrayBuffer, metadataProvider) {
|
|
|
2012
2581
|
// rowPixelSpacing,
|
|
2013
2582
|
// columnPixelSpacing
|
|
2014
2583
|
// } = imagePlaneModule;
|
|
2015
|
-
|
|
2016
2584
|
// const rowLength = columns * columnPixelSpacing;
|
|
2017
2585
|
// const columnLength = rows * rowPixelSpacing;
|
|
2018
|
-
|
|
2019
2586
|
// const entireRowVector = [
|
|
2020
2587
|
// rowLength * columnCosines[0],
|
|
2021
2588
|
// rowLength * columnCosines[1],
|
|
2022
2589
|
// rowLength * columnCosines[2]
|
|
2023
2590
|
// ];
|
|
2024
|
-
|
|
2025
2591
|
// const entireColumnVector = [
|
|
2026
2592
|
// columnLength * rowCosines[0],
|
|
2027
2593
|
// columnLength * rowCosines[1],
|
|
2028
2594
|
// columnLength * rowCosines[2]
|
|
2029
2595
|
// ];
|
|
2030
|
-
|
|
2031
2596
|
// const topLeft = [ipp[0], ipp[1], ipp[2]];
|
|
2032
2597
|
// const topRight = [
|
|
2033
2598
|
// topLeft[0] + entireRowVector[0],
|
|
@@ -2039,29 +2604,160 @@ function generateToolState$1(imageIds, arrayBuffer, metadataProvider) {
|
|
|
2039
2604
|
// topLeft[1] + entireColumnVector[1],
|
|
2040
2605
|
// topLeft[2] + entireColumnVector[2]
|
|
2041
2606
|
// ];
|
|
2042
|
-
|
|
2043
2607
|
// const bottomRight = [
|
|
2044
2608
|
// bottomLeft[0] + entireRowVector[0],
|
|
2045
2609
|
// bottomLeft[1] + entireRowVector[1],
|
|
2046
2610
|
// bottomLeft[2] + entireRowVector[2]
|
|
2047
2611
|
// ];
|
|
2048
|
-
|
|
2049
2612
|
// return [topLeft, topRight, bottomLeft, bottomRight];
|
|
2050
2613
|
// }
|
|
2051
|
-
|
|
2052
2614
|
/**
|
|
2053
2615
|
* Find the reference frame of the segmentation frame in the source data.
|
|
2054
2616
|
*
|
|
2055
2617
|
* @param {Object} multiframe dicom metadata
|
|
2056
2618
|
* @param {Int} frameSegment frame dicom index
|
|
2057
2619
|
* @param {String[]} imageIds A list of imageIds.
|
|
2058
|
-
* @param {Object}
|
|
2059
|
-
* metadata from imageIds.
|
|
2620
|
+
* @param {Object} sopUIDImageIdIndexMap A map of SOPInstanceUID to imageId
|
|
2060
2621
|
* @param {Float} tolerance The tolerance parameter
|
|
2061
2622
|
*
|
|
2062
2623
|
* @returns {String} Returns the imageId
|
|
2063
2624
|
*/
|
|
2064
|
-
function
|
|
2625
|
+
function _generateToolState() {
|
|
2626
|
+
_generateToolState = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(imageIds, arrayBuffer, metadataProvider, options) {
|
|
2627
|
+
var _options$skipOverlapp, skipOverlapping, _options$tolerance, tolerance, _options$TypedArrayCo, TypedArrayConstructor, _options$maxBytesPerC, maxBytesPerChunk, eventTarget, triggerEvent, dicomData, dataset, multiframe, imagePlaneModule, generalSeriesModule, SeriesInstanceUID, ImageOrientationPatient, validOrientations, sliceLength, segMetadata, TransferSyntaxUID, pixelData, pixelDataChunks, rleEncodedFrames, orientation, sopUIDImageIdIndexMap, overlapping, insertFunction, segmentsOnFrameArray, segmentsOnFrame, arrayBufferLength, labelmapBufferArray, imageIdMaps, segmentsPixelIndices, centroidXYZ;
|
|
2628
|
+
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
2629
|
+
while (1) switch (_context.prev = _context.next) {
|
|
2630
|
+
case 0:
|
|
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;
|
|
2632
|
+
dicomData = DicomMessage.readFile(arrayBuffer);
|
|
2633
|
+
dataset = DicomMetaDictionary$2.naturalizeDataset(dicomData.dict);
|
|
2634
|
+
dataset._meta = DicomMetaDictionary$2.namifyDataset(dicomData.meta);
|
|
2635
|
+
multiframe = Normalizer$2.normalizeToDataset([dataset]);
|
|
2636
|
+
imagePlaneModule = metadataProvider.get("imagePlaneModule", imageIds[0]);
|
|
2637
|
+
generalSeriesModule = metadataProvider.get("generalSeriesModule", imageIds[0]);
|
|
2638
|
+
SeriesInstanceUID = generalSeriesModule.seriesInstanceUID;
|
|
2639
|
+
if (!imagePlaneModule) {
|
|
2640
|
+
console.warn("Insufficient metadata, imagePlaneModule missing.");
|
|
2641
|
+
}
|
|
2642
|
+
ImageOrientationPatient = Array.isArray(imagePlaneModule.rowCosines) ? [].concat(_toConsumableArray(imagePlaneModule.rowCosines), _toConsumableArray(imagePlaneModule.columnCosines)) : [imagePlaneModule.rowCosines.x, imagePlaneModule.rowCosines.y, imagePlaneModule.rowCosines.z, imagePlaneModule.columnCosines.x, imagePlaneModule.columnCosines.y, imagePlaneModule.columnCosines.z]; // Get IOP from ref series, compute supported orientations:
|
|
2643
|
+
validOrientations = getValidOrientations(ImageOrientationPatient);
|
|
2644
|
+
sliceLength = multiframe.Columns * multiframe.Rows;
|
|
2645
|
+
segMetadata = getSegmentMetadata(multiframe, SeriesInstanceUID);
|
|
2646
|
+
TransferSyntaxUID = multiframe._meta.TransferSyntaxUID.Value[0];
|
|
2647
|
+
if (!(TransferSyntaxUID === "1.2.840.10008.1.2.5")) {
|
|
2648
|
+
_context.next = 23;
|
|
2649
|
+
break;
|
|
2650
|
+
}
|
|
2651
|
+
rleEncodedFrames = Array.isArray(multiframe.PixelData) ? multiframe.PixelData : [multiframe.PixelData];
|
|
2652
|
+
pixelData = decode(rleEncodedFrames, multiframe.Rows, multiframe.Columns);
|
|
2653
|
+
if (!(multiframe.BitsStored === 1)) {
|
|
2654
|
+
_context.next = 20;
|
|
2655
|
+
break;
|
|
2656
|
+
}
|
|
2657
|
+
console.warn("No implementation for rle + bitbacking.");
|
|
2658
|
+
return _context.abrupt("return");
|
|
2659
|
+
case 20:
|
|
2660
|
+
// Todo: need to test this with rle data
|
|
2661
|
+
pixelDataChunks = [pixelData];
|
|
2662
|
+
_context.next = 26;
|
|
2663
|
+
break;
|
|
2664
|
+
case 23:
|
|
2665
|
+
pixelDataChunks = unpackPixelData(multiframe, {
|
|
2666
|
+
maxBytesPerChunk: maxBytesPerChunk
|
|
2667
|
+
});
|
|
2668
|
+
if (pixelDataChunks) {
|
|
2669
|
+
_context.next = 26;
|
|
2670
|
+
break;
|
|
2671
|
+
}
|
|
2672
|
+
throw new Error("Fractional segmentations are not yet supported");
|
|
2673
|
+
case 26:
|
|
2674
|
+
orientation = checkOrientation(multiframe, validOrientations, [imagePlaneModule.rows, imagePlaneModule.columns, imageIds.length], tolerance); // Pre-compute the sop UID to imageId index map so that in the for loop
|
|
2675
|
+
// we don't have to call metadataProvider.get() for each imageId over
|
|
2676
|
+
// and over again.
|
|
2677
|
+
sopUIDImageIdIndexMap = imageIds.reduce(function (acc, imageId) {
|
|
2678
|
+
var _metadataProvider$get = metadataProvider.get("generalImageModule", imageId),
|
|
2679
|
+
sopInstanceUid = _metadataProvider$get.sopInstanceUid;
|
|
2680
|
+
acc[sopInstanceUid] = imageId;
|
|
2681
|
+
return acc;
|
|
2682
|
+
}, {});
|
|
2683
|
+
overlapping = false;
|
|
2684
|
+
if (!skipOverlapping) {
|
|
2685
|
+
overlapping = checkSEGsOverlapping(pixelDataChunks, multiframe, imageIds, validOrientations, metadataProvider, tolerance, TypedArrayConstructor, sopUIDImageIdIndexMap);
|
|
2686
|
+
}
|
|
2687
|
+
_context.t0 = orientation;
|
|
2688
|
+
_context.next = _context.t0 === "Planar" ? 33 : _context.t0 === "Perpendicular" ? 35 : _context.t0 === "Oblique" ? 36 : 37;
|
|
2689
|
+
break;
|
|
2690
|
+
case 33:
|
|
2691
|
+
if (overlapping) {
|
|
2692
|
+
insertFunction = insertOverlappingPixelDataPlanar;
|
|
2693
|
+
} else {
|
|
2694
|
+
insertFunction = insertPixelDataPlanar;
|
|
2695
|
+
}
|
|
2696
|
+
return _context.abrupt("break", 37);
|
|
2697
|
+
case 35:
|
|
2698
|
+
throw new Error("Segmentations orthogonal to the acquisition plane of the source data are not yet supported.");
|
|
2699
|
+
case 36:
|
|
2700
|
+
throw new Error("Segmentations oblique to the acquisition plane of the source data are not yet supported.");
|
|
2701
|
+
case 37:
|
|
2702
|
+
/* if SEGs are overlapping:
|
|
2703
|
+
1) the labelmapBuffer will contain M volumes which have non-overlapping segments;
|
|
2704
|
+
2) segmentsOnFrame will have M * numberOfFrames values to track in which labelMap are the segments;
|
|
2705
|
+
3) insertFunction will return the number of LabelMaps
|
|
2706
|
+
4) generateToolState return is an array*/
|
|
2707
|
+
segmentsOnFrameArray = [];
|
|
2708
|
+
segmentsOnFrameArray[0] = [];
|
|
2709
|
+
segmentsOnFrame = [];
|
|
2710
|
+
arrayBufferLength = sliceLength * imageIds.length * TypedArrayConstructor.BYTES_PER_ELEMENT;
|
|
2711
|
+
labelmapBufferArray = [];
|
|
2712
|
+
labelmapBufferArray[0] = new ArrayBuffer(arrayBufferLength);
|
|
2713
|
+
|
|
2714
|
+
// Precompute the indices and metadata so that we don't have to call
|
|
2715
|
+
// a function for each imageId in the for loop.
|
|
2716
|
+
imageIdMaps = imageIds.reduce(function (acc, curr, index) {
|
|
2717
|
+
acc.indices[curr] = index;
|
|
2718
|
+
acc.metadata[curr] = metadataProvider.get("instance", curr);
|
|
2719
|
+
return acc;
|
|
2720
|
+
}, {
|
|
2721
|
+
indices: {},
|
|
2722
|
+
metadata: {}
|
|
2723
|
+
}); // This is the centroid calculation for each segment Index, the data structure
|
|
2724
|
+
// is a Map with key = segmentIndex and value = {imageIdIndex: centroid, ...}
|
|
2725
|
+
// later on we will use this data structure to calculate the centroid of the
|
|
2726
|
+
// segment in the labelmapBuffer
|
|
2727
|
+
segmentsPixelIndices = new Map();
|
|
2728
|
+
_context.next = 47;
|
|
2729
|
+
return insertFunction(segmentsOnFrame, segmentsOnFrameArray, labelmapBufferArray, pixelDataChunks, multiframe, imageIds, validOrientations, metadataProvider, tolerance, TypedArrayConstructor, segmentsPixelIndices, sopUIDImageIdIndexMap, imageIdMaps, eventTarget, triggerEvent);
|
|
2730
|
+
case 47:
|
|
2731
|
+
// calculate the centroid of each segment
|
|
2732
|
+
centroidXYZ = new Map();
|
|
2733
|
+
segmentsPixelIndices.forEach(function (imageIdIndexBufferIndex, segmentIndex) {
|
|
2734
|
+
var _calculateCentroid = calculateCentroid(imageIdIndexBufferIndex, multiframe),
|
|
2735
|
+
xAcc = _calculateCentroid.xAcc,
|
|
2736
|
+
yAcc = _calculateCentroid.yAcc,
|
|
2737
|
+
zAcc = _calculateCentroid.zAcc,
|
|
2738
|
+
count = _calculateCentroid.count;
|
|
2739
|
+
centroidXYZ.set(segmentIndex, {
|
|
2740
|
+
x: Math.floor(xAcc / count),
|
|
2741
|
+
y: Math.floor(yAcc / count),
|
|
2742
|
+
z: Math.floor(zAcc / count)
|
|
2743
|
+
});
|
|
2744
|
+
});
|
|
2745
|
+
return _context.abrupt("return", {
|
|
2746
|
+
labelmapBufferArray: labelmapBufferArray,
|
|
2747
|
+
segMetadata: segMetadata,
|
|
2748
|
+
segmentsOnFrame: segmentsOnFrame,
|
|
2749
|
+
segmentsOnFrameArray: segmentsOnFrameArray,
|
|
2750
|
+
centroids: centroidXYZ
|
|
2751
|
+
});
|
|
2752
|
+
case 50:
|
|
2753
|
+
case "end":
|
|
2754
|
+
return _context.stop();
|
|
2755
|
+
}
|
|
2756
|
+
}, _callee);
|
|
2757
|
+
}));
|
|
2758
|
+
return _generateToolState.apply(this, arguments);
|
|
2759
|
+
}
|
|
2760
|
+
function findReferenceSourceImageId(multiframe, frameSegment, imageIds, metadataProvider, tolerance, sopUIDImageIdIndexMap) {
|
|
2065
2761
|
var imageId = undefined;
|
|
2066
2762
|
if (!multiframe) {
|
|
2067
2763
|
return imageId;
|
|
@@ -2101,7 +2797,7 @@ function findReferenceSourceImageId(multiframe, frameSegment, imageIds, metadata
|
|
|
2101
2797
|
}
|
|
2102
2798
|
}
|
|
2103
2799
|
if (frameSourceImageSequence) {
|
|
2104
|
-
imageId =
|
|
2800
|
+
imageId = getImageIdOfSourceImageBySourceImageSequence(frameSourceImageSequence, sopUIDImageIdIndexMap);
|
|
2105
2801
|
}
|
|
2106
2802
|
if (imageId === undefined && ReferencedSeriesSequence) {
|
|
2107
2803
|
var referencedSeriesSequence = Array.isArray(ReferencedSeriesSequence) ? ReferencedSeriesSequence[0] : ReferencedSeriesSequence;
|
|
@@ -2116,7 +2812,7 @@ function findReferenceSourceImageId(multiframe, frameSegment, imageIds, metadata
|
|
|
2116
2812
|
* @returns {boolean} Returns a flag if segmentations overlapping
|
|
2117
2813
|
*/
|
|
2118
2814
|
|
|
2119
|
-
function checkSEGsOverlapping(pixelData, multiframe, imageIds, validOrientations, metadataProvider, tolerance) {
|
|
2815
|
+
function checkSEGsOverlapping(pixelData, multiframe, imageIds, validOrientations, metadataProvider, tolerance, TypedArrayConstructor, sopUIDImageIdIndexMap) {
|
|
2120
2816
|
var SharedFunctionalGroupsSequence = multiframe.SharedFunctionalGroupsSequence,
|
|
2121
2817
|
PerFrameFunctionalGroupsSequence = multiframe.PerFrameFunctionalGroupsSequence,
|
|
2122
2818
|
SegmentSequence = multiframe.SegmentSequence,
|
|
@@ -2143,7 +2839,7 @@ function checkSEGsOverlapping(pixelData, multiframe, imageIds, validOrientations
|
|
|
2143
2839
|
console.warn("Could not retrieve the segment index for frame segment " + frameSegment + ", skipping this frame.");
|
|
2144
2840
|
return "continue";
|
|
2145
2841
|
}
|
|
2146
|
-
var imageId = findReferenceSourceImageId(multiframe, frameSegment, imageIds, metadataProvider, tolerance);
|
|
2842
|
+
var imageId = findReferenceSourceImageId(multiframe, frameSegment, imageIds, metadataProvider, tolerance, sopUIDImageIdIndexMap);
|
|
2147
2843
|
if (!imageId) {
|
|
2148
2844
|
console.warn("Image not present in stack, can't import frame : " + frameSegment + ".");
|
|
2149
2845
|
return "continue";
|
|
@@ -2171,12 +2867,13 @@ function checkSEGsOverlapping(pixelData, multiframe, imageIds, validOrientations
|
|
|
2171
2867
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
2172
2868
|
var _step$value = _slicedToArray(_step.value, 2),
|
|
2173
2869
|
role = _step$value[1];
|
|
2174
|
-
var temp2DArray = new
|
|
2870
|
+
var temp2DArray = new TypedArrayConstructor(sliceLength).fill(0);
|
|
2175
2871
|
for (var i = 0; i < role.length; ++i) {
|
|
2176
2872
|
var _frameSegment = role[i];
|
|
2177
2873
|
var PerFrameFunctionalGroups = PerFrameFunctionalGroupsSequence[_frameSegment];
|
|
2178
2874
|
var ImageOrientationPatientI = sharedImageOrientationPatient || PerFrameFunctionalGroups.PlaneOrientationSequence.ImageOrientationPatient;
|
|
2179
|
-
var
|
|
2875
|
+
var view = readFromUnpackedChunks(pixelData, _frameSegment * sliceLength, sliceLength);
|
|
2876
|
+
var pixelDataI2D = ndarray__WEBPACK_IMPORTED_MODULE_2___default()(view, [Rows, Columns]);
|
|
2180
2877
|
var alignedPixelDataI = alignPixelDataWithSourceData(pixelDataI2D, ImageOrientationPatientI, validOrientations, tolerance);
|
|
2181
2878
|
if (!alignedPixelDataI) {
|
|
2182
2879
|
console.warn("Individual SEG frames are out of plane with respect to the first SEG frame, this is not yet supported, skipping this frame.");
|
|
@@ -2200,15 +2897,14 @@ function checkSEGsOverlapping(pixelData, multiframe, imageIds, validOrientations
|
|
|
2200
2897
|
}
|
|
2201
2898
|
return false;
|
|
2202
2899
|
}
|
|
2203
|
-
function insertOverlappingPixelDataPlanar(segmentsOnFrame, segmentsOnFrameArray, labelmapBufferArray, pixelData, multiframe, imageIds, validOrientations, metadataProvider, tolerance) {
|
|
2900
|
+
function insertOverlappingPixelDataPlanar(segmentsOnFrame, segmentsOnFrameArray, labelmapBufferArray, pixelData, multiframe, imageIds, validOrientations, metadataProvider, tolerance, TypedArrayConstructor, segmentsPixelIndices, sopUIDImageIdIndexMap) {
|
|
2204
2901
|
var SharedFunctionalGroupsSequence = multiframe.SharedFunctionalGroupsSequence,
|
|
2205
2902
|
PerFrameFunctionalGroupsSequence = multiframe.PerFrameFunctionalGroupsSequence,
|
|
2206
2903
|
Rows = multiframe.Rows,
|
|
2207
2904
|
Columns = multiframe.Columns;
|
|
2208
2905
|
var sharedImageOrientationPatient = SharedFunctionalGroupsSequence.PlaneOrientationSequence ? SharedFunctionalGroupsSequence.PlaneOrientationSequence.ImageOrientationPatient : undefined;
|
|
2209
2906
|
var sliceLength = Columns * Rows;
|
|
2210
|
-
var arrayBufferLength = sliceLength * imageIds.length *
|
|
2211
|
-
|
|
2907
|
+
var arrayBufferLength = sliceLength * imageIds.length * TypedArrayConstructor.BYTES_PER_ELEMENT;
|
|
2212
2908
|
// indicate the number of labelMaps
|
|
2213
2909
|
var M = 1;
|
|
2214
2910
|
|
|
@@ -2219,7 +2915,7 @@ function insertOverlappingPixelDataPlanar(segmentsOnFrame, segmentsOnFrameArray,
|
|
|
2219
2915
|
var tempBuffer = labelmapBufferArray[m].slice(0);
|
|
2220
2916
|
|
|
2221
2917
|
// temp list for checking overlaps
|
|
2222
|
-
var tempSegmentsOnFrame =
|
|
2918
|
+
var tempSegmentsOnFrame = lodash_clonedeep__WEBPACK_IMPORTED_MODULE_3___default()(segmentsOnFrameArray[m]);
|
|
2223
2919
|
|
|
2224
2920
|
/** split overlapping SEGs algorithm for each segment:
|
|
2225
2921
|
* A) copy the labelmapBuffer in the array with index 0
|
|
@@ -2241,12 +2937,17 @@ function insertOverlappingPixelDataPlanar(segmentsOnFrame, segmentsOnFrameArray,
|
|
|
2241
2937
|
return "continue";
|
|
2242
2938
|
}
|
|
2243
2939
|
var ImageOrientationPatientI = sharedImageOrientationPatient || PerFrameFunctionalGroups.PlaneOrientationSequence.ImageOrientationPatient;
|
|
2244
|
-
|
|
2940
|
+
|
|
2941
|
+
// Since we moved to the chunks approach, we need to read the data
|
|
2942
|
+
// and handle scenarios where the portion of data is in one chunk
|
|
2943
|
+
// and the other portion is in another chunk
|
|
2944
|
+
var view = readFromUnpackedChunks(pixelData, _i2 * sliceLength, sliceLength);
|
|
2945
|
+
var pixelDataI2D = ndarray__WEBPACK_IMPORTED_MODULE_2___default()(view, [Rows, Columns]);
|
|
2245
2946
|
var alignedPixelDataI = alignPixelDataWithSourceData(pixelDataI2D, ImageOrientationPatientI, validOrientations, tolerance);
|
|
2246
2947
|
if (!alignedPixelDataI) {
|
|
2247
2948
|
throw new Error("Individual SEG frames are out of plane with respect to the first SEG frame. " + "This is not yet supported. Aborting segmentation loading.");
|
|
2248
2949
|
}
|
|
2249
|
-
var imageId = findReferenceSourceImageId(multiframe, _i2, imageIds, metadataProvider, tolerance);
|
|
2950
|
+
var imageId = findReferenceSourceImageId(multiframe, _i2, imageIds, metadataProvider, tolerance, sopUIDImageIdIndexMap);
|
|
2250
2951
|
if (!imageId) {
|
|
2251
2952
|
console.warn("Image not present in stack, can't import frame : " + _i2 + ".");
|
|
2252
2953
|
i = _i2;
|
|
@@ -2259,9 +2960,8 @@ function insertOverlappingPixelDataPlanar(segmentsOnFrame, segmentsOnFrameArray,
|
|
|
2259
2960
|
var imageIdIndex = imageIds.findIndex(function (element) {
|
|
2260
2961
|
return element === imageId;
|
|
2261
2962
|
});
|
|
2262
|
-
var byteOffset = sliceLength *
|
|
2263
|
-
|
|
2264
|
-
var labelmap2DView = new Uint16Array(tempBuffer, byteOffset, sliceLength);
|
|
2963
|
+
var byteOffset = sliceLength * imageIdIndex * TypedArrayConstructor.BYTES_PER_ELEMENT;
|
|
2964
|
+
var labelmap2DView = new TypedArrayConstructor(tempBuffer, byteOffset, sliceLength);
|
|
2265
2965
|
var data = alignedPixelDataI.data;
|
|
2266
2966
|
var segmentOnFrame = false;
|
|
2267
2967
|
for (var j = 0, len = alignedPixelDataI.data.length; j < len; ++j) {
|
|
@@ -2274,7 +2974,7 @@ function insertOverlappingPixelDataPlanar(segmentsOnFrame, segmentsOnFrameArray,
|
|
|
2274
2974
|
M++;
|
|
2275
2975
|
}
|
|
2276
2976
|
tempBuffer = labelmapBufferArray[m].slice(0);
|
|
2277
|
-
tempSegmentsOnFrame =
|
|
2977
|
+
tempSegmentsOnFrame = lodash_clonedeep__WEBPACK_IMPORTED_MODULE_3___default()(segmentsOnFrameArray[m]);
|
|
2278
2978
|
_i2 = 0;
|
|
2279
2979
|
break;
|
|
2280
2980
|
} else {
|
|
@@ -2300,12 +3000,12 @@ function insertOverlappingPixelDataPlanar(segmentsOnFrame, segmentsOnFrameArray,
|
|
|
2300
3000
|
if (_ret2 === "continue") continue;
|
|
2301
3001
|
}
|
|
2302
3002
|
labelmapBufferArray[m] = tempBuffer.slice(0);
|
|
2303
|
-
segmentsOnFrameArray[m] =
|
|
3003
|
+
segmentsOnFrameArray[m] = lodash_clonedeep__WEBPACK_IMPORTED_MODULE_3___default()(tempSegmentsOnFrame);
|
|
2304
3004
|
|
|
2305
3005
|
// reset temp variables/buffers for new segment
|
|
2306
3006
|
m = 0;
|
|
2307
3007
|
tempBuffer = labelmapBufferArray[m].slice(0);
|
|
2308
|
-
tempSegmentsOnFrame =
|
|
3008
|
+
tempSegmentsOnFrame = lodash_clonedeep__WEBPACK_IMPORTED_MODULE_3___default()(segmentsOnFrameArray[m]);
|
|
2309
3009
|
}
|
|
2310
3010
|
}
|
|
2311
3011
|
var getSegmentIndex = function getSegmentIndex(multiframe, frame) {
|
|
@@ -2314,60 +3014,93 @@ var getSegmentIndex = function getSegmentIndex(multiframe, frame) {
|
|
|
2314
3014
|
var PerFrameFunctionalGroups = PerFrameFunctionalGroupsSequence[frame];
|
|
2315
3015
|
return PerFrameFunctionalGroups && PerFrameFunctionalGroups.SegmentIdentificationSequence ? PerFrameFunctionalGroups.SegmentIdentificationSequence.ReferencedSegmentNumber : SharedFunctionalGroupsSequence.SegmentIdentificationSequence ? SharedFunctionalGroupsSequence.SegmentIdentificationSequence.ReferencedSegmentNumber : undefined;
|
|
2316
3016
|
};
|
|
2317
|
-
function insertPixelDataPlanar(segmentsOnFrame, segmentsOnFrameArray, labelmapBufferArray, pixelData, multiframe, imageIds, validOrientations, metadataProvider, tolerance) {
|
|
3017
|
+
function insertPixelDataPlanar(segmentsOnFrame, segmentsOnFrameArray, labelmapBufferArray, pixelData, multiframe, imageIds, validOrientations, metadataProvider, tolerance, TypedArrayConstructor, segmentsPixelIndices, sopUIDImageIdIndexMap, imageIdMaps, eventTarget, triggerEvent) {
|
|
2318
3018
|
var SharedFunctionalGroupsSequence = multiframe.SharedFunctionalGroupsSequence,
|
|
2319
3019
|
PerFrameFunctionalGroupsSequence = multiframe.PerFrameFunctionalGroupsSequence,
|
|
2320
3020
|
Rows = multiframe.Rows,
|
|
2321
3021
|
Columns = multiframe.Columns;
|
|
2322
3022
|
var sharedImageOrientationPatient = SharedFunctionalGroupsSequence.PlaneOrientationSequence ? SharedFunctionalGroupsSequence.PlaneOrientationSequence.ImageOrientationPatient : undefined;
|
|
2323
3023
|
var sliceLength = Columns * Rows;
|
|
2324
|
-
var
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
}
|
|
2345
|
-
var imageIdIndex = imageIds.findIndex(function (element) {
|
|
2346
|
-
return element === imageId;
|
|
2347
|
-
});
|
|
2348
|
-
var byteOffset = sliceLength * 2 * imageIdIndex; // 2 bytes/pixel
|
|
2349
|
-
|
|
2350
|
-
var labelmap2DView = new Uint16Array(labelmapBufferArray[0], byteOffset, sliceLength);
|
|
2351
|
-
var data = alignedPixelDataI.data;
|
|
2352
|
-
for (var j = 0, len = alignedPixelDataI.data.length; j < len; ++j) {
|
|
2353
|
-
if (data[j]) {
|
|
2354
|
-
for (var x = j; x < len; ++x) {
|
|
2355
|
-
if (data[x]) {
|
|
2356
|
-
labelmap2DView[x] = segmentIndex;
|
|
2357
|
-
}
|
|
3024
|
+
var i = 0;
|
|
3025
|
+
var groupsLen = PerFrameFunctionalGroupsSequence.length;
|
|
3026
|
+
var chunkSize = Math.ceil(groupsLen / 10); // 10% of total length
|
|
3027
|
+
|
|
3028
|
+
var shouldTriggerEvent = triggerEvent && eventTarget;
|
|
3029
|
+
|
|
3030
|
+
// Below, we chunk the processing of the frames to avoid blocking the main thread
|
|
3031
|
+
// if the segmentation is large. We also use a promise to allow the caller to
|
|
3032
|
+
// wait for the processing to finish.
|
|
3033
|
+
return new Promise(function (resolve) {
|
|
3034
|
+
function processInChunks() {
|
|
3035
|
+
// process one chunk
|
|
3036
|
+
for (var end = Math.min(i + chunkSize, groupsLen); i < end; ++i) {
|
|
3037
|
+
var PerFrameFunctionalGroups = PerFrameFunctionalGroupsSequence[i];
|
|
3038
|
+
var ImageOrientationPatientI = sharedImageOrientationPatient || PerFrameFunctionalGroups.PlaneOrientationSequence.ImageOrientationPatient;
|
|
3039
|
+
var view = readFromUnpackedChunks(pixelData, i * sliceLength, sliceLength);
|
|
3040
|
+
var pixelDataI2D = ndarray__WEBPACK_IMPORTED_MODULE_2___default()(view, [Rows, Columns]);
|
|
3041
|
+
var alignedPixelDataI = alignPixelDataWithSourceData(pixelDataI2D, ImageOrientationPatientI, validOrientations, tolerance);
|
|
3042
|
+
if (!alignedPixelDataI) {
|
|
3043
|
+
throw new Error("Individual SEG frames are out of plane with respect to the first SEG frame. " + "This is not yet supported. Aborting segmentation loading.");
|
|
2358
3044
|
}
|
|
2359
|
-
|
|
2360
|
-
|
|
3045
|
+
var segmentIndex = getSegmentIndex(multiframe, i);
|
|
3046
|
+
if (segmentIndex === undefined) {
|
|
3047
|
+
throw new Error("Could not retrieve the segment index. Aborting segmentation loading.");
|
|
2361
3048
|
}
|
|
2362
|
-
|
|
2363
|
-
|
|
3049
|
+
if (!segmentsPixelIndices.has(segmentIndex)) {
|
|
3050
|
+
segmentsPixelIndices.set(segmentIndex, {});
|
|
3051
|
+
}
|
|
3052
|
+
var imageId = findReferenceSourceImageId(multiframe, i, imageIds, metadataProvider, tolerance, sopUIDImageIdIndexMap);
|
|
3053
|
+
if (!imageId) {
|
|
3054
|
+
console.warn("Image not present in stack, can't import frame : " + i + ".");
|
|
3055
|
+
continue;
|
|
3056
|
+
}
|
|
3057
|
+
var sourceImageMetadata = imageIdMaps.metadata[imageId];
|
|
3058
|
+
if (Rows !== sourceImageMetadata.Rows || Columns !== sourceImageMetadata.Columns) {
|
|
3059
|
+
throw new Error("Individual SEG frames have different geometry dimensions (Rows and Columns) " + "respect to the source image reference frame. This is not yet supported. " + "Aborting segmentation loading. ");
|
|
3060
|
+
}
|
|
3061
|
+
var imageIdIndex = imageIdMaps.indices[imageId];
|
|
3062
|
+
var byteOffset = sliceLength * imageIdIndex * TypedArrayConstructor.BYTES_PER_ELEMENT;
|
|
3063
|
+
var labelmap2DView = new TypedArrayConstructor(labelmapBufferArray[0], byteOffset, sliceLength);
|
|
3064
|
+
var data = alignedPixelDataI.data;
|
|
3065
|
+
var indexCache = [];
|
|
3066
|
+
for (var j = 0, len = alignedPixelDataI.data.length; j < len; ++j) {
|
|
3067
|
+
if (data[j]) {
|
|
3068
|
+
for (var x = j; x < len; ++x) {
|
|
3069
|
+
if (data[x]) {
|
|
3070
|
+
labelmap2DView[x] = segmentIndex;
|
|
3071
|
+
indexCache.push(x);
|
|
3072
|
+
}
|
|
3073
|
+
}
|
|
3074
|
+
if (!segmentsOnFrame[imageIdIndex]) {
|
|
3075
|
+
segmentsOnFrame[imageIdIndex] = [];
|
|
3076
|
+
}
|
|
3077
|
+
segmentsOnFrame[imageIdIndex].push(segmentIndex);
|
|
3078
|
+
break;
|
|
3079
|
+
}
|
|
3080
|
+
}
|
|
3081
|
+
var segmentIndexObject = segmentsPixelIndices.get(segmentIndex);
|
|
3082
|
+
segmentIndexObject[imageIdIndex] = indexCache;
|
|
3083
|
+
segmentsPixelIndices.set(segmentIndex, segmentIndexObject);
|
|
3084
|
+
}
|
|
3085
|
+
|
|
3086
|
+
// trigger an event after each chunk
|
|
3087
|
+
if (shouldTriggerEvent) {
|
|
3088
|
+
var percentComplete = Math.round(i / groupsLen * 100);
|
|
3089
|
+
triggerEvent(eventTarget, Events$1.SEGMENTATION_LOAD_PROGRESS, {
|
|
3090
|
+
percentComplete: percentComplete
|
|
3091
|
+
});
|
|
3092
|
+
}
|
|
3093
|
+
|
|
3094
|
+
// schedule next chunk
|
|
3095
|
+
if (i < groupsLen) {
|
|
3096
|
+
setTimeout(processInChunks, 0);
|
|
3097
|
+
} else {
|
|
3098
|
+
// resolve the Promise when all chunks have been processed
|
|
3099
|
+
resolve();
|
|
2364
3100
|
}
|
|
2365
3101
|
}
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
var _ret3 = _loop5();
|
|
2369
|
-
if (_ret3 === "continue") continue;
|
|
2370
|
-
}
|
|
3102
|
+
processInChunks();
|
|
3103
|
+
});
|
|
2371
3104
|
}
|
|
2372
3105
|
function checkOrientation(multiframe, validOrientations, sourceDataDimensions, tolerance) {
|
|
2373
3106
|
var SharedFunctionalGroupsSequence = multiframe.SharedFunctionalGroupsSequence,
|
|
@@ -2406,12 +3139,13 @@ function checkIfPerpendicular(iop1, iop2, tolerance) {
|
|
|
2406
3139
|
}
|
|
2407
3140
|
|
|
2408
3141
|
/**
|
|
2409
|
-
* unpackPixelData - Unpacks
|
|
3142
|
+
* unpackPixelData - Unpacks bit packed pixelData if the Segmentation is BINARY.
|
|
2410
3143
|
*
|
|
2411
3144
|
* @param {Object} multiframe The multiframe dataset.
|
|
3145
|
+
* @param {Object} options Options for the unpacking.
|
|
2412
3146
|
* @return {Uint8Array} The unpacked pixelData.
|
|
2413
3147
|
*/
|
|
2414
|
-
function unpackPixelData(multiframe) {
|
|
3148
|
+
function unpackPixelData(multiframe, options) {
|
|
2415
3149
|
var segType = multiframe.SegmentationType;
|
|
2416
3150
|
var data;
|
|
2417
3151
|
if (Array.isArray(multiframe.PixelData)) {
|
|
@@ -2423,7 +3157,10 @@ function unpackPixelData(multiframe) {
|
|
|
2423
3157
|
dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .log */ .cM.error("This segmentation pixeldata is undefined.");
|
|
2424
3158
|
}
|
|
2425
3159
|
if (segType === "BINARY") {
|
|
2426
|
-
|
|
3160
|
+
// For extreme big data, we can't unpack the data at once and we need to
|
|
3161
|
+
// chunk it and unpack each chunk separately.
|
|
3162
|
+
// MAX 2GB is the limit right now to allocate a buffer
|
|
3163
|
+
return getUnpackedChunks(data, options.maxBytesPerChunk);
|
|
2427
3164
|
}
|
|
2428
3165
|
var pixelData = new Uint8Array(data);
|
|
2429
3166
|
var max = multiframe.MaximumFractionalValue;
|
|
@@ -2437,20 +3174,35 @@ function unpackPixelData(multiframe) {
|
|
|
2437
3174
|
dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .log */ .cM.warn("This segmentation object is actually binary... processing as such.");
|
|
2438
3175
|
return pixelData;
|
|
2439
3176
|
}
|
|
3177
|
+
function getUnpackedChunks(data, maxBytesPerChunk) {
|
|
3178
|
+
var bitArray = new Uint8Array(data);
|
|
3179
|
+
var chunks = [];
|
|
3180
|
+
var maxBitsPerChunk = maxBytesPerChunk * 8;
|
|
3181
|
+
var numberOfChunks = Math.ceil(bitArray.length * 8 / maxBitsPerChunk);
|
|
3182
|
+
for (var i = 0; i < numberOfChunks; i++) {
|
|
3183
|
+
var startBit = i * maxBitsPerChunk;
|
|
3184
|
+
var endBit = Math.min(startBit + maxBitsPerChunk, bitArray.length * 8);
|
|
3185
|
+
var startByte = Math.floor(startBit / 8);
|
|
3186
|
+
var endByte = Math.ceil(endBit / 8);
|
|
3187
|
+
var chunk = bitArray.slice(startByte, endByte);
|
|
3188
|
+
var unpackedChunk = BitArray$1.unpack(chunk);
|
|
3189
|
+
chunks.push(unpackedChunk);
|
|
3190
|
+
}
|
|
3191
|
+
return chunks;
|
|
3192
|
+
}
|
|
2440
3193
|
|
|
2441
3194
|
/**
|
|
2442
|
-
*
|
|
3195
|
+
* getImageIdOfSourceImageBySourceImageSequence - Returns the Cornerstone imageId of the source image.
|
|
2443
3196
|
*
|
|
2444
3197
|
* @param {Object} SourceImageSequence Sequence describing the source image.
|
|
2445
3198
|
* @param {String[]} imageIds A list of imageIds.
|
|
2446
|
-
* @param {Object}
|
|
2447
|
-
* metadata from imageIds.
|
|
3199
|
+
* @param {Object} sopUIDImageIdIndexMap A map of SOPInstanceUIDs to imageIds.
|
|
2448
3200
|
* @return {String} The corresponding imageId.
|
|
2449
3201
|
*/
|
|
2450
|
-
function
|
|
3202
|
+
function getImageIdOfSourceImageBySourceImageSequence(SourceImageSequence, sopUIDImageIdIndexMap) {
|
|
2451
3203
|
var ReferencedSOPInstanceUID = SourceImageSequence.ReferencedSOPInstanceUID,
|
|
2452
3204
|
ReferencedFrameNumber = SourceImageSequence.ReferencedFrameNumber;
|
|
2453
|
-
return ReferencedFrameNumber ? getImageIdOfReferencedFrame(ReferencedSOPInstanceUID, ReferencedFrameNumber,
|
|
3205
|
+
return ReferencedFrameNumber ? getImageIdOfReferencedFrame(ReferencedSOPInstanceUID, ReferencedFrameNumber, sopUIDImageIdIndexMap) : sopUIDImageIdIndexMap[ReferencedSOPInstanceUID];
|
|
2454
3206
|
}
|
|
2455
3207
|
|
|
2456
3208
|
/**
|
|
@@ -2460,7 +3212,7 @@ function getImageIdOfSourceImagebySourceImageSequence(SourceImageSequence, image
|
|
|
2460
3212
|
* @param {String} FrameOfReferenceUID Frame of reference.
|
|
2461
3213
|
* @param {Object} PerFrameFunctionalGroup Sequence describing segmentation reference attributes per frame.
|
|
2462
3214
|
* @param {String[]} imageIds A list of imageIds.
|
|
2463
|
-
* @param {Object}
|
|
3215
|
+
* @param {Object} sopUIDImageIdIndexMap A map of SOPInstanceUIDs to imageIds.
|
|
2464
3216
|
* @param {Float} tolerance The tolerance parameter
|
|
2465
3217
|
*
|
|
2466
3218
|
* @return {String} The corresponding imageId.
|
|
@@ -2480,26 +3232,6 @@ function getImageIdOfSourceImagebyGeometry(ReferencedSeriesInstanceUID, FrameOfR
|
|
|
2480
3232
|
}
|
|
2481
3233
|
}
|
|
2482
3234
|
|
|
2483
|
-
/**
|
|
2484
|
-
* getImageIdOfReferencedSingleFramedSOPInstance - Returns the imageId
|
|
2485
|
-
* corresponding to the specified sopInstanceUid for single-frame images.
|
|
2486
|
-
*
|
|
2487
|
-
* @param {String} sopInstanceUid The sopInstanceUid of the desired image.
|
|
2488
|
-
* @param {String[]} imageIds The list of imageIds.
|
|
2489
|
-
* @param {Object} metadataProvider The metadataProvider to obtain sopInstanceUids
|
|
2490
|
-
* from the cornerstone imageIds.
|
|
2491
|
-
* @return {String} The imageId that corresponds to the sopInstanceUid.
|
|
2492
|
-
*/
|
|
2493
|
-
function getImageIdOfReferencedSingleFramedSOPInstance(sopInstanceUid, imageIds, metadataProvider) {
|
|
2494
|
-
return imageIds.find(function (imageId) {
|
|
2495
|
-
var sopCommonModule = metadataProvider.get("sopCommonModule", imageId);
|
|
2496
|
-
if (!sopCommonModule) {
|
|
2497
|
-
return;
|
|
2498
|
-
}
|
|
2499
|
-
return sopCommonModule.sopInstanceUID === sopInstanceUid;
|
|
2500
|
-
});
|
|
2501
|
-
}
|
|
2502
|
-
|
|
2503
3235
|
/**
|
|
2504
3236
|
* getImageIdOfReferencedFrame - Returns the imageId corresponding to the
|
|
2505
3237
|
* specified sopInstanceUid and frameNumber for multi-frame images.
|
|
@@ -2507,23 +3239,16 @@ function getImageIdOfReferencedSingleFramedSOPInstance(sopInstanceUid, imageIds,
|
|
|
2507
3239
|
* @param {String} sopInstanceUid The sopInstanceUid of the desired image.
|
|
2508
3240
|
* @param {Number} frameNumber The frame number.
|
|
2509
3241
|
* @param {String} imageIds The list of imageIds.
|
|
2510
|
-
* @param {Object}
|
|
2511
|
-
* from the cornerstone imageIds.
|
|
3242
|
+
* @param {Object} sopUIDImageIdIndexMap A map of SOPInstanceUIDs to imageIds.
|
|
2512
3243
|
* @return {String} The imageId that corresponds to the sopInstanceUid.
|
|
2513
3244
|
*/
|
|
2514
|
-
function getImageIdOfReferencedFrame(sopInstanceUid, frameNumber,
|
|
2515
|
-
var imageId =
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
return (
|
|
2522
|
-
//frameNumber is zero indexed for cornerstoneDICOMImageLoader image Ids.
|
|
2523
|
-
sopCommonModule.sopInstanceUID === sopInstanceUid && imageIdFrameNumber === frameNumber - 1
|
|
2524
|
-
);
|
|
2525
|
-
});
|
|
2526
|
-
return imageId;
|
|
3245
|
+
function getImageIdOfReferencedFrame(sopInstanceUid, frameNumber, sopUIDImageIdIndexMap) {
|
|
3246
|
+
var imageId = sopUIDImageIdIndexMap[sopInstanceUid];
|
|
3247
|
+
if (!imageId) {
|
|
3248
|
+
return;
|
|
3249
|
+
}
|
|
3250
|
+
var imageIdFrameNumber = Number(imageId.split("frame=")[1]);
|
|
3251
|
+
return imageIdFrameNumber === frameNumber - 1 ? imageId : undefined;
|
|
2527
3252
|
}
|
|
2528
3253
|
|
|
2529
3254
|
/**
|
|
@@ -2635,9 +3360,111 @@ function getSegmentMetadata(multiframe, seriesInstanceUid) {
|
|
|
2635
3360
|
};
|
|
2636
3361
|
}
|
|
2637
3362
|
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
3363
|
+
/**
|
|
3364
|
+
* Reads a range of bytes from an array of ArrayBuffer chunks and
|
|
3365
|
+
* aggregate them into a new Uint8Array.
|
|
3366
|
+
*
|
|
3367
|
+
* @param {ArrayBuffer[]} chunks - An array of ArrayBuffer chunks.
|
|
3368
|
+
* @param {number} offset - The offset of the first byte to read.
|
|
3369
|
+
* @param {number} length - The number of bytes to read.
|
|
3370
|
+
* @returns {Uint8Array} A new Uint8Array containing the requested bytes.
|
|
3371
|
+
*/
|
|
3372
|
+
function readFromUnpackedChunks(chunks, offset, length) {
|
|
3373
|
+
var mapping = getUnpackedOffsetAndLength(chunks, offset, length);
|
|
3374
|
+
|
|
3375
|
+
// If all the data is in one chunk, we can just slice that chunk
|
|
3376
|
+
if (mapping.start.chunkIndex === mapping.end.chunkIndex) {
|
|
3377
|
+
return new Uint8Array(chunks[mapping.start.chunkIndex].buffer, mapping.start.offset, length);
|
|
3378
|
+
} else {
|
|
3379
|
+
// If the data spans multiple chunks, we need to create a new Uint8Array and copy the data from each chunk
|
|
3380
|
+
var result = new Uint8Array(length);
|
|
3381
|
+
var resultOffset = 0;
|
|
3382
|
+
for (var i = mapping.start.chunkIndex; i <= mapping.end.chunkIndex; i++) {
|
|
3383
|
+
var start = i === mapping.start.chunkIndex ? mapping.start.offset : 0;
|
|
3384
|
+
var end = i === mapping.end.chunkIndex ? mapping.end.offset : chunks[i].length;
|
|
3385
|
+
result.set(new Uint8Array(chunks[i].buffer, start, end - start), resultOffset);
|
|
3386
|
+
resultOffset += end - start;
|
|
3387
|
+
}
|
|
3388
|
+
return result;
|
|
3389
|
+
}
|
|
3390
|
+
}
|
|
3391
|
+
function getUnpackedOffsetAndLength(chunks, offset, length) {
|
|
3392
|
+
var totalBytes = chunks.reduce(function (total, chunk) {
|
|
3393
|
+
return total + chunk.length;
|
|
3394
|
+
}, 0);
|
|
3395
|
+
if (offset < 0 || offset + length > totalBytes) {
|
|
3396
|
+
throw new Error("Offset and length out of bounds");
|
|
3397
|
+
}
|
|
3398
|
+
var startChunkIndex = 0;
|
|
3399
|
+
var startOffsetInChunk = offset;
|
|
3400
|
+
while (startOffsetInChunk >= chunks[startChunkIndex].length) {
|
|
3401
|
+
startOffsetInChunk -= chunks[startChunkIndex].length;
|
|
3402
|
+
startChunkIndex++;
|
|
3403
|
+
}
|
|
3404
|
+
var endChunkIndex = startChunkIndex;
|
|
3405
|
+
var endOffsetInChunk = startOffsetInChunk + length;
|
|
3406
|
+
while (endOffsetInChunk > chunks[endChunkIndex].length) {
|
|
3407
|
+
endOffsetInChunk -= chunks[endChunkIndex].length;
|
|
3408
|
+
endChunkIndex++;
|
|
3409
|
+
}
|
|
3410
|
+
return {
|
|
3411
|
+
start: {
|
|
3412
|
+
chunkIndex: startChunkIndex,
|
|
3413
|
+
offset: startOffsetInChunk
|
|
3414
|
+
},
|
|
3415
|
+
end: {
|
|
3416
|
+
chunkIndex: endChunkIndex,
|
|
3417
|
+
offset: endOffsetInChunk
|
|
3418
|
+
}
|
|
3419
|
+
};
|
|
3420
|
+
}
|
|
3421
|
+
function calculateCentroid(imageIdIndexBufferIndex, multiframe) {
|
|
3422
|
+
var xAcc = 0;
|
|
3423
|
+
var yAcc = 0;
|
|
3424
|
+
var zAcc = 0;
|
|
3425
|
+
var count = 0;
|
|
3426
|
+
for (var _i3 = 0, _Object$entries = Object.entries(imageIdIndexBufferIndex); _i3 < _Object$entries.length; _i3++) {
|
|
3427
|
+
var _Object$entries$_i = _slicedToArray(_Object$entries[_i3], 2),
|
|
3428
|
+
imageIdIndex = _Object$entries$_i[0],
|
|
3429
|
+
bufferIndices = _Object$entries$_i[1];
|
|
3430
|
+
var z = Number(imageIdIndex);
|
|
3431
|
+
if (!bufferIndices || bufferIndices.length === 0) {
|
|
3432
|
+
continue;
|
|
3433
|
+
}
|
|
3434
|
+
var _iterator2 = _createForOfIteratorHelper(bufferIndices),
|
|
3435
|
+
_step2;
|
|
3436
|
+
try {
|
|
3437
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
3438
|
+
var bufferIndex = _step2.value;
|
|
3439
|
+
var y = Math.floor(bufferIndex / multiframe.Rows);
|
|
3440
|
+
var x = bufferIndex % multiframe.Rows;
|
|
3441
|
+
xAcc += x;
|
|
3442
|
+
yAcc += y;
|
|
3443
|
+
zAcc += z;
|
|
3444
|
+
count++;
|
|
3445
|
+
}
|
|
3446
|
+
} catch (err) {
|
|
3447
|
+
_iterator2.e(err);
|
|
3448
|
+
} finally {
|
|
3449
|
+
_iterator2.f();
|
|
3450
|
+
}
|
|
3451
|
+
}
|
|
3452
|
+
return {
|
|
3453
|
+
xAcc: xAcc,
|
|
3454
|
+
yAcc: yAcc,
|
|
3455
|
+
zAcc: zAcc,
|
|
3456
|
+
count: count
|
|
3457
|
+
};
|
|
3458
|
+
}
|
|
3459
|
+
var Segmentation$4 = {
|
|
3460
|
+
generateSegmentation: generateSegmentation$2,
|
|
3461
|
+
generateToolState: generateToolState$2,
|
|
3462
|
+
fillSegmentation: fillSegmentation$1
|
|
3463
|
+
};
|
|
3464
|
+
|
|
3465
|
+
var Segmentation$3 = {
|
|
3466
|
+
generateSegmentation: generateSegmentation$1,
|
|
3467
|
+
generateToolState: generateToolState$1,
|
|
2641
3468
|
fillSegmentation: fillSegmentation
|
|
2642
3469
|
};
|
|
2643
3470
|
|
|
@@ -2650,16 +3477,16 @@ var Segmentation$1 = {
|
|
|
2650
3477
|
* @param {number} cornerstoneToolsVersion The cornerstoneTools major version to map against.
|
|
2651
3478
|
* @returns {Object}
|
|
2652
3479
|
*/
|
|
2653
|
-
function generateSegmentation(images, labelmaps3DorBrushData) {
|
|
3480
|
+
function generateSegmentation$1(images, labelmaps3DorBrushData) {
|
|
2654
3481
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
|
|
2655
3482
|
includeSliceSpacing: true
|
|
2656
3483
|
};
|
|
2657
3484
|
var cornerstoneToolsVersion = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 4;
|
|
2658
3485
|
if (cornerstoneToolsVersion === 4) {
|
|
2659
|
-
return Segmentation$
|
|
3486
|
+
return Segmentation$4.generateSegmentation(images, labelmaps3DorBrushData, options);
|
|
2660
3487
|
}
|
|
2661
3488
|
if (cornerstoneToolsVersion === 3) {
|
|
2662
|
-
return Segmentation$
|
|
3489
|
+
return Segmentation$5.generateSegmentation(images, labelmaps3DorBrushData, options);
|
|
2663
3490
|
}
|
|
2664
3491
|
console.warn("No generateSegmentation adapater for cornerstone version ".concat(cornerstoneToolsVersion, ", exiting."));
|
|
2665
3492
|
}
|
|
@@ -2678,323 +3505,52 @@ function generateSegmentation(images, labelmaps3DorBrushData) {
|
|
|
2678
3505
|
* @returns {Object} The toolState and an object from which the
|
|
2679
3506
|
* segment metadata can be derived.
|
|
2680
3507
|
*/
|
|
2681
|
-
function generateToolState(imageIds, arrayBuffer, metadataProvider) {
|
|
3508
|
+
function generateToolState$1(imageIds, arrayBuffer, metadataProvider) {
|
|
2682
3509
|
var skipOverlapping = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
2683
3510
|
var tolerance = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1e-3;
|
|
2684
3511
|
var cornerstoneToolsVersion = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 4;
|
|
2685
3512
|
if (cornerstoneToolsVersion === 4) {
|
|
2686
|
-
return Segmentation$
|
|
3513
|
+
return Segmentation$4.generateToolState(imageIds, arrayBuffer, metadataProvider, skipOverlapping, tolerance);
|
|
2687
3514
|
}
|
|
2688
3515
|
if (cornerstoneToolsVersion === 3) {
|
|
2689
|
-
return Segmentation$
|
|
3516
|
+
return Segmentation$5.generateToolState(imageIds, arrayBuffer, metadataProvider);
|
|
2690
3517
|
}
|
|
2691
3518
|
console.warn("No generateToolState adapater for cornerstone version ".concat(cornerstoneToolsVersion, ", exiting."));
|
|
2692
3519
|
}
|
|
2693
3520
|
|
|
2694
3521
|
/**
|
|
2695
3522
|
* fillSegmentation - Fills a derived segmentation dataset with cornerstoneTools `LabelMap3D` data.
|
|
2696
|
-
*
|
|
2697
|
-
* @param {object[]} segmentation An empty segmentation derived dataset.
|
|
2698
|
-
* @param {Object|Object[]} inputLabelmaps3D The cornerstone `Labelmap3D` object, or an array of objects.
|
|
2699
|
-
* @param {Object} userOptions Options object to override default options.
|
|
2700
|
-
* @returns {Blob} description
|
|
2701
|
-
*/
|
|
2702
|
-
function fillSegmentation(segmentation, inputLabelmaps3D) {
|
|
2703
|
-
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
|
|
2704
|
-
includeSliceSpacing: true
|
|
2705
|
-
};
|
|
2706
|
-
var cornerstoneToolsVersion = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 4;
|
|
2707
|
-
if (cornerstoneToolsVersion === 4) {
|
|
2708
|
-
return Segmentation$
|
|
2709
|
-
}
|
|
2710
|
-
console.warn("No generateSegmentation adapater for cornerstone version ".concat(cornerstoneToolsVersion, ", exiting."));
|
|
2711
|
-
}
|
|
2712
|
-
|
|
2713
|
-
var TID300CobbAngle$2 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.TID300.CobbAngle;
|
|
2714
|
-
var COBB_ANGLE = "CobbAngle";
|
|
2715
|
-
var CobbAngle$1 = /*#__PURE__*/function () {
|
|
2716
|
-
function CobbAngle() {
|
|
2717
|
-
_classCallCheck(this, CobbAngle);
|
|
2718
|
-
}
|
|
2719
|
-
_createClass(CobbAngle, null, [{
|
|
2720
|
-
key: "getMeasurementData",
|
|
2721
|
-
value:
|
|
2722
|
-
// TODO: this function is required for all Cornerstone Tool Adapters, since it is called by MeasurementReport.
|
|
2723
|
-
function getMeasurementData(MeasurementGroup) {
|
|
2724
|
-
var _MeasurementReport$ge = MeasurementReport$1.getSetupMeasurementData(MeasurementGroup),
|
|
2725
|
-
defaultState = _MeasurementReport$ge.defaultState,
|
|
2726
|
-
NUMGroup = _MeasurementReport$ge.NUMGroup,
|
|
2727
|
-
SCOORDGroup = _MeasurementReport$ge.SCOORDGroup;
|
|
2728
|
-
var state = _objectSpread2(_objectSpread2({}, defaultState), {}, {
|
|
2729
|
-
rAngle: NUMGroup.MeasuredValueSequence.NumericValue,
|
|
2730
|
-
toolType: CobbAngle.toolType,
|
|
2731
|
-
handles: {
|
|
2732
|
-
start: {},
|
|
2733
|
-
end: {},
|
|
2734
|
-
start2: {
|
|
2735
|
-
highlight: true,
|
|
2736
|
-
drawnIndependently: true
|
|
2737
|
-
},
|
|
2738
|
-
end2: {
|
|
2739
|
-
highlight: true,
|
|
2740
|
-
drawnIndependently: true
|
|
2741
|
-
},
|
|
2742
|
-
textBox: {
|
|
2743
|
-
hasMoved: false,
|
|
2744
|
-
movesIndependently: false,
|
|
2745
|
-
drawnIndependently: true,
|
|
2746
|
-
allowedOutsideImage: true,
|
|
2747
|
-
hasBoundingBox: true
|
|
2748
|
-
}
|
|
2749
|
-
}
|
|
2750
|
-
});
|
|
2751
|
-
var _SCOORDGroup$GraphicD = _slicedToArray(SCOORDGroup.GraphicData, 8);
|
|
2752
|
-
state.handles.start.x = _SCOORDGroup$GraphicD[0];
|
|
2753
|
-
state.handles.start.y = _SCOORDGroup$GraphicD[1];
|
|
2754
|
-
state.handles.end.x = _SCOORDGroup$GraphicD[2];
|
|
2755
|
-
state.handles.end.y = _SCOORDGroup$GraphicD[3];
|
|
2756
|
-
state.handles.start2.x = _SCOORDGroup$GraphicD[4];
|
|
2757
|
-
state.handles.start2.y = _SCOORDGroup$GraphicD[5];
|
|
2758
|
-
state.handles.end2.x = _SCOORDGroup$GraphicD[6];
|
|
2759
|
-
state.handles.end2.y = _SCOORDGroup$GraphicD[7];
|
|
2760
|
-
return state;
|
|
2761
|
-
}
|
|
2762
|
-
}, {
|
|
2763
|
-
key: "getTID300RepresentationArguments",
|
|
2764
|
-
value: function getTID300RepresentationArguments(tool) {
|
|
2765
|
-
var handles = tool.handles,
|
|
2766
|
-
finding = tool.finding,
|
|
2767
|
-
findingSites = tool.findingSites;
|
|
2768
|
-
var point1 = handles.start;
|
|
2769
|
-
var point2 = handles.end;
|
|
2770
|
-
var point3 = handles.start2;
|
|
2771
|
-
var point4 = handles.end2;
|
|
2772
|
-
var rAngle = tool.rAngle;
|
|
2773
|
-
var trackingIdentifierTextValue = "cornerstoneTools@^4.0.0:CobbAngle";
|
|
2774
|
-
return {
|
|
2775
|
-
point1: point1,
|
|
2776
|
-
point2: point2,
|
|
2777
|
-
point3: point3,
|
|
2778
|
-
point4: point4,
|
|
2779
|
-
rAngle: rAngle,
|
|
2780
|
-
trackingIdentifierTextValue: trackingIdentifierTextValue,
|
|
2781
|
-
finding: finding,
|
|
2782
|
-
findingSites: findingSites || []
|
|
2783
|
-
};
|
|
2784
|
-
}
|
|
2785
|
-
}]);
|
|
2786
|
-
return CobbAngle;
|
|
2787
|
-
}();
|
|
2788
|
-
CobbAngle$1.toolType = COBB_ANGLE;
|
|
2789
|
-
CobbAngle$1.utilityToolType = COBB_ANGLE;
|
|
2790
|
-
CobbAngle$1.TID300Representation = TID300CobbAngle$2;
|
|
2791
|
-
CobbAngle$1.isValidCornerstoneTrackingIdentifier = function (TrackingIdentifier) {
|
|
2792
|
-
if (!TrackingIdentifier.includes(":")) {
|
|
2793
|
-
return false;
|
|
2794
|
-
}
|
|
2795
|
-
var _TrackingIdentifier$s = TrackingIdentifier.split(":"),
|
|
2796
|
-
_TrackingIdentifier$s2 = _slicedToArray(_TrackingIdentifier$s, 2),
|
|
2797
|
-
cornerstone4Tag = _TrackingIdentifier$s2[0],
|
|
2798
|
-
toolType = _TrackingIdentifier$s2[1];
|
|
2799
|
-
if (cornerstone4Tag !== CORNERSTONE_4_TAG) {
|
|
2800
|
-
return false;
|
|
2801
|
-
}
|
|
2802
|
-
return toolType === COBB_ANGLE;
|
|
2803
|
-
};
|
|
2804
|
-
MeasurementReport$1.registerTool(CobbAngle$1);
|
|
2805
|
-
|
|
2806
|
-
var TID300Angle = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.TID300.Angle;
|
|
2807
|
-
var ANGLE = "Angle";
|
|
2808
|
-
var Angle$1 = /*#__PURE__*/function () {
|
|
2809
|
-
function Angle() {
|
|
2810
|
-
_classCallCheck(this, Angle);
|
|
2811
|
-
}
|
|
2812
|
-
_createClass(Angle, null, [{
|
|
2813
|
-
key: "getMeasurementData",
|
|
2814
|
-
value:
|
|
2815
|
-
/**
|
|
2816
|
-
* Generate TID300 measurement data for a plane angle measurement - use a Angle, but label it as Angle
|
|
2817
|
-
*/
|
|
2818
|
-
function getMeasurementData(MeasurementGroup) {
|
|
2819
|
-
var _MeasurementReport$ge = MeasurementReport$1.getSetupMeasurementData(MeasurementGroup),
|
|
2820
|
-
defaultState = _MeasurementReport$ge.defaultState,
|
|
2821
|
-
NUMGroup = _MeasurementReport$ge.NUMGroup,
|
|
2822
|
-
SCOORDGroup = _MeasurementReport$ge.SCOORDGroup;
|
|
2823
|
-
var state = _objectSpread2(_objectSpread2({}, defaultState), {}, {
|
|
2824
|
-
rAngle: NUMGroup.MeasuredValueSequence.NumericValue,
|
|
2825
|
-
toolType: Angle.toolType,
|
|
2826
|
-
handles: {
|
|
2827
|
-
start: {},
|
|
2828
|
-
middle: {},
|
|
2829
|
-
end: {},
|
|
2830
|
-
textBox: {
|
|
2831
|
-
hasMoved: false,
|
|
2832
|
-
movesIndependently: false,
|
|
2833
|
-
drawnIndependently: true,
|
|
2834
|
-
allowedOutsideImage: true,
|
|
2835
|
-
hasBoundingBox: true
|
|
2836
|
-
}
|
|
2837
|
-
}
|
|
2838
|
-
});
|
|
2839
|
-
var _SCOORDGroup$GraphicD = _slicedToArray(SCOORDGroup.GraphicData, 8);
|
|
2840
|
-
state.handles.start.x = _SCOORDGroup$GraphicD[0];
|
|
2841
|
-
state.handles.start.y = _SCOORDGroup$GraphicD[1];
|
|
2842
|
-
state.handles.middle.x = _SCOORDGroup$GraphicD[2];
|
|
2843
|
-
state.handles.middle.y = _SCOORDGroup$GraphicD[3];
|
|
2844
|
-
state.handles.middle.x = _SCOORDGroup$GraphicD[4];
|
|
2845
|
-
state.handles.middle.y = _SCOORDGroup$GraphicD[5];
|
|
2846
|
-
state.handles.end.x = _SCOORDGroup$GraphicD[6];
|
|
2847
|
-
state.handles.end.y = _SCOORDGroup$GraphicD[7];
|
|
2848
|
-
return state;
|
|
2849
|
-
}
|
|
2850
|
-
}, {
|
|
2851
|
-
key: "getTID300RepresentationArguments",
|
|
2852
|
-
value: function getTID300RepresentationArguments(tool) {
|
|
2853
|
-
var handles = tool.handles,
|
|
2854
|
-
finding = tool.finding,
|
|
2855
|
-
findingSites = tool.findingSites;
|
|
2856
|
-
var point1 = handles.start;
|
|
2857
|
-
var point2 = handles.middle;
|
|
2858
|
-
var point3 = handles.middle;
|
|
2859
|
-
var point4 = handles.end;
|
|
2860
|
-
var rAngle = tool.rAngle;
|
|
2861
|
-
var trackingIdentifierTextValue = "cornerstoneTools@^4.0.0:Angle";
|
|
2862
|
-
return {
|
|
2863
|
-
point1: point1,
|
|
2864
|
-
point2: point2,
|
|
2865
|
-
point3: point3,
|
|
2866
|
-
point4: point4,
|
|
2867
|
-
rAngle: rAngle,
|
|
2868
|
-
trackingIdentifierTextValue: trackingIdentifierTextValue,
|
|
2869
|
-
finding: finding,
|
|
2870
|
-
findingSites: findingSites || []
|
|
2871
|
-
};
|
|
2872
|
-
}
|
|
2873
|
-
}]);
|
|
2874
|
-
return Angle;
|
|
2875
|
-
}();
|
|
2876
|
-
Angle$1.toolType = ANGLE;
|
|
2877
|
-
Angle$1.utilityToolType = ANGLE;
|
|
2878
|
-
Angle$1.TID300Representation = TID300Angle;
|
|
2879
|
-
Angle$1.isValidCornerstoneTrackingIdentifier = function (TrackingIdentifier) {
|
|
2880
|
-
if (!TrackingIdentifier.includes(":")) {
|
|
2881
|
-
return false;
|
|
2882
|
-
}
|
|
2883
|
-
var _TrackingIdentifier$s = TrackingIdentifier.split(":"),
|
|
2884
|
-
_TrackingIdentifier$s2 = _slicedToArray(_TrackingIdentifier$s, 2),
|
|
2885
|
-
cornerstone4Tag = _TrackingIdentifier$s2[0],
|
|
2886
|
-
toolType = _TrackingIdentifier$s2[1];
|
|
2887
|
-
if (cornerstone4Tag !== CORNERSTONE_4_TAG) {
|
|
2888
|
-
return false;
|
|
2889
|
-
}
|
|
2890
|
-
return toolType === ANGLE;
|
|
2891
|
-
};
|
|
2892
|
-
MeasurementReport$1.registerTool(Angle$1);
|
|
2893
|
-
|
|
2894
|
-
var TID300Polyline$2 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.TID300.Polyline;
|
|
2895
|
-
var RectangleRoi = /*#__PURE__*/function () {
|
|
2896
|
-
function RectangleRoi() {
|
|
2897
|
-
_classCallCheck(this, RectangleRoi);
|
|
2898
|
-
}
|
|
2899
|
-
_createClass(RectangleRoi, null, [{
|
|
2900
|
-
key: "getMeasurementData",
|
|
2901
|
-
value: function getMeasurementData(MeasurementGroup) {
|
|
2902
|
-
var _MeasurementReport$ge = MeasurementReport$1.getSetupMeasurementData(MeasurementGroup),
|
|
2903
|
-
defaultState = _MeasurementReport$ge.defaultState,
|
|
2904
|
-
SCOORDGroup = _MeasurementReport$ge.SCOORDGroup,
|
|
2905
|
-
NUMGroup = _MeasurementReport$ge.NUMGroup;
|
|
2906
|
-
var state = _objectSpread2(_objectSpread2({}, defaultState), {}, {
|
|
2907
|
-
toolType: RectangleRoi.toolType,
|
|
2908
|
-
handles: {
|
|
2909
|
-
start: {},
|
|
2910
|
-
end: {},
|
|
2911
|
-
textBox: {
|
|
2912
|
-
active: false,
|
|
2913
|
-
hasMoved: false,
|
|
2914
|
-
movesIndependently: false,
|
|
2915
|
-
drawnIndependently: true,
|
|
2916
|
-
allowedOutsideImage: true,
|
|
2917
|
-
hasBoundingBox: true
|
|
2918
|
-
},
|
|
2919
|
-
initialRotation: 0
|
|
2920
|
-
},
|
|
2921
|
-
cachedStats: {
|
|
2922
|
-
area: NUMGroup ? NUMGroup.MeasuredValueSequence.NumericValue : 0
|
|
2923
|
-
},
|
|
2924
|
-
color: undefined,
|
|
2925
|
-
invalidated: true
|
|
2926
|
-
});
|
|
2927
|
-
var _SCOORDGroup$GraphicD = _slicedToArray(SCOORDGroup.GraphicData, 6);
|
|
2928
|
-
state.handles.start.x = _SCOORDGroup$GraphicD[0];
|
|
2929
|
-
state.handles.start.y = _SCOORDGroup$GraphicD[1];
|
|
2930
|
-
_SCOORDGroup$GraphicD[2];
|
|
2931
|
-
_SCOORDGroup$GraphicD[3];
|
|
2932
|
-
state.handles.end.x = _SCOORDGroup$GraphicD[4];
|
|
2933
|
-
state.handles.end.y = _SCOORDGroup$GraphicD[5];
|
|
2934
|
-
return state;
|
|
2935
|
-
}
|
|
2936
|
-
}, {
|
|
2937
|
-
key: "getTID300RepresentationArguments",
|
|
2938
|
-
value: function getTID300RepresentationArguments(tool) {
|
|
2939
|
-
var finding = tool.finding,
|
|
2940
|
-
findingSites = tool.findingSites,
|
|
2941
|
-
_tool$cachedStats = tool.cachedStats,
|
|
2942
|
-
cachedStats = _tool$cachedStats === void 0 ? {} : _tool$cachedStats,
|
|
2943
|
-
handles = tool.handles;
|
|
2944
|
-
var start = handles.start,
|
|
2945
|
-
end = handles.end;
|
|
2946
|
-
var points = [start, {
|
|
2947
|
-
x: start.x,
|
|
2948
|
-
y: end.y
|
|
2949
|
-
}, end, {
|
|
2950
|
-
x: end.x,
|
|
2951
|
-
y: start.y
|
|
2952
|
-
}];
|
|
2953
|
-
var area = cachedStats.area,
|
|
2954
|
-
perimeter = cachedStats.perimeter;
|
|
2955
|
-
var trackingIdentifierTextValue = "cornerstoneTools@^4.0.0:RectangleRoi";
|
|
2956
|
-
return {
|
|
2957
|
-
points: points,
|
|
2958
|
-
area: area,
|
|
2959
|
-
perimeter: perimeter,
|
|
2960
|
-
trackingIdentifierTextValue: trackingIdentifierTextValue,
|
|
2961
|
-
finding: finding,
|
|
2962
|
-
findingSites: findingSites || []
|
|
2963
|
-
};
|
|
2964
|
-
}
|
|
2965
|
-
}]);
|
|
2966
|
-
return RectangleRoi;
|
|
2967
|
-
}();
|
|
2968
|
-
RectangleRoi.toolType = "RectangleRoi";
|
|
2969
|
-
RectangleRoi.utilityToolType = "RectangleRoi";
|
|
2970
|
-
RectangleRoi.TID300Representation = TID300Polyline$2;
|
|
2971
|
-
RectangleRoi.isValidCornerstoneTrackingIdentifier = function (TrackingIdentifier) {
|
|
2972
|
-
if (!TrackingIdentifier.includes(":")) {
|
|
2973
|
-
return false;
|
|
2974
|
-
}
|
|
2975
|
-
var _TrackingIdentifier$s = TrackingIdentifier.split(":"),
|
|
2976
|
-
_TrackingIdentifier$s2 = _slicedToArray(_TrackingIdentifier$s, 2),
|
|
2977
|
-
cornerstone4Tag = _TrackingIdentifier$s2[0],
|
|
2978
|
-
toolType = _TrackingIdentifier$s2[1];
|
|
2979
|
-
if (cornerstone4Tag !== CORNERSTONE_4_TAG) {
|
|
2980
|
-
return false;
|
|
3523
|
+
*
|
|
3524
|
+
* @param {object[]} segmentation An empty segmentation derived dataset.
|
|
3525
|
+
* @param {Object|Object[]} inputLabelmaps3D The cornerstone `Labelmap3D` object, or an array of objects.
|
|
3526
|
+
* @param {Object} userOptions Options object to override default options.
|
|
3527
|
+
* @returns {Blob} description
|
|
3528
|
+
*/
|
|
3529
|
+
function fillSegmentation(segmentation, inputLabelmaps3D) {
|
|
3530
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
|
|
3531
|
+
includeSliceSpacing: true
|
|
3532
|
+
};
|
|
3533
|
+
var cornerstoneToolsVersion = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 4;
|
|
3534
|
+
if (cornerstoneToolsVersion === 4) {
|
|
3535
|
+
return Segmentation$4.fillSegmentation(segmentation, inputLabelmaps3D, options);
|
|
2981
3536
|
}
|
|
2982
|
-
|
|
2983
|
-
}
|
|
2984
|
-
MeasurementReport$1.registerTool(RectangleRoi);
|
|
3537
|
+
console.warn("No generateSegmentation adapater for cornerstone version ".concat(cornerstoneToolsVersion, ", exiting."));
|
|
3538
|
+
}
|
|
2985
3539
|
|
|
2986
|
-
var
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
3540
|
+
var CornerstoneSR = {
|
|
3541
|
+
Length: Length$1,
|
|
3542
|
+
FreehandRoi: FreehandRoi,
|
|
3543
|
+
Bidirectional: Bidirectional$1,
|
|
3544
|
+
EllipticalRoi: EllipticalRoi,
|
|
3545
|
+
CircleRoi: CircleRoi,
|
|
3546
|
+
ArrowAnnotate: ArrowAnnotate$1,
|
|
3547
|
+
MeasurementReport: MeasurementReport$1,
|
|
3548
|
+
CobbAngle: CobbAngle$1,
|
|
3549
|
+
Angle: Angle$1,
|
|
3550
|
+
RectangleRoi: RectangleRoi
|
|
3551
|
+
};
|
|
3552
|
+
var CornerstoneSEG = {
|
|
3553
|
+
Segmentation: Segmentation$3
|
|
2998
3554
|
};
|
|
2999
3555
|
|
|
3000
3556
|
/******************************************************************************
|
|
@@ -3049,9 +3605,9 @@ var CodingScheme = {
|
|
|
3049
3605
|
|
|
3050
3606
|
var TID1500 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.TID1500, addAccessors = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.addAccessors;
|
|
3051
3607
|
var StructuredReport = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .derivations */ .U7.StructuredReport;
|
|
3052
|
-
var Normalizer = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .normalizers */ .oq.Normalizer;
|
|
3608
|
+
var Normalizer$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .normalizers */ .oq.Normalizer;
|
|
3053
3609
|
var TID1500MeasurementReport = TID1500.TID1500MeasurementReport, TID1501MeasurementGroup = TID1500.TID1501MeasurementGroup;
|
|
3054
|
-
var DicomMetaDictionary = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.DicomMetaDictionary;
|
|
3610
|
+
var DicomMetaDictionary$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.DicomMetaDictionary;
|
|
3055
3611
|
var FINDING = { CodingSchemeDesignator: "DCM", CodeValue: "121071" };
|
|
3056
3612
|
var FINDING_SITE = { CodingSchemeDesignator: "SCT", CodeValue: "363698007" };
|
|
3057
3613
|
var FINDING_SITE_OLD = { CodingSchemeDesignator: "SRT", CodeValue: "G-C0E3" };
|
|
@@ -3120,7 +3676,7 @@ var MeasurementReport = /** @class */ (function () {
|
|
|
3120
3676
|
vr: "UI"
|
|
3121
3677
|
},
|
|
3122
3678
|
ImplementationClassUID: {
|
|
3123
|
-
Value: [DicomMetaDictionary.uid()],
|
|
3679
|
+
Value: [DicomMetaDictionary$1.uid()],
|
|
3124
3680
|
vr: "UI"
|
|
3125
3681
|
},
|
|
3126
3682
|
ImplementationVersionName: {
|
|
@@ -3155,7 +3711,7 @@ var MeasurementReport = /** @class */ (function () {
|
|
|
3155
3711
|
description: undefined,
|
|
3156
3712
|
sopInstanceUid: ReferencedSOPInstanceUID,
|
|
3157
3713
|
annotation: {
|
|
3158
|
-
annotationUID: DicomMetaDictionary.uid(),
|
|
3714
|
+
annotationUID: DicomMetaDictionary$1.uid(),
|
|
3159
3715
|
metadata: {
|
|
3160
3716
|
toolName: toolType,
|
|
3161
3717
|
referencedImageId: referencedImageId,
|
|
@@ -3218,7 +3774,7 @@ var MeasurementReport = /** @class */ (function () {
|
|
|
3218
3774
|
if ((instance &&
|
|
3219
3775
|
instance.NumberOfFrames &&
|
|
3220
3776
|
instance.NumberOfFrames > 1) ||
|
|
3221
|
-
Normalizer.isMultiframeSOPClassUID(sopClassUID)) {
|
|
3777
|
+
Normalizer$1.isMultiframeSOPClassUID(sopClassUID)) {
|
|
3222
3778
|
ReferencedSOPSequence.ReferencedFrameNumber = frameNumber;
|
|
3223
3779
|
}
|
|
3224
3780
|
// Loop through each tool type for the image
|
|
@@ -3853,26 +4409,26 @@ var EllipticalROI = /** @class */ (function () {
|
|
|
3853
4409
|
]);
|
|
3854
4410
|
pointsWorld.push(worldPos);
|
|
3855
4411
|
}
|
|
3856
|
-
var majorAxisStart =
|
|
3857
|
-
var majorAxisEnd =
|
|
3858
|
-
var minorAxisStart =
|
|
3859
|
-
var minorAxisEnd =
|
|
3860
|
-
var majorAxisVec =
|
|
3861
|
-
|
|
4412
|
+
var majorAxisStart = gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.fromValues */ .R3.fromValues.apply(gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3 */ .R3, pointsWorld[0]);
|
|
4413
|
+
var majorAxisEnd = gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.fromValues */ .R3.fromValues.apply(gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3 */ .R3, pointsWorld[1]);
|
|
4414
|
+
var minorAxisStart = gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.fromValues */ .R3.fromValues.apply(gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3 */ .R3, pointsWorld[2]);
|
|
4415
|
+
var minorAxisEnd = gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.fromValues */ .R3.fromValues.apply(gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3 */ .R3, pointsWorld[3]);
|
|
4416
|
+
var majorAxisVec = gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.create */ .R3.create();
|
|
4417
|
+
gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.sub */ .R3.sub(majorAxisVec, majorAxisEnd, majorAxisStart);
|
|
3862
4418
|
// normalize majorAxisVec to avoid scaling issues
|
|
3863
|
-
|
|
3864
|
-
var minorAxisVec =
|
|
3865
|
-
|
|
3866
|
-
|
|
4419
|
+
gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.normalize */ .R3.normalize(majorAxisVec, majorAxisVec);
|
|
4420
|
+
var minorAxisVec = gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.create */ .R3.create();
|
|
4421
|
+
gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.sub */ .R3.sub(minorAxisVec, minorAxisEnd, minorAxisStart);
|
|
4422
|
+
gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.normalize */ .R3.normalize(minorAxisVec, minorAxisVec);
|
|
3867
4423
|
var imagePlaneModule = metadata.get("imagePlaneModule", referencedImageId);
|
|
3868
4424
|
if (!imagePlaneModule) {
|
|
3869
4425
|
throw new Error("imageId does not have imagePlaneModule metadata");
|
|
3870
4426
|
}
|
|
3871
4427
|
var columnCosines = imagePlaneModule.columnCosines;
|
|
3872
4428
|
// find which axis is parallel to the columnCosines
|
|
3873
|
-
var columnCosinesVec =
|
|
3874
|
-
var projectedMajorAxisOnColVec =
|
|
3875
|
-
var projectedMinorAxisOnColVec =
|
|
4429
|
+
var columnCosinesVec = gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.fromValues */ .R3.fromValues(columnCosines[0], columnCosines[1], columnCosines[2]);
|
|
4430
|
+
var projectedMajorAxisOnColVec = gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.dot */ .R3.dot(columnCosinesVec, majorAxisVec);
|
|
4431
|
+
var projectedMinorAxisOnColVec = gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.dot */ .R3.dot(columnCosinesVec, minorAxisVec);
|
|
3876
4432
|
var absoluteOfMajorDotProduct = Math.abs(projectedMajorAxisOnColVec);
|
|
3877
4433
|
var absoluteOfMinorDotProduct = Math.abs(projectedMinorAxisOnColVec);
|
|
3878
4434
|
var ellipsePoints = [];
|
|
@@ -4177,7 +4733,7 @@ var PlanarFreehandROI = /** @class */ (function () {
|
|
|
4177
4733
|
]);
|
|
4178
4734
|
worldCoords.push(point);
|
|
4179
4735
|
}
|
|
4180
|
-
var distanceBetweenFirstAndLastPoint =
|
|
4736
|
+
var distanceBetweenFirstAndLastPoint = gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.distance */ .R3.distance(worldCoords[worldCoords.length - 1], worldCoords[0]);
|
|
4181
4737
|
var isOpenContour = true;
|
|
4182
4738
|
// If the contour is closed, this should have been encoded as exactly the same point, so check for a very small difference.
|
|
4183
4739
|
if (distanceBetweenFirstAndLastPoint < closedContourThreshold) {
|
|
@@ -4329,7 +4885,836 @@ Probe.isValidCornerstoneTrackingIdentifier = function (TrackingIdentifier) {
|
|
|
4329
4885
|
};
|
|
4330
4886
|
MeasurementReport.registerTool(Probe);
|
|
4331
4887
|
|
|
4332
|
-
var
|
|
4888
|
+
var Normalizer = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .normalizers */ .oq.Normalizer;
|
|
4889
|
+
var SegmentationDerivation = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .derivations */ .U7.Segmentation;
|
|
4890
|
+
/**
|
|
4891
|
+
* generateSegmentation - Generates a DICOM Segmentation object given cornerstoneTools data.
|
|
4892
|
+
*
|
|
4893
|
+
* @param images - An array of the cornerstone image objects, which includes imageId and metadata
|
|
4894
|
+
* @param labelmaps - An array of the 3D Volumes that contain the segmentation data.
|
|
4895
|
+
*/
|
|
4896
|
+
function generateSegmentation(images, labelmaps, metadata, options) {
|
|
4897
|
+
if (options === void 0) { options = {}; }
|
|
4898
|
+
var segmentation = _createMultiframeSegmentationFromReferencedImages(images, metadata, options);
|
|
4899
|
+
return fillSegmentation$1(segmentation, labelmaps, options);
|
|
4900
|
+
}
|
|
4901
|
+
/**
|
|
4902
|
+
* _createMultiframeSegmentationFromReferencedImages - description
|
|
4903
|
+
*
|
|
4904
|
+
* @param images - An array of the cornerstone image objects related to the reference
|
|
4905
|
+
* series that the segmentation is derived from. You can use methods such as
|
|
4906
|
+
* volume.getCornerstoneImages() to get this array.
|
|
4907
|
+
*
|
|
4908
|
+
* @param options - the options object for the SegmentationDerivation.
|
|
4909
|
+
* @returns The Seg derived dataSet.
|
|
4910
|
+
*/
|
|
4911
|
+
function _createMultiframeSegmentationFromReferencedImages(images, metadata, options) {
|
|
4912
|
+
var datasets = images.map(function (image) {
|
|
4913
|
+
// add the sopClassUID to the dataset
|
|
4914
|
+
var instance = metadata.get("instance", image.imageId);
|
|
4915
|
+
return __assign(__assign(__assign({}, image), instance), {
|
|
4916
|
+
// Todo: move to dcmjs tag style
|
|
4917
|
+
SOPClassUID: instance.SopClassUID || instance.SOPClassUID, SOPInstanceUID: instance.SopInstanceUID || instance.SOPInstanceUID, PixelData: image.getPixelData(), _vrMap: {
|
|
4918
|
+
PixelData: "OW"
|
|
4919
|
+
}, _meta: {} });
|
|
4920
|
+
});
|
|
4921
|
+
var multiframe = Normalizer.normalizeToDataset(datasets);
|
|
4922
|
+
return new SegmentationDerivation([multiframe], options);
|
|
4923
|
+
}
|
|
4924
|
+
|
|
4925
|
+
/**
|
|
4926
|
+
* Generates 2D label maps from a 3D label map.
|
|
4927
|
+
* @param labelmap3D - The 3D label map object to generate 2D label maps from. It is derived
|
|
4928
|
+
* from the volume labelmap.
|
|
4929
|
+
* @returns The label map object containing the 2D label maps and segments on label maps.
|
|
4930
|
+
*/
|
|
4931
|
+
function generateLabelMaps2DFrom3D(labelmap3D) {
|
|
4932
|
+
// 1. we need to generate labelmaps2D from labelmaps3D, a labelmap2D is for each
|
|
4933
|
+
// slice
|
|
4934
|
+
var scalarData = labelmap3D.scalarData, dimensions = labelmap3D.dimensions;
|
|
4935
|
+
// scalarData is a flat array of all the pixels in the volume.
|
|
4936
|
+
var labelmaps2D = [];
|
|
4937
|
+
var segmentsOnLabelmap3D = new Set();
|
|
4938
|
+
// X-Y are the row and column dimensions, Z is the number of slices.
|
|
4939
|
+
for (var z = 0; z < dimensions[2]; z++) {
|
|
4940
|
+
var pixelData = scalarData.slice(z * dimensions[0] * dimensions[1], (z + 1) * dimensions[0] * dimensions[1]);
|
|
4941
|
+
var segmentsOnLabelmap = [];
|
|
4942
|
+
for (var i = 0; i < pixelData.length; i++) {
|
|
4943
|
+
var segment = pixelData[i];
|
|
4944
|
+
if (!segmentsOnLabelmap.includes(segment) && segment !== 0) {
|
|
4945
|
+
segmentsOnLabelmap.push(segment);
|
|
4946
|
+
}
|
|
4947
|
+
}
|
|
4948
|
+
var labelmap2D = {
|
|
4949
|
+
segmentsOnLabelmap: segmentsOnLabelmap,
|
|
4950
|
+
pixelData: pixelData,
|
|
4951
|
+
rows: dimensions[1],
|
|
4952
|
+
columns: dimensions[0]
|
|
4953
|
+
};
|
|
4954
|
+
if (segmentsOnLabelmap.length === 0) {
|
|
4955
|
+
continue;
|
|
4956
|
+
}
|
|
4957
|
+
segmentsOnLabelmap.forEach(function (segmentIndex) {
|
|
4958
|
+
segmentsOnLabelmap3D.add(segmentIndex);
|
|
4959
|
+
});
|
|
4960
|
+
labelmaps2D[dimensions[2] - 1 - z] = labelmap2D;
|
|
4961
|
+
}
|
|
4962
|
+
// remove segment 0 from segmentsOnLabelmap3D
|
|
4963
|
+
labelmap3D.segmentsOnLabelmap = Array.from(segmentsOnLabelmap3D);
|
|
4964
|
+
labelmap3D.labelmaps2D = labelmaps2D;
|
|
4965
|
+
return labelmap3D;
|
|
4966
|
+
}
|
|
4967
|
+
|
|
4968
|
+
var Segmentation$2 = CornerstoneSEG.Segmentation;
|
|
4969
|
+
var generateToolStateCornerstoneLegacy = Segmentation$2.generateToolState;
|
|
4970
|
+
/**
|
|
4971
|
+
* generateToolState - Given a set of cornerstoneTools imageIds and a Segmentation buffer,
|
|
4972
|
+
* derive cornerstoneTools toolState and brush metadata.
|
|
4973
|
+
*
|
|
4974
|
+
* @param imageIds - An array of the imageIds.
|
|
4975
|
+
* @param arrayBuffer - The SEG arrayBuffer.
|
|
4976
|
+
* @param skipOverlapping - skip checks for overlapping segs, default value false.
|
|
4977
|
+
* @param tolerance - default value 1.e-3.
|
|
4978
|
+
*
|
|
4979
|
+
* @returns a list of array buffer for each labelMap
|
|
4980
|
+
* an object from which the segment metadata can be derived
|
|
4981
|
+
* list containing the track of segments per frame
|
|
4982
|
+
* list containing the track of segments per frame for each labelMap (available only for the overlapping case).
|
|
4983
|
+
*/
|
|
4984
|
+
function generateToolState(imageIds, arrayBuffer, metadataProvider, skipOverlapping, tolerance) {
|
|
4985
|
+
if (skipOverlapping === void 0) { skipOverlapping = false; }
|
|
4986
|
+
if (tolerance === void 0) { tolerance = 1e-3; }
|
|
4987
|
+
return generateToolStateCornerstoneLegacy(imageIds, arrayBuffer, metadataProvider, skipOverlapping, tolerance);
|
|
4988
|
+
}
|
|
4989
|
+
|
|
4990
|
+
var Segmentation$1 = /*#__PURE__*/Object.freeze({
|
|
4991
|
+
__proto__: null,
|
|
4992
|
+
generateLabelMaps2DFrom3D: generateLabelMaps2DFrom3D,
|
|
4993
|
+
generateSegmentation: generateSegmentation,
|
|
4994
|
+
generateToolState: generateToolState
|
|
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
|
+
|
|
5717
|
+
var Cornerstone3DSR = {
|
|
4333
5718
|
Bidirectional: Bidirectional,
|
|
4334
5719
|
CobbAngle: CobbAngle,
|
|
4335
5720
|
Angle: Angle,
|
|
@@ -4344,6 +5729,12 @@ var Cornerstone3D = {
|
|
|
4344
5729
|
CodeScheme: CodingScheme,
|
|
4345
5730
|
CORNERSTONE_3D_TAG: CORNERSTONE_3D_TAG
|
|
4346
5731
|
};
|
|
5732
|
+
var Cornerstone3DSEG = {
|
|
5733
|
+
Segmentation: Segmentation$1
|
|
5734
|
+
};
|
|
5735
|
+
var Cornerstone3DRT = {
|
|
5736
|
+
RTSS: RTSS
|
|
5737
|
+
};
|
|
4347
5738
|
|
|
4348
5739
|
var Colors = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.Colors,
|
|
4349
5740
|
BitArray = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.BitArray;
|
|
@@ -4528,23 +5919,29 @@ var Segmentation = /*#__PURE__*/function () {
|
|
|
4528
5919
|
return Segmentation;
|
|
4529
5920
|
}();
|
|
4530
5921
|
|
|
4531
|
-
var
|
|
4532
|
-
|
|
5922
|
+
var VTKjsSEG = {
|
|
5923
|
+
Segmentation: Segmentation
|
|
4533
5924
|
};
|
|
4534
5925
|
|
|
4535
|
-
var
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
5926
|
+
var adaptersSR = {
|
|
5927
|
+
Cornerstone: CornerstoneSR,
|
|
5928
|
+
Cornerstone3D: Cornerstone3DSR
|
|
5929
|
+
};
|
|
5930
|
+
var adaptersSEG = {
|
|
5931
|
+
Cornerstone: CornerstoneSEG,
|
|
5932
|
+
Cornerstone3D: Cornerstone3DSEG,
|
|
5933
|
+
VTKjs: VTKjsSEG
|
|
5934
|
+
};
|
|
5935
|
+
var adaptersRT = {
|
|
5936
|
+
Cornerstone3D: Cornerstone3DRT
|
|
4539
5937
|
};
|
|
4540
5938
|
|
|
4541
5939
|
|
|
4542
|
-
//# sourceMappingURL=adapters.es.js.map
|
|
4543
5940
|
|
|
4544
5941
|
|
|
4545
5942
|
/***/ }),
|
|
4546
5943
|
|
|
4547
|
-
/***/
|
|
5944
|
+
/***/ 27318:
|
|
4548
5945
|
/***/ ((module) => {
|
|
4549
5946
|
|
|
4550
5947
|
"use strict";
|
|
@@ -4562,7 +5959,7 @@ module.exports = iota
|
|
|
4562
5959
|
|
|
4563
5960
|
/***/ }),
|
|
4564
5961
|
|
|
4565
|
-
/***/
|
|
5962
|
+
/***/ 8516:
|
|
4566
5963
|
/***/ ((module) => {
|
|
4567
5964
|
|
|
4568
5965
|
/*!
|
|
@@ -4580,11 +5977,11 @@ module.exports = function isBuffer (obj) {
|
|
|
4580
5977
|
|
|
4581
5978
|
/***/ }),
|
|
4582
5979
|
|
|
4583
|
-
/***/
|
|
5980
|
+
/***/ 87513:
|
|
4584
5981
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
4585
5982
|
|
|
4586
|
-
var iota = __webpack_require__(
|
|
4587
|
-
var isBuffer = __webpack_require__(
|
|
5983
|
+
var iota = __webpack_require__(27318)
|
|
5984
|
+
var isBuffer = __webpack_require__(8516)
|
|
4588
5985
|
|
|
4589
5986
|
var hasTypedArrays = ((typeof Float64Array) !== "undefined")
|
|
4590
5987
|
|