@ohif/app 3.7.0-beta.7 → 3.7.0-beta.71
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/{270.bundle.4564621556b0f963a004.js → 116.bundle.422d1a76d8daccfed61d.js} +1037 -823
- package/dist/{917.bundle.37f76105d2e1a70d94cf.js → 12.bundle.078c14f666c71663ae8e.js} +6 -6
- package/dist/{295.bundle.957b1159fec14b9199a1.js → 125.bundle.aeaad798561853bf6939.js} +6 -6
- package/dist/{208.bundle.21c449bf9b00123e1db3.js → 128.bundle.fdb6d1d5391b79de4936.js} +6 -6
- package/dist/{616.bundle.be469f44809e9b2485b2.js → 150.bundle.c99cc2e1df7cd4085265.js} +163 -106
- package/dist/{351.bundle.0742237651aef9694a65.js → 181.bundle.73dd6f63fe0ddc52b7eb.js} +225 -203
- package/dist/{351.css → 181.css} +1 -1
- package/dist/{606.bundle.5d876f5f3dd8287f0a28.js → 202.bundle.591726b6144882ba0ee0.js} +1459 -811
- package/dist/{926.bundle.dbc9d0e591cb9217fda2.js → 220.bundle.f7e1c96c94245e70f2be.js} +990 -400
- package/dist/{664.bundle.09abae984223969d1bde.js → 23.bundle.e008ad788170f2ed5569.js} +5 -6
- package/dist/{976.bundle.c1df3878a015cdf0e51f.js → 236.bundle.226efc38e453a4aeb7dd.js} +72 -83
- package/dist/{55.bundle.550a823e75eb608e8d5e.js → 250.bundle.8bc4553ee5c56bf7cf32.js} +51 -35
- package/dist/{973.bundle.f4b8ccf7ad2ff9f6041c.js → 281.bundle.e9554f25a9eeac2f43e6.js} +18 -14
- package/dist/{744.bundle.d07b9ad7b31de0ba4956.js → 30.bundle.c8dfb82c70ae9ff67f14.js} +185 -174
- package/dist/{192.bundle.1efc10937535a37a17f0.js → 348.bundle.e5082a6425f719eb6658.js} +43 -19
- package/dist/{404.bundle.d980e423e9670737ef12.js → 359.bundle.8da7f102410ca9c0c999.js} +13 -19
- package/dist/{790.bundle.ed28f0930111217b742a.js → 410.bundle.5d03eeef5b705198bf5e.js} +10 -7
- package/dist/{151.bundle.31ea35044218837bf73f.js → 417.bundle.6cadc61b8a455776de31.js} +49 -17
- package/dist/{569.bundle.21f8ad57c06a210448b5.js → 451.bundle.e59fcdb1f1d3fbe71cd4.js} +83 -101
- package/dist/{581.bundle.dc6197189f7c88c27d4c.js → 471.bundle.b598d406ddfc2666851b.js} +65 -93
- package/dist/{199.bundle.7cec631fcf4b8475abda.js → 506.bundle.869288177e788d808aaa.js} +86 -10
- package/dist/{935.bundle.deeffff0e4f7b528e3c3.js → 604.bundle.a51f83e64004bca5f497.js} +2 -3
- package/dist/{984.bundle.b33e9e702a96c5ae9fb7.js → 663.bundle.6a389399e5196510e0de.js} +67 -37
- package/dist/{531.bundle.2a82fb1d69e5b57cc72b.js → 677.bundle.ec5f2b4707db33bd4d8e.js} +731 -447
- package/dist/{205.bundle.b5a473c200dcf2bbcdb4.js → 686.bundle.b3dbf84eefbef768843f.js} +6 -6
- package/dist/{50.bundle.9b5c9aaaf1188ab0794a.js → 687.bundle.67d721785216e064fc52.js} +218 -9
- package/dist/{331.bundle.bd0c13931a21d53086c9.js → 754.bundle.a5c9246c77659eab2739.js} +12413 -7539
- package/dist/{728.bundle.d13856835357400fef82.js → 774.bundle.8ba82ee206266eb2da5e.js} +90 -63
- package/dist/{381.bundle.0905e683605fcbc0895f.js → 775.bundle.2285e7e0e67878948c0d.js} +16 -16
- package/dist/{283.bundle.8ffad59b5844a24b2a62.js → 782.bundle.6d57b35a056506c94352.js} +112 -62
- package/dist/{642.bundle.88a563313292ae2cdd2e.js → 814.bundle.ad8ebe6cffa96a5cfc1f.js} +6 -6
- package/dist/{799.bundle.758558e64147e5aad612.js → 822.bundle.5cdd9439a62e5c7e902f.js} +81 -34
- package/dist/{953.bundle.3b0189ebc11cf0946f18.js → 886.bundle.9e526affbd17b0ed96a6.js} +34 -29
- package/dist/{82.bundle.b824c7d8ff72de0fc149.js → 90.bundle.d7a1e818bbbd3bce5419.js} +1397 -366
- package/dist/945.min.worker.js +1 -1
- package/dist/945.min.worker.js.map +1 -1
- package/dist/{707.bundle.0b18a871c9eb8df9e992.js → 967.bundle.8b4adf9b5a7392b51d0c.js} +584 -435
- package/dist/app-config.js +7 -7
- package/dist/{app.bundle.f0885cb776ab9ae8974b.js → app.bundle.1905c07065c4b93afa5a.js} +69865 -67829
- package/dist/app.bundle.css +9 -9
- 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 +1 -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 +19 -20
- package/dist/780.bundle.fd0f13dc92e9caa0581e.js +0 -4769
- package/dist/index.worker.1c69152d710fa7b84bce.worker.js.map +0 -1
- /package/dist/{55.css → 250.css} +0 -0
- /package/dist/{806.css → 579.css} +0 -0
- /package/dist/{707.css → 967.css} +0 -0
|
@@ -1,19 +1,23 @@
|
|
|
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 */ Yb: () => (/* binding */ index),
|
|
9
|
+
/* harmony export */ adaptersSR: () => (/* binding */ adaptersSR),
|
|
10
|
+
/* harmony export */ ok: () => (/* binding */ adaptersSEG)
|
|
9
11
|
/* harmony export */ });
|
|
10
|
-
/* unused harmony export
|
|
11
|
-
/* harmony import */ var dcmjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(
|
|
12
|
-
/* harmony import */ var ndarray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(
|
|
12
|
+
/* unused harmony export helpers */
|
|
13
|
+
/* harmony import */ var dcmjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(67540);
|
|
14
|
+
/* harmony import */ var ndarray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(87513);
|
|
13
15
|
/* harmony import */ var ndarray__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(ndarray__WEBPACK_IMPORTED_MODULE_1__);
|
|
14
|
-
/* harmony import */ var lodash_clonedeep__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(
|
|
16
|
+
/* harmony import */ var lodash_clonedeep__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(11677);
|
|
15
17
|
/* harmony import */ var lodash_clonedeep__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(lodash_clonedeep__WEBPACK_IMPORTED_MODULE_2__);
|
|
16
|
-
/* harmony import */ var
|
|
18
|
+
/* harmony import */ var buffer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(58955);
|
|
19
|
+
/* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(45451);
|
|
20
|
+
|
|
17
21
|
|
|
18
22
|
|
|
19
23
|
|
|
@@ -67,6 +71,337 @@ function _objectSpread2(target) {
|
|
|
67
71
|
}
|
|
68
72
|
return target;
|
|
69
73
|
}
|
|
74
|
+
function _regeneratorRuntime() {
|
|
75
|
+
_regeneratorRuntime = function () {
|
|
76
|
+
return exports;
|
|
77
|
+
};
|
|
78
|
+
var exports = {},
|
|
79
|
+
Op = Object.prototype,
|
|
80
|
+
hasOwn = Op.hasOwnProperty,
|
|
81
|
+
defineProperty = Object.defineProperty || function (obj, key, desc) {
|
|
82
|
+
obj[key] = desc.value;
|
|
83
|
+
},
|
|
84
|
+
$Symbol = "function" == typeof Symbol ? Symbol : {},
|
|
85
|
+
iteratorSymbol = $Symbol.iterator || "@@iterator",
|
|
86
|
+
asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator",
|
|
87
|
+
toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
|
|
88
|
+
function define(obj, key, value) {
|
|
89
|
+
return Object.defineProperty(obj, key, {
|
|
90
|
+
value: value,
|
|
91
|
+
enumerable: !0,
|
|
92
|
+
configurable: !0,
|
|
93
|
+
writable: !0
|
|
94
|
+
}), obj[key];
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
define({}, "");
|
|
98
|
+
} catch (err) {
|
|
99
|
+
define = function (obj, key, value) {
|
|
100
|
+
return obj[key] = value;
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function wrap(innerFn, outerFn, self, tryLocsList) {
|
|
104
|
+
var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator,
|
|
105
|
+
generator = Object.create(protoGenerator.prototype),
|
|
106
|
+
context = new Context(tryLocsList || []);
|
|
107
|
+
return defineProperty(generator, "_invoke", {
|
|
108
|
+
value: makeInvokeMethod(innerFn, self, context)
|
|
109
|
+
}), generator;
|
|
110
|
+
}
|
|
111
|
+
function tryCatch(fn, obj, arg) {
|
|
112
|
+
try {
|
|
113
|
+
return {
|
|
114
|
+
type: "normal",
|
|
115
|
+
arg: fn.call(obj, arg)
|
|
116
|
+
};
|
|
117
|
+
} catch (err) {
|
|
118
|
+
return {
|
|
119
|
+
type: "throw",
|
|
120
|
+
arg: err
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
exports.wrap = wrap;
|
|
125
|
+
var ContinueSentinel = {};
|
|
126
|
+
function Generator() {}
|
|
127
|
+
function GeneratorFunction() {}
|
|
128
|
+
function GeneratorFunctionPrototype() {}
|
|
129
|
+
var IteratorPrototype = {};
|
|
130
|
+
define(IteratorPrototype, iteratorSymbol, function () {
|
|
131
|
+
return this;
|
|
132
|
+
});
|
|
133
|
+
var getProto = Object.getPrototypeOf,
|
|
134
|
+
NativeIteratorPrototype = getProto && getProto(getProto(values([])));
|
|
135
|
+
NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype);
|
|
136
|
+
var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype);
|
|
137
|
+
function defineIteratorMethods(prototype) {
|
|
138
|
+
["next", "throw", "return"].forEach(function (method) {
|
|
139
|
+
define(prototype, method, function (arg) {
|
|
140
|
+
return this._invoke(method, arg);
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
function AsyncIterator(generator, PromiseImpl) {
|
|
145
|
+
function invoke(method, arg, resolve, reject) {
|
|
146
|
+
var record = tryCatch(generator[method], generator, arg);
|
|
147
|
+
if ("throw" !== record.type) {
|
|
148
|
+
var result = record.arg,
|
|
149
|
+
value = result.value;
|
|
150
|
+
return value && "object" == typeof value && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) {
|
|
151
|
+
invoke("next", value, resolve, reject);
|
|
152
|
+
}, function (err) {
|
|
153
|
+
invoke("throw", err, resolve, reject);
|
|
154
|
+
}) : PromiseImpl.resolve(value).then(function (unwrapped) {
|
|
155
|
+
result.value = unwrapped, resolve(result);
|
|
156
|
+
}, function (error) {
|
|
157
|
+
return invoke("throw", error, resolve, reject);
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
reject(record.arg);
|
|
161
|
+
}
|
|
162
|
+
var previousPromise;
|
|
163
|
+
defineProperty(this, "_invoke", {
|
|
164
|
+
value: function (method, arg) {
|
|
165
|
+
function callInvokeWithMethodAndArg() {
|
|
166
|
+
return new PromiseImpl(function (resolve, reject) {
|
|
167
|
+
invoke(method, arg, resolve, reject);
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
function makeInvokeMethod(innerFn, self, context) {
|
|
175
|
+
var state = "suspendedStart";
|
|
176
|
+
return function (method, arg) {
|
|
177
|
+
if ("executing" === state) throw new Error("Generator is already running");
|
|
178
|
+
if ("completed" === state) {
|
|
179
|
+
if ("throw" === method) throw arg;
|
|
180
|
+
return doneResult();
|
|
181
|
+
}
|
|
182
|
+
for (context.method = method, context.arg = arg;;) {
|
|
183
|
+
var delegate = context.delegate;
|
|
184
|
+
if (delegate) {
|
|
185
|
+
var delegateResult = maybeInvokeDelegate(delegate, context);
|
|
186
|
+
if (delegateResult) {
|
|
187
|
+
if (delegateResult === ContinueSentinel) continue;
|
|
188
|
+
return delegateResult;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) {
|
|
192
|
+
if ("suspendedStart" === state) throw state = "completed", context.arg;
|
|
193
|
+
context.dispatchException(context.arg);
|
|
194
|
+
} else "return" === context.method && context.abrupt("return", context.arg);
|
|
195
|
+
state = "executing";
|
|
196
|
+
var record = tryCatch(innerFn, self, context);
|
|
197
|
+
if ("normal" === record.type) {
|
|
198
|
+
if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue;
|
|
199
|
+
return {
|
|
200
|
+
value: record.arg,
|
|
201
|
+
done: context.done
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
"throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg);
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
function maybeInvokeDelegate(delegate, context) {
|
|
209
|
+
var methodName = context.method,
|
|
210
|
+
method = delegate.iterator[methodName];
|
|
211
|
+
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;
|
|
212
|
+
var record = tryCatch(method, delegate.iterator, context.arg);
|
|
213
|
+
if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel;
|
|
214
|
+
var info = record.arg;
|
|
215
|
+
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);
|
|
216
|
+
}
|
|
217
|
+
function pushTryEntry(locs) {
|
|
218
|
+
var entry = {
|
|
219
|
+
tryLoc: locs[0]
|
|
220
|
+
};
|
|
221
|
+
1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry);
|
|
222
|
+
}
|
|
223
|
+
function resetTryEntry(entry) {
|
|
224
|
+
var record = entry.completion || {};
|
|
225
|
+
record.type = "normal", delete record.arg, entry.completion = record;
|
|
226
|
+
}
|
|
227
|
+
function Context(tryLocsList) {
|
|
228
|
+
this.tryEntries = [{
|
|
229
|
+
tryLoc: "root"
|
|
230
|
+
}], tryLocsList.forEach(pushTryEntry, this), this.reset(!0);
|
|
231
|
+
}
|
|
232
|
+
function values(iterable) {
|
|
233
|
+
if (iterable) {
|
|
234
|
+
var iteratorMethod = iterable[iteratorSymbol];
|
|
235
|
+
if (iteratorMethod) return iteratorMethod.call(iterable);
|
|
236
|
+
if ("function" == typeof iterable.next) return iterable;
|
|
237
|
+
if (!isNaN(iterable.length)) {
|
|
238
|
+
var i = -1,
|
|
239
|
+
next = function next() {
|
|
240
|
+
for (; ++i < iterable.length;) if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next;
|
|
241
|
+
return next.value = undefined, next.done = !0, next;
|
|
242
|
+
};
|
|
243
|
+
return next.next = next;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
next: doneResult
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
function doneResult() {
|
|
251
|
+
return {
|
|
252
|
+
value: undefined,
|
|
253
|
+
done: !0
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
return GeneratorFunction.prototype = GeneratorFunctionPrototype, defineProperty(Gp, "constructor", {
|
|
257
|
+
value: GeneratorFunctionPrototype,
|
|
258
|
+
configurable: !0
|
|
259
|
+
}), defineProperty(GeneratorFunctionPrototype, "constructor", {
|
|
260
|
+
value: GeneratorFunction,
|
|
261
|
+
configurable: !0
|
|
262
|
+
}), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) {
|
|
263
|
+
var ctor = "function" == typeof genFun && genFun.constructor;
|
|
264
|
+
return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name));
|
|
265
|
+
}, exports.mark = function (genFun) {
|
|
266
|
+
return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun;
|
|
267
|
+
}, exports.awrap = function (arg) {
|
|
268
|
+
return {
|
|
269
|
+
__await: arg
|
|
270
|
+
};
|
|
271
|
+
}, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () {
|
|
272
|
+
return this;
|
|
273
|
+
}), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) {
|
|
274
|
+
void 0 === PromiseImpl && (PromiseImpl = Promise);
|
|
275
|
+
var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl);
|
|
276
|
+
return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) {
|
|
277
|
+
return result.done ? result.value : iter.next();
|
|
278
|
+
});
|
|
279
|
+
}, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () {
|
|
280
|
+
return this;
|
|
281
|
+
}), define(Gp, "toString", function () {
|
|
282
|
+
return "[object Generator]";
|
|
283
|
+
}), exports.keys = function (val) {
|
|
284
|
+
var object = Object(val),
|
|
285
|
+
keys = [];
|
|
286
|
+
for (var key in object) keys.push(key);
|
|
287
|
+
return keys.reverse(), function next() {
|
|
288
|
+
for (; keys.length;) {
|
|
289
|
+
var key = keys.pop();
|
|
290
|
+
if (key in object) return next.value = key, next.done = !1, next;
|
|
291
|
+
}
|
|
292
|
+
return next.done = !0, next;
|
|
293
|
+
};
|
|
294
|
+
}, exports.values = values, Context.prototype = {
|
|
295
|
+
constructor: Context,
|
|
296
|
+
reset: function (skipTempReset) {
|
|
297
|
+
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);
|
|
298
|
+
},
|
|
299
|
+
stop: function () {
|
|
300
|
+
this.done = !0;
|
|
301
|
+
var rootRecord = this.tryEntries[0].completion;
|
|
302
|
+
if ("throw" === rootRecord.type) throw rootRecord.arg;
|
|
303
|
+
return this.rval;
|
|
304
|
+
},
|
|
305
|
+
dispatchException: function (exception) {
|
|
306
|
+
if (this.done) throw exception;
|
|
307
|
+
var context = this;
|
|
308
|
+
function handle(loc, caught) {
|
|
309
|
+
return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught;
|
|
310
|
+
}
|
|
311
|
+
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
|
|
312
|
+
var entry = this.tryEntries[i],
|
|
313
|
+
record = entry.completion;
|
|
314
|
+
if ("root" === entry.tryLoc) return handle("end");
|
|
315
|
+
if (entry.tryLoc <= this.prev) {
|
|
316
|
+
var hasCatch = hasOwn.call(entry, "catchLoc"),
|
|
317
|
+
hasFinally = hasOwn.call(entry, "finallyLoc");
|
|
318
|
+
if (hasCatch && hasFinally) {
|
|
319
|
+
if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
|
|
320
|
+
if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
|
|
321
|
+
} else if (hasCatch) {
|
|
322
|
+
if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
|
|
323
|
+
} else {
|
|
324
|
+
if (!hasFinally) throw new Error("try statement without catch or finally");
|
|
325
|
+
if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
},
|
|
330
|
+
abrupt: function (type, arg) {
|
|
331
|
+
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
|
|
332
|
+
var entry = this.tryEntries[i];
|
|
333
|
+
if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) {
|
|
334
|
+
var finallyEntry = entry;
|
|
335
|
+
break;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null);
|
|
339
|
+
var record = finallyEntry ? finallyEntry.completion : {};
|
|
340
|
+
return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record);
|
|
341
|
+
},
|
|
342
|
+
complete: function (record, afterLoc) {
|
|
343
|
+
if ("throw" === record.type) throw record.arg;
|
|
344
|
+
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;
|
|
345
|
+
},
|
|
346
|
+
finish: function (finallyLoc) {
|
|
347
|
+
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
|
|
348
|
+
var entry = this.tryEntries[i];
|
|
349
|
+
if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel;
|
|
350
|
+
}
|
|
351
|
+
},
|
|
352
|
+
catch: function (tryLoc) {
|
|
353
|
+
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
|
|
354
|
+
var entry = this.tryEntries[i];
|
|
355
|
+
if (entry.tryLoc === tryLoc) {
|
|
356
|
+
var record = entry.completion;
|
|
357
|
+
if ("throw" === record.type) {
|
|
358
|
+
var thrown = record.arg;
|
|
359
|
+
resetTryEntry(entry);
|
|
360
|
+
}
|
|
361
|
+
return thrown;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
throw new Error("illegal catch attempt");
|
|
365
|
+
},
|
|
366
|
+
delegateYield: function (iterable, resultName, nextLoc) {
|
|
367
|
+
return this.delegate = {
|
|
368
|
+
iterator: values(iterable),
|
|
369
|
+
resultName: resultName,
|
|
370
|
+
nextLoc: nextLoc
|
|
371
|
+
}, "next" === this.method && (this.arg = undefined), ContinueSentinel;
|
|
372
|
+
}
|
|
373
|
+
}, exports;
|
|
374
|
+
}
|
|
375
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
376
|
+
try {
|
|
377
|
+
var info = gen[key](arg);
|
|
378
|
+
var value = info.value;
|
|
379
|
+
} catch (error) {
|
|
380
|
+
reject(error);
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
if (info.done) {
|
|
384
|
+
resolve(value);
|
|
385
|
+
} else {
|
|
386
|
+
Promise.resolve(value).then(_next, _throw);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
function _asyncToGenerator(fn) {
|
|
390
|
+
return function () {
|
|
391
|
+
var self = this,
|
|
392
|
+
args = arguments;
|
|
393
|
+
return new Promise(function (resolve, reject) {
|
|
394
|
+
var gen = fn.apply(self, args);
|
|
395
|
+
function _next(value) {
|
|
396
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
|
|
397
|
+
}
|
|
398
|
+
function _throw(err) {
|
|
399
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
|
|
400
|
+
}
|
|
401
|
+
_next(undefined);
|
|
402
|
+
});
|
|
403
|
+
};
|
|
404
|
+
}
|
|
70
405
|
function _classCallCheck(instance, Constructor) {
|
|
71
406
|
if (!(instance instanceof Constructor)) {
|
|
72
407
|
throw new TypeError("Cannot call a class as a function");
|
|
@@ -203,19 +538,43 @@ function _toPropertyKey(arg) {
|
|
|
203
538
|
return typeof key === "symbol" ? key : String(key);
|
|
204
539
|
}
|
|
205
540
|
|
|
206
|
-
var toArray = function
|
|
207
|
-
|
|
541
|
+
var toArray = function (x) { return (Array.isArray(x) ? x : [x]); };
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* Returns a function that checks if a given content item's ConceptNameCodeSequence.CodeMeaning
|
|
545
|
+
* matches the provided codeMeaningName.
|
|
546
|
+
* @param codeMeaningName - The CodeMeaning to match against.
|
|
547
|
+
* @returns A function that takes a content item and returns a boolean indicating whether the
|
|
548
|
+
* content item's CodeMeaning matches the provided codeMeaningName.
|
|
549
|
+
*/
|
|
550
|
+
var codeMeaningEquals = function (codeMeaningName) {
|
|
551
|
+
return function (contentItem) {
|
|
552
|
+
return (contentItem.ConceptNameCodeSequence.CodeMeaning === codeMeaningName);
|
|
553
|
+
};
|
|
208
554
|
};
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
555
|
+
|
|
556
|
+
/**
|
|
557
|
+
* Checks if a given content item's GraphicType property matches a specified value.
|
|
558
|
+
* @param {string} graphicType - The value to compare the content item's GraphicType property to.
|
|
559
|
+
* @returns {function} A function that takes a content item and returns a boolean indicating whether its GraphicType property matches the specified value.
|
|
560
|
+
*/
|
|
561
|
+
var graphicTypeEquals = function (graphicType) {
|
|
562
|
+
return function (contentItem) {
|
|
563
|
+
return contentItem && contentItem.GraphicType === graphicType;
|
|
564
|
+
};
|
|
213
565
|
};
|
|
214
566
|
|
|
567
|
+
var index$1 = /*#__PURE__*/Object.freeze({
|
|
568
|
+
__proto__: null,
|
|
569
|
+
codeMeaningEquals: codeMeaningEquals,
|
|
570
|
+
graphicTypeEquals: graphicTypeEquals,
|
|
571
|
+
toArray: toArray
|
|
572
|
+
});
|
|
573
|
+
|
|
215
574
|
var TID1500$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.TID1500,
|
|
216
575
|
addAccessors$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.addAccessors;
|
|
217
576
|
var StructuredReport$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .derivations */ .U7.StructuredReport;
|
|
218
|
-
var Normalizer$
|
|
577
|
+
var Normalizer$4 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .normalizers */ .oq.Normalizer;
|
|
219
578
|
var TID1500MeasurementReport$1 = TID1500$1.TID1500MeasurementReport,
|
|
220
579
|
TID1501MeasurementGroup$1 = TID1500$1.TID1501MeasurementGroup;
|
|
221
580
|
var DicomMetaDictionary$3 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.DicomMetaDictionary;
|
|
@@ -347,7 +706,7 @@ var MeasurementReport$1 = /*#__PURE__*/function () {
|
|
|
347
706
|
ReferencedSOPClassUID: sopCommonModule.sopClassUID,
|
|
348
707
|
ReferencedSOPInstanceUID: sopCommonModule.sopInstanceUID
|
|
349
708
|
};
|
|
350
|
-
if (Normalizer$
|
|
709
|
+
if (Normalizer$4.isMultiframeSOPClassUID(sopCommonModule.sopClassUID)) {
|
|
351
710
|
ReferencedSOPSequence.ReferencedFrameNumber = frameNumber;
|
|
352
711
|
}
|
|
353
712
|
|
|
@@ -1181,176 +1540,449 @@ ArrowAnnotate$1.isValidCornerstoneTrackingIdentifier = function (TrackingIdentif
|
|
|
1181
1540
|
};
|
|
1182
1541
|
MeasurementReport$1.registerTool(ArrowAnnotate$1);
|
|
1183
1542
|
|
|
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!");
|
|
1543
|
+
var TID300CobbAngle$2 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.TID300.CobbAngle;
|
|
1544
|
+
var COBB_ANGLE = "CobbAngle";
|
|
1545
|
+
var CobbAngle$1 = /*#__PURE__*/function () {
|
|
1546
|
+
function CobbAngle() {
|
|
1547
|
+
_classCallCheck(this, CobbAngle);
|
|
1234
1548
|
}
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1549
|
+
_createClass(CobbAngle, null, [{
|
|
1550
|
+
key: "getMeasurementData",
|
|
1551
|
+
value:
|
|
1552
|
+
// TODO: this function is required for all Cornerstone Tool Adapters, since it is called by MeasurementReport.
|
|
1553
|
+
function getMeasurementData(MeasurementGroup) {
|
|
1554
|
+
var _MeasurementReport$ge = MeasurementReport$1.getSetupMeasurementData(MeasurementGroup),
|
|
1555
|
+
defaultState = _MeasurementReport$ge.defaultState,
|
|
1556
|
+
NUMGroup = _MeasurementReport$ge.NUMGroup,
|
|
1557
|
+
SCOORDGroup = _MeasurementReport$ge.SCOORDGroup;
|
|
1558
|
+
var state = _objectSpread2(_objectSpread2({}, defaultState), {}, {
|
|
1559
|
+
rAngle: NUMGroup.MeasuredValueSequence.NumericValue,
|
|
1560
|
+
toolType: CobbAngle.toolType,
|
|
1561
|
+
handles: {
|
|
1562
|
+
start: {},
|
|
1563
|
+
end: {},
|
|
1564
|
+
start2: {
|
|
1565
|
+
highlight: true,
|
|
1566
|
+
drawnIndependently: true
|
|
1567
|
+
},
|
|
1568
|
+
end2: {
|
|
1569
|
+
highlight: true,
|
|
1570
|
+
drawnIndependently: true
|
|
1571
|
+
},
|
|
1572
|
+
textBox: {
|
|
1573
|
+
hasMoved: false,
|
|
1574
|
+
movesIndependently: false,
|
|
1575
|
+
drawnIndependently: true,
|
|
1576
|
+
allowedOutsideImage: true,
|
|
1577
|
+
hasBoundingBox: true
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
});
|
|
1581
|
+
var _SCOORDGroup$GraphicD = _slicedToArray(SCOORDGroup.GraphicData, 8);
|
|
1582
|
+
state.handles.start.x = _SCOORDGroup$GraphicD[0];
|
|
1583
|
+
state.handles.start.y = _SCOORDGroup$GraphicD[1];
|
|
1584
|
+
state.handles.end.x = _SCOORDGroup$GraphicD[2];
|
|
1585
|
+
state.handles.end.y = _SCOORDGroup$GraphicD[3];
|
|
1586
|
+
state.handles.start2.x = _SCOORDGroup$GraphicD[4];
|
|
1587
|
+
state.handles.start2.y = _SCOORDGroup$GraphicD[5];
|
|
1588
|
+
state.handles.end2.x = _SCOORDGroup$GraphicD[6];
|
|
1589
|
+
state.handles.end2.y = _SCOORDGroup$GraphicD[7];
|
|
1590
|
+
return state;
|
|
1591
|
+
}
|
|
1592
|
+
}, {
|
|
1593
|
+
key: "getTID300RepresentationArguments",
|
|
1594
|
+
value: function getTID300RepresentationArguments(tool) {
|
|
1595
|
+
var handles = tool.handles,
|
|
1596
|
+
finding = tool.finding,
|
|
1597
|
+
findingSites = tool.findingSites;
|
|
1598
|
+
var point1 = handles.start;
|
|
1599
|
+
var point2 = handles.end;
|
|
1600
|
+
var point3 = handles.start2;
|
|
1601
|
+
var point4 = handles.end2;
|
|
1602
|
+
var rAngle = tool.rAngle;
|
|
1603
|
+
var trackingIdentifierTextValue = "cornerstoneTools@^4.0.0:CobbAngle";
|
|
1604
|
+
return {
|
|
1605
|
+
point1: point1,
|
|
1606
|
+
point2: point2,
|
|
1607
|
+
point3: point3,
|
|
1608
|
+
point4: point4,
|
|
1609
|
+
rAngle: rAngle,
|
|
1610
|
+
trackingIdentifierTextValue: trackingIdentifierTextValue,
|
|
1611
|
+
finding: finding,
|
|
1612
|
+
findingSites: findingSites || []
|
|
1613
|
+
};
|
|
1614
|
+
}
|
|
1615
|
+
}]);
|
|
1616
|
+
return CobbAngle;
|
|
1617
|
+
}();
|
|
1618
|
+
CobbAngle$1.toolType = COBB_ANGLE;
|
|
1619
|
+
CobbAngle$1.utilityToolType = COBB_ANGLE;
|
|
1620
|
+
CobbAngle$1.TID300Representation = TID300CobbAngle$2;
|
|
1621
|
+
CobbAngle$1.isValidCornerstoneTrackingIdentifier = function (TrackingIdentifier) {
|
|
1622
|
+
if (!TrackingIdentifier.includes(":")) {
|
|
1623
|
+
return false;
|
|
1243
1624
|
}
|
|
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);
|
|
1625
|
+
var _TrackingIdentifier$s = TrackingIdentifier.split(":"),
|
|
1626
|
+
_TrackingIdentifier$s2 = _slicedToArray(_TrackingIdentifier$s, 2),
|
|
1627
|
+
cornerstone4Tag = _TrackingIdentifier$s2[0],
|
|
1628
|
+
toolType = _TrackingIdentifier$s2[1];
|
|
1629
|
+
if (cornerstone4Tag !== CORNERSTONE_4_TAG) {
|
|
1630
|
+
return false;
|
|
1255
1631
|
}
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
var imageId = images[frame].imageId;
|
|
1266
|
-
var imageIdSpecificToolState = toolState[imageId];
|
|
1267
|
-
var brushPixelData = imageIdSpecificToolState.brush.data[segmentIndex].pixelData;
|
|
1268
|
-
for (var p = 0; p < brushPixelData.length; p++) {
|
|
1269
|
-
pixelData[pixelDataIndex] = brushPixelData[p];
|
|
1270
|
-
pixelDataIndex++;
|
|
1271
|
-
}
|
|
1632
|
+
return toolType === COBB_ANGLE;
|
|
1633
|
+
};
|
|
1634
|
+
MeasurementReport$1.registerTool(CobbAngle$1);
|
|
1635
|
+
|
|
1636
|
+
var TID300Angle = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.TID300.Angle;
|
|
1637
|
+
var ANGLE = "Angle";
|
|
1638
|
+
var Angle$1 = /*#__PURE__*/function () {
|
|
1639
|
+
function Angle() {
|
|
1640
|
+
_classCallCheck(this, Angle);
|
|
1272
1641
|
}
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1642
|
+
_createClass(Angle, null, [{
|
|
1643
|
+
key: "getMeasurementData",
|
|
1644
|
+
value:
|
|
1645
|
+
/**
|
|
1646
|
+
* Generate TID300 measurement data for a plane angle measurement - use a Angle, but label it as Angle
|
|
1647
|
+
*/
|
|
1648
|
+
function getMeasurementData(MeasurementGroup) {
|
|
1649
|
+
var _MeasurementReport$ge = MeasurementReport$1.getSetupMeasurementData(MeasurementGroup),
|
|
1650
|
+
defaultState = _MeasurementReport$ge.defaultState,
|
|
1651
|
+
NUMGroup = _MeasurementReport$ge.NUMGroup,
|
|
1652
|
+
SCOORDGroup = _MeasurementReport$ge.SCOORDGroup;
|
|
1653
|
+
var state = _objectSpread2(_objectSpread2({}, defaultState), {}, {
|
|
1654
|
+
rAngle: NUMGroup.MeasuredValueSequence.NumericValue,
|
|
1655
|
+
toolType: Angle.toolType,
|
|
1656
|
+
handles: {
|
|
1657
|
+
start: {},
|
|
1658
|
+
middle: {},
|
|
1659
|
+
end: {},
|
|
1660
|
+
textBox: {
|
|
1661
|
+
hasMoved: false,
|
|
1662
|
+
movesIndependently: false,
|
|
1663
|
+
drawnIndependently: true,
|
|
1664
|
+
allowedOutsideImage: true,
|
|
1665
|
+
hasBoundingBox: true
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
});
|
|
1669
|
+
var _SCOORDGroup$GraphicD = _slicedToArray(SCOORDGroup.GraphicData, 8);
|
|
1670
|
+
state.handles.start.x = _SCOORDGroup$GraphicD[0];
|
|
1671
|
+
state.handles.start.y = _SCOORDGroup$GraphicD[1];
|
|
1672
|
+
state.handles.middle.x = _SCOORDGroup$GraphicD[2];
|
|
1673
|
+
state.handles.middle.y = _SCOORDGroup$GraphicD[3];
|
|
1674
|
+
state.handles.middle.x = _SCOORDGroup$GraphicD[4];
|
|
1675
|
+
state.handles.middle.y = _SCOORDGroup$GraphicD[5];
|
|
1676
|
+
state.handles.end.x = _SCOORDGroup$GraphicD[6];
|
|
1677
|
+
state.handles.end.y = _SCOORDGroup$GraphicD[7];
|
|
1678
|
+
return state;
|
|
1282
1679
|
}
|
|
1283
|
-
}
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1680
|
+
}, {
|
|
1681
|
+
key: "getTID300RepresentationArguments",
|
|
1682
|
+
value: function getTID300RepresentationArguments(tool) {
|
|
1683
|
+
var handles = tool.handles,
|
|
1684
|
+
finding = tool.finding,
|
|
1685
|
+
findingSites = tool.findingSites;
|
|
1686
|
+
var point1 = handles.start;
|
|
1687
|
+
var point2 = handles.middle;
|
|
1688
|
+
var point3 = handles.middle;
|
|
1689
|
+
var point4 = handles.end;
|
|
1690
|
+
var rAngle = tool.rAngle;
|
|
1691
|
+
var trackingIdentifierTextValue = "cornerstoneTools@^4.0.0:Angle";
|
|
1692
|
+
return {
|
|
1693
|
+
point1: point1,
|
|
1694
|
+
point2: point2,
|
|
1695
|
+
point3: point3,
|
|
1696
|
+
point4: point4,
|
|
1697
|
+
rAngle: rAngle,
|
|
1698
|
+
trackingIdentifierTextValue: trackingIdentifierTextValue,
|
|
1699
|
+
finding: finding,
|
|
1700
|
+
findingSites: findingSites || []
|
|
1701
|
+
};
|
|
1292
1702
|
}
|
|
1703
|
+
}]);
|
|
1704
|
+
return Angle;
|
|
1705
|
+
}();
|
|
1706
|
+
Angle$1.toolType = ANGLE;
|
|
1707
|
+
Angle$1.utilityToolType = ANGLE;
|
|
1708
|
+
Angle$1.TID300Representation = TID300Angle;
|
|
1709
|
+
Angle$1.isValidCornerstoneTrackingIdentifier = function (TrackingIdentifier) {
|
|
1710
|
+
if (!TrackingIdentifier.includes(":")) {
|
|
1711
|
+
return false;
|
|
1293
1712
|
}
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
var numSegments = 0;
|
|
1301
|
-
for (var i = 0; i < segments.length; i++) {
|
|
1302
|
-
if (segments[i]) {
|
|
1303
|
-
numSegments++;
|
|
1304
|
-
}
|
|
1713
|
+
var _TrackingIdentifier$s = TrackingIdentifier.split(":"),
|
|
1714
|
+
_TrackingIdentifier$s2 = _slicedToArray(_TrackingIdentifier$s, 2),
|
|
1715
|
+
cornerstone4Tag = _TrackingIdentifier$s2[0],
|
|
1716
|
+
toolType = _TrackingIdentifier$s2[1];
|
|
1717
|
+
if (cornerstone4Tag !== CORNERSTONE_4_TAG) {
|
|
1718
|
+
return false;
|
|
1305
1719
|
}
|
|
1306
|
-
return
|
|
1307
|
-
}
|
|
1720
|
+
return toolType === ANGLE;
|
|
1721
|
+
};
|
|
1722
|
+
MeasurementReport$1.registerTool(Angle$1);
|
|
1308
1723
|
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
function
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1724
|
+
var TID300Polyline$2 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.TID300.Polyline;
|
|
1725
|
+
var RectangleRoi = /*#__PURE__*/function () {
|
|
1726
|
+
function RectangleRoi() {
|
|
1727
|
+
_classCallCheck(this, RectangleRoi);
|
|
1728
|
+
}
|
|
1729
|
+
_createClass(RectangleRoi, null, [{
|
|
1730
|
+
key: "getMeasurementData",
|
|
1731
|
+
value: function getMeasurementData(MeasurementGroup) {
|
|
1732
|
+
var _MeasurementReport$ge = MeasurementReport$1.getSetupMeasurementData(MeasurementGroup),
|
|
1733
|
+
defaultState = _MeasurementReport$ge.defaultState,
|
|
1734
|
+
SCOORDGroup = _MeasurementReport$ge.SCOORDGroup,
|
|
1735
|
+
NUMGroup = _MeasurementReport$ge.NUMGroup;
|
|
1736
|
+
var state = _objectSpread2(_objectSpread2({}, defaultState), {}, {
|
|
1737
|
+
toolType: RectangleRoi.toolType,
|
|
1738
|
+
handles: {
|
|
1739
|
+
start: {},
|
|
1740
|
+
end: {},
|
|
1741
|
+
textBox: {
|
|
1742
|
+
active: false,
|
|
1743
|
+
hasMoved: false,
|
|
1744
|
+
movesIndependently: false,
|
|
1745
|
+
drawnIndependently: true,
|
|
1746
|
+
allowedOutsideImage: true,
|
|
1747
|
+
hasBoundingBox: true
|
|
1748
|
+
},
|
|
1749
|
+
initialRotation: 0
|
|
1750
|
+
},
|
|
1751
|
+
cachedStats: {
|
|
1752
|
+
area: NUMGroup ? NUMGroup.MeasuredValueSequence.NumericValue : 0
|
|
1753
|
+
},
|
|
1754
|
+
color: undefined,
|
|
1755
|
+
invalidated: true
|
|
1756
|
+
});
|
|
1757
|
+
var _SCOORDGroup$GraphicD = _slicedToArray(SCOORDGroup.GraphicData, 6);
|
|
1758
|
+
state.handles.start.x = _SCOORDGroup$GraphicD[0];
|
|
1759
|
+
state.handles.start.y = _SCOORDGroup$GraphicD[1];
|
|
1760
|
+
_SCOORDGroup$GraphicD[2];
|
|
1761
|
+
_SCOORDGroup$GraphicD[3];
|
|
1762
|
+
state.handles.end.x = _SCOORDGroup$GraphicD[4];
|
|
1763
|
+
state.handles.end.y = _SCOORDGroup$GraphicD[5];
|
|
1764
|
+
return state;
|
|
1765
|
+
}
|
|
1766
|
+
}, {
|
|
1767
|
+
key: "getTID300RepresentationArguments",
|
|
1768
|
+
value: function getTID300RepresentationArguments(tool) {
|
|
1769
|
+
var finding = tool.finding,
|
|
1770
|
+
findingSites = tool.findingSites,
|
|
1771
|
+
_tool$cachedStats = tool.cachedStats,
|
|
1772
|
+
cachedStats = _tool$cachedStats === void 0 ? {} : _tool$cachedStats,
|
|
1773
|
+
handles = tool.handles;
|
|
1774
|
+
var start = handles.start,
|
|
1775
|
+
end = handles.end;
|
|
1776
|
+
var points = [start, {
|
|
1777
|
+
x: start.x,
|
|
1778
|
+
y: end.y
|
|
1779
|
+
}, end, {
|
|
1780
|
+
x: end.x,
|
|
1781
|
+
y: start.y
|
|
1782
|
+
}];
|
|
1783
|
+
var area = cachedStats.area,
|
|
1784
|
+
perimeter = cachedStats.perimeter;
|
|
1785
|
+
var trackingIdentifierTextValue = "cornerstoneTools@^4.0.0:RectangleRoi";
|
|
1786
|
+
return {
|
|
1787
|
+
points: points,
|
|
1788
|
+
area: area,
|
|
1789
|
+
perimeter: perimeter,
|
|
1790
|
+
trackingIdentifierTextValue: trackingIdentifierTextValue,
|
|
1791
|
+
finding: finding,
|
|
1792
|
+
findingSites: findingSites || []
|
|
1793
|
+
};
|
|
1333
1794
|
}
|
|
1795
|
+
}]);
|
|
1796
|
+
return RectangleRoi;
|
|
1797
|
+
}();
|
|
1798
|
+
RectangleRoi.toolType = "RectangleRoi";
|
|
1799
|
+
RectangleRoi.utilityToolType = "RectangleRoi";
|
|
1800
|
+
RectangleRoi.TID300Representation = TID300Polyline$2;
|
|
1801
|
+
RectangleRoi.isValidCornerstoneTrackingIdentifier = function (TrackingIdentifier) {
|
|
1802
|
+
if (!TrackingIdentifier.includes(":")) {
|
|
1803
|
+
return false;
|
|
1334
1804
|
}
|
|
1335
|
-
var
|
|
1336
|
-
|
|
1337
|
-
|
|
1805
|
+
var _TrackingIdentifier$s = TrackingIdentifier.split(":"),
|
|
1806
|
+
_TrackingIdentifier$s2 = _slicedToArray(_TrackingIdentifier$s, 2),
|
|
1807
|
+
cornerstone4Tag = _TrackingIdentifier$s2[0],
|
|
1808
|
+
toolType = _TrackingIdentifier$s2[1];
|
|
1809
|
+
if (cornerstone4Tag !== CORNERSTONE_4_TAG) {
|
|
1810
|
+
return false;
|
|
1811
|
+
}
|
|
1812
|
+
return toolType === RectangleRoi.toolType;
|
|
1813
|
+
};
|
|
1814
|
+
MeasurementReport$1.registerTool(RectangleRoi);
|
|
1815
|
+
|
|
1816
|
+
var _utilities$orientatio$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.orientation,
|
|
1817
|
+
rotateDirectionCosinesInPlane$1 = _utilities$orientatio$1.rotateDirectionCosinesInPlane,
|
|
1818
|
+
flipIOP$1 = _utilities$orientatio$1.flipImageOrientationPatient,
|
|
1819
|
+
flipMatrix2D$1 = _utilities$orientatio$1.flipMatrix2D,
|
|
1820
|
+
rotateMatrix902D$1 = _utilities$orientatio$1.rotateMatrix902D;
|
|
1821
|
+
var datasetToBlob = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.datasetToBlob,
|
|
1822
|
+
BitArray$2 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.BitArray,
|
|
1823
|
+
DicomMessage$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.DicomMessage,
|
|
1824
|
+
DicomMetaDictionary$2 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.DicomMetaDictionary;
|
|
1825
|
+
var Normalizer$3 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .normalizers */ .oq.Normalizer;
|
|
1826
|
+
var SegmentationDerivation$2 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .derivations */ .U7.Segmentation;
|
|
1827
|
+
var Segmentation$5 = {
|
|
1828
|
+
generateSegmentation: generateSegmentation$3,
|
|
1829
|
+
generateToolState: generateToolState$3
|
|
1830
|
+
};
|
|
1338
1831
|
|
|
1339
1832
|
/**
|
|
1340
|
-
* generateToolState - Given a set of cornrstoneTools imageIds and a Segmentation buffer,
|
|
1341
|
-
* derive cornerstoneTools toolState and brush metadata.
|
|
1342
1833
|
*
|
|
1343
|
-
* @
|
|
1834
|
+
* @typedef {Object} BrushData
|
|
1835
|
+
* @property {Object} toolState - The cornerstoneTools global toolState.
|
|
1836
|
+
* @property {Object[]} segments - The cornerstoneTools segment metadata that corresponds to the
|
|
1837
|
+
* seriesInstanceUid.
|
|
1838
|
+
*/
|
|
1839
|
+
|
|
1840
|
+
/**
|
|
1841
|
+
* generateSegmentation - Generates cornerstoneTools brush data, given a stack of
|
|
1842
|
+
* imageIds, images and the cornerstoneTools brushData.
|
|
1843
|
+
*
|
|
1844
|
+
* @param {object[]} images An array of the cornerstone image objects.
|
|
1845
|
+
* @param {BrushData} brushData and object containing the brushData.
|
|
1846
|
+
* @returns {type} description
|
|
1847
|
+
*/
|
|
1848
|
+
function generateSegmentation$3(images, brushData) {
|
|
1849
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
|
|
1850
|
+
includeSliceSpacing: true
|
|
1851
|
+
};
|
|
1852
|
+
var toolState = brushData.toolState,
|
|
1853
|
+
segments = brushData.segments;
|
|
1854
|
+
|
|
1855
|
+
// Calculate the dimensions of the data cube.
|
|
1856
|
+
var image0 = images[0];
|
|
1857
|
+
var dims = {
|
|
1858
|
+
x: image0.columns,
|
|
1859
|
+
y: image0.rows,
|
|
1860
|
+
z: images.length
|
|
1861
|
+
};
|
|
1862
|
+
dims.xy = dims.x * dims.y;
|
|
1863
|
+
var numSegments = _getSegCount(seg, segments);
|
|
1864
|
+
if (!numSegments) {
|
|
1865
|
+
throw new Error("No segments to export!");
|
|
1866
|
+
}
|
|
1867
|
+
var isMultiframe = image0.imageId.includes("?frame");
|
|
1868
|
+
var seg = _createSegFromImages$1(images, isMultiframe, options);
|
|
1869
|
+
var _getNumberOfFramesPer = _getNumberOfFramesPerSegment(toolState, images, segments),
|
|
1870
|
+
referencedFramesPerSegment = _getNumberOfFramesPer.referencedFramesPerSegment,
|
|
1871
|
+
segmentIndicies = _getNumberOfFramesPer.segmentIndicies;
|
|
1872
|
+
var NumberOfFrames = 0;
|
|
1873
|
+
for (var i = 0; i < referencedFramesPerSegment.length; i++) {
|
|
1874
|
+
NumberOfFrames += referencedFramesPerSegment[i].length;
|
|
1875
|
+
}
|
|
1876
|
+
seg.setNumberOfFrames(NumberOfFrames);
|
|
1877
|
+
for (var _i = 0; _i < segmentIndicies.length; _i++) {
|
|
1878
|
+
var segmentIndex = segmentIndicies[_i];
|
|
1879
|
+
var referencedFrameIndicies = referencedFramesPerSegment[_i];
|
|
1880
|
+
|
|
1881
|
+
// Frame numbers start from 1.
|
|
1882
|
+
var referencedFrameNumbers = referencedFrameIndicies.map(function (element) {
|
|
1883
|
+
return element + 1;
|
|
1884
|
+
});
|
|
1885
|
+
var segment = segments[segmentIndex];
|
|
1886
|
+
seg.addSegment(segment, _extractCornerstoneToolsPixelData(segmentIndex, referencedFrameIndicies, toolState, images, dims), referencedFrameNumbers);
|
|
1887
|
+
}
|
|
1888
|
+
seg.bitPackPixelData();
|
|
1889
|
+
var segBlob = datasetToBlob(seg.dataset);
|
|
1890
|
+
return segBlob;
|
|
1891
|
+
}
|
|
1892
|
+
function _extractCornerstoneToolsPixelData(segmentIndex, referencedFrames, toolState, images, dims) {
|
|
1893
|
+
var pixelData = new Uint8Array(dims.xy * referencedFrames.length);
|
|
1894
|
+
var pixelDataIndex = 0;
|
|
1895
|
+
for (var i = 0; i < referencedFrames.length; i++) {
|
|
1896
|
+
var frame = referencedFrames[i];
|
|
1897
|
+
var imageId = images[frame].imageId;
|
|
1898
|
+
var imageIdSpecificToolState = toolState[imageId];
|
|
1899
|
+
var brushPixelData = imageIdSpecificToolState.brush.data[segmentIndex].pixelData;
|
|
1900
|
+
for (var p = 0; p < brushPixelData.length; p++) {
|
|
1901
|
+
pixelData[pixelDataIndex] = brushPixelData[p];
|
|
1902
|
+
pixelDataIndex++;
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
return pixelData;
|
|
1906
|
+
}
|
|
1907
|
+
function _getNumberOfFramesPerSegment(toolState, images, segments) {
|
|
1908
|
+
var segmentIndicies = [];
|
|
1909
|
+
var referencedFramesPerSegment = [];
|
|
1910
|
+
for (var i = 0; i < segments.length; i++) {
|
|
1911
|
+
if (segments[i]) {
|
|
1912
|
+
segmentIndicies.push(i);
|
|
1913
|
+
referencedFramesPerSegment.push([]);
|
|
1914
|
+
}
|
|
1915
|
+
}
|
|
1916
|
+
for (var z = 0; z < images.length; z++) {
|
|
1917
|
+
var imageId = images[z].imageId;
|
|
1918
|
+
var imageIdSpecificToolState = toolState[imageId];
|
|
1919
|
+
for (var _i2 = 0; _i2 < segmentIndicies.length; _i2++) {
|
|
1920
|
+
var segIdx = segmentIndicies[_i2];
|
|
1921
|
+
if (imageIdSpecificToolState && imageIdSpecificToolState.brush && imageIdSpecificToolState.brush.data && imageIdSpecificToolState.brush.data[segIdx] && imageIdSpecificToolState.brush.data[segIdx].pixelData) {
|
|
1922
|
+
referencedFramesPerSegment[_i2].push(z);
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
}
|
|
1926
|
+
return {
|
|
1927
|
+
referencedFramesPerSegment: referencedFramesPerSegment,
|
|
1928
|
+
segmentIndicies: segmentIndicies
|
|
1929
|
+
};
|
|
1930
|
+
}
|
|
1931
|
+
function _getSegCount(seg, segments) {
|
|
1932
|
+
var numSegments = 0;
|
|
1933
|
+
for (var i = 0; i < segments.length; i++) {
|
|
1934
|
+
if (segments[i]) {
|
|
1935
|
+
numSegments++;
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
return numSegments;
|
|
1939
|
+
}
|
|
1940
|
+
|
|
1941
|
+
/**
|
|
1942
|
+
* _createSegFromImages - description
|
|
1943
|
+
*
|
|
1944
|
+
* @param {Object[]} images An array of the cornerstone image objects.
|
|
1945
|
+
* @param {Boolean} isMultiframe Whether the images are multiframe.
|
|
1946
|
+
* @returns {Object} The Seg derived dataSet.
|
|
1947
|
+
*/
|
|
1948
|
+
function _createSegFromImages$1(images, isMultiframe, options) {
|
|
1949
|
+
var datasets = [];
|
|
1950
|
+
if (isMultiframe) {
|
|
1951
|
+
var image = images[0];
|
|
1952
|
+
var arrayBuffer = image.data.byteArray.buffer;
|
|
1953
|
+
var dicomData = DicomMessage$1.readFile(arrayBuffer);
|
|
1954
|
+
var dataset = DicomMetaDictionary$2.naturalizeDataset(dicomData.dict);
|
|
1955
|
+
dataset._meta = DicomMetaDictionary$2.namifyDataset(dicomData.meta);
|
|
1956
|
+
datasets.push(dataset);
|
|
1957
|
+
} else {
|
|
1958
|
+
for (var i = 0; i < images.length; i++) {
|
|
1959
|
+
var _image = images[i];
|
|
1960
|
+
var _arrayBuffer = _image.data.byteArray.buffer;
|
|
1961
|
+
var _dicomData = DicomMessage$1.readFile(_arrayBuffer);
|
|
1962
|
+
var _dataset = DicomMetaDictionary$2.naturalizeDataset(_dicomData.dict);
|
|
1963
|
+
_dataset._meta = DicomMetaDictionary$2.namifyDataset(_dicomData.meta);
|
|
1964
|
+
datasets.push(_dataset);
|
|
1965
|
+
}
|
|
1966
|
+
}
|
|
1967
|
+
var multiframe = Normalizer$3.normalizeToDataset(datasets);
|
|
1968
|
+
return new SegmentationDerivation$2([multiframe], options);
|
|
1969
|
+
}
|
|
1970
|
+
|
|
1971
|
+
/**
|
|
1972
|
+
* generateToolState - Given a set of cornrstoneTools imageIds and a Segmentation buffer,
|
|
1973
|
+
* derive cornerstoneTools toolState and brush metadata.
|
|
1974
|
+
*
|
|
1975
|
+
* @param {string[]} imageIds An array of the imageIds.
|
|
1344
1976
|
* @param {ArrayBuffer} arrayBuffer The SEG arrayBuffer.
|
|
1345
1977
|
* @param {*} metadataProvider
|
|
1346
1978
|
* @returns {Object} The toolState and an object from which the
|
|
1347
1979
|
* segment metadata can be derived.
|
|
1348
1980
|
*/
|
|
1349
|
-
function generateToolState$
|
|
1981
|
+
function generateToolState$3(imageIds, arrayBuffer, metadataProvider) {
|
|
1350
1982
|
var dicomData = DicomMessage$1.readFile(arrayBuffer);
|
|
1351
1983
|
var dataset = DicomMetaDictionary$2.naturalizeDataset(dicomData.dict);
|
|
1352
1984
|
dataset._meta = DicomMetaDictionary$2.namifyDataset(dicomData.meta);
|
|
1353
|
-
var multiframe = Normalizer$
|
|
1985
|
+
var multiframe = Normalizer$3.normalizeToDataset([dataset]);
|
|
1354
1986
|
var imagePlaneModule = metadataProvider.get("imagePlaneModule", imageIds[0]);
|
|
1355
1987
|
if (!imagePlaneModule) {
|
|
1356
1988
|
console.warn("Insufficient metadata, imagePlaneModule missing.");
|
|
@@ -1465,7 +2097,7 @@ function addImageIdSpecificBrushToolState(toolState, imageId, segmentIndex, pixe
|
|
|
1465
2097
|
function getImageIdOfSourceImage(SourceImageSequence, imageIds, metadataProvider) {
|
|
1466
2098
|
var ReferencedSOPInstanceUID = SourceImageSequence.ReferencedSOPInstanceUID,
|
|
1467
2099
|
ReferencedFrameNumber = SourceImageSequence.ReferencedFrameNumber;
|
|
1468
|
-
return ReferencedFrameNumber ? getImageIdOfReferencedFrame$1(ReferencedSOPInstanceUID, ReferencedFrameNumber, imageIds, metadataProvider) : getImageIdOfReferencedSingleFramedSOPInstance
|
|
2100
|
+
return ReferencedFrameNumber ? getImageIdOfReferencedFrame$1(ReferencedSOPInstanceUID, ReferencedFrameNumber, imageIds, metadataProvider) : getImageIdOfReferencedSingleFramedSOPInstance(ReferencedSOPInstanceUID, imageIds, metadataProvider);
|
|
1469
2101
|
}
|
|
1470
2102
|
|
|
1471
2103
|
/**
|
|
@@ -1478,7 +2110,7 @@ function getImageIdOfSourceImage(SourceImageSequence, imageIds, metadataProvider
|
|
|
1478
2110
|
* from the cornerstone imageIds.
|
|
1479
2111
|
* @return {String} The imageId that corresponds to the sopInstanceUid.
|
|
1480
2112
|
*/
|
|
1481
|
-
function getImageIdOfReferencedSingleFramedSOPInstance
|
|
2113
|
+
function getImageIdOfReferencedSingleFramedSOPInstance(sopInstanceUid, imageIds, metadataProvider) {
|
|
1482
2114
|
return imageIds.find(function (imageId) {
|
|
1483
2115
|
var sopCommonModule = metadataProvider.get("sopCommonModule", imageId);
|
|
1484
2116
|
if (!sopCommonModule) {
|
|
@@ -1604,26 +2236,38 @@ function getSegmentMetadata$1(multiframe) {
|
|
|
1604
2236
|
};
|
|
1605
2237
|
}
|
|
1606
2238
|
|
|
2239
|
+
/**
|
|
2240
|
+
* Cornerstone adapters events
|
|
2241
|
+
*/
|
|
2242
|
+
var Events;
|
|
2243
|
+
(function (Events) {
|
|
2244
|
+
/**
|
|
2245
|
+
* Cornerstone segmentation load progress event
|
|
2246
|
+
*/
|
|
2247
|
+
Events["SEGMENTATION_LOAD_PROGRESS"] = "CORNERSTONE_ADAPTER_SEGMENTATION_LOAD_PROGRESS";
|
|
2248
|
+
})(Events || (Events = {}));
|
|
2249
|
+
var Events$1 = Events;
|
|
2250
|
+
|
|
2251
|
+
var index = /*#__PURE__*/Object.freeze({
|
|
2252
|
+
__proto__: null,
|
|
2253
|
+
Events: Events$1
|
|
2254
|
+
});
|
|
2255
|
+
|
|
1607
2256
|
var _utilities$orientatio = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.orientation,
|
|
1608
2257
|
rotateDirectionCosinesInPlane = _utilities$orientatio.rotateDirectionCosinesInPlane,
|
|
1609
2258
|
flipIOP = _utilities$orientatio.flipImageOrientationPatient,
|
|
1610
2259
|
flipMatrix2D = _utilities$orientatio.flipMatrix2D,
|
|
1611
2260
|
rotateMatrix902D = _utilities$orientatio.rotateMatrix902D,
|
|
1612
2261
|
nearlyEqual = _utilities$orientatio.nearlyEqual;
|
|
1613
|
-
var
|
|
1614
|
-
BitArray$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .
|
|
1615
|
-
DicomMessage = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .
|
|
1616
|
-
DicomMetaDictionary$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .
|
|
1617
|
-
var Normalizer$
|
|
1618
|
-
var SegmentationDerivation = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .derivations */ .U7.Segmentation;
|
|
2262
|
+
var datasetToDict = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.datasetToDict,
|
|
2263
|
+
BitArray$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.BitArray,
|
|
2264
|
+
DicomMessage = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.DicomMessage,
|
|
2265
|
+
DicomMetaDictionary$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.DicomMetaDictionary;
|
|
2266
|
+
var Normalizer$2 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .normalizers */ .oq.Normalizer;
|
|
2267
|
+
var SegmentationDerivation$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .derivations */ .U7.Segmentation;
|
|
1619
2268
|
var _utilities$compressio = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.compression,
|
|
1620
2269
|
encode = _utilities$compressio.encode,
|
|
1621
2270
|
decode = _utilities$compressio.decode;
|
|
1622
|
-
var Segmentation$2 = {
|
|
1623
|
-
generateSegmentation: generateSegmentation$1,
|
|
1624
|
-
generateToolState: generateToolState$1,
|
|
1625
|
-
fillSegmentation: fillSegmentation$1
|
|
1626
|
-
};
|
|
1627
2271
|
|
|
1628
2272
|
/**
|
|
1629
2273
|
*
|
|
@@ -1632,10 +2276,9 @@ var Segmentation$2 = {
|
|
|
1632
2276
|
* @property {Object[]} segments - The cornerstoneTools segment metadata that corresponds to the
|
|
1633
2277
|
* seriesInstanceUid.
|
|
1634
2278
|
*/
|
|
1635
|
-
|
|
1636
2279
|
var generateSegmentationDefaultOptions = {
|
|
1637
2280
|
includeSliceSpacing: true,
|
|
1638
|
-
rleEncode:
|
|
2281
|
+
rleEncode: false
|
|
1639
2282
|
};
|
|
1640
2283
|
|
|
1641
2284
|
/**
|
|
@@ -1648,7 +2291,7 @@ var generateSegmentationDefaultOptions = {
|
|
|
1648
2291
|
* @param {Object} userOptions Options to pass to the segmentation derivation and `fillSegmentation`.
|
|
1649
2292
|
* @returns {Blob}
|
|
1650
2293
|
*/
|
|
1651
|
-
function generateSegmentation$
|
|
2294
|
+
function generateSegmentation$2(images, inputLabelmaps3D) {
|
|
1652
2295
|
var userOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
1653
2296
|
var isMultiframe = images[0].imageId.includes("?frame");
|
|
1654
2297
|
var segmentation = _createSegFromImages(images, isMultiframe, userOptions);
|
|
@@ -1714,7 +2357,7 @@ function fillSegmentation$1(segmentation, inputLabelmaps3D) {
|
|
|
1714
2357
|
return element + 1;
|
|
1715
2358
|
});
|
|
1716
2359
|
var segmentMetadata = metadata[segmentIndex];
|
|
1717
|
-
var labelmaps =
|
|
2360
|
+
var labelmaps = _getLabelmapsFromReferencedFrameIndicies(labelmap3D, referencedFrameIndicies);
|
|
1718
2361
|
segmentation.addSegmentFromLabelmap(segmentMetadata, labelmaps, segmentIndex, referencedFrameNumbers);
|
|
1719
2362
|
}
|
|
1720
2363
|
}
|
|
@@ -1743,10 +2386,13 @@ function fillSegmentation$1(segmentation, inputLabelmaps3D) {
|
|
|
1743
2386
|
// If no rleEncoding, at least bitpack the data.
|
|
1744
2387
|
segmentation.bitPackPixelData();
|
|
1745
2388
|
}
|
|
1746
|
-
var
|
|
2389
|
+
var buffer = buffer__WEBPACK_IMPORTED_MODULE_3__/* .Buffer */ .lW.from(datasetToDict(segmentation.dataset).write());
|
|
2390
|
+
var segBlob = new Blob([buffer], {
|
|
2391
|
+
type: "application/dicom"
|
|
2392
|
+
});
|
|
1747
2393
|
return segBlob;
|
|
1748
2394
|
}
|
|
1749
|
-
function
|
|
2395
|
+
function _getLabelmapsFromReferencedFrameIndicies(labelmap3D, referencedFrameIndicies) {
|
|
1750
2396
|
var labelmaps2D = labelmap3D.labelmaps2D;
|
|
1751
2397
|
var labelmaps = [];
|
|
1752
2398
|
for (var i = 0; i < referencedFrameIndicies.length; i++) {
|
|
@@ -1782,8 +2428,8 @@ function _createSegFromImages(images, isMultiframe, options) {
|
|
|
1782
2428
|
datasets.push(_dataset);
|
|
1783
2429
|
}
|
|
1784
2430
|
}
|
|
1785
|
-
var multiframe = Normalizer$
|
|
1786
|
-
return new SegmentationDerivation([multiframe], options);
|
|
2431
|
+
var multiframe = Normalizer$2.normalizeToDataset(datasets);
|
|
2432
|
+
return new SegmentationDerivation$1([multiframe], options);
|
|
1787
2433
|
}
|
|
1788
2434
|
|
|
1789
2435
|
/**
|
|
@@ -1793,8 +2439,7 @@ function _createSegFromImages(images, isMultiframe, options) {
|
|
|
1793
2439
|
* @param {string[]} imageIds - An array of the imageIds.
|
|
1794
2440
|
* @param {ArrayBuffer} arrayBuffer - The SEG arrayBuffer.
|
|
1795
2441
|
* @param {*} metadataProvider.
|
|
1796
|
-
* @param {
|
|
1797
|
-
* @param {number} tolerance - default value 1.e-3.
|
|
2442
|
+
* @param {obj} options - Options object.
|
|
1798
2443
|
*
|
|
1799
2444
|
* @return {[]ArrayBuffer}a list of array buffer for each labelMap
|
|
1800
2445
|
* @return {Object} an object from which the segment metadata can be derived
|
|
@@ -1802,83 +2447,9 @@ function _createSegFromImages(images, isMultiframe, options) {
|
|
|
1802
2447
|
* @return {[][][]} 3D list containing the track of segments per frame for each labelMap
|
|
1803
2448
|
* (available only for the overlapping case).
|
|
1804
2449
|
*/
|
|
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(
|
|
2450
|
+
function generateToolState$2(_x, _x2, _x3, _x4) {
|
|
2451
|
+
return _generateToolState.apply(this, arguments);
|
|
2452
|
+
} // function insertPixelDataPerpendicular(
|
|
1882
2453
|
// segmentsOnFrame,
|
|
1883
2454
|
// labelmapBuffer,
|
|
1884
2455
|
// pixelData,
|
|
@@ -1893,30 +2464,23 @@ function generateToolState$1(imageIds, arrayBuffer, metadataProvider) {
|
|
|
1893
2464
|
// Rows,
|
|
1894
2465
|
// Columns
|
|
1895
2466
|
// } = multiframe;
|
|
1896
|
-
|
|
1897
2467
|
// const firstImagePlaneModule = metadataProvider.get(
|
|
1898
2468
|
// "imagePlaneModule",
|
|
1899
2469
|
// imageIds[0]
|
|
1900
2470
|
// );
|
|
1901
|
-
|
|
1902
2471
|
// const lastImagePlaneModule = metadataProvider.get(
|
|
1903
2472
|
// "imagePlaneModule",
|
|
1904
2473
|
// imageIds[imageIds.length - 1]
|
|
1905
2474
|
// );
|
|
1906
|
-
|
|
1907
2475
|
// console.log(firstImagePlaneModule);
|
|
1908
2476
|
// console.log(lastImagePlaneModule);
|
|
1909
|
-
|
|
1910
2477
|
// const corners = [
|
|
1911
2478
|
// ...getCorners(firstImagePlaneModule),
|
|
1912
2479
|
// ...getCorners(lastImagePlaneModule)
|
|
1913
2480
|
// ];
|
|
1914
|
-
|
|
1915
2481
|
// console.log(`corners:`);
|
|
1916
2482
|
// console.log(corners);
|
|
1917
|
-
|
|
1918
2483
|
// const indexToWorld = mat4.create();
|
|
1919
|
-
|
|
1920
2484
|
// const ippFirstFrame = firstImagePlaneModule.imagePositionPatient;
|
|
1921
2485
|
// const rowCosines = Array.isArray(firstImagePlaneModule.rowCosines)
|
|
1922
2486
|
// ? [...firstImagePlaneModule.rowCosines]
|
|
@@ -1925,7 +2489,6 @@ function generateToolState$1(imageIds, arrayBuffer, metadataProvider) {
|
|
|
1925
2489
|
// firstImagePlaneModule.rowCosines.y,
|
|
1926
2490
|
// firstImagePlaneModule.rowCosines.z
|
|
1927
2491
|
// ];
|
|
1928
|
-
|
|
1929
2492
|
// const columnCosines = Array.isArray(firstImagePlaneModule.columnCosines)
|
|
1930
2493
|
// ? [...firstImagePlaneModule.columnCosines]
|
|
1931
2494
|
// : [
|
|
@@ -1933,9 +2496,7 @@ function generateToolState$1(imageIds, arrayBuffer, metadataProvider) {
|
|
|
1933
2496
|
// firstImagePlaneModule.columnCosines.y,
|
|
1934
2497
|
// firstImagePlaneModule.columnCosines.z
|
|
1935
2498
|
// ];
|
|
1936
|
-
|
|
1937
2499
|
// const { pixelSpacing } = firstImagePlaneModule;
|
|
1938
|
-
|
|
1939
2500
|
// mat4.set(
|
|
1940
2501
|
// indexToWorld,
|
|
1941
2502
|
// // Column 1
|
|
@@ -1959,50 +2520,36 @@ function generateToolState$1(imageIds, arrayBuffer, metadataProvider) {
|
|
|
1959
2520
|
// 0,
|
|
1960
2521
|
// 1
|
|
1961
2522
|
// );
|
|
1962
|
-
|
|
1963
2523
|
// // TODO -> Get origin and (x,y,z) increments to build a translation matrix:
|
|
1964
2524
|
// // TODO -> Equation C.7.6.2.1-1
|
|
1965
|
-
|
|
1966
2525
|
// // | cx*di rx* Xx 0 | |x|
|
|
1967
2526
|
// // | cy*di ry Xy 0 | |y|
|
|
1968
2527
|
// // | cz*di rz Xz 0 | |z|
|
|
1969
2528
|
// // | tx ty tz 1 | |1|
|
|
1970
|
-
|
|
1971
2529
|
// // const [
|
|
1972
2530
|
// // 0, 0 , 0 , 0,
|
|
1973
2531
|
// // 0, 0 , 0 , 0,
|
|
1974
2532
|
// // 0, 0 , 0 , 0,
|
|
1975
2533
|
// // ipp[0], ipp[1] , ipp[2] , 1,
|
|
1976
2534
|
// // ]
|
|
1977
|
-
|
|
1978
2535
|
// // Each frame:
|
|
1979
|
-
|
|
1980
2536
|
// // Find which corner the first voxel lines up with (one of 8 corners.)
|
|
1981
|
-
|
|
1982
2537
|
// // Find how i,j,k orient with respect to source volume.
|
|
1983
2538
|
// // Go through each frame, find location in source to start, and whether to increment +/ix,+/-y,+/-z
|
|
1984
2539
|
// // through each voxel.
|
|
1985
|
-
|
|
1986
2540
|
// // [1,0,0,0,1,0]
|
|
1987
|
-
|
|
1988
2541
|
// // const [
|
|
1989
|
-
|
|
1990
2542
|
// // ]
|
|
1991
|
-
|
|
1992
2543
|
// // Invert transformation matrix to get worldToIndex
|
|
1993
|
-
|
|
1994
2544
|
// // Apply world to index on each point to fill up the matrix.
|
|
1995
|
-
|
|
1996
2545
|
// // const sharedImageOrientationPatient = SharedFunctionalGroupsSequence.PlaneOrientationSequence
|
|
1997
2546
|
// // ? SharedFunctionalGroupsSequence.PlaneOrientationSequence
|
|
1998
2547
|
// // .ImageOrientationPatient
|
|
1999
2548
|
// // : undefined;
|
|
2000
2549
|
// // const sliceLength = Columns * Rows;
|
|
2001
2550
|
// }
|
|
2002
|
-
|
|
2003
2551
|
// function getCorners(imagePlaneModule) {
|
|
2004
2552
|
// // console.log(imagePlaneModule);
|
|
2005
|
-
|
|
2006
2553
|
// const {
|
|
2007
2554
|
// rows,
|
|
2008
2555
|
// columns,
|
|
@@ -2012,22 +2559,18 @@ function generateToolState$1(imageIds, arrayBuffer, metadataProvider) {
|
|
|
2012
2559
|
// rowPixelSpacing,
|
|
2013
2560
|
// columnPixelSpacing
|
|
2014
2561
|
// } = imagePlaneModule;
|
|
2015
|
-
|
|
2016
2562
|
// const rowLength = columns * columnPixelSpacing;
|
|
2017
2563
|
// const columnLength = rows * rowPixelSpacing;
|
|
2018
|
-
|
|
2019
2564
|
// const entireRowVector = [
|
|
2020
2565
|
// rowLength * columnCosines[0],
|
|
2021
2566
|
// rowLength * columnCosines[1],
|
|
2022
2567
|
// rowLength * columnCosines[2]
|
|
2023
2568
|
// ];
|
|
2024
|
-
|
|
2025
2569
|
// const entireColumnVector = [
|
|
2026
2570
|
// columnLength * rowCosines[0],
|
|
2027
2571
|
// columnLength * rowCosines[1],
|
|
2028
2572
|
// columnLength * rowCosines[2]
|
|
2029
2573
|
// ];
|
|
2030
|
-
|
|
2031
2574
|
// const topLeft = [ipp[0], ipp[1], ipp[2]];
|
|
2032
2575
|
// const topRight = [
|
|
2033
2576
|
// topLeft[0] + entireRowVector[0],
|
|
@@ -2039,29 +2582,160 @@ function generateToolState$1(imageIds, arrayBuffer, metadataProvider) {
|
|
|
2039
2582
|
// topLeft[1] + entireColumnVector[1],
|
|
2040
2583
|
// topLeft[2] + entireColumnVector[2]
|
|
2041
2584
|
// ];
|
|
2042
|
-
|
|
2043
2585
|
// const bottomRight = [
|
|
2044
2586
|
// bottomLeft[0] + entireRowVector[0],
|
|
2045
2587
|
// bottomLeft[1] + entireRowVector[1],
|
|
2046
2588
|
// bottomLeft[2] + entireRowVector[2]
|
|
2047
2589
|
// ];
|
|
2048
|
-
|
|
2049
2590
|
// return [topLeft, topRight, bottomLeft, bottomRight];
|
|
2050
2591
|
// }
|
|
2051
|
-
|
|
2052
2592
|
/**
|
|
2053
2593
|
* Find the reference frame of the segmentation frame in the source data.
|
|
2054
2594
|
*
|
|
2055
2595
|
* @param {Object} multiframe dicom metadata
|
|
2056
2596
|
* @param {Int} frameSegment frame dicom index
|
|
2057
2597
|
* @param {String[]} imageIds A list of imageIds.
|
|
2058
|
-
* @param {Object}
|
|
2059
|
-
* metadata from imageIds.
|
|
2598
|
+
* @param {Object} sopUIDImageIdIndexMap A map of SOPInstanceUID to imageId
|
|
2060
2599
|
* @param {Float} tolerance The tolerance parameter
|
|
2061
2600
|
*
|
|
2062
2601
|
* @returns {String} Returns the imageId
|
|
2063
2602
|
*/
|
|
2064
|
-
function
|
|
2603
|
+
function _generateToolState() {
|
|
2604
|
+
_generateToolState = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(imageIds, arrayBuffer, metadataProvider, options) {
|
|
2605
|
+
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;
|
|
2606
|
+
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
2607
|
+
while (1) switch (_context.prev = _context.next) {
|
|
2608
|
+
case 0:
|
|
2609
|
+
_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;
|
|
2610
|
+
dicomData = DicomMessage.readFile(arrayBuffer);
|
|
2611
|
+
dataset = DicomMetaDictionary$1.naturalizeDataset(dicomData.dict);
|
|
2612
|
+
dataset._meta = DicomMetaDictionary$1.namifyDataset(dicomData.meta);
|
|
2613
|
+
multiframe = Normalizer$2.normalizeToDataset([dataset]);
|
|
2614
|
+
imagePlaneModule = metadataProvider.get("imagePlaneModule", imageIds[0]);
|
|
2615
|
+
generalSeriesModule = metadataProvider.get("generalSeriesModule", imageIds[0]);
|
|
2616
|
+
SeriesInstanceUID = generalSeriesModule.seriesInstanceUID;
|
|
2617
|
+
if (!imagePlaneModule) {
|
|
2618
|
+
console.warn("Insufficient metadata, imagePlaneModule missing.");
|
|
2619
|
+
}
|
|
2620
|
+
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:
|
|
2621
|
+
validOrientations = getValidOrientations(ImageOrientationPatient);
|
|
2622
|
+
sliceLength = multiframe.Columns * multiframe.Rows;
|
|
2623
|
+
segMetadata = getSegmentMetadata(multiframe, SeriesInstanceUID);
|
|
2624
|
+
TransferSyntaxUID = multiframe._meta.TransferSyntaxUID.Value[0];
|
|
2625
|
+
if (!(TransferSyntaxUID === "1.2.840.10008.1.2.5")) {
|
|
2626
|
+
_context.next = 23;
|
|
2627
|
+
break;
|
|
2628
|
+
}
|
|
2629
|
+
rleEncodedFrames = Array.isArray(multiframe.PixelData) ? multiframe.PixelData : [multiframe.PixelData];
|
|
2630
|
+
pixelData = decode(rleEncodedFrames, multiframe.Rows, multiframe.Columns);
|
|
2631
|
+
if (!(multiframe.BitsStored === 1)) {
|
|
2632
|
+
_context.next = 20;
|
|
2633
|
+
break;
|
|
2634
|
+
}
|
|
2635
|
+
console.warn("No implementation for rle + bitbacking.");
|
|
2636
|
+
return _context.abrupt("return");
|
|
2637
|
+
case 20:
|
|
2638
|
+
// Todo: need to test this with rle data
|
|
2639
|
+
pixelDataChunks = [pixelData];
|
|
2640
|
+
_context.next = 26;
|
|
2641
|
+
break;
|
|
2642
|
+
case 23:
|
|
2643
|
+
pixelDataChunks = unpackPixelData(multiframe, {
|
|
2644
|
+
maxBytesPerChunk: maxBytesPerChunk
|
|
2645
|
+
});
|
|
2646
|
+
if (pixelDataChunks) {
|
|
2647
|
+
_context.next = 26;
|
|
2648
|
+
break;
|
|
2649
|
+
}
|
|
2650
|
+
throw new Error("Fractional segmentations are not yet supported");
|
|
2651
|
+
case 26:
|
|
2652
|
+
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
|
|
2653
|
+
// we don't have to call metadataProvider.get() for each imageId over
|
|
2654
|
+
// and over again.
|
|
2655
|
+
sopUIDImageIdIndexMap = imageIds.reduce(function (acc, imageId) {
|
|
2656
|
+
var _metadataProvider$get = metadataProvider.get("generalImageModule", imageId),
|
|
2657
|
+
sopInstanceUid = _metadataProvider$get.sopInstanceUid;
|
|
2658
|
+
acc[sopInstanceUid] = imageId;
|
|
2659
|
+
return acc;
|
|
2660
|
+
}, {});
|
|
2661
|
+
overlapping = false;
|
|
2662
|
+
if (!skipOverlapping) {
|
|
2663
|
+
overlapping = checkSEGsOverlapping(pixelDataChunks, multiframe, imageIds, validOrientations, metadataProvider, tolerance, TypedArrayConstructor, sopUIDImageIdIndexMap);
|
|
2664
|
+
}
|
|
2665
|
+
_context.t0 = orientation;
|
|
2666
|
+
_context.next = _context.t0 === "Planar" ? 33 : _context.t0 === "Perpendicular" ? 35 : _context.t0 === "Oblique" ? 36 : 37;
|
|
2667
|
+
break;
|
|
2668
|
+
case 33:
|
|
2669
|
+
if (overlapping) {
|
|
2670
|
+
insertFunction = insertOverlappingPixelDataPlanar;
|
|
2671
|
+
} else {
|
|
2672
|
+
insertFunction = insertPixelDataPlanar;
|
|
2673
|
+
}
|
|
2674
|
+
return _context.abrupt("break", 37);
|
|
2675
|
+
case 35:
|
|
2676
|
+
throw new Error("Segmentations orthogonal to the acquisition plane of the source data are not yet supported.");
|
|
2677
|
+
case 36:
|
|
2678
|
+
throw new Error("Segmentations oblique to the acquisition plane of the source data are not yet supported.");
|
|
2679
|
+
case 37:
|
|
2680
|
+
/* if SEGs are overlapping:
|
|
2681
|
+
1) the labelmapBuffer will contain M volumes which have non-overlapping segments;
|
|
2682
|
+
2) segmentsOnFrame will have M * numberOfFrames values to track in which labelMap are the segments;
|
|
2683
|
+
3) insertFunction will return the number of LabelMaps
|
|
2684
|
+
4) generateToolState return is an array*/
|
|
2685
|
+
segmentsOnFrameArray = [];
|
|
2686
|
+
segmentsOnFrameArray[0] = [];
|
|
2687
|
+
segmentsOnFrame = [];
|
|
2688
|
+
arrayBufferLength = sliceLength * imageIds.length * TypedArrayConstructor.BYTES_PER_ELEMENT;
|
|
2689
|
+
labelmapBufferArray = [];
|
|
2690
|
+
labelmapBufferArray[0] = new ArrayBuffer(arrayBufferLength);
|
|
2691
|
+
|
|
2692
|
+
// Precompute the indices and metadata so that we don't have to call
|
|
2693
|
+
// a function for each imageId in the for loop.
|
|
2694
|
+
imageIdMaps = imageIds.reduce(function (acc, curr, index) {
|
|
2695
|
+
acc.indices[curr] = index;
|
|
2696
|
+
acc.metadata[curr] = metadataProvider.get("instance", curr);
|
|
2697
|
+
return acc;
|
|
2698
|
+
}, {
|
|
2699
|
+
indices: {},
|
|
2700
|
+
metadata: {}
|
|
2701
|
+
}); // This is the centroid calculation for each segment Index, the data structure
|
|
2702
|
+
// is a Map with key = segmentIndex and value = {imageIdIndex: centroid, ...}
|
|
2703
|
+
// later on we will use this data structure to calculate the centroid of the
|
|
2704
|
+
// segment in the labelmapBuffer
|
|
2705
|
+
segmentsPixelIndices = new Map();
|
|
2706
|
+
_context.next = 47;
|
|
2707
|
+
return insertFunction(segmentsOnFrame, segmentsOnFrameArray, labelmapBufferArray, pixelDataChunks, multiframe, imageIds, validOrientations, metadataProvider, tolerance, TypedArrayConstructor, segmentsPixelIndices, sopUIDImageIdIndexMap, imageIdMaps, eventTarget, triggerEvent);
|
|
2708
|
+
case 47:
|
|
2709
|
+
// calculate the centroid of each segment
|
|
2710
|
+
centroidXYZ = new Map();
|
|
2711
|
+
segmentsPixelIndices.forEach(function (imageIdIndexBufferIndex, segmentIndex) {
|
|
2712
|
+
var _calculateCentroid = calculateCentroid(imageIdIndexBufferIndex, multiframe),
|
|
2713
|
+
xAcc = _calculateCentroid.xAcc,
|
|
2714
|
+
yAcc = _calculateCentroid.yAcc,
|
|
2715
|
+
zAcc = _calculateCentroid.zAcc,
|
|
2716
|
+
count = _calculateCentroid.count;
|
|
2717
|
+
centroidXYZ.set(segmentIndex, {
|
|
2718
|
+
x: Math.floor(xAcc / count),
|
|
2719
|
+
y: Math.floor(yAcc / count),
|
|
2720
|
+
z: Math.floor(zAcc / count)
|
|
2721
|
+
});
|
|
2722
|
+
});
|
|
2723
|
+
return _context.abrupt("return", {
|
|
2724
|
+
labelmapBufferArray: labelmapBufferArray,
|
|
2725
|
+
segMetadata: segMetadata,
|
|
2726
|
+
segmentsOnFrame: segmentsOnFrame,
|
|
2727
|
+
segmentsOnFrameArray: segmentsOnFrameArray,
|
|
2728
|
+
centroids: centroidXYZ
|
|
2729
|
+
});
|
|
2730
|
+
case 50:
|
|
2731
|
+
case "end":
|
|
2732
|
+
return _context.stop();
|
|
2733
|
+
}
|
|
2734
|
+
}, _callee);
|
|
2735
|
+
}));
|
|
2736
|
+
return _generateToolState.apply(this, arguments);
|
|
2737
|
+
}
|
|
2738
|
+
function findReferenceSourceImageId(multiframe, frameSegment, imageIds, metadataProvider, tolerance, sopUIDImageIdIndexMap) {
|
|
2065
2739
|
var imageId = undefined;
|
|
2066
2740
|
if (!multiframe) {
|
|
2067
2741
|
return imageId;
|
|
@@ -2101,7 +2775,7 @@ function findReferenceSourceImageId(multiframe, frameSegment, imageIds, metadata
|
|
|
2101
2775
|
}
|
|
2102
2776
|
}
|
|
2103
2777
|
if (frameSourceImageSequence) {
|
|
2104
|
-
imageId =
|
|
2778
|
+
imageId = getImageIdOfSourceImageBySourceImageSequence(frameSourceImageSequence, sopUIDImageIdIndexMap);
|
|
2105
2779
|
}
|
|
2106
2780
|
if (imageId === undefined && ReferencedSeriesSequence) {
|
|
2107
2781
|
var referencedSeriesSequence = Array.isArray(ReferencedSeriesSequence) ? ReferencedSeriesSequence[0] : ReferencedSeriesSequence;
|
|
@@ -2116,7 +2790,7 @@ function findReferenceSourceImageId(multiframe, frameSegment, imageIds, metadata
|
|
|
2116
2790
|
* @returns {boolean} Returns a flag if segmentations overlapping
|
|
2117
2791
|
*/
|
|
2118
2792
|
|
|
2119
|
-
function checkSEGsOverlapping(pixelData, multiframe, imageIds, validOrientations, metadataProvider, tolerance) {
|
|
2793
|
+
function checkSEGsOverlapping(pixelData, multiframe, imageIds, validOrientations, metadataProvider, tolerance, TypedArrayConstructor, sopUIDImageIdIndexMap) {
|
|
2120
2794
|
var SharedFunctionalGroupsSequence = multiframe.SharedFunctionalGroupsSequence,
|
|
2121
2795
|
PerFrameFunctionalGroupsSequence = multiframe.PerFrameFunctionalGroupsSequence,
|
|
2122
2796
|
SegmentSequence = multiframe.SegmentSequence,
|
|
@@ -2143,7 +2817,7 @@ function checkSEGsOverlapping(pixelData, multiframe, imageIds, validOrientations
|
|
|
2143
2817
|
console.warn("Could not retrieve the segment index for frame segment " + frameSegment + ", skipping this frame.");
|
|
2144
2818
|
return "continue";
|
|
2145
2819
|
}
|
|
2146
|
-
var imageId = findReferenceSourceImageId(multiframe, frameSegment, imageIds, metadataProvider, tolerance);
|
|
2820
|
+
var imageId = findReferenceSourceImageId(multiframe, frameSegment, imageIds, metadataProvider, tolerance, sopUIDImageIdIndexMap);
|
|
2147
2821
|
if (!imageId) {
|
|
2148
2822
|
console.warn("Image not present in stack, can't import frame : " + frameSegment + ".");
|
|
2149
2823
|
return "continue";
|
|
@@ -2171,12 +2845,13 @@ function checkSEGsOverlapping(pixelData, multiframe, imageIds, validOrientations
|
|
|
2171
2845
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
2172
2846
|
var _step$value = _slicedToArray(_step.value, 2),
|
|
2173
2847
|
role = _step$value[1];
|
|
2174
|
-
var temp2DArray = new
|
|
2848
|
+
var temp2DArray = new TypedArrayConstructor(sliceLength).fill(0);
|
|
2175
2849
|
for (var i = 0; i < role.length; ++i) {
|
|
2176
2850
|
var _frameSegment = role[i];
|
|
2177
2851
|
var PerFrameFunctionalGroups = PerFrameFunctionalGroupsSequence[_frameSegment];
|
|
2178
2852
|
var ImageOrientationPatientI = sharedImageOrientationPatient || PerFrameFunctionalGroups.PlaneOrientationSequence.ImageOrientationPatient;
|
|
2179
|
-
var
|
|
2853
|
+
var view = readFromUnpackedChunks(pixelData, _frameSegment * sliceLength, sliceLength);
|
|
2854
|
+
var pixelDataI2D = ndarray__WEBPACK_IMPORTED_MODULE_1___default()(view, [Rows, Columns]);
|
|
2180
2855
|
var alignedPixelDataI = alignPixelDataWithSourceData(pixelDataI2D, ImageOrientationPatientI, validOrientations, tolerance);
|
|
2181
2856
|
if (!alignedPixelDataI) {
|
|
2182
2857
|
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 +2875,14 @@ function checkSEGsOverlapping(pixelData, multiframe, imageIds, validOrientations
|
|
|
2200
2875
|
}
|
|
2201
2876
|
return false;
|
|
2202
2877
|
}
|
|
2203
|
-
function insertOverlappingPixelDataPlanar(segmentsOnFrame, segmentsOnFrameArray, labelmapBufferArray, pixelData, multiframe, imageIds, validOrientations, metadataProvider, tolerance) {
|
|
2878
|
+
function insertOverlappingPixelDataPlanar(segmentsOnFrame, segmentsOnFrameArray, labelmapBufferArray, pixelData, multiframe, imageIds, validOrientations, metadataProvider, tolerance, TypedArrayConstructor, segmentsPixelIndices, sopUIDImageIdIndexMap) {
|
|
2204
2879
|
var SharedFunctionalGroupsSequence = multiframe.SharedFunctionalGroupsSequence,
|
|
2205
2880
|
PerFrameFunctionalGroupsSequence = multiframe.PerFrameFunctionalGroupsSequence,
|
|
2206
2881
|
Rows = multiframe.Rows,
|
|
2207
2882
|
Columns = multiframe.Columns;
|
|
2208
2883
|
var sharedImageOrientationPatient = SharedFunctionalGroupsSequence.PlaneOrientationSequence ? SharedFunctionalGroupsSequence.PlaneOrientationSequence.ImageOrientationPatient : undefined;
|
|
2209
2884
|
var sliceLength = Columns * Rows;
|
|
2210
|
-
var arrayBufferLength = sliceLength * imageIds.length *
|
|
2211
|
-
|
|
2885
|
+
var arrayBufferLength = sliceLength * imageIds.length * TypedArrayConstructor.BYTES_PER_ELEMENT;
|
|
2212
2886
|
// indicate the number of labelMaps
|
|
2213
2887
|
var M = 1;
|
|
2214
2888
|
|
|
@@ -2241,12 +2915,17 @@ function insertOverlappingPixelDataPlanar(segmentsOnFrame, segmentsOnFrameArray,
|
|
|
2241
2915
|
return "continue";
|
|
2242
2916
|
}
|
|
2243
2917
|
var ImageOrientationPatientI = sharedImageOrientationPatient || PerFrameFunctionalGroups.PlaneOrientationSequence.ImageOrientationPatient;
|
|
2244
|
-
|
|
2918
|
+
|
|
2919
|
+
// Since we moved to the chunks approach, we need to read the data
|
|
2920
|
+
// and handle scenarios where the portion of data is in one chunk
|
|
2921
|
+
// and the other portion is in another chunk
|
|
2922
|
+
var view = readFromUnpackedChunks(pixelData, _i2 * sliceLength, sliceLength);
|
|
2923
|
+
var pixelDataI2D = ndarray__WEBPACK_IMPORTED_MODULE_1___default()(view, [Rows, Columns]);
|
|
2245
2924
|
var alignedPixelDataI = alignPixelDataWithSourceData(pixelDataI2D, ImageOrientationPatientI, validOrientations, tolerance);
|
|
2246
2925
|
if (!alignedPixelDataI) {
|
|
2247
2926
|
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
2927
|
}
|
|
2249
|
-
var imageId = findReferenceSourceImageId(multiframe, _i2, imageIds, metadataProvider, tolerance);
|
|
2928
|
+
var imageId = findReferenceSourceImageId(multiframe, _i2, imageIds, metadataProvider, tolerance, sopUIDImageIdIndexMap);
|
|
2250
2929
|
if (!imageId) {
|
|
2251
2930
|
console.warn("Image not present in stack, can't import frame : " + _i2 + ".");
|
|
2252
2931
|
i = _i2;
|
|
@@ -2259,9 +2938,8 @@ function insertOverlappingPixelDataPlanar(segmentsOnFrame, segmentsOnFrameArray,
|
|
|
2259
2938
|
var imageIdIndex = imageIds.findIndex(function (element) {
|
|
2260
2939
|
return element === imageId;
|
|
2261
2940
|
});
|
|
2262
|
-
var byteOffset = sliceLength *
|
|
2263
|
-
|
|
2264
|
-
var labelmap2DView = new Uint16Array(tempBuffer, byteOffset, sliceLength);
|
|
2941
|
+
var byteOffset = sliceLength * imageIdIndex * TypedArrayConstructor.BYTES_PER_ELEMENT;
|
|
2942
|
+
var labelmap2DView = new TypedArrayConstructor(tempBuffer, byteOffset, sliceLength);
|
|
2265
2943
|
var data = alignedPixelDataI.data;
|
|
2266
2944
|
var segmentOnFrame = false;
|
|
2267
2945
|
for (var j = 0, len = alignedPixelDataI.data.length; j < len; ++j) {
|
|
@@ -2314,60 +2992,93 @@ var getSegmentIndex = function getSegmentIndex(multiframe, frame) {
|
|
|
2314
2992
|
var PerFrameFunctionalGroups = PerFrameFunctionalGroupsSequence[frame];
|
|
2315
2993
|
return PerFrameFunctionalGroups && PerFrameFunctionalGroups.SegmentIdentificationSequence ? PerFrameFunctionalGroups.SegmentIdentificationSequence.ReferencedSegmentNumber : SharedFunctionalGroupsSequence.SegmentIdentificationSequence ? SharedFunctionalGroupsSequence.SegmentIdentificationSequence.ReferencedSegmentNumber : undefined;
|
|
2316
2994
|
};
|
|
2317
|
-
function insertPixelDataPlanar(segmentsOnFrame, segmentsOnFrameArray, labelmapBufferArray, pixelData, multiframe, imageIds, validOrientations, metadataProvider, tolerance) {
|
|
2995
|
+
function insertPixelDataPlanar(segmentsOnFrame, segmentsOnFrameArray, labelmapBufferArray, pixelData, multiframe, imageIds, validOrientations, metadataProvider, tolerance, TypedArrayConstructor, segmentsPixelIndices, sopUIDImageIdIndexMap, imageIdMaps, eventTarget, triggerEvent) {
|
|
2318
2996
|
var SharedFunctionalGroupsSequence = multiframe.SharedFunctionalGroupsSequence,
|
|
2319
2997
|
PerFrameFunctionalGroupsSequence = multiframe.PerFrameFunctionalGroupsSequence,
|
|
2320
2998
|
Rows = multiframe.Rows,
|
|
2321
2999
|
Columns = multiframe.Columns;
|
|
2322
3000
|
var sharedImageOrientationPatient = SharedFunctionalGroupsSequence.PlaneOrientationSequence ? SharedFunctionalGroupsSequence.PlaneOrientationSequence.ImageOrientationPatient : undefined;
|
|
2323
3001
|
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
|
-
}
|
|
3002
|
+
var i = 0;
|
|
3003
|
+
var groupsLen = PerFrameFunctionalGroupsSequence.length;
|
|
3004
|
+
var chunkSize = Math.ceil(groupsLen / 10); // 10% of total length
|
|
3005
|
+
|
|
3006
|
+
var shouldTriggerEvent = triggerEvent && eventTarget;
|
|
3007
|
+
|
|
3008
|
+
// Below, we chunk the processing of the frames to avoid blocking the main thread
|
|
3009
|
+
// if the segmentation is large. We also use a promise to allow the caller to
|
|
3010
|
+
// wait for the processing to finish.
|
|
3011
|
+
return new Promise(function (resolve) {
|
|
3012
|
+
function processInChunks() {
|
|
3013
|
+
// process one chunk
|
|
3014
|
+
for (var end = Math.min(i + chunkSize, groupsLen); i < end; ++i) {
|
|
3015
|
+
var PerFrameFunctionalGroups = PerFrameFunctionalGroupsSequence[i];
|
|
3016
|
+
var ImageOrientationPatientI = sharedImageOrientationPatient || PerFrameFunctionalGroups.PlaneOrientationSequence.ImageOrientationPatient;
|
|
3017
|
+
var view = readFromUnpackedChunks(pixelData, i * sliceLength, sliceLength);
|
|
3018
|
+
var pixelDataI2D = ndarray__WEBPACK_IMPORTED_MODULE_1___default()(view, [Rows, Columns]);
|
|
3019
|
+
var alignedPixelDataI = alignPixelDataWithSourceData(pixelDataI2D, ImageOrientationPatientI, validOrientations, tolerance);
|
|
3020
|
+
if (!alignedPixelDataI) {
|
|
3021
|
+
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
3022
|
}
|
|
2359
|
-
|
|
2360
|
-
|
|
3023
|
+
var segmentIndex = getSegmentIndex(multiframe, i);
|
|
3024
|
+
if (segmentIndex === undefined) {
|
|
3025
|
+
throw new Error("Could not retrieve the segment index. Aborting segmentation loading.");
|
|
2361
3026
|
}
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
3027
|
+
if (!segmentsPixelIndices.has(segmentIndex)) {
|
|
3028
|
+
segmentsPixelIndices.set(segmentIndex, {});
|
|
3029
|
+
}
|
|
3030
|
+
var imageId = findReferenceSourceImageId(multiframe, i, imageIds, metadataProvider, tolerance, sopUIDImageIdIndexMap);
|
|
3031
|
+
if (!imageId) {
|
|
3032
|
+
console.warn("Image not present in stack, can't import frame : " + i + ".");
|
|
3033
|
+
continue;
|
|
3034
|
+
}
|
|
3035
|
+
var sourceImageMetadata = imageIdMaps.metadata[imageId];
|
|
3036
|
+
if (Rows !== sourceImageMetadata.Rows || Columns !== sourceImageMetadata.Columns) {
|
|
3037
|
+
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. ");
|
|
3038
|
+
}
|
|
3039
|
+
var imageIdIndex = imageIdMaps.indices[imageId];
|
|
3040
|
+
var byteOffset = sliceLength * imageIdIndex * TypedArrayConstructor.BYTES_PER_ELEMENT;
|
|
3041
|
+
var labelmap2DView = new TypedArrayConstructor(labelmapBufferArray[0], byteOffset, sliceLength);
|
|
3042
|
+
var data = alignedPixelDataI.data;
|
|
3043
|
+
var indexCache = [];
|
|
3044
|
+
for (var j = 0, len = alignedPixelDataI.data.length; j < len; ++j) {
|
|
3045
|
+
if (data[j]) {
|
|
3046
|
+
for (var x = j; x < len; ++x) {
|
|
3047
|
+
if (data[x]) {
|
|
3048
|
+
labelmap2DView[x] = segmentIndex;
|
|
3049
|
+
indexCache.push(x);
|
|
3050
|
+
}
|
|
3051
|
+
}
|
|
3052
|
+
if (!segmentsOnFrame[imageIdIndex]) {
|
|
3053
|
+
segmentsOnFrame[imageIdIndex] = [];
|
|
3054
|
+
}
|
|
3055
|
+
segmentsOnFrame[imageIdIndex].push(segmentIndex);
|
|
3056
|
+
break;
|
|
3057
|
+
}
|
|
3058
|
+
}
|
|
3059
|
+
var segmentIndexObject = segmentsPixelIndices.get(segmentIndex);
|
|
3060
|
+
segmentIndexObject[imageIdIndex] = indexCache;
|
|
3061
|
+
segmentsPixelIndices.set(segmentIndex, segmentIndexObject);
|
|
3062
|
+
}
|
|
3063
|
+
|
|
3064
|
+
// trigger an event after each chunk
|
|
3065
|
+
if (shouldTriggerEvent) {
|
|
3066
|
+
var percentComplete = Math.round(i / groupsLen * 100);
|
|
3067
|
+
triggerEvent(eventTarget, Events$1.SEGMENTATION_LOAD_PROGRESS, {
|
|
3068
|
+
percentComplete: percentComplete
|
|
3069
|
+
});
|
|
3070
|
+
}
|
|
3071
|
+
|
|
3072
|
+
// schedule next chunk
|
|
3073
|
+
if (i < groupsLen) {
|
|
3074
|
+
setTimeout(processInChunks, 0);
|
|
3075
|
+
} else {
|
|
3076
|
+
// resolve the Promise when all chunks have been processed
|
|
3077
|
+
resolve();
|
|
3078
|
+
}
|
|
3079
|
+
}
|
|
3080
|
+
processInChunks();
|
|
3081
|
+
});
|
|
2371
3082
|
}
|
|
2372
3083
|
function checkOrientation(multiframe, validOrientations, sourceDataDimensions, tolerance) {
|
|
2373
3084
|
var SharedFunctionalGroupsSequence = multiframe.SharedFunctionalGroupsSequence,
|
|
@@ -2406,12 +3117,13 @@ function checkIfPerpendicular(iop1, iop2, tolerance) {
|
|
|
2406
3117
|
}
|
|
2407
3118
|
|
|
2408
3119
|
/**
|
|
2409
|
-
* unpackPixelData - Unpacks
|
|
3120
|
+
* unpackPixelData - Unpacks bit packed pixelData if the Segmentation is BINARY.
|
|
2410
3121
|
*
|
|
2411
3122
|
* @param {Object} multiframe The multiframe dataset.
|
|
3123
|
+
* @param {Object} options Options for the unpacking.
|
|
2412
3124
|
* @return {Uint8Array} The unpacked pixelData.
|
|
2413
3125
|
*/
|
|
2414
|
-
function unpackPixelData(multiframe) {
|
|
3126
|
+
function unpackPixelData(multiframe, options) {
|
|
2415
3127
|
var segType = multiframe.SegmentationType;
|
|
2416
3128
|
var data;
|
|
2417
3129
|
if (Array.isArray(multiframe.PixelData)) {
|
|
@@ -2423,7 +3135,10 @@ function unpackPixelData(multiframe) {
|
|
|
2423
3135
|
dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .log */ .cM.error("This segmentation pixeldata is undefined.");
|
|
2424
3136
|
}
|
|
2425
3137
|
if (segType === "BINARY") {
|
|
2426
|
-
|
|
3138
|
+
// For extreme big data, we can't unpack the data at once and we need to
|
|
3139
|
+
// chunk it and unpack each chunk separately.
|
|
3140
|
+
// MAX 2GB is the limit right now to allocate a buffer
|
|
3141
|
+
return getUnpackedChunks(data, options.maxBytesPerChunk);
|
|
2427
3142
|
}
|
|
2428
3143
|
var pixelData = new Uint8Array(data);
|
|
2429
3144
|
var max = multiframe.MaximumFractionalValue;
|
|
@@ -2437,20 +3152,35 @@ function unpackPixelData(multiframe) {
|
|
|
2437
3152
|
dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .log */ .cM.warn("This segmentation object is actually binary... processing as such.");
|
|
2438
3153
|
return pixelData;
|
|
2439
3154
|
}
|
|
3155
|
+
function getUnpackedChunks(data, maxBytesPerChunk) {
|
|
3156
|
+
var bitArray = new Uint8Array(data);
|
|
3157
|
+
var chunks = [];
|
|
3158
|
+
var maxBitsPerChunk = maxBytesPerChunk * 8;
|
|
3159
|
+
var numberOfChunks = Math.ceil(bitArray.length * 8 / maxBitsPerChunk);
|
|
3160
|
+
for (var i = 0; i < numberOfChunks; i++) {
|
|
3161
|
+
var startBit = i * maxBitsPerChunk;
|
|
3162
|
+
var endBit = Math.min(startBit + maxBitsPerChunk, bitArray.length * 8);
|
|
3163
|
+
var startByte = Math.floor(startBit / 8);
|
|
3164
|
+
var endByte = Math.ceil(endBit / 8);
|
|
3165
|
+
var chunk = bitArray.slice(startByte, endByte);
|
|
3166
|
+
var unpackedChunk = BitArray$1.unpack(chunk);
|
|
3167
|
+
chunks.push(unpackedChunk);
|
|
3168
|
+
}
|
|
3169
|
+
return chunks;
|
|
3170
|
+
}
|
|
2440
3171
|
|
|
2441
3172
|
/**
|
|
2442
|
-
*
|
|
3173
|
+
* getImageIdOfSourceImageBySourceImageSequence - Returns the Cornerstone imageId of the source image.
|
|
2443
3174
|
*
|
|
2444
3175
|
* @param {Object} SourceImageSequence Sequence describing the source image.
|
|
2445
3176
|
* @param {String[]} imageIds A list of imageIds.
|
|
2446
|
-
* @param {Object}
|
|
2447
|
-
* metadata from imageIds.
|
|
3177
|
+
* @param {Object} sopUIDImageIdIndexMap A map of SOPInstanceUIDs to imageIds.
|
|
2448
3178
|
* @return {String} The corresponding imageId.
|
|
2449
3179
|
*/
|
|
2450
|
-
function
|
|
3180
|
+
function getImageIdOfSourceImageBySourceImageSequence(SourceImageSequence, sopUIDImageIdIndexMap) {
|
|
2451
3181
|
var ReferencedSOPInstanceUID = SourceImageSequence.ReferencedSOPInstanceUID,
|
|
2452
3182
|
ReferencedFrameNumber = SourceImageSequence.ReferencedFrameNumber;
|
|
2453
|
-
return ReferencedFrameNumber ? getImageIdOfReferencedFrame(ReferencedSOPInstanceUID, ReferencedFrameNumber,
|
|
3183
|
+
return ReferencedFrameNumber ? getImageIdOfReferencedFrame(ReferencedSOPInstanceUID, ReferencedFrameNumber, sopUIDImageIdIndexMap) : sopUIDImageIdIndexMap[ReferencedSOPInstanceUID];
|
|
2454
3184
|
}
|
|
2455
3185
|
|
|
2456
3186
|
/**
|
|
@@ -2460,7 +3190,7 @@ function getImageIdOfSourceImagebySourceImageSequence(SourceImageSequence, image
|
|
|
2460
3190
|
* @param {String} FrameOfReferenceUID Frame of reference.
|
|
2461
3191
|
* @param {Object} PerFrameFunctionalGroup Sequence describing segmentation reference attributes per frame.
|
|
2462
3192
|
* @param {String[]} imageIds A list of imageIds.
|
|
2463
|
-
* @param {Object}
|
|
3193
|
+
* @param {Object} sopUIDImageIdIndexMap A map of SOPInstanceUIDs to imageIds.
|
|
2464
3194
|
* @param {Float} tolerance The tolerance parameter
|
|
2465
3195
|
*
|
|
2466
3196
|
* @return {String} The corresponding imageId.
|
|
@@ -2480,26 +3210,6 @@ function getImageIdOfSourceImagebyGeometry(ReferencedSeriesInstanceUID, FrameOfR
|
|
|
2480
3210
|
}
|
|
2481
3211
|
}
|
|
2482
3212
|
|
|
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
3213
|
/**
|
|
2504
3214
|
* getImageIdOfReferencedFrame - Returns the imageId corresponding to the
|
|
2505
3215
|
* specified sopInstanceUid and frameNumber for multi-frame images.
|
|
@@ -2507,23 +3217,16 @@ function getImageIdOfReferencedSingleFramedSOPInstance(sopInstanceUid, imageIds,
|
|
|
2507
3217
|
* @param {String} sopInstanceUid The sopInstanceUid of the desired image.
|
|
2508
3218
|
* @param {Number} frameNumber The frame number.
|
|
2509
3219
|
* @param {String} imageIds The list of imageIds.
|
|
2510
|
-
* @param {Object}
|
|
2511
|
-
* from the cornerstone imageIds.
|
|
3220
|
+
* @param {Object} sopUIDImageIdIndexMap A map of SOPInstanceUIDs to imageIds.
|
|
2512
3221
|
* @return {String} The imageId that corresponds to the sopInstanceUid.
|
|
2513
3222
|
*/
|
|
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;
|
|
3223
|
+
function getImageIdOfReferencedFrame(sopInstanceUid, frameNumber, sopUIDImageIdIndexMap) {
|
|
3224
|
+
var imageId = sopUIDImageIdIndexMap[sopInstanceUid];
|
|
3225
|
+
if (!imageId) {
|
|
3226
|
+
return;
|
|
3227
|
+
}
|
|
3228
|
+
var imageIdFrameNumber = Number(imageId.split("frame=")[1]);
|
|
3229
|
+
return imageIdFrameNumber === frameNumber - 1 ? imageId : undefined;
|
|
2527
3230
|
}
|
|
2528
3231
|
|
|
2529
3232
|
/**
|
|
@@ -2604,397 +3307,228 @@ function alignPixelDataWithSourceData(pixelData2D, iop, orientations, tolerance)
|
|
|
2604
3307
|
* compareArrays - Returns true if array1 and array2 are equal
|
|
2605
3308
|
* within a tolerance.
|
|
2606
3309
|
*
|
|
2607
|
-
* @param {Number[]} array1 - An array.
|
|
2608
|
-
* @param {Number[]} array2 - An array.
|
|
2609
|
-
* @param {Number} tolerance.
|
|
2610
|
-
* @return {Boolean} True if array1 and array2 are equal.
|
|
2611
|
-
*/
|
|
2612
|
-
function compareArrays(array1, array2, tolerance) {
|
|
2613
|
-
if (array1.length != array2.length) {
|
|
2614
|
-
return false;
|
|
2615
|
-
}
|
|
2616
|
-
for (var i = 0; i < array1.length; ++i) {
|
|
2617
|
-
if (!nearlyEqual(array1[i], array2[i], tolerance)) {
|
|
2618
|
-
return false;
|
|
2619
|
-
}
|
|
2620
|
-
}
|
|
2621
|
-
return true;
|
|
2622
|
-
}
|
|
2623
|
-
function getSegmentMetadata(multiframe, seriesInstanceUid) {
|
|
2624
|
-
var segmentSequence = multiframe.SegmentSequence;
|
|
2625
|
-
var data = [];
|
|
2626
|
-
if (Array.isArray(segmentSequence)) {
|
|
2627
|
-
data = [undefined].concat(_toConsumableArray(segmentSequence));
|
|
2628
|
-
} else {
|
|
2629
|
-
// Only one segment, will be stored as an object.
|
|
2630
|
-
data = [undefined, segmentSequence];
|
|
2631
|
-
}
|
|
2632
|
-
return {
|
|
2633
|
-
seriesInstanceUid: seriesInstanceUid,
|
|
2634
|
-
data: data
|
|
2635
|
-
};
|
|
2636
|
-
}
|
|
2637
|
-
|
|
2638
|
-
var Segmentation$1 = {
|
|
2639
|
-
generateSegmentation: generateSegmentation,
|
|
2640
|
-
generateToolState: generateToolState,
|
|
2641
|
-
fillSegmentation: fillSegmentation
|
|
2642
|
-
};
|
|
2643
|
-
|
|
2644
|
-
/**
|
|
2645
|
-
* generateSegmentation - Generates a DICOM Segmentation object given cornerstoneTools data.
|
|
2646
|
-
*
|
|
2647
|
-
* @param {object[]} images An array of the cornerstone image objects.
|
|
2648
|
-
* @param {Object|Object[]} labelmaps3DorBrushData For 4.X: The cornerstone `Labelmap3D` object, or an array of objects.
|
|
2649
|
-
* For 3.X: the BrushData.
|
|
2650
|
-
* @param {number} cornerstoneToolsVersion The cornerstoneTools major version to map against.
|
|
2651
|
-
* @returns {Object}
|
|
2652
|
-
*/
|
|
2653
|
-
function generateSegmentation(images, labelmaps3DorBrushData) {
|
|
2654
|
-
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
|
|
2655
|
-
includeSliceSpacing: true
|
|
2656
|
-
};
|
|
2657
|
-
var cornerstoneToolsVersion = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 4;
|
|
2658
|
-
if (cornerstoneToolsVersion === 4) {
|
|
2659
|
-
return Segmentation$2.generateSegmentation(images, labelmaps3DorBrushData, options);
|
|
2660
|
-
}
|
|
2661
|
-
if (cornerstoneToolsVersion === 3) {
|
|
2662
|
-
return Segmentation$3.generateSegmentation(images, labelmaps3DorBrushData, options);
|
|
2663
|
-
}
|
|
2664
|
-
console.warn("No generateSegmentation adapater for cornerstone version ".concat(cornerstoneToolsVersion, ", exiting."));
|
|
2665
|
-
}
|
|
2666
|
-
|
|
2667
|
-
/**
|
|
2668
|
-
* generateToolState - Given a set of cornrstoneTools imageIds and a Segmentation buffer,
|
|
2669
|
-
* derive cornerstoneTools toolState and brush metadata.
|
|
2670
|
-
*
|
|
2671
|
-
* @param {string[]} imageIds An array of the imageIds.
|
|
2672
|
-
* @param {ArrayBuffer} arrayBuffer The SEG arrayBuffer.
|
|
2673
|
-
* @param {*} metadataProvider
|
|
2674
|
-
* @param {bool} skipOverlapping - skip checks for overlapping segs, default value false.
|
|
2675
|
-
* @param {number} tolerance - default value 1.e-3.
|
|
2676
|
-
* @param {number} cornerstoneToolsVersion - default value 4.
|
|
2677
|
-
*
|
|
2678
|
-
* @returns {Object} The toolState and an object from which the
|
|
2679
|
-
* segment metadata can be derived.
|
|
2680
|
-
*/
|
|
2681
|
-
function generateToolState(imageIds, arrayBuffer, metadataProvider) {
|
|
2682
|
-
var skipOverlapping = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
2683
|
-
var tolerance = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1e-3;
|
|
2684
|
-
var cornerstoneToolsVersion = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 4;
|
|
2685
|
-
if (cornerstoneToolsVersion === 4) {
|
|
2686
|
-
return Segmentation$2.generateToolState(imageIds, arrayBuffer, metadataProvider, skipOverlapping, tolerance);
|
|
2687
|
-
}
|
|
2688
|
-
if (cornerstoneToolsVersion === 3) {
|
|
2689
|
-
return Segmentation$3.generateToolState(imageIds, arrayBuffer, metadataProvider);
|
|
2690
|
-
}
|
|
2691
|
-
console.warn("No generateToolState adapater for cornerstone version ".concat(cornerstoneToolsVersion, ", exiting."));
|
|
2692
|
-
}
|
|
2693
|
-
|
|
2694
|
-
/**
|
|
2695
|
-
* 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$2.fillSegmentation(segmentation, inputLabelmaps3D, options);
|
|
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(":")) {
|
|
3310
|
+
* @param {Number[]} array1 - An array.
|
|
3311
|
+
* @param {Number[]} array2 - An array.
|
|
3312
|
+
* @param {Number} tolerance.
|
|
3313
|
+
* @return {Boolean} True if array1 and array2 are equal.
|
|
3314
|
+
*/
|
|
3315
|
+
function compareArrays(array1, array2, tolerance) {
|
|
3316
|
+
if (array1.length != array2.length) {
|
|
2881
3317
|
return false;
|
|
2882
3318
|
}
|
|
2883
|
-
var
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
if (cornerstone4Tag !== CORNERSTONE_4_TAG) {
|
|
2888
|
-
return false;
|
|
3319
|
+
for (var i = 0; i < array1.length; ++i) {
|
|
3320
|
+
if (!nearlyEqual(array1[i], array2[i], tolerance)) {
|
|
3321
|
+
return false;
|
|
3322
|
+
}
|
|
2889
3323
|
}
|
|
2890
|
-
return
|
|
2891
|
-
}
|
|
2892
|
-
|
|
3324
|
+
return true;
|
|
3325
|
+
}
|
|
3326
|
+
function getSegmentMetadata(multiframe, seriesInstanceUid) {
|
|
3327
|
+
var segmentSequence = multiframe.SegmentSequence;
|
|
3328
|
+
var data = [];
|
|
3329
|
+
if (Array.isArray(segmentSequence)) {
|
|
3330
|
+
data = [undefined].concat(_toConsumableArray(segmentSequence));
|
|
3331
|
+
} else {
|
|
3332
|
+
// Only one segment, will be stored as an object.
|
|
3333
|
+
data = [undefined, segmentSequence];
|
|
3334
|
+
}
|
|
3335
|
+
return {
|
|
3336
|
+
seriesInstanceUid: seriesInstanceUid,
|
|
3337
|
+
data: data
|
|
3338
|
+
};
|
|
3339
|
+
}
|
|
2893
3340
|
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
3341
|
+
/**
|
|
3342
|
+
* Reads a range of bytes from an array of ArrayBuffer chunks and
|
|
3343
|
+
* aggregate them into a new Uint8Array.
|
|
3344
|
+
*
|
|
3345
|
+
* @param {ArrayBuffer[]} chunks - An array of ArrayBuffer chunks.
|
|
3346
|
+
* @param {number} offset - The offset of the first byte to read.
|
|
3347
|
+
* @param {number} length - The number of bytes to read.
|
|
3348
|
+
* @returns {Uint8Array} A new Uint8Array containing the requested bytes.
|
|
3349
|
+
*/
|
|
3350
|
+
function readFromUnpackedChunks(chunks, offset, length) {
|
|
3351
|
+
var mapping = getUnpackedOffsetAndLength(chunks, offset, length);
|
|
3352
|
+
|
|
3353
|
+
// If all the data is in one chunk, we can just slice that chunk
|
|
3354
|
+
if (mapping.start.chunkIndex === mapping.end.chunkIndex) {
|
|
3355
|
+
return new Uint8Array(chunks[mapping.start.chunkIndex].buffer, mapping.start.offset, length);
|
|
3356
|
+
} else {
|
|
3357
|
+
// If the data spans multiple chunks, we need to create a new Uint8Array and copy the data from each chunk
|
|
3358
|
+
var result = new Uint8Array(length);
|
|
3359
|
+
var resultOffset = 0;
|
|
3360
|
+
for (var i = mapping.start.chunkIndex; i <= mapping.end.chunkIndex; i++) {
|
|
3361
|
+
var start = i === mapping.start.chunkIndex ? mapping.start.offset : 0;
|
|
3362
|
+
var end = i === mapping.end.chunkIndex ? mapping.end.offset : chunks[i].length;
|
|
3363
|
+
result.set(new Uint8Array(chunks[i].buffer, start, end - start), resultOffset);
|
|
3364
|
+
resultOffset += end - start;
|
|
3365
|
+
}
|
|
3366
|
+
return result;
|
|
2898
3367
|
}
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
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;
|
|
3368
|
+
}
|
|
3369
|
+
function getUnpackedOffsetAndLength(chunks, offset, length) {
|
|
3370
|
+
var totalBytes = chunks.reduce(function (total, chunk) {
|
|
3371
|
+
return total + chunk.length;
|
|
3372
|
+
}, 0);
|
|
3373
|
+
if (offset < 0 || offset + length > totalBytes) {
|
|
3374
|
+
throw new Error("Offset and length out of bounds");
|
|
3375
|
+
}
|
|
3376
|
+
var startChunkIndex = 0;
|
|
3377
|
+
var startOffsetInChunk = offset;
|
|
3378
|
+
while (startOffsetInChunk >= chunks[startChunkIndex].length) {
|
|
3379
|
+
startOffsetInChunk -= chunks[startChunkIndex].length;
|
|
3380
|
+
startChunkIndex++;
|
|
3381
|
+
}
|
|
3382
|
+
var endChunkIndex = startChunkIndex;
|
|
3383
|
+
var endOffsetInChunk = startOffsetInChunk + length;
|
|
3384
|
+
while (endOffsetInChunk > chunks[endChunkIndex].length) {
|
|
3385
|
+
endOffsetInChunk -= chunks[endChunkIndex].length;
|
|
3386
|
+
endChunkIndex++;
|
|
3387
|
+
}
|
|
3388
|
+
return {
|
|
3389
|
+
start: {
|
|
3390
|
+
chunkIndex: startChunkIndex,
|
|
3391
|
+
offset: startOffsetInChunk
|
|
3392
|
+
},
|
|
3393
|
+
end: {
|
|
3394
|
+
chunkIndex: endChunkIndex,
|
|
3395
|
+
offset: endOffsetInChunk
|
|
2935
3396
|
}
|
|
2936
|
-
}
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
3397
|
+
};
|
|
3398
|
+
}
|
|
3399
|
+
function calculateCentroid(imageIdIndexBufferIndex, multiframe) {
|
|
3400
|
+
var xAcc = 0;
|
|
3401
|
+
var yAcc = 0;
|
|
3402
|
+
var zAcc = 0;
|
|
3403
|
+
var count = 0;
|
|
3404
|
+
for (var _i3 = 0, _Object$entries = Object.entries(imageIdIndexBufferIndex); _i3 < _Object$entries.length; _i3++) {
|
|
3405
|
+
var _Object$entries$_i = _slicedToArray(_Object$entries[_i3], 2),
|
|
3406
|
+
imageIdIndex = _Object$entries$_i[0],
|
|
3407
|
+
bufferIndices = _Object$entries$_i[1];
|
|
3408
|
+
var z = Number(imageIdIndex);
|
|
3409
|
+
if (!bufferIndices || bufferIndices.length === 0) {
|
|
3410
|
+
continue;
|
|
3411
|
+
}
|
|
3412
|
+
var _iterator2 = _createForOfIteratorHelper(bufferIndices),
|
|
3413
|
+
_step2;
|
|
3414
|
+
try {
|
|
3415
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
3416
|
+
var bufferIndex = _step2.value;
|
|
3417
|
+
var y = Math.floor(bufferIndex / multiframe.Rows);
|
|
3418
|
+
var x = bufferIndex % multiframe.Rows;
|
|
3419
|
+
xAcc += x;
|
|
3420
|
+
yAcc += y;
|
|
3421
|
+
zAcc += z;
|
|
3422
|
+
count++;
|
|
3423
|
+
}
|
|
3424
|
+
} catch (err) {
|
|
3425
|
+
_iterator2.e(err);
|
|
3426
|
+
} finally {
|
|
3427
|
+
_iterator2.f();
|
|
2964
3428
|
}
|
|
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;
|
|
2981
3429
|
}
|
|
2982
|
-
return
|
|
3430
|
+
return {
|
|
3431
|
+
xAcc: xAcc,
|
|
3432
|
+
yAcc: yAcc,
|
|
3433
|
+
zAcc: zAcc,
|
|
3434
|
+
count: count
|
|
3435
|
+
};
|
|
3436
|
+
}
|
|
3437
|
+
var Segmentation$4 = {
|
|
3438
|
+
generateSegmentation: generateSegmentation$2,
|
|
3439
|
+
generateToolState: generateToolState$2,
|
|
3440
|
+
fillSegmentation: fillSegmentation$1
|
|
2983
3441
|
};
|
|
2984
|
-
MeasurementReport$1.registerTool(RectangleRoi);
|
|
2985
3442
|
|
|
2986
|
-
var
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
3443
|
+
var Segmentation$3 = {
|
|
3444
|
+
generateSegmentation: generateSegmentation$1,
|
|
3445
|
+
generateToolState: generateToolState$1,
|
|
3446
|
+
fillSegmentation: fillSegmentation
|
|
3447
|
+
};
|
|
3448
|
+
|
|
3449
|
+
/**
|
|
3450
|
+
* generateSegmentation - Generates a DICOM Segmentation object given cornerstoneTools data.
|
|
3451
|
+
*
|
|
3452
|
+
* @param {object[]} images An array of the cornerstone image objects.
|
|
3453
|
+
* @param {Object|Object[]} labelmaps3DorBrushData For 4.X: The cornerstone `Labelmap3D` object, or an array of objects.
|
|
3454
|
+
* For 3.X: the BrushData.
|
|
3455
|
+
* @param {number} cornerstoneToolsVersion The cornerstoneTools major version to map against.
|
|
3456
|
+
* @returns {Object}
|
|
3457
|
+
*/
|
|
3458
|
+
function generateSegmentation$1(images, labelmaps3DorBrushData) {
|
|
3459
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
|
|
3460
|
+
includeSliceSpacing: true
|
|
3461
|
+
};
|
|
3462
|
+
var cornerstoneToolsVersion = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 4;
|
|
3463
|
+
if (cornerstoneToolsVersion === 4) {
|
|
3464
|
+
return Segmentation$4.generateSegmentation(images, labelmaps3DorBrushData, options);
|
|
3465
|
+
}
|
|
3466
|
+
if (cornerstoneToolsVersion === 3) {
|
|
3467
|
+
return Segmentation$5.generateSegmentation(images, labelmaps3DorBrushData, options);
|
|
3468
|
+
}
|
|
3469
|
+
console.warn("No generateSegmentation adapater for cornerstone version ".concat(cornerstoneToolsVersion, ", exiting."));
|
|
3470
|
+
}
|
|
3471
|
+
|
|
3472
|
+
/**
|
|
3473
|
+
* generateToolState - Given a set of cornrstoneTools imageIds and a Segmentation buffer,
|
|
3474
|
+
* derive cornerstoneTools toolState and brush metadata.
|
|
3475
|
+
*
|
|
3476
|
+
* @param {string[]} imageIds An array of the imageIds.
|
|
3477
|
+
* @param {ArrayBuffer} arrayBuffer The SEG arrayBuffer.
|
|
3478
|
+
* @param {*} metadataProvider
|
|
3479
|
+
* @param {bool} skipOverlapping - skip checks for overlapping segs, default value false.
|
|
3480
|
+
* @param {number} tolerance - default value 1.e-3.
|
|
3481
|
+
* @param {number} cornerstoneToolsVersion - default value 4.
|
|
3482
|
+
*
|
|
3483
|
+
* @returns {Object} The toolState and an object from which the
|
|
3484
|
+
* segment metadata can be derived.
|
|
3485
|
+
*/
|
|
3486
|
+
function generateToolState$1(imageIds, arrayBuffer, metadataProvider) {
|
|
3487
|
+
var skipOverlapping = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
3488
|
+
var tolerance = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1e-3;
|
|
3489
|
+
var cornerstoneToolsVersion = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 4;
|
|
3490
|
+
if (cornerstoneToolsVersion === 4) {
|
|
3491
|
+
return Segmentation$4.generateToolState(imageIds, arrayBuffer, metadataProvider, skipOverlapping, tolerance);
|
|
3492
|
+
}
|
|
3493
|
+
if (cornerstoneToolsVersion === 3) {
|
|
3494
|
+
return Segmentation$5.generateToolState(imageIds, arrayBuffer, metadataProvider);
|
|
3495
|
+
}
|
|
3496
|
+
console.warn("No generateToolState adapater for cornerstone version ".concat(cornerstoneToolsVersion, ", exiting."));
|
|
3497
|
+
}
|
|
3498
|
+
|
|
3499
|
+
/**
|
|
3500
|
+
* fillSegmentation - Fills a derived segmentation dataset with cornerstoneTools `LabelMap3D` data.
|
|
3501
|
+
*
|
|
3502
|
+
* @param {object[]} segmentation An empty segmentation derived dataset.
|
|
3503
|
+
* @param {Object|Object[]} inputLabelmaps3D The cornerstone `Labelmap3D` object, or an array of objects.
|
|
3504
|
+
* @param {Object} userOptions Options object to override default options.
|
|
3505
|
+
* @returns {Blob} description
|
|
3506
|
+
*/
|
|
3507
|
+
function fillSegmentation(segmentation, inputLabelmaps3D) {
|
|
3508
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
|
|
3509
|
+
includeSliceSpacing: true
|
|
3510
|
+
};
|
|
3511
|
+
var cornerstoneToolsVersion = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 4;
|
|
3512
|
+
if (cornerstoneToolsVersion === 4) {
|
|
3513
|
+
return Segmentation$4.fillSegmentation(segmentation, inputLabelmaps3D, options);
|
|
3514
|
+
}
|
|
3515
|
+
console.warn("No generateSegmentation adapater for cornerstone version ".concat(cornerstoneToolsVersion, ", exiting."));
|
|
3516
|
+
}
|
|
3517
|
+
|
|
3518
|
+
var CornerstoneSR = {
|
|
3519
|
+
Length: Length$1,
|
|
3520
|
+
FreehandRoi: FreehandRoi,
|
|
3521
|
+
Bidirectional: Bidirectional$1,
|
|
3522
|
+
EllipticalRoi: EllipticalRoi,
|
|
3523
|
+
CircleRoi: CircleRoi,
|
|
3524
|
+
ArrowAnnotate: ArrowAnnotate$1,
|
|
3525
|
+
MeasurementReport: MeasurementReport$1,
|
|
3526
|
+
CobbAngle: CobbAngle$1,
|
|
3527
|
+
Angle: Angle$1,
|
|
3528
|
+
RectangleRoi: RectangleRoi
|
|
3529
|
+
};
|
|
3530
|
+
var CornerstoneSEG = {
|
|
3531
|
+
Segmentation: Segmentation$3
|
|
2998
3532
|
};
|
|
2999
3533
|
|
|
3000
3534
|
/******************************************************************************
|
|
@@ -3049,7 +3583,7 @@ var CodingScheme = {
|
|
|
3049
3583
|
|
|
3050
3584
|
var TID1500 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.TID1500, addAccessors = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .utilities */ .hC.addAccessors;
|
|
3051
3585
|
var StructuredReport = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .derivations */ .U7.StructuredReport;
|
|
3052
|
-
var Normalizer = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .normalizers */ .oq.Normalizer;
|
|
3586
|
+
var Normalizer$1 = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .normalizers */ .oq.Normalizer;
|
|
3053
3587
|
var TID1500MeasurementReport = TID1500.TID1500MeasurementReport, TID1501MeasurementGroup = TID1500.TID1501MeasurementGroup;
|
|
3054
3588
|
var DicomMetaDictionary = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.DicomMetaDictionary;
|
|
3055
3589
|
var FINDING = { CodingSchemeDesignator: "DCM", CodeValue: "121071" };
|
|
@@ -3218,7 +3752,7 @@ var MeasurementReport = /** @class */ (function () {
|
|
|
3218
3752
|
if ((instance &&
|
|
3219
3753
|
instance.NumberOfFrames &&
|
|
3220
3754
|
instance.NumberOfFrames > 1) ||
|
|
3221
|
-
Normalizer.isMultiframeSOPClassUID(sopClassUID)) {
|
|
3755
|
+
Normalizer$1.isMultiframeSOPClassUID(sopClassUID)) {
|
|
3222
3756
|
ReferencedSOPSequence.ReferencedFrameNumber = frameNumber;
|
|
3223
3757
|
}
|
|
3224
3758
|
// Loop through each tool type for the image
|
|
@@ -3853,26 +4387,26 @@ var EllipticalROI = /** @class */ (function () {
|
|
|
3853
4387
|
]);
|
|
3854
4388
|
pointsWorld.push(worldPos);
|
|
3855
4389
|
}
|
|
3856
|
-
var majorAxisStart =
|
|
3857
|
-
var majorAxisEnd =
|
|
3858
|
-
var minorAxisStart =
|
|
3859
|
-
var minorAxisEnd =
|
|
3860
|
-
var majorAxisVec =
|
|
3861
|
-
|
|
4390
|
+
var majorAxisStart = gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.fromValues */ .R3.fromValues.apply(gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3 */ .R3, pointsWorld[0]);
|
|
4391
|
+
var majorAxisEnd = gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.fromValues */ .R3.fromValues.apply(gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3 */ .R3, pointsWorld[1]);
|
|
4392
|
+
var minorAxisStart = gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.fromValues */ .R3.fromValues.apply(gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3 */ .R3, pointsWorld[2]);
|
|
4393
|
+
var minorAxisEnd = gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.fromValues */ .R3.fromValues.apply(gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3 */ .R3, pointsWorld[3]);
|
|
4394
|
+
var majorAxisVec = gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.create */ .R3.create();
|
|
4395
|
+
gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.sub */ .R3.sub(majorAxisVec, majorAxisEnd, majorAxisStart);
|
|
3862
4396
|
// normalize majorAxisVec to avoid scaling issues
|
|
3863
|
-
|
|
3864
|
-
var minorAxisVec =
|
|
3865
|
-
|
|
3866
|
-
|
|
4397
|
+
gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.normalize */ .R3.normalize(majorAxisVec, majorAxisVec);
|
|
4398
|
+
var minorAxisVec = gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.create */ .R3.create();
|
|
4399
|
+
gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.sub */ .R3.sub(minorAxisVec, minorAxisEnd, minorAxisStart);
|
|
4400
|
+
gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.normalize */ .R3.normalize(minorAxisVec, minorAxisVec);
|
|
3867
4401
|
var imagePlaneModule = metadata.get("imagePlaneModule", referencedImageId);
|
|
3868
4402
|
if (!imagePlaneModule) {
|
|
3869
4403
|
throw new Error("imageId does not have imagePlaneModule metadata");
|
|
3870
4404
|
}
|
|
3871
4405
|
var columnCosines = imagePlaneModule.columnCosines;
|
|
3872
4406
|
// find which axis is parallel to the columnCosines
|
|
3873
|
-
var columnCosinesVec =
|
|
3874
|
-
var projectedMajorAxisOnColVec =
|
|
3875
|
-
var projectedMinorAxisOnColVec =
|
|
4407
|
+
var columnCosinesVec = gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.fromValues */ .R3.fromValues(columnCosines[0], columnCosines[1], columnCosines[2]);
|
|
4408
|
+
var projectedMajorAxisOnColVec = gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.dot */ .R3.dot(columnCosinesVec, majorAxisVec);
|
|
4409
|
+
var projectedMinorAxisOnColVec = gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.dot */ .R3.dot(columnCosinesVec, minorAxisVec);
|
|
3876
4410
|
var absoluteOfMajorDotProduct = Math.abs(projectedMajorAxisOnColVec);
|
|
3877
4411
|
var absoluteOfMinorDotProduct = Math.abs(projectedMinorAxisOnColVec);
|
|
3878
4412
|
var ellipsePoints = [];
|
|
@@ -4177,7 +4711,7 @@ var PlanarFreehandROI = /** @class */ (function () {
|
|
|
4177
4711
|
]);
|
|
4178
4712
|
worldCoords.push(point);
|
|
4179
4713
|
}
|
|
4180
|
-
var distanceBetweenFirstAndLastPoint =
|
|
4714
|
+
var distanceBetweenFirstAndLastPoint = gl_matrix__WEBPACK_IMPORTED_MODULE_4__/* .vec3.distance */ .R3.distance(worldCoords[worldCoords.length - 1], worldCoords[0]);
|
|
4181
4715
|
var isOpenContour = true;
|
|
4182
4716
|
// If the contour is closed, this should have been encoded as exactly the same point, so check for a very small difference.
|
|
4183
4717
|
if (distanceBetweenFirstAndLastPoint < closedContourThreshold) {
|
|
@@ -4329,7 +4863,115 @@ Probe.isValidCornerstoneTrackingIdentifier = function (TrackingIdentifier) {
|
|
|
4329
4863
|
};
|
|
4330
4864
|
MeasurementReport.registerTool(Probe);
|
|
4331
4865
|
|
|
4332
|
-
var
|
|
4866
|
+
var Normalizer = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .normalizers */ .oq.Normalizer;
|
|
4867
|
+
var SegmentationDerivation = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .derivations */ .U7.Segmentation;
|
|
4868
|
+
/**
|
|
4869
|
+
* generateSegmentation - Generates a DICOM Segmentation object given cornerstoneTools data.
|
|
4870
|
+
*
|
|
4871
|
+
* @param images - An array of the cornerstone image objects, which includes imageId and metadata
|
|
4872
|
+
* @param labelmaps - An array of the 3D Volumes that contain the segmentation data.
|
|
4873
|
+
*/
|
|
4874
|
+
function generateSegmentation(images, labelmaps, metadata, options) {
|
|
4875
|
+
var segmentation = _createMultiframeSegmentationFromReferencedImages(images, metadata, options);
|
|
4876
|
+
return fillSegmentation$1(segmentation, labelmaps, options);
|
|
4877
|
+
}
|
|
4878
|
+
/**
|
|
4879
|
+
* _createMultiframeSegmentationFromReferencedImages - description
|
|
4880
|
+
*
|
|
4881
|
+
* @param images - An array of the cornerstone image objects related to the reference
|
|
4882
|
+
* series that the segmentation is derived from. You can use methods such as
|
|
4883
|
+
* volume.getCornerstoneImages() to get this array.
|
|
4884
|
+
*
|
|
4885
|
+
* @param options - the options object for the SegmentationDerivation.
|
|
4886
|
+
* @returns The Seg derived dataSet.
|
|
4887
|
+
*/
|
|
4888
|
+
function _createMultiframeSegmentationFromReferencedImages(images, metadata, options) {
|
|
4889
|
+
var datasets = images.map(function (image) {
|
|
4890
|
+
// add the sopClassUID to the dataset
|
|
4891
|
+
var instance = metadata.get("instance", image.imageId);
|
|
4892
|
+
return __assign(__assign(__assign({}, image), instance), {
|
|
4893
|
+
// Todo: move to dcmjs tag style
|
|
4894
|
+
SOPClassUID: instance.SopClassUID, SOPInstanceUID: instance.SopInstanceUID, PixelData: image.getPixelData(), _vrMap: {
|
|
4895
|
+
PixelData: "OW"
|
|
4896
|
+
}, _meta: {} });
|
|
4897
|
+
});
|
|
4898
|
+
var multiframe = Normalizer.normalizeToDataset(datasets);
|
|
4899
|
+
return new SegmentationDerivation([multiframe], options);
|
|
4900
|
+
}
|
|
4901
|
+
|
|
4902
|
+
/**
|
|
4903
|
+
* Generates 2D label maps from a 3D label map.
|
|
4904
|
+
* @param labelmap3D - The 3D label map object to generate 2D label maps from. It is derived
|
|
4905
|
+
* from the volume labelmap.
|
|
4906
|
+
* @returns The label map object containing the 2D label maps and segments on label maps.
|
|
4907
|
+
*/
|
|
4908
|
+
function generateLabelMaps2DFrom3D(labelmap3D) {
|
|
4909
|
+
// 1. we need to generate labelmaps2D from labelmaps3D, a labelmap2D is for each
|
|
4910
|
+
// slice
|
|
4911
|
+
var scalarData = labelmap3D.scalarData, dimensions = labelmap3D.dimensions;
|
|
4912
|
+
// scalarData is a flat array of all the pixels in the volume.
|
|
4913
|
+
var labelmaps2D = [];
|
|
4914
|
+
var segmentsOnLabelmap3D = new Set();
|
|
4915
|
+
// X-Y are the row and column dimensions, Z is the number of slices.
|
|
4916
|
+
for (var z = 0; z < dimensions[2]; z++) {
|
|
4917
|
+
var pixelData = scalarData.slice(z * dimensions[0] * dimensions[1], (z + 1) * dimensions[0] * dimensions[1]);
|
|
4918
|
+
var segmentsOnLabelmap = [];
|
|
4919
|
+
for (var i = 0; i < pixelData.length; i++) {
|
|
4920
|
+
var segment = pixelData[i];
|
|
4921
|
+
if (!segmentsOnLabelmap.includes(segment) && segment !== 0) {
|
|
4922
|
+
segmentsOnLabelmap.push(segment);
|
|
4923
|
+
}
|
|
4924
|
+
}
|
|
4925
|
+
var labelmap2D = {
|
|
4926
|
+
segmentsOnLabelmap: segmentsOnLabelmap,
|
|
4927
|
+
pixelData: pixelData,
|
|
4928
|
+
rows: dimensions[1],
|
|
4929
|
+
columns: dimensions[0]
|
|
4930
|
+
};
|
|
4931
|
+
if (segmentsOnLabelmap.length === 0) {
|
|
4932
|
+
continue;
|
|
4933
|
+
}
|
|
4934
|
+
segmentsOnLabelmap.forEach(function (segmentIndex) {
|
|
4935
|
+
segmentsOnLabelmap3D.add(segmentIndex);
|
|
4936
|
+
});
|
|
4937
|
+
labelmaps2D[dimensions[2] - 1 - z] = labelmap2D;
|
|
4938
|
+
}
|
|
4939
|
+
// remove segment 0 from segmentsOnLabelmap3D
|
|
4940
|
+
labelmap3D.segmentsOnLabelmap = Array.from(segmentsOnLabelmap3D);
|
|
4941
|
+
labelmap3D.labelmaps2D = labelmaps2D;
|
|
4942
|
+
return labelmap3D;
|
|
4943
|
+
}
|
|
4944
|
+
|
|
4945
|
+
var Segmentation$2 = CornerstoneSEG.Segmentation;
|
|
4946
|
+
var generateToolStateCornerstoneLegacy = Segmentation$2.generateToolState;
|
|
4947
|
+
/**
|
|
4948
|
+
* generateToolState - Given a set of cornerstoneTools imageIds and a Segmentation buffer,
|
|
4949
|
+
* derive cornerstoneTools toolState and brush metadata.
|
|
4950
|
+
*
|
|
4951
|
+
* @param imageIds - An array of the imageIds.
|
|
4952
|
+
* @param arrayBuffer - The SEG arrayBuffer.
|
|
4953
|
+
* @param skipOverlapping - skip checks for overlapping segs, default value false.
|
|
4954
|
+
* @param tolerance - default value 1.e-3.
|
|
4955
|
+
*
|
|
4956
|
+
* @returns a list of array buffer for each labelMap
|
|
4957
|
+
* an object from which the segment metadata can be derived
|
|
4958
|
+
* list containing the track of segments per frame
|
|
4959
|
+
* list containing the track of segments per frame for each labelMap (available only for the overlapping case).
|
|
4960
|
+
*/
|
|
4961
|
+
function generateToolState(imageIds, arrayBuffer, metadataProvider, skipOverlapping, tolerance) {
|
|
4962
|
+
if (skipOverlapping === void 0) { skipOverlapping = false; }
|
|
4963
|
+
if (tolerance === void 0) { tolerance = 1e-3; }
|
|
4964
|
+
return generateToolStateCornerstoneLegacy(imageIds, arrayBuffer, metadataProvider, skipOverlapping, tolerance);
|
|
4965
|
+
}
|
|
4966
|
+
|
|
4967
|
+
var Segmentation$1 = /*#__PURE__*/Object.freeze({
|
|
4968
|
+
__proto__: null,
|
|
4969
|
+
generateLabelMaps2DFrom3D: generateLabelMaps2DFrom3D,
|
|
4970
|
+
generateSegmentation: generateSegmentation,
|
|
4971
|
+
generateToolState: generateToolState
|
|
4972
|
+
});
|
|
4973
|
+
|
|
4974
|
+
var Cornerstone3DSR = {
|
|
4333
4975
|
Bidirectional: Bidirectional,
|
|
4334
4976
|
CobbAngle: CobbAngle,
|
|
4335
4977
|
Angle: Angle,
|
|
@@ -4344,6 +4986,9 @@ var Cornerstone3D = {
|
|
|
4344
4986
|
CodeScheme: CodingScheme,
|
|
4345
4987
|
CORNERSTONE_3D_TAG: CORNERSTONE_3D_TAG
|
|
4346
4988
|
};
|
|
4989
|
+
var Cornerstone3DSEG = {
|
|
4990
|
+
Segmentation: Segmentation$1
|
|
4991
|
+
};
|
|
4347
4992
|
|
|
4348
4993
|
var Colors = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.Colors,
|
|
4349
4994
|
BitArray = dcmjs__WEBPACK_IMPORTED_MODULE_0__/* .data */ .aT.BitArray;
|
|
@@ -4528,23 +5173,26 @@ var Segmentation = /*#__PURE__*/function () {
|
|
|
4528
5173
|
return Segmentation;
|
|
4529
5174
|
}();
|
|
4530
5175
|
|
|
4531
|
-
var
|
|
4532
|
-
|
|
5176
|
+
var VTKjsSEG = {
|
|
5177
|
+
Segmentation: Segmentation
|
|
4533
5178
|
};
|
|
4534
5179
|
|
|
4535
|
-
var
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
5180
|
+
var adaptersSR = {
|
|
5181
|
+
Cornerstone: CornerstoneSR,
|
|
5182
|
+
Cornerstone3D: Cornerstone3DSR
|
|
5183
|
+
};
|
|
5184
|
+
var adaptersSEG = {
|
|
5185
|
+
Cornerstone: CornerstoneSEG,
|
|
5186
|
+
Cornerstone3D: Cornerstone3DSEG,
|
|
5187
|
+
VTKjs: VTKjsSEG
|
|
4539
5188
|
};
|
|
4540
5189
|
|
|
4541
5190
|
|
|
4542
|
-
//# sourceMappingURL=adapters.es.js.map
|
|
4543
5191
|
|
|
4544
5192
|
|
|
4545
5193
|
/***/ }),
|
|
4546
5194
|
|
|
4547
|
-
/***/
|
|
5195
|
+
/***/ 27318:
|
|
4548
5196
|
/***/ ((module) => {
|
|
4549
5197
|
|
|
4550
5198
|
"use strict";
|
|
@@ -4562,7 +5210,7 @@ module.exports = iota
|
|
|
4562
5210
|
|
|
4563
5211
|
/***/ }),
|
|
4564
5212
|
|
|
4565
|
-
/***/
|
|
5213
|
+
/***/ 8516:
|
|
4566
5214
|
/***/ ((module) => {
|
|
4567
5215
|
|
|
4568
5216
|
/*!
|
|
@@ -4580,11 +5228,11 @@ module.exports = function isBuffer (obj) {
|
|
|
4580
5228
|
|
|
4581
5229
|
/***/ }),
|
|
4582
5230
|
|
|
4583
|
-
/***/
|
|
5231
|
+
/***/ 87513:
|
|
4584
5232
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
4585
5233
|
|
|
4586
|
-
var iota = __webpack_require__(
|
|
4587
|
-
var isBuffer = __webpack_require__(
|
|
5234
|
+
var iota = __webpack_require__(27318)
|
|
5235
|
+
var isBuffer = __webpack_require__(8516)
|
|
4588
5236
|
|
|
4589
5237
|
var hasTypedArrays = ((typeof Float64Array) !== "undefined")
|
|
4590
5238
|
|