@aics/vole-app 3.4.2 → 3.4.4
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/es/aics-image-viewer/components/useVolume.js +18 -10
- package/es/aics-image-viewer/shared/utils/controlPointsToLut.js +10 -26
- package/es/aics-image-viewer/shared/utils/sceneStore.js +4 -2
- package/es/aics-image-viewer/state/deserialize.js +95 -0
- package/es/aics-image-viewer/state/test/deserialize.test.js +52 -1
- package/package.json +4 -3
- package/type-declarations/aics-image-viewer/shared/utils/controlPointsToLut.d.ts +2 -2
- package/type-declarations/aics-image-viewer/state/deserialize.d.ts +21 -1
|
@@ -184,11 +184,21 @@ var useVolume = function useVolume(scenePaths, options) {
|
|
|
184
184
|
throw e;
|
|
185
185
|
}, [onErrorRef]);
|
|
186
186
|
|
|
187
|
-
// channel indexes
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
187
|
+
// channelGroupedByType groups channel indexes by their category.
|
|
188
|
+
// It depends on `viewerChannelSettings` and the channel names in the current image.
|
|
189
|
+
// TODO this can be derived much more easily once `Volume` has events
|
|
190
|
+
var channelNamesKey = channelSettings.map(function (_ref3) {
|
|
191
|
+
var name = _ref3.name;
|
|
192
|
+
return name;
|
|
193
|
+
}).join("\0");
|
|
194
|
+
var channelNames = useMemo(function () {
|
|
195
|
+
return channelNamesKey.split("\0");
|
|
196
|
+
}, [channelNamesKey]);
|
|
197
|
+
var useDefaultViewerChannelSettings = useViewerState(select("useDefaultViewerChannelSettings"));
|
|
198
|
+
var channelGroupedByType = useMemo(function () {
|
|
199
|
+
var viewerChannelSettings = useDefaultViewerChannelSettings ? getDefaultViewerChannelSettings() : options === null || options === void 0 ? void 0 : options.viewerChannelSettings;
|
|
200
|
+
return makeChannelIndexGrouping(channelNames, viewerChannelSettings);
|
|
201
|
+
}, [channelNames, options === null || options === void 0 ? void 0 : options.viewerChannelSettings, useDefaultViewerChannelSettings]);
|
|
192
202
|
var onChannelDataLoaded = useCallback(function (aimg, channelIndex) {
|
|
193
203
|
// let the hook caller know that this channel has loaded
|
|
194
204
|
var isInitialLoad = channelVersionsRef.current[channelIndex] === CHANNEL_INITIAL_LOAD;
|
|
@@ -208,8 +218,6 @@ var useVolume = function useVolume(scenePaths, options) {
|
|
|
208
218
|
var _useViewerState$getSt = useViewerState.getState(),
|
|
209
219
|
useDefaultViewerChannelSettings = _useViewerState$getSt.useDefaultViewerChannelSettings;
|
|
210
220
|
var viewerChannelSettings = useDefaultViewerChannelSettings ? getDefaultViewerChannelSettings() : options === null || options === void 0 ? void 0 : options.viewerChannelSettings;
|
|
211
|
-
var grouping = makeChannelIndexGrouping(channelNames, viewerChannelSettings);
|
|
212
|
-
setChannelGroupedByType(grouping);
|
|
213
221
|
return initChannelSettings(channelNames, viewerChannelSettings);
|
|
214
222
|
}, [initChannelSettings, options === null || options === void 0 ? void 0 : options.viewerChannelSettings]);
|
|
215
223
|
|
|
@@ -219,7 +227,7 @@ var useVolume = function useVolume(scenePaths, options) {
|
|
|
219
227
|
setLoadThrewError(false);
|
|
220
228
|
inInitialLoadRef.current = true;
|
|
221
229
|
var openImage = /*#__PURE__*/function () {
|
|
222
|
-
var
|
|
230
|
+
var _ref4 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
|
|
223
231
|
var scene, time, loadSpec, aimg, channelNames, newChannelSettings, requiredLoadSpec, requiredChannelsToLoad, _useViewerState$getSt2, useDefaultViewerChannelSettings, viewerChannelSettings, maskChannelName, maskChannelIndex, viewMode, slice;
|
|
224
232
|
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
225
233
|
while (1) switch (_context.prev = _context.next) {
|
|
@@ -292,11 +300,11 @@ var useVolume = function useVolume(scenePaths, options) {
|
|
|
292
300
|
}, _callee);
|
|
293
301
|
}));
|
|
294
302
|
return function openImage() {
|
|
295
|
-
return
|
|
303
|
+
return _ref4.apply(this, arguments);
|
|
296
304
|
};
|
|
297
305
|
}();
|
|
298
306
|
openImage();
|
|
299
|
-
}, [sceneLoader, onError, onCreateImageRef, onChangeSceneRef, onChannelLoadedRef, channelVersionsRef, setChannelVersions, playControls, setIsLoading, onChannelDataLoaded, changeViewerSetting,
|
|
307
|
+
}, [sceneLoader, onError, onCreateImageRef, onChangeSceneRef, onChannelLoadedRef, channelVersionsRef, setChannelVersions, playControls, setIsLoading, onChannelDataLoaded, changeViewerSetting, setChannelStateForNewImage, options === null || options === void 0 ? void 0 : options.viewerChannelSettings]);
|
|
300
308
|
// of the above dependencies, we expect only `sceneLoader` to change.
|
|
301
309
|
|
|
302
310
|
var setTime = useCallback(function (view3d, time) {
|
|
@@ -86,26 +86,15 @@ function parseLutValue(value, histogram) {
|
|
|
86
86
|
* "autoij:0" // use Auto-IJ to calculate min and max.
|
|
87
87
|
* ```
|
|
88
88
|
*/
|
|
89
|
-
export function
|
|
90
|
-
|
|
91
|
-
// TODO: Consider minimizing the types/classes this function is interacting
|
|
92
|
-
// with, since it is only using `initSettings.lut` and the returned Lut is a
|
|
93
|
-
// wrapper around the control point array, e.g.
|
|
94
|
-
// `parseControlPointsFromLutParam(histogram: Histogram, lutParam: [string,
|
|
95
|
-
// string] | undefined): ControlPoint[] | undefined`
|
|
96
|
-
|
|
97
|
-
// There are two possible locations for the LUT settings, due to legacy
|
|
98
|
-
// reasons. `initSettings.lut` is deprecated in favor of
|
|
99
|
-
// `initSettings.intensity.lut`.
|
|
100
|
-
var settingsLut = (_initSettings$intensi = (_initSettings$intensi2 = initSettings.intensity) === null || _initSettings$intensi2 === void 0 ? void 0 : _initSettings$intensi2.lut) !== null && _initSettings$intensi !== void 0 ? _initSettings$intensi : initSettings.lut;
|
|
101
|
-
if (settingsLut === undefined || settingsLut.length !== 2) {
|
|
89
|
+
export function parseLutSetting(histogram, lutSetting) {
|
|
90
|
+
if (lutSetting === undefined || lutSetting.length !== 2) {
|
|
102
91
|
return undefined;
|
|
103
92
|
}
|
|
104
93
|
var lutValues;
|
|
105
|
-
if (
|
|
94
|
+
if (lutSetting[0] === "autoij" || lutSetting[1] === "autoij") {
|
|
106
95
|
lutValues = histogram.findAutoIJBins();
|
|
107
96
|
} else {
|
|
108
|
-
lutValues = [parseLutValue(
|
|
97
|
+
lutValues = [parseLutValue(lutSetting[0], histogram), parseLutValue(lutSetting[1], histogram)];
|
|
109
98
|
}
|
|
110
99
|
if (!Number.isFinite(lutValues[0]) || !Number.isFinite(lutValues[1])) {
|
|
111
100
|
return undefined;
|
|
@@ -156,8 +145,12 @@ export function initializeLut(aimg, channelIndex, channelSettings) {
|
|
|
156
145
|
// Attempt to load a LUT from the settings, which will be used as a fallback
|
|
157
146
|
// to initialize the control points and ramp.
|
|
158
147
|
if (initSettings) {
|
|
159
|
-
var
|
|
160
|
-
|
|
148
|
+
var _initSettings$intensi, _initSettings$intensi2, _parseLutSetting;
|
|
149
|
+
// There are two possible locations for the LUT settings, due to legacy
|
|
150
|
+
// reasons. `initSettings.lut` is deprecated in favor of
|
|
151
|
+
// `initSettings.intensity.lut`.
|
|
152
|
+
var lutSetting = (_initSettings$intensi = (_initSettings$intensi2 = initSettings.intensity) === null || _initSettings$intensi2 === void 0 ? void 0 : _initSettings$intensi2.lut) !== null && _initSettings$intensi !== void 0 ? _initSettings$intensi : initSettings.lut;
|
|
153
|
+
lut = (_parseLutSetting = parseLutSetting(histogram, lutSetting)) !== null && _parseLutSetting !== void 0 ? _parseLutSetting : defaultLut;
|
|
161
154
|
}
|
|
162
155
|
|
|
163
156
|
// Use raw intensity values for control points or ramp if provided in the
|
|
@@ -189,15 +182,6 @@ export function initializeLut(aimg, channelIndex, channelSettings) {
|
|
|
189
182
|
});
|
|
190
183
|
});
|
|
191
184
|
}
|
|
192
|
-
|
|
193
|
-
// Apply whatever lut is currently visible
|
|
194
|
-
var visibleLut;
|
|
195
|
-
if (initSettings !== null && initSettings !== void 0 && initSettings.controlPointsEnabled) {
|
|
196
|
-
visibleLut = new Lut().createFromControlPoints(controlPoints);
|
|
197
|
-
} else {
|
|
198
|
-
visibleLut = new Lut().createFromControlPoints(ramp);
|
|
199
|
-
}
|
|
200
|
-
aimg.setLut(channelIndex, visibleLut);
|
|
201
185
|
return {
|
|
202
186
|
ramp: ramp,
|
|
203
187
|
controlPoints: controlPoints
|
|
@@ -102,10 +102,12 @@ var SceneStore = /*#__PURE__*/function () {
|
|
|
102
102
|
return channelIndex < imageInfo.channelNames.length;
|
|
103
103
|
}),
|
|
104
104
|
time: Math.min(spec.time, maxTime)
|
|
105
|
-
});
|
|
105
|
+
}); // TODO it's not great that this is the caller's responsibility... fix this more robustly in vole-core
|
|
106
|
+
image.loadSpec = _objectSpread(_objectSpread({}, image.loadSpec), adjustedSpec);
|
|
107
|
+
image.loadSpecRequired = _objectSpread(_objectSpread({}, image.loadSpecRequired), adjustedSpec);
|
|
106
108
|
options === null || options === void 0 || (_options$onCreateScen = options.onCreateScene) === null || _options$onCreateScen === void 0 || _options$onCreateScen.call(options, image, scene, adjustedSpec);
|
|
107
109
|
loader.loadVolumeData(image, adjustedSpec, options === null || options === void 0 ? void 0 : options.onChannelLoaded);
|
|
108
|
-
case
|
|
110
|
+
case 16:
|
|
109
111
|
case "end":
|
|
110
112
|
return _context2.stop();
|
|
111
113
|
}
|
|
@@ -12,6 +12,7 @@ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol
|
|
|
12
12
|
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
13
13
|
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
14
14
|
import { ImageType, RenderMode, ViewMode } from "../shared/enums";
|
|
15
|
+
import { controlPointsToRamp, parseLutSetting } from "../shared/utils/controlPointsToLut";
|
|
15
16
|
import { removeUndefinedProperties } from "../shared/utils/datatypes";
|
|
16
17
|
import { clamp } from "../shared/utils/math";
|
|
17
18
|
import { CameraTransformKeys, ViewerChannelSettingKeys, ViewerStateKeys } from "./types";
|
|
@@ -434,4 +435,98 @@ export function deserializeViewerChannelSetting(channelIndex, jsonState) {
|
|
|
434
435
|
}
|
|
435
436
|
}
|
|
436
437
|
return result;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Parses a `ViewerChannelStateParams` object into a partial `ChannelState`.
|
|
442
|
+
*
|
|
443
|
+
* This is used to convert raw URL params into internal channel state fields,
|
|
444
|
+
* leaving absent or invalid values undefined.
|
|
445
|
+
*
|
|
446
|
+
* This function optionally accepts the target channel's `Histogram`. This
|
|
447
|
+
* argument is required to parse the following params correctly:
|
|
448
|
+
*
|
|
449
|
+
* - `lut`, which contains instructions for how to set the channel's
|
|
450
|
+
* intensities *relative to its intensity distribution*.
|
|
451
|
+
* - `rmp`, the legacy ramp parameter represented as histogram bin indices
|
|
452
|
+
* - `cps`, the legacy control points parameter where `x` values are
|
|
453
|
+
* represented as histogram bin indices
|
|
454
|
+
*
|
|
455
|
+
* If `histogram` is left undefined, e.g. because the channel has not yet been
|
|
456
|
+
* loaded, these params are ignored.
|
|
457
|
+
*/
|
|
458
|
+
export function deserializeChannelState(jsonState, histogram) {
|
|
459
|
+
var result = {
|
|
460
|
+
volumeEnabled: parseStringBoolean(jsonState[ViewerChannelSettingKeys.VolumeEnabled]),
|
|
461
|
+
isosurfaceEnabled: parseStringBoolean(jsonState[ViewerChannelSettingKeys.SurfaceEnabled]),
|
|
462
|
+
isovalue: parseStringFloat(jsonState[ViewerChannelSettingKeys.IsosurfaceValue], -Infinity, Infinity),
|
|
463
|
+
keepIntensityRange: parseStringBoolean(jsonState[ViewerChannelSettingKeys.KeepRange]),
|
|
464
|
+
opacity: parseStringFloat(jsonState[ViewerChannelSettingKeys.IsosurfaceAlpha], 0, 1),
|
|
465
|
+
colorizeEnabled: parseStringBoolean(jsonState[ViewerChannelSettingKeys.Colorize]),
|
|
466
|
+
colorizeAlpha: parseStringFloat(jsonState[ViewerChannelSettingKeys.ColorizeAlpha], 0, 1),
|
|
467
|
+
useControlPoints: parseStringBoolean(jsonState[ViewerChannelSettingKeys.ControlPointsEnabled]),
|
|
468
|
+
color: parseHexColorAsColorArray(jsonState[ViewerChannelSettingKeys.Color])
|
|
469
|
+
};
|
|
470
|
+
var lutSerialized = jsonState[ViewerChannelSettingKeys.Lut];
|
|
471
|
+
var pointsFromLut = undefined;
|
|
472
|
+
if (histogram !== undefined && lutSerialized !== undefined && LUT_REGEX.test(lutSerialized)) {
|
|
473
|
+
var _lutSerialized$split = lutSerialized.split(":"),
|
|
474
|
+
_lutSerialized$split2 = _slicedToArray(_lutSerialized$split, 2),
|
|
475
|
+
min = _lutSerialized$split2[0],
|
|
476
|
+
max = _lutSerialized$split2[1];
|
|
477
|
+
var lut = parseLutSetting(histogram, [min.trim(), max.trim()]);
|
|
478
|
+
pointsFromLut = lut === null || lut === void 0 ? void 0 : lut.controlPoints.map(function (point) {
|
|
479
|
+
return _objectSpread(_objectSpread({}, point), {}, {
|
|
480
|
+
x: histogram.getValueFromBinIndex(point.x)
|
|
481
|
+
});
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
if (jsonState[ViewerChannelSettingKeys.Ramp]) {
|
|
485
|
+
if (RAMP_REGEX.test(jsonState[ViewerChannelSettingKeys.Ramp])) {
|
|
486
|
+
var _jsonState$ViewerChan7 = jsonState[ViewerChannelSettingKeys.Ramp].split(":"),
|
|
487
|
+
_jsonState$ViewerChan8 = _slicedToArray(_jsonState$ViewerChan7, 2),
|
|
488
|
+
_min3 = _jsonState$ViewerChan8[0],
|
|
489
|
+
_max3 = _jsonState$ViewerChan8[1];
|
|
490
|
+
result.ramp = [Number.parseFloat(_min3), Number.parseFloat(_max3)];
|
|
491
|
+
}
|
|
492
|
+
} else if (jsonState[ViewerChannelSettingKeys.RampLegacy]) {
|
|
493
|
+
if (histogram !== undefined) {
|
|
494
|
+
if (RAMP_REGEX.test(jsonState[ViewerChannelSettingKeys.RampLegacy])) {
|
|
495
|
+
var _jsonState$ViewerChan9 = jsonState[ViewerChannelSettingKeys.RampLegacy].split(":"),
|
|
496
|
+
_jsonState$ViewerChan10 = _slicedToArray(_jsonState$ViewerChan9, 2),
|
|
497
|
+
rawMin = _jsonState$ViewerChan10[0],
|
|
498
|
+
rawMax = _jsonState$ViewerChan10[1];
|
|
499
|
+
var _min4 = histogram.getValueFromBinIndex(Number.parseFloat(rawMin));
|
|
500
|
+
var _max4 = histogram.getValueFromBinIndex(Number.parseFloat(rawMax));
|
|
501
|
+
result.ramp = [_min4, _max4];
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
} else if (pointsFromLut !== undefined) {
|
|
505
|
+
result.ramp = controlPointsToRamp(pointsFromLut);
|
|
506
|
+
}
|
|
507
|
+
if (jsonState[ViewerChannelSettingKeys.ControlPoints]) {
|
|
508
|
+
var parsedResult = parseControlPoints(jsonState[ViewerChannelSettingKeys.ControlPoints]);
|
|
509
|
+
if (parsedResult) {
|
|
510
|
+
result.controlPoints = parsedResult;
|
|
511
|
+
}
|
|
512
|
+
} else if (jsonState[ViewerChannelSettingKeys.ControlPointsLegacy]) {
|
|
513
|
+
if (histogram !== undefined) {
|
|
514
|
+
var _parsedResult2 = parseControlPoints(jsonState[ViewerChannelSettingKeys.ControlPointsLegacy]);
|
|
515
|
+
if (_parsedResult2) {
|
|
516
|
+
result.controlPoints = _parsedResult2.map(function (_ref) {
|
|
517
|
+
var opacity = _ref.opacity,
|
|
518
|
+
color = _ref.color,
|
|
519
|
+
x = _ref.x;
|
|
520
|
+
return {
|
|
521
|
+
opacity: opacity,
|
|
522
|
+
color: color,
|
|
523
|
+
x: histogram.getValueFromBinIndex(x)
|
|
524
|
+
};
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
} else if (pointsFromLut !== undefined) {
|
|
529
|
+
result.controlPoints = pointsFromLut;
|
|
530
|
+
}
|
|
531
|
+
return removeUndefinedProperties(result);
|
|
437
532
|
}
|
|
@@ -12,7 +12,7 @@ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol"
|
|
|
12
12
|
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
13
13
|
import { describe, expect, it } from "@jest/globals";
|
|
14
14
|
import { RenderMode, ViewMode } from "../../shared/enums";
|
|
15
|
-
import { CONTROL_POINTS_REGEX, deserializeViewerChannelSetting, deserializeViewerState, LEGACY_CONTROL_POINTS_REGEX, parseHexColorAsColorArray, parseKeyValueList, parseStringEnum, parseStringFloat, parseStringInt } from "../deserialize";
|
|
15
|
+
import { CONTROL_POINTS_REGEX, deserializeChannelState, deserializeViewerChannelSetting, deserializeViewerState, LEGACY_CONTROL_POINTS_REGEX, parseHexColorAsColorArray, parseKeyValueList, parseStringEnum, parseStringFloat, parseStringInt } from "../deserialize";
|
|
16
16
|
import { serializeViewerState } from "../serialize";
|
|
17
17
|
import { CUSTOM_TEST_VIEWER_STATE, DEFAULT_TEST_VIEWER_CHANNEL_SETTING, DEFAULT_TEST_VIEWER_STATE, SERIALIZED_CUSTOM_TEST_VIEWER_STATE, SERIALIZED_DEFAULT_TEST_VIEWER_STATE } from "./test_data";
|
|
18
18
|
|
|
@@ -306,6 +306,57 @@ describe("deserializeViewerChannelSetting", function () {
|
|
|
306
306
|
expect(result.isovalue).toBeUndefined();
|
|
307
307
|
});
|
|
308
308
|
});
|
|
309
|
+
describe("deserializeChannelState", function () {
|
|
310
|
+
it("returns an empty object for empty input", function () {
|
|
311
|
+
expect(deserializeChannelState({})).toEqual({});
|
|
312
|
+
});
|
|
313
|
+
it("parses channel state fields", function () {
|
|
314
|
+
var data = {
|
|
315
|
+
col: "ff0000",
|
|
316
|
+
clz: "1",
|
|
317
|
+
cza: "0.5",
|
|
318
|
+
isa: "0.75",
|
|
319
|
+
ven: "1",
|
|
320
|
+
sen: "1",
|
|
321
|
+
isv: "128",
|
|
322
|
+
ram: "0:255",
|
|
323
|
+
cpe: "1",
|
|
324
|
+
pin: "1"
|
|
325
|
+
};
|
|
326
|
+
expect(deserializeChannelState(data)).toEqual({
|
|
327
|
+
color: [255, 0, 0],
|
|
328
|
+
colorizeEnabled: true,
|
|
329
|
+
colorizeAlpha: 0.5,
|
|
330
|
+
opacity: 0.75,
|
|
331
|
+
volumeEnabled: true,
|
|
332
|
+
isosurfaceEnabled: true,
|
|
333
|
+
isovalue: 128,
|
|
334
|
+
ramp: [0, 255],
|
|
335
|
+
useControlPoints: true,
|
|
336
|
+
keepIntensityRange: true
|
|
337
|
+
});
|
|
338
|
+
});
|
|
339
|
+
it("prefers new control points and ramp fields over legacy fields", function () {
|
|
340
|
+
var data = {
|
|
341
|
+
cpt: "0:0:000000:255:1:ffffff",
|
|
342
|
+
cps: "0:0:ff0000:255:1:00ff00",
|
|
343
|
+
ram: "1:2",
|
|
344
|
+
rmp: "3:4"
|
|
345
|
+
};
|
|
346
|
+
expect(deserializeChannelState(data)).toEqual({
|
|
347
|
+
controlPoints: [{
|
|
348
|
+
x: 0,
|
|
349
|
+
opacity: 0,
|
|
350
|
+
color: [0, 0, 0]
|
|
351
|
+
}, {
|
|
352
|
+
x: 255,
|
|
353
|
+
opacity: 1,
|
|
354
|
+
color: [255, 255, 255]
|
|
355
|
+
}],
|
|
356
|
+
ramp: [1, 2]
|
|
357
|
+
});
|
|
358
|
+
});
|
|
359
|
+
});
|
|
309
360
|
describe("deserializeViewerState", function () {
|
|
310
361
|
it("returns an empty object for empty input", function () {
|
|
311
362
|
expect(deserializeViewerState({})).toEqual({});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aics/vole-app",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.4",
|
|
4
4
|
"description": "web view of cell volume images",
|
|
5
5
|
"main": "es/index.js",
|
|
6
6
|
"module": "es/index.js",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"deploy": "gh-pages -d imageviewer -t true",
|
|
44
44
|
"checks": "npm run lint && npm run typeCheck && npm run test"
|
|
45
45
|
},
|
|
46
|
-
"author": "
|
|
46
|
+
"author": "Allen Institute, Cell Science",
|
|
47
47
|
"license": "BSD-3-Clause",
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@aics/vole-core": "^4.9.2",
|
|
@@ -60,6 +60,7 @@
|
|
|
60
60
|
"react-color": "^2.19.3",
|
|
61
61
|
"react-router-dom": "^6.26.2",
|
|
62
62
|
"styled-components": "^6.1.13",
|
|
63
|
+
"three": "0.184.0",
|
|
63
64
|
"usehooks-ts": "^3.1.0",
|
|
64
65
|
"uuid": "^13.0.0",
|
|
65
66
|
"zustand": "^5.0.6"
|
|
@@ -85,7 +86,7 @@
|
|
|
85
86
|
"@types/react": "^18.x",
|
|
86
87
|
"@types/react-color": "^3.0.12",
|
|
87
88
|
"@types/react-dom": "^18.x",
|
|
88
|
-
"@types/three": "
|
|
89
|
+
"@types/three": "0.184.0",
|
|
89
90
|
"@typescript-eslint/eslint-plugin": "^8.46.2",
|
|
90
91
|
"@typescript-eslint/parser": "^8.46.2",
|
|
91
92
|
"antd": "^5.16.2",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ControlPoint, type Histogram, Lut, type Volume } from "@aics/vole-core";
|
|
2
|
-
import { type
|
|
2
|
+
import { type ViewerChannelSettings } from "./viewerChannelSettings";
|
|
3
3
|
/**
|
|
4
4
|
* @param {Object[]} controlPoints - array of `{x:number, opacity:number,
|
|
5
5
|
* color:string}`, where `x` is a histogram bin index.
|
|
@@ -35,7 +35,7 @@ export declare function getDefaultLut(histogram: Histogram): Lut;
|
|
|
35
35
|
* "autoij:0" // use Auto-IJ to calculate min and max.
|
|
36
36
|
* ```
|
|
37
37
|
*/
|
|
38
|
-
export declare function
|
|
38
|
+
export declare function parseLutSetting(histogram: Histogram, lutSetting: [string, string] | undefined): Lut | undefined;
|
|
39
39
|
/**
|
|
40
40
|
* Initializes the lookup table (LUT) that maps from volume intensity values to color + opacity and applies the LUT to the volume.
|
|
41
41
|
*
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import type { Histogram } from "@aics/vole-core";
|
|
1
2
|
import type { ColorArray } from "../shared/utils/colorRepresentations";
|
|
2
3
|
import type { ViewerChannelSetting } from "../shared/utils/viewerChannelSettings";
|
|
3
|
-
import { type ViewerChannelStateParams, type ViewerState, type ViewerStateParams } from "./types";
|
|
4
|
+
import { type ChannelState, type ViewerChannelStateParams, type ViewerState, type ViewerStateParams } from "./types";
|
|
4
5
|
/**
|
|
5
6
|
* LEGACY: Matches a COMMA-separated list of control points, where each control point is represented
|
|
6
7
|
* by a triplet of `{x}:{opacity}:{hex color}`.
|
|
@@ -68,3 +69,22 @@ export declare function deserializeViewerState(params: ViewerStateParams): Parti
|
|
|
68
69
|
* @returns A ViewerChannelSetting object.
|
|
69
70
|
*/
|
|
70
71
|
export declare function deserializeViewerChannelSetting(channelIndex: number, jsonState: ViewerChannelStateParams): ViewerChannelSetting;
|
|
72
|
+
/**
|
|
73
|
+
* Parses a `ViewerChannelStateParams` object into a partial `ChannelState`.
|
|
74
|
+
*
|
|
75
|
+
* This is used to convert raw URL params into internal channel state fields,
|
|
76
|
+
* leaving absent or invalid values undefined.
|
|
77
|
+
*
|
|
78
|
+
* This function optionally accepts the target channel's `Histogram`. This
|
|
79
|
+
* argument is required to parse the following params correctly:
|
|
80
|
+
*
|
|
81
|
+
* - `lut`, which contains instructions for how to set the channel's
|
|
82
|
+
* intensities *relative to its intensity distribution*.
|
|
83
|
+
* - `rmp`, the legacy ramp parameter represented as histogram bin indices
|
|
84
|
+
* - `cps`, the legacy control points parameter where `x` values are
|
|
85
|
+
* represented as histogram bin indices
|
|
86
|
+
*
|
|
87
|
+
* If `histogram` is left undefined, e.g. because the channel has not yet been
|
|
88
|
+
* loaded, these params are ignored.
|
|
89
|
+
*/
|
|
90
|
+
export declare function deserializeChannelState(jsonState: ViewerChannelStateParams, histogram?: Histogram): Partial<ChannelState>;
|