Skip to content

Commit

Permalink
Merger mode tasks (#4269)
Browse files Browse the repository at this point in the history
* add merger mode tasks
* fix evolution and add changelog
* try to fix schema issues
* fix schema
* Merge branch 'master' of github.com:scalableminds/webknossos into merger-mode-tasks
* update migrations
* update documentation and fix #4273
* new snapshots (new mergerMode field in tasktype settings)
* change width of experience domain column
* Merge branch 'merger-mode-tasks' of github.com:scalableminds/webknossos into merger-mode-tasks
  • Loading branch information
daniel-wer authored and bulldozer-boy[bot] committed Sep 4, 2019
1 parent f126028 commit f1fe3ca
Show file tree
Hide file tree
Showing 26 changed files with 213 additions and 59 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.md).
### Added
- Indicating active nml downloads with a loading icon. [#4228](https://github.com/scalableminds/webknossos/pull/4228)
- Added possibility for users to see their own time statistics. [#4220](https://github.com/scalableminds/webknossos/pull/4220)
- Added merger mode as a setting for task types. Enabling this setting will automatically activate merger mode in tasks. [#4269](https://github.com/scalableminds/webknossos/pull/4269)
- The segmentation layer can now be turned invisible and also supports the find data feature. [#4232](https://github.com/scalableminds/webknossos/pull/4232)
- Enabled the advanced search for the comment tab. [#4238](https://github.com/scalableminds/webknossos/pull/4238)
- Added limited support for `uint64` segmentation layer by using the lower 4 bytes. [#4233](https://github.com/scalableminds/webknossos/pull/4233)
Expand Down
3 changes: 2 additions & 1 deletion MIGRATIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ User-facing changes are documented in the [changelog](CHANGELOG.md).
-

### Postgres Evolutions:
-
- [045-annotationsettings-mergerMode.sql](conf/evolutions/045-annotationsettings-mergerMode.sql)


## [19.09.0](https://github.com/scalableminds/webknossos/releases/tag/19.09.0) - 2019-08-28
No migrations necessary.
Expand Down
1 change: 1 addition & 0 deletions app/models/annotation/AnnotationSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ case class AnnotationSettings(
preferredMode: Option[String] = None,
branchPointsAllowed: Boolean = true,
somaClickingAllowed: Boolean = true,
mergerMode: Boolean = false,
allowedMagnifications: Option[JsValue] = None
)

Expand Down
6 changes: 4 additions & 2 deletions app/models/task/TaskType.scala
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class TaskTypeDAO @Inject()(sqlClient: SQLClient)(implicit ec: ExecutionContext)
r.settingsPreferredmode,
r.settingsBranchpointsallowed,
r.settingsSomaclickingallowed,
r.settingsMergermode,
r.settingsAllowedmagnifications.map(Json.parse)
),
r.recommendedconfiguration.map(Json.parse),
Expand Down Expand Up @@ -115,10 +116,10 @@ class TaskTypeDAO @Inject()(sqlClient: SQLClient)(implicit ec: ExecutionContext)
for {
_ <- run(
sqlu"""insert into webknossos.taskTypes(_id, _team, summary, description, settings_allowedModes, settings_preferredMode,
settings_branchPointsAllowed, settings_somaClickingAllowed, settings_allowedMagnifications, recommendedConfiguration, tracingType, created, isDeleted)
settings_branchPointsAllowed, settings_somaClickingAllowed, settings_mergerMode, settings_allowedMagnifications, recommendedConfiguration, tracingType, created, isDeleted)
values(${t._id.id}, ${t._team.id}, ${t.summary}, ${t.description}, '#${sanitize(
writeArrayTuple(t.settings.allowedModes))}', #${optionLiteral(t.settings.preferredMode.map(sanitize(_)))},
${t.settings.branchPointsAllowed}, ${t.settings.somaClickingAllowed}, #${optionLiteral(
${t.settings.branchPointsAllowed}, ${t.settings.somaClickingAllowed}, ${t.settings.mergerMode}, #${optionLiteral(
t.settings.allowedMagnifications.map(c => sanitize(Json.toJson(c).toString)))}, #${optionLiteral(
t.recommendedConfiguration.map(c => sanitize(Json.toJson(c).toString)))}, '#${t.tracingType.toString}',
${new java.sql.Timestamp(t.created)}, ${t.isDeleted})""")
Expand All @@ -137,6 +138,7 @@ class TaskTypeDAO @Inject()(sqlClient: SQLClient)(implicit ec: ExecutionContext)
settings_preferredMode = #${optionLiteral(t.settings.preferredMode.map(sanitize(_)))},
settings_branchPointsAllowed = ${t.settings.branchPointsAllowed},
settings_somaClickingAllowed = ${t.settings.somaClickingAllowed},
settings_mergerMode = ${t.settings.mergerMode},
settings_allowedMagnifications = #${optionLiteral(
t.settings.allowedMagnifications.map(c => sanitize(Json.toJson(c).toString)))},
recommendedConfiguration = #${optionLiteral(
Expand Down
12 changes: 12 additions & 0 deletions conf/evolutions/045-annotationsettings-mergerMode.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-- https://github.com/scalableminds/webknossos/pull/???

START TRANSACTION;

DROP VIEW webknossos.taskTypes_;
ALTER TABLE webknossos.taskTypes ADD COLUMN settings_mergerMode BOOLEAN NOT NULL DEFAULT false;

CREATE VIEW webknossos.taskTypes_ AS SELECT * FROM webknossos.taskTypes WHERE NOT isDeleted;

UPDATE webknossos.releaseInformation SET schemaVersion = 45;

COMMIT TRANSACTION;
10 changes: 10 additions & 0 deletions conf/evolutions/reversions/045-annotationsettings-mergerMode.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
START TRANSACTION;

DROP VIEW webknossos.taskTypes_;
ALTER TABLE webknossos.taskTypes DROP settings_mergerMode;

CREATE VIEW webknossos.taskTypes_ AS SELECT * FROM webknossos.taskTypes WHERE NOT isDeleted;

UPDATE webknossos.releaseInformation SET schemaVersion = 44;

COMMIT TRANSACTION;
15 changes: 13 additions & 2 deletions docs/keyboard_shortcuts.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Keyboard Shortcuts
# Keyboard & Mouse Shortcuts

Find all available keyboard shortcuts for webKnossos listed below.
Find all available keyboard & mouse shortcuts for webKnossos listed below.

## General

Expand Down Expand Up @@ -83,3 +83,14 @@ Find all available keyboard shortcuts for webKnossos listed below.
| SHIFT + Mousewheel or SHIFT + I, O | Change Brush Size (Brush Mode) |
| V | Copy Segmentation of Current Cell From Previous Slice |
| SHIFT + V | Copy Segmentation of Current Cell From Next Slice |

## Mesh Related Shortcuts

The following bindings only work if isosurface rendering is activated in the settings and a segmentation exists.

| Key Binding | Operation |
| ------------------------------------------------------ | ----------------------------------------------------------- |
| Shift + Click on a segment in the orthogonal viewports | Initiate isosurface rendering for that cell |
| Shift + Click on a segment in the 3D viewport | Change the active position to the clicked position |
| Ctrl + Click on a segment in the 3D viewport | Remove the isosurface of the clicked cell |

1 change: 1 addition & 0 deletions frontend/javascripts/admin/api_flow_types.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ export type APISettings = {|
+preferredMode?: APIAllowedMode,
+branchPointsAllowed: boolean,
+somaClickingAllowed: boolean,
+mergerMode?: boolean,
+allowedMagnifications?: {
shouldRestrict: boolean,
min?: number,
Expand Down
23 changes: 23 additions & 0 deletions frontend/javascripts/admin/help/keyboardshortcut_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,21 @@ const KeyboardShortcutView = () => {
},
];

const isosurfaceShortcuts = [
{
keybinding: "Shift + Click on a segment in the orthogonal viewports",
action: "Initiate isosurface rendering for that cell",
},
{
keybinding: "Shift + Click on a segment in the 3D viewport",
action: "Change the active position to the clicked position",
},
{
keybinding: "Ctrl + Click on a segment in the 3D viewport",
action: "Remove the isosurface of the clicked cell",
},
];

return (
<div className="container help">
<h3>Keyboard Shortcuts</h3>
Expand Down Expand Up @@ -277,6 +292,14 @@ const KeyboardShortcutView = () => {
pagination={false}
rowKey={(_, index) => index}
/>

<h3>Isosurface Shortcuts</h3>
<Table
dataSource={isosurfaceShortcuts}
columns={columns}
pagination={false}
rowKey={(_, index) => index}
/>
</div>
);
};
Expand Down
7 changes: 7 additions & 0 deletions frontend/javascripts/admin/tasktype/task_type_create_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ class TaskTypeCreateView extends React.PureComponent<Props, State> {
settings: {
somaClickingAllowed: true,
branchPointsAllowed: true,
mergerMode: false,
preferredMode: null,
allowedMagnifications: {
shouldRestrict: false,
Expand Down Expand Up @@ -278,6 +279,12 @@ class TaskTypeCreateView extends React.PureComponent<Props, State> {
valuePropName: "checked",
})(<Checkbox>Allow Branchpoints</Checkbox>)}
</FormItem>

<FormItem>
{getFieldDecorator("settings.mergerMode", {
valuePropName: "checked",
})(<Checkbox>Merger Mode</Checkbox>)}
</FormItem>
</div>

<FormItem style={{ marginBottom: 6 }}>
Expand Down
6 changes: 6 additions & 0 deletions frontend/javascripts/admin/tasktype/task_type_list_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,12 @@ class TaskTypeListView extends React.PureComponent<Props, State> {
Allow Single-node-tree mode (&quot;Soma clicking&quot;)
</Tag>,
);
if (settings.mergerMode)
elements.push(
<Tag color="purple" key="mergerMode">
Merger Mode
</Tag>,
);
return elements;
}}
width={200}
Expand Down
1 change: 1 addition & 0 deletions frontend/javascripts/admin/user/user_list_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ class UserListView extends React.PureComponent<PropsWithRouter, State> {
title="Experiences"
dataIndex="experiences"
key="experiences"
width={250}
render={(experiences: ExperienceMap, user: APIUser) =>
_.map(experiences, (value, domain) => (
<Tag key={`experience_${user.id}_${domain}`}>
Expand Down
82 changes: 82 additions & 0 deletions frontend/javascripts/oxalis/controller/merger_mode_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// @flow

import { connect } from "react-redux";
import React, { PureComponent } from "react";
import _ from "lodash";

import type { OxalisState } from "oxalis/store";
import { enableMergerMode, disableMergerMode } from "oxalis/merger_mode";

import MergerModeModalView from "oxalis/view/settings/merger_mode_modal_view";

type MergerModeControllerProps = {
isMergerModeEnabled: boolean,
};

type State = {
isMergerModeModalVisible: boolean,
isMergerModeModalClosable: boolean,
mergerModeProgress: number,
};

class MergerModeController extends PureComponent<MergerModeControllerProps, State> {
state = {
isMergerModeModalVisible: false,
isMergerModeModalClosable: false,
mergerModeProgress: 0,
};

componentDidMount() {
if (this.props.isMergerModeEnabled) this.handleMergerModeChange(true);
}

componentDidUpdate(prevProps: MergerModeControllerProps) {
if (prevProps.isMergerModeEnabled !== this.props.isMergerModeEnabled) {
this.handleMergerModeChange(this.props.isMergerModeEnabled);
}
}

handleMergerModeChange = async (active: boolean) => {
if (active) {
this.setState({
isMergerModeModalVisible: true,
isMergerModeModalClosable: false,
mergerModeProgress: 0,
});
const onUpdateProgress = mergerModeProgress => this.setState({ mergerModeProgress });
await enableMergerMode(onUpdateProgress);
// The modal is only closeable after the merger mode is fully enabled
// and finished preprocessing
this.setState({ isMergerModeModalClosable: true });
} else {
this.setState({
isMergerModeModalVisible: false,
isMergerModeModalClosable: false,
});
disableMergerMode();
}
};

render() {
const { isMergerModeModalVisible, isMergerModeModalClosable } = this.state;
return (
<React.Fragment>
{isMergerModeModalVisible ? (
<MergerModeModalView
isCloseable={isMergerModeModalClosable}
onClose={() => this.setState({ isMergerModeModalVisible: false })}
progress={this.state.mergerModeProgress}
/>
) : null}
</React.Fragment>
);
}
}

const mapStateToProps = (state: OxalisState) => ({
isMergerModeEnabled: state.temporaryConfiguration.isMergerModeEnabled,
});

export default connect<MergerModeControllerProps, {||}, _, _, _, _>(mapStateToProps)(
MergerModeController,
);
1 change: 1 addition & 0 deletions frontend/javascripts/oxalis/default_state.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const initialAnnotationInfo = {
allowAccess: true,
allowDownload: false,
somaClickingAllowed: false,
mergerMode: false,
allowedModes: ["orthogonal", "oblique", "flight"],
},
isPublic: false,
Expand Down
7 changes: 7 additions & 0 deletions frontend/javascripts/oxalis/model/sagas/task_saga.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
updateUserSettingAction,
} from "oxalis/model/actions/settings_actions";
import { setActiveUserAction } from "oxalis/model/actions/user_actions";
import { setMergerModeEnabledAction } from "oxalis/model/actions/skeletontracing_actions";
import { updateLastTaskTypeIdOfUser } from "admin/admin_rest_api";
import NewTaskDescriptionModal from "oxalis/view/new_task_description_modal";
import RecommendedConfigurationModal from "oxalis/view/recommended_configuration_modal";
Expand Down Expand Up @@ -83,6 +84,10 @@ function* maybeShowRecommendedConfiguration(taskType: APITaskType): Saga<void> {
}
}

function* maybeActivateMergerMode(taskType: APITaskType): Saga<void> {
if (taskType.settings.mergerMode) yield* put(setMergerModeEnabledAction(true));
}

export default function* watchTasksAsync(): Saga<void> {
yield* take("WK_READY");

Expand All @@ -91,6 +96,8 @@ export default function* watchTasksAsync(): Saga<void> {
const allowUpdate = yield* select(state => state.tracing.restrictions.allowUpdate);
if (task == null || activeUser == null || !allowUpdate) return;

yield* call(maybeActivateMergerMode, task.type);

const { lastTaskTypeId } = activeUser;
const isDifferentTaskType = lastTaskTypeId == null || lastTaskTypeId !== task.type.id;
if (isDifferentTaskType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import NmlUploadZoneContainer from "oxalis/view/nml_upload_zone_container";
import OxalisController from "oxalis/controller";
import RecordingSwitch from "oxalis/view/recording_switch";
import SettingsView from "oxalis/view/settings/settings_view";
import MergerModeController from "oxalis/controller/merger_mode_controller";
import TDViewControls from "oxalis/view/td_view_controls";
import Toast from "libs/toast";
import TracingView from "oxalis/view/tracing_view";
Expand Down Expand Up @@ -235,7 +236,7 @@ class TracingLayoutView extends React.PureComponent<Props, State> {
{/* Don't render SettingsView if it's hidden to improve performance */}
{!this.state.isSettingsCollapsed ? <SettingsView /> : null}
</Sider>

<MergerModeController />
<div id={canvasAndLayoutContainerID} style={{ position: "relative" }}>
<TracingView />
<GoldenLayoutAdapter
Expand Down
Loading

0 comments on commit f1fe3ca

Please sign in to comment.