Skip to content

Commit

Permalink
Merge branch 'master' into add-y-scale-to-histogram
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelBuessemeyer authored Dec 3, 2019
2 parents 6c6c576 + bcc2bd2 commit b6d6734
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 11 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.md).
-

### Fixed
-
- Fixed an issue where webKnossos would complain in certain scenarios when resolutions of datasets were not complete. [#4344](https://github.com/scalableminds/webknossos/pull/4344)

### Removed
-
Expand All @@ -37,10 +37,12 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.md).

### Changed
- Some user actions, like deleting a group with all subtrees, resulted in lots of entries in the undo stack (one for each deleted tree). Those actions are now handled as a single atomic change and can be undone with a single undo invocation. [#4312](https://github.com/scalableminds/webknossos/pull/4312)
- The "Find Data" feature will jump to the center of the layer's bounding box, if no data could be found. The "Find Data" feature can be found next to each layer's name in the dataset settings tab. [#4346](https://github.com/scalableminds/webknossos/pull/4346)

### Fixed
- Fixed broken sorting in the dataset table of the dashboard. [#4318](https://github.com/scalableminds/webknossos/pull/4318)
- Fixed annotation access to match the text in the modal. [#4314](https://github.com/scalableminds/webknossos/pull/4314)
- Fixed that the brush tool could be selected in an read-only tracing. [#4345](https://github.com/scalableminds/webknossos/pull/4345)
- Fixed the name of downloaded annotation zips. [#4330](https://github.com/scalableminds/webknossos/pull/4330)


Expand Down
2 changes: 1 addition & 1 deletion frontend/javascripts/libs/toast.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ const Toast = {

if (type === "error") {
toastConfig = Object.assign(toastConfig, {
icon: <Icon type="cross-circle-o" className="alert-wiggle" style={{ color: "#a94442" }} />,
icon: <Icon type="close-circle-o" className="alert-wiggle" style={{ color: "#a94442" }} />,
style: {
backgroundColor: "#f2dede",
borderColor: "#ebccd1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,16 @@ function VolumeTracingReducer(state: OxalisState, action: VolumeTracingAction):
.map(volumeTracing => {
switch (action.type) {
case "SET_TOOL": {
if (!state.tracing.restrictions.allowUpdate) {
return state;
}
return setToolReducer(state, volumeTracing, action.tool);
}

case "CYCLE_TOOL": {
if (!state.tracing.restrictions.allowUpdate) {
return state;
}
const tools = Object.keys(VolumeToolEnum);
const currentToolIndex = tools.indexOf(volumeTracing.activeTool);
const newTool = tools[(currentToolIndex + 1) % tools.length];
Expand Down
2 changes: 2 additions & 0 deletions frontend/javascripts/oxalis/model/sagas/root_saga.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
pushAnnotationAsync,
saveTracingAsync,
collectUndoStates,
toggleErrorHighlighting,
} from "oxalis/model/sagas/save_saga";
import {
warnAboutSegmentationOpacity,
Expand Down Expand Up @@ -55,6 +56,7 @@ function* restartableSaga(): Saga<void> {
} catch (err) {
console.error(err);
ErrorHandling.notify(err, {});
toggleErrorHighlighting(true);
alert(`\
Internal error.
Please reload the page to avoid losing data.
Expand Down
18 changes: 12 additions & 6 deletions frontend/javascripts/oxalis/model_initialization.js
Original file line number Diff line number Diff line change
Expand Up @@ -308,13 +308,14 @@ function initializeDataset(
Store.dispatch(setDatasetAction(dataset));
}

function ensureDenseLayerResolutions(dataset: APIDataset) {
export function ensureDenseLayerResolutions(dataset: APIDataset) {
const mostExtensiveResolutions = convertToDenseResolution(getMostExtensiveResolutions(dataset));
for (const layer of dataset.dataSource.dataLayers) {
layer.resolutions = convertToDenseResolution(layer.resolutions);
layer.resolutions = convertToDenseResolution(layer.resolutions, mostExtensiveResolutions);
}
}

function ensureMatchingLayerResolutions(dataset: APIDataset): void {
export function ensureMatchingLayerResolutions(dataset: APIDataset): void {
const mostExtensiveResolutions = getMostExtensiveResolutions(dataset);
for (const layer of dataset.dataSource.dataLayers) {
for (const resolution of layer.resolutions) {
Expand All @@ -325,7 +326,10 @@ function ensureMatchingLayerResolutions(dataset: APIDataset): void {
}
}

function convertToDenseResolution(resolutions: Array<Vector3>) {
export function convertToDenseResolution(
resolutions: Array<Vector3>,
fallbackDenseResolutions?: Array<Vector3>,
): Array<Vector3> {
// Each resolution entry can be characterized by it's greatest resolution dimension.
// E.g., the resolution array [[1, 1, 1], [2, 2, 1], [4, 4, 2]] defines that
// a log zoomstep of 2 corresponds to the resolution [2, 2, 1] (and not [4, 4, 2]).
Expand All @@ -339,11 +343,13 @@ function convertToDenseResolution(resolutions: Array<Vector3>) {
}
const paddedResolutionCount = 1 + Math.log2(_.max(resolutions.map(v => _.max(v))));
const resolutionsLookUp = _.keyBy(resolutions, _.max);
const fallbackResolutionsLookUp = _.keyBy(fallbackDenseResolutions || [], _.max);

return _.range(0, paddedResolutionCount).map(exp => {
const resPower = 2 ** exp;
// If the resolution does not exist, use a fallback resolution
return resolutionsLookUp[resPower] || [resPower, resPower, resPower];
// If the resolution does not exist, use either the given fallback resolution or an isotropic fallback
const fallback = fallbackResolutionsLookUp[resPower] || [resPower, resPower, resPower];
return resolutionsLookUp[resPower] || fallback;
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ class VolumeActionsView extends PureComponent<Props> {
</RadioGroup>
<ButtonGroup>
<ButtonComponent onClick={this.handleCreateCell}>
New <span style={{ textDecoration: "underline" }}>C</span>ell
New&nbsp;
<span style={{ textDecoration: "underline" }}>C</span>ell
</ButtonComponent>
</ButtonGroup>
</div>
Expand Down
15 changes: 13 additions & 2 deletions frontend/javascripts/oxalis/view/settings/dataset_settings_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type { Dispatch } from "redux";
import { connect } from "react-redux";
import * as React from "react";
import _ from "lodash";
import { V3 } from "libs/mjs";

import type { APIDataset, APIHistogramData } from "admin/api_flow_types";
import { AsyncIconButton } from "components/async_clickables";
Expand All @@ -20,7 +21,11 @@ import {
import { findDataPositionForLayer, getHistogramForLayer } from "admin/admin_rest_api";
import { getGpuFactorsWithLabels } from "oxalis/model/bucket_data_handling/data_rendering_logic";
import { getMaxZoomValueForResolution } from "oxalis/model/accessors/flycam_accessor";
import { hasSegmentation, getElementClass } from "oxalis/model/accessors/dataset_accessor";
import {
hasSegmentation,
getElementClass,
getLayerBoundaries,
} from "oxalis/model/accessors/dataset_accessor";
import { setPositionAction, setZoomStepAction } from "oxalis/model/actions/flycam_actions";
import {
updateDatasetSettingAction,
Expand Down Expand Up @@ -307,7 +312,13 @@ class DatasetSettings extends React.PureComponent<DatasetSettingsProps, State> {
layerName,
);
if (!position || !resolution) {
Toast.warning(`Couldn't find data within layer "${layerName}."`);
const { upperBoundary, lowerBoundary } = getLayerBoundaries(dataset, layerName);
const centerPosition = V3.add(lowerBoundary, upperBoundary).map(el => el / 2);

Toast.warning(
`Couldn't find data within layer "${layerName}." Jumping to the center of the layer's bounding box.`,
);
this.props.onSetPosition(centerPosition);
return;
}

Expand Down
41 changes: 41 additions & 0 deletions frontend/javascripts/test/model/model_resolutions.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// @noflow
import test from "ava";

import {
ensureDenseLayerResolutions,
ensureMatchingLayerResolutions,
convertToDenseResolution,
} from "oxalis/model_initialization";

test("Simple convertToDenseResolution", t => {
const denseResolutions = convertToDenseResolution([[2, 2, 1], [4, 4, 2]]);
t.deepEqual(denseResolutions, [[1, 1, 1], [2, 2, 1], [4, 4, 2]]);
});

test("Complex convertToDenseResolution", t => {
const dataset = {
dataSource: {
dataLayers: [
{
resolutions: [[2, 2, 1], [4, 4, 1], [8, 8, 1], [16, 16, 2], [32, 32, 4]],
},
{
resolutions: [[32, 32, 4]],
},
],
},
};
ensureDenseLayerResolutions(dataset);
ensureMatchingLayerResolutions(dataset);
const expectedResolutions = [
[1, 1, 1],
[2, 2, 1],
[4, 4, 1],
[8, 8, 1],
[16, 16, 2],
[32, 32, 4],
];

t.deepEqual(dataset.dataSource.dataLayers[0].resolutions, expectedResolutions);
t.deepEqual(dataset.dataSource.dataLayers[1].resolutions, expectedResolutions);
});

0 comments on commit b6d6734

Please sign in to comment.