@aics/vole-app 2.13.2 → 2.13.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.
|
@@ -178,6 +178,33 @@ var App = function App(props) {
|
|
|
178
178
|
|
|
179
179
|
// we need to keep track of channel ranges for remapping control points
|
|
180
180
|
var channelRangesRef = useRef([]);
|
|
181
|
+
var onCreateImage = useCallback(function (newImage) {
|
|
182
|
+
if (newImage === null) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
channelRangesRef.current = new Array(newImage.channelNames.length).fill(undefined);
|
|
186
|
+
var channelSettings = viewerState.current.channelSettings;
|
|
187
|
+
view3d.addVolume(newImage, {
|
|
188
|
+
// Immediately passing down channel parameters isn't strictly necessary, but keeps things looking consistent on load
|
|
189
|
+
channels: newImage.channelNames.map(function (name) {
|
|
190
|
+
// TODO do we really need to be searching by name here?
|
|
191
|
+
var ch = channelSettings.find(function (channel) {
|
|
192
|
+
return channel.name === name;
|
|
193
|
+
});
|
|
194
|
+
if (!ch) {
|
|
195
|
+
return {};
|
|
196
|
+
}
|
|
197
|
+
return {
|
|
198
|
+
enabled: ch.volumeEnabled,
|
|
199
|
+
isosurfaceEnabled: ch.isosurfaceEnabled,
|
|
200
|
+
isovalue: ch.isovalue,
|
|
201
|
+
isosurfaceOpacity: ch.opacity,
|
|
202
|
+
color: ch.color
|
|
203
|
+
};
|
|
204
|
+
})
|
|
205
|
+
});
|
|
206
|
+
view3d.updateActiveChannels(newImage);
|
|
207
|
+
}, [view3d, viewerState]);
|
|
181
208
|
var onChannelLoaded = useCallback(function (image, channelIndex, isInitialLoad) {
|
|
182
209
|
// TODO this was once a search by name - is that still necessary or will the index always be correct?
|
|
183
210
|
var thisChannelSettings = channelSettings[channelIndex];
|
|
@@ -185,18 +212,17 @@ var App = function App(props) {
|
|
|
185
212
|
getChannelsAwaitingResetOnLoad = _viewerState$current2.getChannelsAwaitingResetOnLoad,
|
|
186
213
|
getCurrentViewerChannelSettings = _viewerState$current2.getCurrentViewerChannelSettings,
|
|
187
214
|
changeChannelSetting = _viewerState$current2.changeChannelSetting;
|
|
188
|
-
var ramp = thisChannelSettings.ramp,
|
|
189
|
-
controlPoints = thisChannelSettings.controlPoints;
|
|
190
215
|
var thisChannel = image.getChannel(channelIndex);
|
|
191
|
-
|
|
216
|
+
var noLut = !thisChannelSettings || !thisChannelSettings.controlPoints || !thisChannelSettings.ramp;
|
|
217
|
+
if (isInitialLoad || noLut || getChannelsAwaitingResetOnLoad().has(channelIndex)) {
|
|
192
218
|
// This channel needs its LUT initialized
|
|
193
219
|
var _initializeLut = initializeLut(image, channelIndex, getCurrentViewerChannelSettings()),
|
|
194
|
-
|
|
195
|
-
|
|
220
|
+
ramp = _initializeLut.ramp,
|
|
221
|
+
controlPoints = _initializeLut.controlPoints;
|
|
196
222
|
var dtype = thisChannel.dtype;
|
|
197
223
|
changeChannelSetting(channelIndex, {
|
|
198
|
-
controlPoints:
|
|
199
|
-
ramp: controlPointsToRamp(
|
|
224
|
+
controlPoints: controlPoints,
|
|
225
|
+
ramp: controlPointsToRamp(ramp),
|
|
200
226
|
// set the default range of the transfer function editor to cover the full range of the data type
|
|
201
227
|
plotMin: DTYPE_RANGE[dtype].min,
|
|
202
228
|
plotMax: DTYPE_RANGE[dtype].max
|
|
@@ -215,13 +241,13 @@ var App = function App(props) {
|
|
|
215
241
|
});
|
|
216
242
|
} else {
|
|
217
243
|
// ramp was just automatically remapped - update in state
|
|
218
|
-
var
|
|
244
|
+
var _ramp = controlPointsToRamp(thisChannel.lut.controlPoints);
|
|
219
245
|
// now manually remap control points using the channel's old range
|
|
220
|
-
var
|
|
221
|
-
var remappedControlPoints = remapControlPointsForChannel(
|
|
246
|
+
var _controlPoints = thisChannelSettings.controlPoints;
|
|
247
|
+
var remappedControlPoints = remapControlPointsForChannel(_controlPoints, oldRange, thisChannel);
|
|
222
248
|
changeChannelSetting(channelIndex, {
|
|
223
249
|
controlPoints: remappedControlPoints,
|
|
224
|
-
ramp:
|
|
250
|
+
ramp: _ramp
|
|
225
251
|
});
|
|
226
252
|
}
|
|
227
253
|
}
|
|
@@ -230,7 +256,6 @@ var App = function App(props) {
|
|
|
230
256
|
channelRangesRef.current[channelIndex] = [thisChannel.rawMin, thisChannel.rawMax];
|
|
231
257
|
view3d.updateLuts(image);
|
|
232
258
|
view3d.onVolumeData(image, [channelIndex]);
|
|
233
|
-
view3d.setVolumeChannelEnabled(image, channelIndex, thisChannelSettings.volumeEnabled);
|
|
234
259
|
if (image.channelNames[channelIndex] === maskChannelName) {
|
|
235
260
|
view3d.setVolumeChannelAsMask(image, channelIndex);
|
|
236
261
|
}
|
|
@@ -239,6 +264,7 @@ var App = function App(props) {
|
|
|
239
264
|
}
|
|
240
265
|
}, [view3d, channelSettings, maskChannelName, viewerState]);
|
|
241
266
|
var volume = useVolume(scenes, {
|
|
267
|
+
onCreateImage: onCreateImage,
|
|
242
268
|
onChannelLoaded: onChannelLoaded,
|
|
243
269
|
onError: showError,
|
|
244
270
|
maskChannelName: maskChannelName
|
|
@@ -246,36 +272,6 @@ var App = function App(props) {
|
|
|
246
272
|
var image = volume.image,
|
|
247
273
|
setTime = volume.setTime,
|
|
248
274
|
setScene = volume.setScene;
|
|
249
|
-
|
|
250
|
-
// add the image to the viewer on load
|
|
251
|
-
useEffect(function () {
|
|
252
|
-
if (image === null) {
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
channelRangesRef.current = new Array(image.channelNames.length).fill(undefined);
|
|
256
|
-
var channelSettings = viewerState.current.channelSettings;
|
|
257
|
-
view3d.addVolume(image, {
|
|
258
|
-
// Immediately passing down channel parameters isn't strictly necessary, but keeps things looking consistent on load
|
|
259
|
-
channels: image.channelNames.map(function (name) {
|
|
260
|
-
// TODO do we really need to be searching by name here?
|
|
261
|
-
var ch = channelSettings.find(function (channel) {
|
|
262
|
-
return channel.name === name;
|
|
263
|
-
});
|
|
264
|
-
if (!ch) {
|
|
265
|
-
return {};
|
|
266
|
-
}
|
|
267
|
-
return {
|
|
268
|
-
enabled: ch.volumeEnabled,
|
|
269
|
-
isosurfaceEnabled: ch.isosurfaceEnabled,
|
|
270
|
-
isovalue: ch.isovalue,
|
|
271
|
-
isosurfaceOpacity: ch.opacity,
|
|
272
|
-
color: ch.color
|
|
273
|
-
};
|
|
274
|
-
})
|
|
275
|
-
});
|
|
276
|
-
view3d.updateActiveChannels(image);
|
|
277
|
-
return view3d.removeAllVolumes.bind(view3d);
|
|
278
|
-
}, [image, view3d, viewerState]);
|
|
279
275
|
var hasRawImage = !!(props.rawData && props.rawDims);
|
|
280
276
|
var numScenes = hasRawImage ? 1 : (_scenes$length = (_scenes2 = props.imageUrl.scenes) === null || _scenes2 === void 0 ? void 0 : _scenes2.length) !== null && _scenes$length !== void 0 ? _scenes$length : 1;
|
|
281
277
|
var numSlices = (_image$imageInfo$volu = image === null || image === void 0 ? void 0 : image.imageInfo.volumeSize) !== null && _image$imageInfo$volu !== void 0 ? _image$imageInfo$volu : {
|
|
@@ -66,6 +66,7 @@ var useVolume = function useVolume(scenePaths, options) {
|
|
|
66
66
|
var viewerStateRef = useContext(ViewerStateContext).ref;
|
|
67
67
|
var onErrorRef = useEffectEventRef(options === null || options === void 0 ? void 0 : options.onError);
|
|
68
68
|
var onChannelLoadedRef = useEffectEventRef(options === null || options === void 0 ? void 0 : options.onChannelLoaded);
|
|
69
|
+
var onCreateImageRef = useEffectEventRef(options === null || options === void 0 ? void 0 : options.onCreateImage);
|
|
69
70
|
var maskChannelName = options === null || options === void 0 ? void 0 : options.maskChannelName;
|
|
70
71
|
|
|
71
72
|
// set up our big objects: the image, its loading infrastructure, and controls for playback
|
|
@@ -223,7 +224,7 @@ var useVolume = function useVolume(scenePaths, options) {
|
|
|
223
224
|
};
|
|
224
225
|
var openImage = /*#__PURE__*/function () {
|
|
225
226
|
var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
|
|
226
|
-
var _getCurrentViewerChan;
|
|
227
|
+
var _onCreateImageRef$cur, _getCurrentViewerChan;
|
|
227
228
|
var _viewerStateRef$curre2, scene, time, loadSpec, aimg, channelNames, newChannelSettings, requiredLoadSpec, requiredChannelsToLoad, maskChannelName, maskChannelIndex, slice;
|
|
228
229
|
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
229
230
|
while (1) switch (_context.prev = _context.next) {
|
|
@@ -239,6 +240,7 @@ var useVolume = function useVolume(scenePaths, options) {
|
|
|
239
240
|
newChannelSettings = setChannelStateForNewImage(channelNames);
|
|
240
241
|
setChannelVersions(new Array(channelNames.length).fill(CHANNEL_INITIAL_LOAD));
|
|
241
242
|
setImage(aimg);
|
|
243
|
+
(_onCreateImageRef$cur = onCreateImageRef.current) === null || _onCreateImageRef$cur === void 0 || _onCreateImageRef$cur.call(onCreateImageRef, aimg);
|
|
242
244
|
playControls.stepAxis = function (axis) {
|
|
243
245
|
var _viewerStateRef$curre3 = viewerStateRef.current,
|
|
244
246
|
time = _viewerStateRef$curre3.time,
|
|
@@ -285,7 +287,7 @@ var useVolume = function useVolume(scenePaths, options) {
|
|
|
285
287
|
// initiate loading only after setting up new channel settings,
|
|
286
288
|
// in case the loader callback fires before the state is set
|
|
287
289
|
sceneLoader.loadScene(scene, aimg, requiredLoadSpec)["catch"](onError);
|
|
288
|
-
case
|
|
290
|
+
case 21:
|
|
289
291
|
case "end":
|
|
290
292
|
return _context.stop();
|
|
291
293
|
}
|
|
@@ -296,7 +298,7 @@ var useVolume = function useVolume(scenePaths, options) {
|
|
|
296
298
|
};
|
|
297
299
|
}();
|
|
298
300
|
openImage();
|
|
299
|
-
}, [sceneLoader, onError, onChannelLoadedRef, viewerStateRef, channelVersionsRef, setChannelVersions, playControls, setIsLoading, onChannelDataLoaded]);
|
|
301
|
+
}, [sceneLoader, onError, onCreateImageRef, onChannelLoadedRef, viewerStateRef, channelVersionsRef, setChannelVersions, playControls, setIsLoading, onChannelDataLoaded]);
|
|
300
302
|
// of the above dependencies, we expect only `sceneLoader` to change.
|
|
301
303
|
|
|
302
304
|
var setTime = useCallback(function (view3d, time) {
|
|
@@ -8,6 +8,7 @@ function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r),
|
|
|
8
8
|
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
9
9
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
10
10
|
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); }
|
|
11
|
+
import { VolumeFileFormat } from "@aics/vole-core";
|
|
11
12
|
var SceneStore = /*#__PURE__*/function () {
|
|
12
13
|
function SceneStore(context, paths) {
|
|
13
14
|
_classCallCheck(this, SceneStore);
|
|
@@ -38,6 +39,7 @@ var SceneStore = /*#__PURE__*/function () {
|
|
|
38
39
|
options = {};
|
|
39
40
|
if (_typeof(path) === "object" && !Array.isArray(path)) {
|
|
40
41
|
options.rawArrayOptions = path;
|
|
42
|
+
options.fileType = VolumeFileFormat.DATA;
|
|
41
43
|
path = "";
|
|
42
44
|
}
|
|
43
45
|
_context.next = 8;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aics/vole-app",
|
|
3
|
-
"version": "2.13.
|
|
3
|
+
"version": "2.13.4",
|
|
4
4
|
"description": "web view of cell volume images",
|
|
5
5
|
"repository": "github:allen-cell-animated/vole-app",
|
|
6
6
|
"main": "es/index.js",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"author": "Megan Riel-Mehan",
|
|
42
42
|
"license": "ISC",
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@aics/vole-core": "^
|
|
44
|
+
"@aics/vole-core": "^4.1.0",
|
|
45
45
|
"@ant-design/icons": "^5.2.5",
|
|
46
46
|
"@fortawesome/fontawesome-svg-core": "^6.5.2",
|
|
47
47
|
"@fortawesome/free-solid-svg-icons": "^6.5.2",
|
|
@@ -3,6 +3,8 @@ import { AxisName } from "../shared/types";
|
|
|
3
3
|
import PlayControls from "../shared/utils/playControls";
|
|
4
4
|
import { ChannelGrouping } from "../shared/utils/viewerChannelSettings";
|
|
5
5
|
export type UseVolumeOptions = {
|
|
6
|
+
/** Callback for when the volume is created. */
|
|
7
|
+
onCreateImage?: (image: Volume) => void;
|
|
6
8
|
/** Callback for when a single channel of the volume has loaded. */
|
|
7
9
|
onChannelLoaded?: (image: Volume, channelIndex: number, isInitialLoad: boolean) => void;
|
|
8
10
|
/** Callback for when image loading encounters an error. */
|