Skip to content

Commit

Permalink
Make "Registering of All Segments for a BBox"- feature mag aware (#8082)
Browse files Browse the repository at this point in the history
* mag register all segments for bbox feature mag aware

* remove console.logs

* add error toasts for missing mag or segmentation layer

* add changelog

* improve changelog

* move line

* bubble up API error to open toast in view

* fix mag-related edge case

* register segments for segmentation layers without volume annotation layers

* add warning toast if segmentation layer isnt editable
  • Loading branch information
knollengewaechs authored Sep 19, 2024
1 parent a4cf17c commit 1f9007c
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 25 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released
- It is now possible to focus a bounding box in the bounding box tab by clicking its edges in a viewport or via a newly added context menu entry. [#8054](https://github.com/scalableminds/webknossos/pull/8054)
- Added the option to export nd datasets as ome tiff or tiff stack. Previously, this was only possible for 3d datasets. [#7971](https://github.com/scalableminds/webknossos/pull/7971)
- Added an assertion to the backend to ensure unique keys in the metadata info of datasets and folders. [#8068](https://github.com/scalableminds/webknossos/issues/8068)
- The feature to register all segments within a bounding box now takes the current magnification into consideration, e.g. for calculating the volume limit for a bounding box. [#8082](https://github.com/scalableminds/webknossos/pull/8082)

### Changed
- Clicking on a bounding box within the bounding box tab centers it within the viewports and focusses it in the list. [#8049](https://github.com/scalableminds/webknossos/pull/8049)
Expand Down
73 changes: 49 additions & 24 deletions frontend/javascripts/oxalis/api/api_latest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -656,35 +656,55 @@ class TracingApi {
bbName: string,
options?: { maximumSegmentCount?: number; maximumVolume?: number },
) => {
const state = Store.getState();
const maximumVolume = options?.maximumVolume ?? Constants.REGISTER_SEGMENTS_BB_MAX_VOLUME_VX;
const maximumSegmentCount =
options?.maximumSegmentCount ?? Constants.REGISTER_SEGMENTS_BB_MAX_SEGMENT_COUNT;
const shape = Utils.computeShapeFromBoundingBox({ min, max });
const volume = Math.ceil(shape[0] * shape[1] * shape[2]);

const segmentationLayerName = api.data.getVisibleSegmentationLayerName();
if (segmentationLayerName == null) {
throw new Error(
"No segmentation layer is currently visible. Enable the one you want to register segments for.",
);
}

const resolutionInfo = getResolutionInfo(
getLayerByName(state.dataset, segmentationLayerName).resolutions,
);
const theoreticalMagIndex = getActiveMagIndexForLayer(state, segmentationLayerName);
const existingMagIndex = resolutionInfo.getIndexOrClosestHigherIndex(theoreticalMagIndex);
if (existingMagIndex == null) {
throw new Error("The index of the current mag could not be found.");
}
const currentMag = resolutionInfo.getResolutionByIndex(existingMagIndex);
if (currentMag == null) {
throw new Error("No mag could be found.");
}

const volume =
Math.ceil(shape[0] / currentMag[0]) *
Math.ceil(shape[1] / currentMag[1]) *
Math.ceil(shape[2] / currentMag[2]);
if (volume > maximumVolume) {
Toast.error(
`The volume of the bounding box exceeds ${maximumVolume} Vx, please make it smaller.`,
throw new Error(
`The volume of the bounding box exceeds ${maximumVolume} vx, please make it smaller. Currently, the bounding box has a volume of ${volume} vx in the active resolution (${currentMag.join("-")}).`,
);
return;
} else if (volume > maximumVolume / 8) {
Toast.warning(
"The volume of the bounding box is very large, registering all segments might take a while.",
);
}

const segmentationLayerName = api.data.getSegmentationLayerNames()[0];
const layer = getLayerByName(Store.getState().dataset, segmentationLayerName);

const resolutionInfo = getResolutionInfo(layer.resolutions);
const finestResolution = resolutionInfo.getFinestResolution();
// By default, getDataForBoundingBox uses the finest existing magnification.
// We use that as strides to traverse the data array properly.
const [dx, dy, dz] = finestResolution;

const data = await api.data.getDataForBoundingBox(segmentationLayerName, {
min,
max,
});
const data = await api.data.getDataForBoundingBox(
segmentationLayerName,
{
min,
max,
},
existingMagIndex,
);
const [dx, dy, dz] = currentMag;

const segmentIdToPosition = new Map();
let idx = 0;
Expand All @@ -703,21 +723,26 @@ class TracingApi {
const segmentIdCount = Array.from(segmentIdToPosition.entries()).length;
const halfMaxNoSegments = maximumSegmentCount / 2;
if (segmentIdCount > maximumSegmentCount) {
Toast.error(
throw new Error(
`The given bounding box contains ${segmentIdCount} segments, but only ${maximumSegmentCount} segments can be registered at once. Please reduce the size of the bounding box.`,
);
return;
} else if (segmentIdCount > halfMaxNoSegments) {
Toast.warning(
`The bounding box contains more than ${halfMaxNoSegments} segments. Registering all segments might take a while.`,
);
}

const groupId = api.tracing.createSegmentGroup(
`Segments for ${bbName}`,
-1,
segmentationLayerName,
);
let groupId = MISSING_GROUP_ID;
try {
groupId = api.tracing.createSegmentGroup(`Segments for ${bbName}`, -1, segmentationLayerName);
} catch (_e) {
console.info(
`Volume tracing could not be found for the currently visible segmentation layer, registering segments for ${bbName} within root group.`,
);
Toast.warning(
"The current segmentation layer is not editable and the segment list will not be persisted across page reloads. You can make it editable by clicking on the lock symbol to the right of the layer name.",
);
}
const updateSegmentActions: BatchableUpdateSegmentAction[] = [];
for (const [segmentId, position] of segmentIdToPosition.entries()) {
api.tracing.registerSegment(segmentId, position, undefined, segmentationLayerName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import type { OxalisState } from "oxalis/store";
import type { APISegmentationLayer } from "types/api_flow_types";
import { api } from "oxalis/singletons";
import FastTooltip from "components/fast_tooltip";
import Toast from "libs/toast";
import { handleGenericError } from "libs/error_handling";

const ROW_GUTTER = 1;

Expand Down Expand Up @@ -488,7 +490,9 @@ class UserBoundingBoxInput extends React.PureComponent<UserBoundingBoxInputProps
onRegisterSegmentsForBB(value: Vector6, name: string): void {
const min: Vector3 = [value[0], value[1], value[2]];
const max: Vector3 = [value[0] + value[3], value[1] + value[4], value[2] + value[5]];
api.tracing.registerSegmentsForBoundingBox(min, max, name);
api.tracing
.registerSegmentsForBoundingBox(min, max, name)
.catch((error) => Toast.error(error.message));
this.maybeCloseContextMenu();
}

Expand Down

0 comments on commit 1f9007c

Please sign in to comment.