From 0cf3a1f6c6d2ef10f0c5838a3ea77388480557ec Mon Sep 17 00:00:00 2001 From: Arthur Hilbert Date: Wed, 1 Jun 2022 17:44:01 +0200 Subject: [PATCH 1/5] display warning when resolution gets too low during zooming --- frontend/javascripts/messages.ts | 2 ++ .../oxalis/model/sagas/dataset_saga.ts | 31 +++++++++++++++++-- .../oxalis/model/sagas/root_saga.ts | 3 +- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/frontend/javascripts/messages.ts b/frontend/javascripts/messages.ts index 2a9575c0780..26a15016b62 100644 --- a/frontend/javascripts/messages.ts +++ b/frontend/javascripts/messages.ts @@ -284,6 +284,8 @@ instead. Only enable this option if you understand its effect. All layers will n "This dataset location is marked as 'scratch' and meant for testing only. Please move this dataset to a permanent storage location and reimport it.", "dataset.resolution_mismatch": "This dataset contains multiple layers which differ in their resolution. Please convert the layers to make their resolutions match. Otherwise, rendering errors cannot be avoided.", + "dataset.z1_downsampling_hint": + "The currently rendered quality is not optimal due to the available magnifications and the viewport arrangement. To improve the quality try to increase the size of the XY viewport (e.g., by maximizing it).", "annotation.finish": "Are you sure you want to permanently finish this annotation?", "annotation.was_finished": "Annotation was archived", "annotation.no_fallback_data_included": diff --git a/frontend/javascripts/oxalis/model/sagas/dataset_saga.ts b/frontend/javascripts/oxalis/model/sagas/dataset_saga.ts index ef48552aae2..fd25a57a6f9 100644 --- a/frontend/javascripts/oxalis/model/sagas/dataset_saga.ts +++ b/frontend/javascripts/oxalis/model/sagas/dataset_saga.ts @@ -1,10 +1,11 @@ -/* eslint-disable import/prefer-default-export */ import type { Saga } from "oxalis/model/sagas/effect-generators"; import { select } from "oxalis/model/sagas/effect-generators"; -import { takeEvery } from "typed-redux-saga"; +import { call, takeEvery } from "typed-redux-saga"; +import { sleep } from "libs/utils"; import { getEnabledLayers } from "oxalis/model/accessors/dataset_accessor"; import Toast from "libs/toast"; import messages from "messages"; +import { getCurrentResolution } from "../accessors/flycam_accessor"; export function* watchMaximumRenderableLayers(): Saga { function* warnMaybe(): Saga { const maximumLayerCountToRender = yield* select( @@ -31,3 +32,29 @@ export function* watchMaximumRenderableLayers(): Saga { yield* takeEvery(["WK_READY", "UPDATE_LAYER_SETTING", "UPDATE_DATASET_SETTING"], warnMaybe); } + +let downsamplingWarningDidShow = false; +export function* watchZ1Downsampling(): Saga { + function* maybeShowWarning(): Saga { + const currentRes = yield* select((state) => getCurrentResolution(state)); + const currentZoomStep = yield* select((state) => state.flycam.zoomStep); + const minVoxelPerPixel = 0.5; + + if (!downsamplingWarningDidShow) { + // checking the downsampled dimensions x and y + for (let i = 0; i < 2; i++) { + const voxelPerPixelXY = currentZoomStep / currentRes[i]; + if (voxelPerPixelXY < minVoxelPerPixel) { + Toast.warning(messages["dataset.z1_downsampling_hint"]); + downsamplingWarningDidShow = false; + } + } + } + } + yield* takeEvery("WK_READY", maybeShowWarning); + yield* call(sleep, 2000); + yield* takeEvery( + ["ZOOM_IN", "ZOOM_OUT", "ZOOM_BY_DELTA", "SET_ZOOM_STEP", "SET_STORED_LAYOUTS"], + maybeShowWarning, + ); +} diff --git a/frontend/javascripts/oxalis/model/sagas/root_saga.ts b/frontend/javascripts/oxalis/model/sagas/root_saga.ts index 746f4c6c87a..a8a3665c6cb 100644 --- a/frontend/javascripts/oxalis/model/sagas/root_saga.ts +++ b/frontend/javascripts/oxalis/model/sagas/root_saga.ts @@ -9,7 +9,7 @@ import SkeletontracingSagas from "oxalis/model/sagas/skeletontracing_saga"; import ErrorHandling from "libs/error_handling"; import handleMeshChanges from "oxalis/model/sagas/handle_mesh_changes"; import isosurfaceSaga from "oxalis/model/sagas/isosurface_saga"; -import { watchMaximumRenderableLayers } from "oxalis/model/sagas/dataset_saga"; +import { watchMaximumRenderableLayers, watchZ1Downsampling } from "oxalis/model/sagas/dataset_saga"; import { watchToolDeselection } from "oxalis/model/sagas/annotation_tool_saga"; import SettingsSaga from "oxalis/model/sagas/settings_saga"; import watchTasksAsync, { warnAboutMagRestriction } from "oxalis/model/sagas/task_saga"; @@ -47,6 +47,7 @@ function* restartableSaga(): Saga { ...AnnotationSagas.map((saga) => call(saga)), ...SaveSagas.map((saga) => call(saga)), ...VolumetracingSagas.map((saga) => call(saga)), + call(watchZ1Downsampling), ]); } catch (err) { rootSagaCrashed = true; From aa459aea8ffba0c42373e6ec768ecd7c3a24ae7f Mon Sep 17 00:00:00 2001 From: Arthur Hilbert Date: Thu, 2 Jun 2022 13:42:46 +0200 Subject: [PATCH 2/5] code review changes --- .../oxalis/model/sagas/dataset_saga.ts | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/frontend/javascripts/oxalis/model/sagas/dataset_saga.ts b/frontend/javascripts/oxalis/model/sagas/dataset_saga.ts index fd25a57a6f9..6e73461efc0 100644 --- a/frontend/javascripts/oxalis/model/sagas/dataset_saga.ts +++ b/frontend/javascripts/oxalis/model/sagas/dataset_saga.ts @@ -33,26 +33,40 @@ export function* watchMaximumRenderableLayers(): Saga { yield* takeEvery(["WK_READY", "UPDATE_LAYER_SETTING", "UPDATE_DATASET_SETTING"], warnMaybe); } -let downsamplingWarningDidShow = false; +let userClosedWarning = false; export function* watchZ1Downsampling(): Saga { function* maybeShowWarning(): Saga { const currentRes = yield* select((state) => getCurrentResolution(state)); const currentZoomStep = yield* select((state) => state.flycam.zoomStep); - const minVoxelPerPixel = 0.5; - - if (!downsamplingWarningDidShow) { - // checking the downsampled dimensions x and y + if (currentZoomStep < 1) { + // If the user has zoomed into the data, + // the rendering quality is expected to be relatively low. + // Don't show any warnings in that case. + return; + } + const minVoxelPerPixel = 0.2; + const setUserClosedWarningTrue = () => { + userClosedWarning = true; + }; + if (!userClosedWarning) { + // checking only the downsampled dimensions x and y for (let i = 0; i < 2; i++) { const voxelPerPixelXY = currentZoomStep / currentRes[i]; if (voxelPerPixelXY < minVoxelPerPixel) { - Toast.warning(messages["dataset.z1_downsampling_hint"]); - downsamplingWarningDidShow = false; + Toast.warning(messages["dataset.z1_downsampling_hint"], { + sticky: true, + key: "DOWNSAMPLING_CAUSES_BAD_QUALITY", + onClose: setUserClosedWarningTrue, + }); + } else { + Toast.close("DOWNSAMPLING_CAUSES_BAD_QUALITY"); } } } } yield* takeEvery("WK_READY", maybeShowWarning); yield* call(sleep, 2000); + yield* call(maybeShowWarning); yield* takeEvery( ["ZOOM_IN", "ZOOM_OUT", "ZOOM_BY_DELTA", "SET_ZOOM_STEP", "SET_STORED_LAYOUTS"], maybeShowWarning, From bd385439ee916f26e5a0714545d2ae43fb9ec919 Mon Sep 17 00:00:00 2001 From: Arthur Hilbert Date: Thu, 2 Jun 2022 13:52:08 +0200 Subject: [PATCH 3/5] updated unreleased changelog --- CHANGELOG.unreleased.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 3e8e84141bd..9abf81feeaf 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -11,6 +11,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released [Commits](https://github.com/scalableminds/webknossos/compare/22.06.0...HEAD) ### Added +Added a warning for when the resolution in the XY viewport on z=1-downsampled datasets becomes too chunky, explaining the problem and how to mitigate it. [#6255](https://github.com/scalableminds/webknossos/pull/6255) ### Changed From 67dc8f7ea6dcd29cd43f1f089de7d1a001d21f54 Mon Sep 17 00:00:00 2001 From: Philipp Otto Date: Thu, 2 Jun 2022 13:55:22 +0200 Subject: [PATCH 4/5] fix crashing dashboard; debounce z1 warnings and tweak quality threshold --- .../javascripts/oxalis/model/sagas/dataset_saga.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/frontend/javascripts/oxalis/model/sagas/dataset_saga.ts b/frontend/javascripts/oxalis/model/sagas/dataset_saga.ts index 6e73461efc0..1e21741b5f0 100644 --- a/frontend/javascripts/oxalis/model/sagas/dataset_saga.ts +++ b/frontend/javascripts/oxalis/model/sagas/dataset_saga.ts @@ -1,6 +1,6 @@ import type { Saga } from "oxalis/model/sagas/effect-generators"; import { select } from "oxalis/model/sagas/effect-generators"; -import { call, takeEvery } from "typed-redux-saga"; +import { call, take, takeEvery, takeLatest } from "typed-redux-saga"; import { sleep } from "libs/utils"; import { getEnabledLayers } from "oxalis/model/accessors/dataset_accessor"; import Toast from "libs/toast"; @@ -36,6 +36,9 @@ export function* watchMaximumRenderableLayers(): Saga { let userClosedWarning = false; export function* watchZ1Downsampling(): Saga { function* maybeShowWarning(): Saga { + // In combination with `takeLatest` sleeping here at the beginning of the saga + // effectively debounces the saga to avoid that it is executed unnecessarily often. + yield* call(sleep, 200); const currentRes = yield* select((state) => getCurrentResolution(state)); const currentZoomStep = yield* select((state) => state.flycam.zoomStep); if (currentZoomStep < 1) { @@ -44,7 +47,7 @@ export function* watchZ1Downsampling(): Saga { // Don't show any warnings in that case. return; } - const minVoxelPerPixel = 0.2; + const minVoxelPerPixel = 0.1; const setUserClosedWarningTrue = () => { userClosedWarning = true; }; @@ -64,10 +67,9 @@ export function* watchZ1Downsampling(): Saga { } } } - yield* takeEvery("WK_READY", maybeShowWarning); - yield* call(sleep, 2000); + yield* take("WK_READY"); yield* call(maybeShowWarning); - yield* takeEvery( + yield* takeLatest( ["ZOOM_IN", "ZOOM_OUT", "ZOOM_BY_DELTA", "SET_ZOOM_STEP", "SET_STORED_LAYOUTS"], maybeShowWarning, ); From 39ffe004cad233ef536b79e6d2e41ba1ccf4adcb Mon Sep 17 00:00:00 2001 From: Arthur Hilbert Date: Thu, 2 Jun 2022 14:14:06 +0200 Subject: [PATCH 5/5] code review changes 2 --- CHANGELOG.unreleased.md | 2 +- frontend/javascripts/messages.ts | 2 +- .../oxalis/model/sagas/dataset_saga.ts | 27 +++++++++---------- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 9abf81feeaf..51a272a263b 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -11,7 +11,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released [Commits](https://github.com/scalableminds/webknossos/compare/22.06.0...HEAD) ### Added -Added a warning for when the resolution in the XY viewport on z=1-downsampled datasets becomes too chunky, explaining the problem and how to mitigate it. [#6255](https://github.com/scalableminds/webknossos/pull/6255) +Added a warning for when the resolution in the XY viewport on z=1-downsampled datasets becomes too low, explaining the problem and how to mitigate it. [#6255](https://github.com/scalableminds/webknossos/pull/6255) ### Changed diff --git a/frontend/javascripts/messages.ts b/frontend/javascripts/messages.ts index 26a15016b62..28e4d7bd4fe 100644 --- a/frontend/javascripts/messages.ts +++ b/frontend/javascripts/messages.ts @@ -285,7 +285,7 @@ instead. Only enable this option if you understand its effect. All layers will n "dataset.resolution_mismatch": "This dataset contains multiple layers which differ in their resolution. Please convert the layers to make their resolutions match. Otherwise, rendering errors cannot be avoided.", "dataset.z1_downsampling_hint": - "The currently rendered quality is not optimal due to the available magnifications and the viewport arrangement. To improve the quality try to increase the size of the XY viewport (e.g., by maximizing it).", + "The currently rendered quality is not optimal due to the available magnifications and the viewport arrangement. To improve the quality try to increase the size of the XY viewport (e.g. by maximizing it).", "annotation.finish": "Are you sure you want to permanently finish this annotation?", "annotation.was_finished": "Annotation was archived", "annotation.no_fallback_data_included": diff --git a/frontend/javascripts/oxalis/model/sagas/dataset_saga.ts b/frontend/javascripts/oxalis/model/sagas/dataset_saga.ts index 1e21741b5f0..46d321d6013 100644 --- a/frontend/javascripts/oxalis/model/sagas/dataset_saga.ts +++ b/frontend/javascripts/oxalis/model/sagas/dataset_saga.ts @@ -48,22 +48,21 @@ export function* watchZ1Downsampling(): Saga { return; } const minVoxelPerPixel = 0.1; - const setUserClosedWarningTrue = () => { - userClosedWarning = true; - }; if (!userClosedWarning) { // checking only the downsampled dimensions x and y - for (let i = 0; i < 2; i++) { - const voxelPerPixelXY = currentZoomStep / currentRes[i]; - if (voxelPerPixelXY < minVoxelPerPixel) { - Toast.warning(messages["dataset.z1_downsampling_hint"], { - sticky: true, - key: "DOWNSAMPLING_CAUSES_BAD_QUALITY", - onClose: setUserClosedWarningTrue, - }); - } else { - Toast.close("DOWNSAMPLING_CAUSES_BAD_QUALITY"); - } + const showWarning = + currentZoomStep / currentRes[0] < minVoxelPerPixel || + currentZoomStep / currentRes[1] < minVoxelPerPixel; + if (showWarning) { + Toast.warning(messages["dataset.z1_downsampling_hint"], { + sticky: true, + key: "DOWNSAMPLING_CAUSES_BAD_QUALITY", + onClose: () => { + userClosedWarning = true; + }, + }); + } else { + Toast.close("DOWNSAMPLING_CAUSES_BAD_QUALITY"); } } }