From c0fab5a9e6c096f49d57b8a4a0b0ffcfe978fc56 Mon Sep 17 00:00:00 2001 From: Charlie Meister Date: Mon, 2 Dec 2024 11:14:42 +0100 Subject: [PATCH] Rename resolution to mag in local variables (#8168) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * rename local vars in ai_model_list_view, create_explorative_modal, model_initialization, api_latest and plane_material_factory * rename to mag up to volume interpolation saga * continue renaming local vars * rename more occurences of resolution to mag * change ServerNode resolution to mag * remove shader code edit * fix test: rename resolution to mag in volumetracing saga spec * rename resolution in create node action * rename resolution to mag in DataLayer type * revert shader code edit * add changelog * rename resolution to mag in MutableNode and add type checking file for skeletontracingreducer test * change dummy trees to test compatibility of backend and frontend CreadeNodeAction * fix createnode method * rename resolution to magnification in shader relevant code * address review: revert one change and rename resInfo * lint * refresh annotations e2e snapshot --------- Co-authored-by: Michael Büßemeyer --- CHANGELOG.unreleased.md | 1 + .../admin/tasktype/task_type_create_view.tsx | 16 +-- .../admin/voxelytics/ai_model_list_view.tsx | 4 +- .../create_explorative_modal.tsx | 58 ++++----- frontend/javascripts/oxalis/api/api_latest.ts | 50 ++++---- .../controller/combinations/move_handlers.ts | 4 +- .../materials/plane_material_factory.ts | 42 +++--- .../javascripts/oxalis/geometries/skeleton.ts | 4 +- .../model/accessors/dataset_accessor.ts | 30 ++--- .../oxalis/model/accessors/flycam_accessor.ts | 80 ++++++------ .../oxalis/model/accessors/tool_accessor.ts | 7 +- .../model/accessors/volumetracing_accessor.ts | 32 ++--- .../model/actions/skeletontracing_actions.tsx | 4 +- .../model/bucket_data_handling/bucket.ts | 10 +- .../model/bucket_data_handling/data_cube.ts | 32 ++--- .../layer_rendering_manager.ts | 12 +- .../prefetch_strategy_arbitrary.ts | 8 +- .../prefetch_strategy_plane.ts | 16 +-- .../bucket_data_handling/wkstore_adapter.ts | 17 +-- .../javascripts/oxalis/model/data_layer.ts | 8 +- .../model/helpers/generate_dummy_trees.ts | 2 +- .../oxalis/model/helpers/mag_info.ts | 52 ++++---- .../oxalis/model/helpers/nml_helpers.ts | 6 +- .../model/helpers/position_converter.ts | 73 +++++------ .../model/reducers/skeletontracing_reducer.ts | 13 +- .../skeletontracing_reducer_helpers.ts | 6 +- .../oxalis/model/sagas/clip_histogram_saga.ts | 8 +- .../oxalis/model/sagas/dataset_saga.ts | 6 +- .../oxalis/model/sagas/mesh_saga.ts | 38 +++--- .../oxalis/model/sagas/min_cut_saga.ts | 52 +++----- .../oxalis/model/sagas/prefetch_saga.ts | 16 +-- .../oxalis/model/sagas/proofread_saga.ts | 6 +- .../sagas/quick_select_heuristic_saga.ts | 16 +-- .../model/sagas/quick_select_ml_saga.ts | 26 ++-- .../oxalis/model/sagas/save_saga.ts | 8 +- .../oxalis/model/sagas/update_actions.ts | 15 ++- .../oxalis/model/sagas/volume/helpers.ts | 48 +++---- .../sagas/volume/volume_interpolation_saga.ts | 34 ++--- .../oxalis/model/sagas/volumetracing_saga.tsx | 19 ++- .../volume_annotation_sampling.ts | 37 +++--- .../oxalis/model_initialization.ts | 10 +- .../javascripts/oxalis/shaders/coords.glsl.ts | 20 +-- .../oxalis/shaders/main_data_shaders.glsl.ts | 12 +- .../oxalis/shaders/texture_access.glsl.ts | 8 +- frontend/javascripts/oxalis/store.ts | 2 +- .../view/action-bar/download_modal_view.tsx | 12 +- .../view/action-bar/starting_job_modals.tsx | 2 +- .../oxalis/view/action-bar/toolbar_view.tsx | 9 +- .../javascripts/oxalis/view/context_menu.tsx | 13 +- .../oxalis/view/jobs/train_ai_model.tsx | 4 +- .../left-border-tabs/layer_settings_tab.tsx | 30 ++--- .../modals/add_volume_layer_modal.tsx | 26 ++-- .../connectome_tab/connectome_view.tsx | 2 +- .../dataset_info_tab_view.tsx | 26 ++-- .../segments_tab/segment_statistics_modal.tsx | 13 +- .../segments_tab/segments_view.tsx | 46 +++---- .../javascripts/oxalis/view/statusbar.tsx | 10 +- .../workers/async_bucket_picker.worker.ts | 8 +- frontend/javascripts/router.tsx | 12 +- .../backend-snapshot-tests/annotations.e2e.ts | 2 + .../test/fixtures/{resolutions.ts => mags.ts} | 0 .../test/geometries/skeleton.spec.ts | 4 +- frontend/javascripts/test/libs/nml.spec.ts | 2 +- .../test/model/binary/cube.spec.ts | 4 +- .../test/model/flycam_accessors.spec.ts | 8 +- .../test/model/model_resolutions.spec.ts | 32 ++--- .../volume_annotation_sampling.spec.ts | 26 ++-- .../reducers/skeletontracing_reducer.spec.ts | 88 ++++++------- .../volumetracing/volumetracing_saga.spec.ts | 20 +-- .../test/shaders/shader_syntax.spec.ts | 14 +- .../annotations.e2e.js.md | 120 +++++++++--------- .../annotations.e2e.js.snap | Bin 16823 -> 16824 bytes .../stylesheets/trace_view/_tracing_view.less | 2 +- 73 files changed, 721 insertions(+), 782 deletions(-) rename frontend/javascripts/test/fixtures/{resolutions.ts => mags.ts} (100%) diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 8133a22b57d..fa39be36db5 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -15,6 +15,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released - Added the total volume of a dataset to a tooltip in the dataset info tab. [#8229](https://github.com/scalableminds/webknossos/pull/8229) ### Changed +- Renamed "resolution" to "magnification" in more places within the codebase, including local variables. [#8168](https://github.com/scalableminds/webknossos/pull/8168) - Reading image files on datastore filesystem is now done asynchronously. [#8126](https://github.com/scalableminds/webknossos/pull/8126) - Datasets can now be renamed and can have duplicate names. [#8075](https://github.com/scalableminds/webknossos/pull/8075) - Improved error messages for starting jobs on datasets from other organizations. [#8181](https://github.com/scalableminds/webknossos/pull/8181) diff --git a/frontend/javascripts/admin/tasktype/task_type_create_view.tsx b/frontend/javascripts/admin/tasktype/task_type_create_view.tsx index ea68f941f5d..081a1109ccb 100644 --- a/frontend/javascripts/admin/tasktype/task_type_create_view.tsx +++ b/frontend/javascripts/admin/tasktype/task_type_create_view.tsx @@ -36,7 +36,7 @@ type Props = { }; type FormValues = { - isResolutionRestricted: boolean; + isMagRestricted: boolean; summary: string; teamId: string; description: string; @@ -103,7 +103,7 @@ function TaskTypeCreateView({ taskTypeId, history }: Props) { const taskType = taskTypeId ? await getTaskType(taskTypeId) : null; const defaultValues = { - isResolutionRestricted: false, + isMagRestricted: false, settings: { somaClickingAllowed: true, branchPointsAllowed: true, @@ -131,7 +131,7 @@ function TaskTypeCreateView({ taskTypeId, history }: Props) { } if (taskType?.settings.magRestrictions.min || taskType?.settings.magRestrictions.max) - form.setFieldValue(["isResolutionRestricted"], true); + form.setFieldValue(["isMagRestricted"], true); } async function onFinish(formValues: FormValues) { @@ -139,7 +139,7 @@ function TaskTypeCreateView({ taskTypeId, history }: Props) { settings, teamId, recommendedConfiguration, - isResolutionRestricted: _isResolutionRestricted, + isMagRestricted: _isMagRestricted, ...rest } = formValues; const teamName = teams.find((team) => team.id === teamId)!["name"]; @@ -411,7 +411,7 @@ function TaskTypeCreateView({ taskTypeId, history }: Props) { - !prevValues.isResolutionRestricted || - prevValues.isResolutionRestricted !== curValues.isResolutionRestricted + !prevValues.isMagRestricted || + prevValues.isMagRestricted !== curValues.isMagRestricted } > {({ getFieldValue }) => - getFieldValue(["isResolutionRestricted"]) ? ( + getFieldValue(["isMagRestricted"]) ? (
void }) { const volumeTracingIndex = volumeTracings.findIndex( (tracing) => tracing.tracingId === annotationLayer.tracingId, ); - const resolutions = volumeTracingMags[volumeTracingIndex] || ([[1, 1, 1]] as Vector3[]); - return getMagInfo(resolutions).getFinestMag(); + const mags = volumeTracingMags[volumeTracingIndex] || ([[1, 1, 1]] as Vector3[]); + return getMagInfo(mags).getFinestMag(); } else { const segmentationLayer = getSegmentationLayerByName(dataset, layerName); return getMagInfo(segmentationLayer.resolutions).getFinestMag(); diff --git a/frontend/javascripts/dashboard/advanced_dataset/create_explorative_modal.tsx b/frontend/javascripts/dashboard/advanced_dataset/create_explorative_modal.tsx index 094d6bb5d06..de387d053d3 100644 --- a/frontend/javascripts/dashboard/advanced_dataset/create_explorative_modal.tsx +++ b/frontend/javascripts/dashboard/advanced_dataset/create_explorative_modal.tsx @@ -90,24 +90,24 @@ export function RestrictMagnificationSlider({ magIndices, setMagIndices, }: RestrictMagnificationSliderProps) { - let highestResolutionIndex = magInfo.getCoarsestMagIndex(); - let lowestResolutionIndex = magInfo.getFinestMagIndex(); + let highestMagIndex = magInfo.getCoarsestMagIndex(); + let lowestMagIndex = magInfo.getFinestMagIndex(); if (selectedSegmentationLayer != null) { - const datasetFallbackLayerResolutionInfo = getMagInfo(selectedSegmentationLayer.resolutions); - highestResolutionIndex = datasetFallbackLayerResolutionInfo.getCoarsestMagIndex(); - lowestResolutionIndex = datasetFallbackLayerResolutionInfo.getFinestMagIndex(); + const datasetFallbackLayerMagInfo = getMagInfo(selectedSegmentationLayer.resolutions); + highestMagIndex = datasetFallbackLayerMagInfo.getCoarsestMagIndex(); + lowestMagIndex = datasetFallbackLayerMagInfo.getFinestMagIndex(); } - const highResolutionIndex = Math.min(highestResolutionIndex, magIndices[1]); - const lowResolutionIndex = Math.max(lowestResolutionIndex, magIndices[0]); + const highMagIndex = Math.min(highestMagIndex, magIndices[1]); + const lowMagIndex = Math.max(lowestMagIndex, magIndices[0]); - // biome-ignore lint/correctness/useExhaustiveDependencies: setResolutionIndices should also be added to the dependencies. Consider fixing this. + // biome-ignore lint/correctness/useExhaustiveDependencies: setMagIndices should also be added to the dependencies. Consider fixing this. useEffect(() => { - setMagIndices([lowestResolutionIndex, highestResolutionIndex]); - }, [lowestResolutionIndex, highestResolutionIndex]); + setMagIndices([lowestMagIndex, highestMagIndex]); + }, [lowestMagIndex, highestMagIndex]); - return lowestResolutionIndex < highestResolutionIndex ? ( + return lowestMagIndex < highestMagIndex ? (
- {magInfo.getMagByIndexOrThrow(lowResolutionIndex).join("-")} + {magInfo.getMagByIndexOrThrow(lowMagIndex).join("-")}
setMagIndices(value)} range step={1} - min={lowestResolutionIndex} - max={highestResolutionIndex} - value={[lowResolutionIndex, highResolutionIndex]} + min={lowestMagIndex} + max={highestMagIndex} + value={[lowMagIndex, highMagIndex]} style={{ flexGrow: 1, }} @@ -157,7 +157,7 @@ export function RestrictMagnificationSlider({ textAlign: "right", }} > - {magInfo.getMagByIndexOrThrow(highResolutionIndex).join("-")} + {magInfo.getMagByIndexOrThrow(highMagIndex).join("-")} @@ -167,7 +167,7 @@ export function RestrictMagnificationSlider({ function CreateExplorativeModal({ datasetId, onClose }: Props) { const dataset = useFetch(() => getDataset(datasetId), null, [datasetId]); const [annotationType, setAnnotationType] = useState("hybrid"); - const [userDefinedResolutionIndices, setUserDefinedResolutionIndices] = useState([0, 10000]); + const [userDefinedMagIndices, setUserDefinedMagIndices] = useState([0, 10000]); const [selectedSegmentationLayerName, setSelectedSegmentationLayerName] = useState< string | undefined >(undefined); @@ -194,22 +194,22 @@ function CreateExplorativeModal({ datasetId, onClose }: Props) { selectedSegmentationLayer != null ? `&fallbackLayerName=${selectedSegmentationLayer.name}` : ""; - const resolutionInfo = + const magInfo = selectedSegmentationLayer == null ? getSomeMagInfoForDataset(dataset) : getMagInfo(selectedSegmentationLayer.resolutions); - const highestResolutionIndex = resolutionInfo.getCoarsestMagIndex(); - const lowestResolutionIndex = resolutionInfo.getFinestMagIndex(); + const highestMagIndex = magInfo.getCoarsestMagIndex(); + const lowestMagIndex = magInfo.getFinestMagIndex(); - const highResolutionIndex = Math.min(highestResolutionIndex, userDefinedResolutionIndices[1]); - const lowResolutionIndex = Math.max(lowestResolutionIndex, userDefinedResolutionIndices[0]); - const resolutionSlider = + const highMagIndex = Math.min(highestMagIndex, userDefinedMagIndices[1]); + const lowMagIndex = Math.max(lowestMagIndex, userDefinedMagIndices[0]); + const magSlider = annotationType !== "skeleton" ? ( ) : null; modalContent = ( @@ -235,7 +235,7 @@ function CreateExplorativeModal({ datasetId, onClose }: Props) { /> ) : null} - {resolutionSlider} + {magSlider}
diff --git a/frontend/javascripts/oxalis/api/api_latest.ts b/frontend/javascripts/oxalis/api/api_latest.ts index f59747ff279..924460157f8 100644 --- a/frontend/javascripts/oxalis/api/api_latest.ts +++ b/frontend/javascripts/oxalis/api/api_latest.ts @@ -670,15 +670,13 @@ class TracingApi { ); } - const resolutionInfo = getMagInfo( - getLayerByName(state.dataset, segmentationLayerName).resolutions, - ); + const magInfo = getMagInfo(getLayerByName(state.dataset, segmentationLayerName).resolutions); const theoreticalMagIndex = getActiveMagIndexForLayer(state, segmentationLayerName); - const existingMagIndex = resolutionInfo.getIndexOrClosestHigherIndex(theoreticalMagIndex); + const existingMagIndex = magInfo.getIndexOrClosestHigherIndex(theoreticalMagIndex); if (existingMagIndex == null) { throw new Error("The index of the current mag could not be found."); } - const currentMag = resolutionInfo.getMagByIndex(existingMagIndex); + const currentMag = magInfo.getMagByIndex(existingMagIndex); if (currentMag == null) { throw new Error("No mag could be found."); } @@ -1843,8 +1841,8 @@ class DataApi { zoomStep = _zoomStep; } else { const layer = getLayerByName(Store.getState().dataset, layerName); - const resolutionInfo = getMagInfo(layer.resolutions); - zoomStep = resolutionInfo.getFinestMagIndex(); + const magInfo = getMagInfo(layer.resolutions); + zoomStep = magInfo.getFinestMagIndex(); } const cube = this.model.getCubeByLayerName(layerName); @@ -1900,19 +1898,19 @@ class DataApi { additionalCoordinates: AdditionalCoordinate[] | null = null, ) { const layer = getLayerByName(Store.getState().dataset, layerName); - const resolutionInfo = getMagInfo(layer.resolutions); + const magInfo = getMagInfo(layer.resolutions); let zoomStep; if (_zoomStep != null) { zoomStep = _zoomStep; } else { - zoomStep = resolutionInfo.getFinestMagIndex(); + zoomStep = magInfo.getFinestMagIndex(); } - const resolutions = resolutionInfo.getDenseMags(); + const mags = magInfo.getDenseMags(); const bucketAddresses = this.getBucketAddressesInCuboid( mag1Bbox, - resolutions, + mags, zoomStep, additionalCoordinates, ); @@ -1927,13 +1925,13 @@ class DataApi { bucketAddresses.map((addr) => this.getLoadedBucket(layerName, addr)), ); const { elementClass } = getLayerByName(Store.getState().dataset, layerName); - return this.cutOutCuboid(buckets, mag1Bbox, elementClass, resolutions, zoomStep); + return this.cutOutCuboid(buckets, mag1Bbox, elementClass, mags, zoomStep); } async getViewportData( viewport: OrthoView, layerName: string, - maybeResolutionIndex: number | null | undefined, + maybeMagIndex: number | null | undefined, additionalCoordinates: AdditionalCoordinate[] | null, ) { const state = Store.getState(); @@ -1946,11 +1944,11 @@ class DataApi { viewport, ); const layer = getLayerByName(state.dataset, layerName); - const resolutionInfo = getMagInfo(layer.resolutions); - if (maybeResolutionIndex == null) { - maybeResolutionIndex = getActiveMagIndexForLayer(state, layerName); + const magInfo = getMagInfo(layer.resolutions); + if (maybeMagIndex == null) { + maybeMagIndex = getActiveMagIndexForLayer(state, layerName); } - const zoomStep = resolutionInfo.getClosestExistingIndex(maybeResolutionIndex); + const zoomStep = magInfo.getClosestExistingIndex(maybeMagIndex); const min = dimensions.transDim( V3.sub([curU, curV, curW], [halfViewportExtentU, halfViewportExtentV, 0]), @@ -1961,10 +1959,10 @@ class DataApi { viewport, ); - const resolution = resolutionInfo.getMagByIndexOrThrow(zoomStep); - const resolutionUVX = dimensions.transDim(resolution, viewport); - const widthInVoxel = Math.ceil(halfViewportExtentU / resolutionUVX[0]); - const heightInVoxel = Math.ceil(halfViewportExtentV / resolutionUVX[1]); + const mag = magInfo.getMagByIndexOrThrow(zoomStep); + const magUVX = dimensions.transDim(mag, viewport); + const widthInVoxel = Math.ceil(halfViewportExtentU / magUVX[0]); + const heightInVoxel = Math.ceil(halfViewportExtentV / magUVX[1]); if (widthInVoxel * heightInVoxel > 1024 ** 2) { throw new Error( "Requested data for viewport cannot be loaded, since the amount of data is too large for the available magnification. Please zoom in further or ensure that coarser magnifications are available.", @@ -2036,12 +2034,12 @@ class DataApi { magnifications: Array, zoomStep: number, ): TypedArray { - const resolution = magnifications[zoomStep]; + const mag = magnifications[zoomStep]; // All calculations in this method are in zoomStep-space, so in global coordinates which are divided // by the mag - const topLeft = scaleGlobalPositionWithMagnification(bbox.min, resolution); + const topLeft = scaleGlobalPositionWithMagnification(bbox.min, mag); // Ceil the bounding box bottom right instead of flooring, because it is exclusive - const bottomRight = scaleGlobalPositionWithMagnification(bbox.max, resolution, true); + const bottomRight = scaleGlobalPositionWithMagnification(bbox.max, mag, true); const extent: Vector3 = V3.sub(bottomRight, topLeft); const [TypedArrayClass, channelCount] = getConstructorForElementClass(elementClass); const result = new TypedArrayClass(channelCount * extent[0] * extent[1] * extent[2]); @@ -2107,8 +2105,8 @@ class DataApi { magnification?: Vector3, ): string { const { dataset } = Store.getState(); - const resolutionInfo = getMagInfo(getLayerByName(dataset, layerName, true).resolutions); - magnification = magnification || resolutionInfo.getFinestMag(); + const magInfo = getMagInfo(getLayerByName(dataset, layerName, true).resolutions); + magnification = magnification || magInfo.getFinestMag(); const magString = magnification.join("-"); return ( diff --git a/frontend/javascripts/oxalis/controller/combinations/move_handlers.ts b/frontend/javascripts/oxalis/controller/combinations/move_handlers.ts index 60727fe4ba8..1029b08f6f1 100644 --- a/frontend/javascripts/oxalis/controller/combinations/move_handlers.ts +++ b/frontend/javascripts/oxalis/controller/combinations/move_handlers.ts @@ -49,9 +49,9 @@ export const moveW = (deltaW: number, oneSlide: boolean): void => { // The following logic might not always make sense when having layers // that are transformed each. Todo: Rethink / adapt the logic once // problems occur. Tracked in #6926. - const { representativeResolution } = getActiveMagInfo(Store.getState()); + const { representativeMag } = getActiveMagInfo(Store.getState()); const wDim = Dimensions.getIndices(activeViewport)[2]; - const wStep = (representativeResolution || [1, 1, 1])[wDim]; + const wStep = (representativeMag || [1, 1, 1])[wDim]; Store.dispatch( moveFlycamOrthoAction( Dimensions.transDim([0, 0, Math.sign(deltaW) * Math.max(1, wStep)], activeViewport), diff --git a/frontend/javascripts/oxalis/geometries/materials/plane_material_factory.ts b/frontend/javascripts/oxalis/geometries/materials/plane_material_factory.ts index 4005d0e0f14..87c5a6220c7 100644 --- a/frontend/javascripts/oxalis/geometries/materials/plane_material_factory.ts +++ b/frontend/javascripts/oxalis/geometries/materials/plane_material_factory.ts @@ -484,12 +484,12 @@ class PlaneMaterialFactory { const state = Store.getState(); for (const [layerName, activeMagIndex] of Object.entries(activeMagIndices)) { const layer = getLayerByName(state.dataset, layerName); - const resolutionInfo = getMagInfo(layer.resolutions); + const magInfo = getMagInfo(layer.resolutions); // If the active mag doesn't exist, a fallback mag is likely rendered. Use that // to determine a representative mag. - const suitableMagIndex = resolutionInfo.getIndexOrClosestHigherIndex(activeMagIndex); + const suitableMagIndex = magInfo.getIndexOrClosestHigherIndex(activeMagIndex); const suitableMag = - suitableMagIndex != null ? resolutionInfo.getMagByIndex(suitableMagIndex) : null; + suitableMagIndex != null ? magInfo.getMagByIndex(suitableMagIndex) : null; const hasTransform = !_.isEqual( getTransformsForLayer( @@ -565,24 +565,24 @@ class PlaneMaterialFactory { this.storePropertyUnsubscribers.push( listenToStoreProperty( (storeState) => getMagInfoByLayer(storeState.dataset), - (resolutionInfosByLayer) => { - const allDenseResolutions = Object.values(resolutionInfosByLayer).map((resInfo) => - resInfo.getDenseMags(), + (magInfosByLayer) => { + const allDenseMags = Object.values(magInfosByLayer).map((magInfo) => + magInfo.getDenseMags(), ); - const flatResolutions = _.flattenDeep(allDenseResolutions); - this.uniforms.allResolutions = { - value: flatResolutions, + const flatMags = _.flattenDeep(allDenseMags); + this.uniforms.allMagnifications = { + value: flatMags, }; let cumSum = 0; - const resolutionCountCumSum = [cumSum]; - for (const denseResolutions of allDenseResolutions) { - cumSum += denseResolutions.length; - resolutionCountCumSum.push(cumSum); + const magCountCumSum = [cumSum]; + for (const denseMags of allDenseMags) { + cumSum += denseMags.length; + magCountCumSum.push(cumSum); } - this.uniforms.resolutionCountCumSum = { - value: resolutionCountCumSum, + this.uniforms.magnificationCountCumSum = { + value: magCountCumSum, }; }, true, @@ -1099,7 +1099,7 @@ class PlaneMaterialFactory { colorLayerNames, segmentationLayerNames, textureLayerInfos, - resolutionsCount: this.getTotalMagCount(), + magnificationsCount: this.getTotalMagCount(), voxelSizeFactor, isOrthogonal: this.isOrthogonal, tpsTransformPerLayer: this.scaledTpsInvPerLayer, @@ -1112,11 +1112,11 @@ class PlaneMaterialFactory { getTotalMagCount(): number { const storeState = Store.getState(); - const allDenseResolutions = Object.values(getMagInfoByLayer(storeState.dataset)).map( - (resInfo) => resInfo.getDenseMags(), + const allDenseMags = Object.values(getMagInfoByLayer(storeState.dataset)).map((magInfo) => + magInfo.getDenseMags(), ); - const flatResolutions = _.flatten(allDenseResolutions); - return flatResolutions.length; + const flatMags = _.flatten(allDenseMags); + return flatMags.length; } getVertexShader(): string { @@ -1134,7 +1134,7 @@ class PlaneMaterialFactory { colorLayerNames, segmentationLayerNames, textureLayerInfos, - resolutionsCount: this.getTotalMagCount(), + magnificationsCount: this.getTotalMagCount(), voxelSizeFactor, isOrthogonal: this.isOrthogonal, tpsTransformPerLayer: this.scaledTpsInvPerLayer, diff --git a/frontend/javascripts/oxalis/geometries/skeleton.ts b/frontend/javascripts/oxalis/geometries/skeleton.ts index 3b4c8968ae0..eb4af6c3f14 100644 --- a/frontend/javascripts/oxalis/geometries/skeleton.ts +++ b/frontend/javascripts/oxalis/geometries/skeleton.ts @@ -13,7 +13,7 @@ import NodeShader, { import Store from "oxalis/throttled_store"; import * as Utils from "libs/utils"; import type { AdditionalCoordinate } from "types/api_flow_types"; -import type { UpdateActionNode } from "oxalis/model/sagas/update_actions"; +import type { CreateActionNode, UpdateActionNode } from "oxalis/model/sagas/update_actions"; const MAX_CAPACITY = 1000; @@ -518,7 +518,7 @@ class Skeleton { /** * Creates a new node in a WebGL buffer. */ - createNode(treeId: number, node: Node | UpdateActionNode) { + createNode(treeId: number, node: Node | UpdateActionNode | CreateActionNode) { const id = this.combineIds(node.id, treeId); this.create( id, diff --git a/frontend/javascripts/oxalis/model/accessors/dataset_accessor.ts b/frontend/javascripts/oxalis/model/accessors/dataset_accessor.ts index fc863b0a36b..90fac26ea8f 100644 --- a/frontend/javascripts/oxalis/model/accessors/dataset_accessor.ts +++ b/frontend/javascripts/oxalis/model/accessors/dataset_accessor.ts @@ -79,46 +79,46 @@ export const getMagnificationUnion = memoizeOne((dataset: APIDataset): Array Number(a) - Number(b)) .map((el) => Number(el)); - return keys.map((key) => resolutionUnionDict[key]); + return keys.map((key) => magUnionDict[key]); }); export function getWidestMags(dataset: APIDataset): Vector3[] { - const allLayerResolutions = dataset.dataSource.dataLayers.map((layer) => + const allLayerMags = dataset.dataSource.dataLayers.map((layer) => convertToDenseMag(layer.resolutions), ); - return _.maxBy(allLayerResolutions, (resolutions) => resolutions.length) || []; + return _.maxBy(allLayerMags, (mags) => mags.length) || []; } export const getSomeMagInfoForDataset = memoizeOne((dataset: APIDataset): MagInfo => { - const resolutionUnion = getMagnificationUnion(dataset); - const areMagsDistinct = resolutionUnion.every((mags) => mags.length <= 1); + const magUnion = getMagnificationUnion(dataset); + const areMagsDistinct = magUnion.every((mags) => mags.length <= 1); if (areMagsDistinct) { - return new MagInfo(resolutionUnion.map((mags) => mags[0])); + return new MagInfo(magUnion.map((mags) => mags[0])); } else { return new MagInfo(getWidestMags(dataset)); } diff --git a/frontend/javascripts/oxalis/model/accessors/flycam_accessor.ts b/frontend/javascripts/oxalis/model/accessors/flycam_accessor.ts index ac78958929c..c3040f57e8f 100644 --- a/frontend/javascripts/oxalis/model/accessors/flycam_accessor.ts +++ b/frontend/javascripts/oxalis/model/accessors/flycam_accessor.ts @@ -102,12 +102,12 @@ function calculateTotalBucketCountForZoomLevel( return counter; } -// This function returns the maximum zoom value in which a given magnification (resolutionIndex) +// This function returns the maximum zoom value in which a given magnification (magIndex) // can be rendered without exceeding the necessary bucket capacity. // Similar to other functions in this module, the function name is prefixed with _ which means // that there is a memoized function as a counterpart (which is not prefixed with _). // Example: -// The function might return 1.3 for resolutionIndex 0, which means that until a zoom value of 1.3 +// The function might return 1.3 for magIndex 0, which means that until a zoom value of 1.3 // the first magnification can still be rendered. // For magIndex 1, the function might return 1.5 etc. // These values are used to determine the appropriate magnification for a given zoom value (e.g., a zoom value of 1.4 @@ -150,7 +150,7 @@ export function _getMaximumZoomForAllMags( Math.log(maxSupportedZoomValue) / Math.log(ZOOM_STEP_INTERVAL) + ZOOM_IN_START_EXPONENT; let currentIterationCount = 0; - let currentResolutionIndex = 0; + let currentMagIndex = 0; const maxZoomValueThresholds = []; if (typeof maximumCapacity !== "number" || isNaN(maximumCapacity)) { @@ -159,13 +159,13 @@ export function _getMaximumZoomForAllMags( throw new Error("Internal error: Invalid maximum capacity provided."); } - while (currentIterationCount < maximumIterationCount && currentResolutionIndex < mags.length) { + while (currentIterationCount < maximumIterationCount && currentMagIndex < mags.length) { const nextZoomValue = currentMaxZoomValue * ZOOM_STEP_INTERVAL; const nextCapacity = calculateTotalBucketCountForZoomLevel( viewMode, loadingStrategy, mags, - currentResolutionIndex, + currentMagIndex, nextZoomValue, viewportRects, unzoomedMatrix, @@ -177,7 +177,7 @@ export function _getMaximumZoomForAllMags( if (nextCapacity > maximumCapacity) { maxZoomValueThresholds.push(currentMaxZoomValue); - currentResolutionIndex++; + currentMagIndex++; } currentMaxZoomValue = nextZoomValue; @@ -353,13 +353,13 @@ export function getActiveMagIndexForLayer(state: OxalisState, layerName: string) because no appropriate mag exists. */ export function getCurrentMag(state: OxalisState, layerName: string): Vector3 | null | undefined { - const resolutionInfo = getMagInfo(getLayerByName(state.dataset, layerName).resolutions); + const magInfo = getMagInfo(getLayerByName(state.dataset, layerName).resolutions); const magIndex = getActiveMagIndexForLayer(state, layerName); - const existingMagIndex = resolutionInfo.getIndexOrClosestHigherIndex(magIndex); + const existingMagIndex = magInfo.getIndexOrClosestHigherIndex(magIndex); if (existingMagIndex == null) { return null; } - return resolutionInfo.getMagByIndex(existingMagIndex); + return magInfo.getMagByIndex(existingMagIndex); } function _getValidZoomRangeForUser(state: OxalisState): [number, number] { @@ -377,14 +377,14 @@ function _getValidZoomRangeForUser(state: OxalisState): [number, number] { export const getValidZoomRangeForUser = reuseInstanceOnEquality(_getValidZoomRangeForUser); -export function getMaxZoomValueForResolution( +export function getMaxZoomValueForMag( state: OxalisState, layerName: string, - targetResolution: Vector3, + targetMag: Vector3, ): number { - const targetResolutionIdentifier = Math.max(...targetResolution); + const targetMagIdentifier = Math.max(...targetMag); // Extract the max value from the range - const maxZoom = getValidZoomRangeForMag(state, layerName, targetResolutionIdentifier)[1]; + const maxZoom = getValidZoomRangeForMag(state, layerName, targetMagIdentifier)[1]; if (maxZoom == null) { // This should never happen as long as a valid target mag is passed to this function. throw new Error("Zoom range could not be determined for target magnification."); @@ -395,19 +395,19 @@ export function getMaxZoomValueForResolution( function getValidZoomRangeForMag( state: OxalisState, layerName: string, - resolutionIdentifier: number, + magIdentifier: number, ): Vector2 | [null, null] { const maximumZoomSteps = getMaximumZoomForAllMagsFromStore(state, layerName); // maximumZoomSteps is densely defined for all mags starting from magnification 1,1,1. // Therefore, we can use log2 as an index. - const targetResolutionIndex = Math.log2(resolutionIdentifier); + const targetMagIndex = Math.log2(magIdentifier); - if (targetResolutionIndex > maximumZoomSteps.length) { + if (targetMagIndex > maximumZoomSteps.length) { return [null, null]; } - const max = maximumZoomSteps[targetResolutionIndex]; - const min = targetResolutionIndex > 0 ? maximumZoomSteps[targetResolutionIndex - 1] : 0; + const max = maximumZoomSteps[targetMagIndex]; + const min = targetMagIndex > 0 ? maximumZoomSteps[targetMagIndex - 1] : 0; // Since the min of the requested range is derived from the max of the previous range, // we add a small delta so that the returned range is inclusive. return [min + Number.EPSILON, max]; @@ -424,7 +424,7 @@ export function getValidTaskZoomRange( baseDatasetViewConfiguration.zoom.minimum, Number.POSITIVE_INFINITY, ] as Vector2; - const { magRestrictions: resolutionRestrictions } = state.tracing.restrictions; + const { magRestrictions } = state.tracing.restrictions; // We use the first color layer as a heuristic to check the validity of the zoom range, // as we don't know to which layer a restriction is meant to be applied. // If the layers don't have any transforms, the layer choice doesn't matter, anyway. @@ -442,19 +442,19 @@ export function getValidTaskZoomRange( return ( (magIdentifier == null ? defaultRange[idx] - : // If the magIdentifier is defined, but doesn't match any resolution, we default to the defaultRange values + : // If the magIdentifier is defined, but doesn't match any mag, we default to the defaultRange values getValidZoomRangeForMag(state, firstColorLayerName, magIdentifier)[idx]) || defaultRange[idx] ); } - const min = getMinMax(resolutionRestrictions.min, true); - const max = getMinMax(resolutionRestrictions.max, false); + const min = getMinMax(magRestrictions.min, true); + const max = getMinMax(magRestrictions.max, false); return [min, max]; } export function isMagRestrictionViolated(state: OxalisState): boolean { - const { magRestrictions: resolutionRestrictions } = state.tracing.restrictions; + const { magRestrictions } = state.tracing.restrictions; // We use the first color layer as a heuristic to check the validity of the zoom range, // as we don't know to which layer a restriction is meant to be applied. // If the layers don't have any transforms, the layer choice doesn't matter, anyway. @@ -465,11 +465,11 @@ export function isMagRestrictionViolated(state: OxalisState): boolean { } const zoomStep = getActiveMagIndexForLayer(state, firstColorLayerName); - if (resolutionRestrictions.min != null && zoomStep < Math.log2(resolutionRestrictions.min)) { + if (magRestrictions.min != null && zoomStep < Math.log2(magRestrictions.min)) { return true; } - if (resolutionRestrictions.max != null && zoomStep > Math.log2(resolutionRestrictions.max)) { + if (magRestrictions.max != null && zoomStep > Math.log2(magRestrictions.max)) { return true; } @@ -578,10 +578,10 @@ function _getUnrenderableLayerInfosForCurrentZoom( .map((layer: DataLayerType) => ({ layer, activeMagIdx: activeMagIndices[layer.name], - resolutionInfo: getMagInfo(layer.resolutions), + magInfo: getMagInfo(layer.resolutions), })) - .filter(({ activeMagIdx, resolutionInfo }) => { - const isPresent = resolutionInfo.hasIndex(activeMagIdx); + .filter(({ activeMagIdx, magInfo: magInfo }) => { + const isPresent = magInfo.hasIndex(activeMagIdx); if (isPresent) { // The layer exists. Thus, it is not unrenderable. @@ -600,11 +600,11 @@ function _getUnrenderableLayerInfosForCurrentZoom( // zoomSteps can be rendered. return !_.range(1, MAX_ZOOM_STEP_DIFF + 1).some((diff) => { const fallbackZoomStep = activeMagIdx + diff; - return resolutionInfo.hasIndex(fallbackZoomStep); + return magInfo.hasIndex(fallbackZoomStep); }); }) - .map(({ layer, resolutionInfo, activeMagIdx }) => { - const smallerOrHigherInfo = resolutionInfo.hasSmallerAndOrHigherIndex(activeMagIdx); + .map(({ layer, magInfo, activeMagIdx }) => { + const smallerOrHigherInfo = magInfo.hasSmallerAndOrHigherIndex(activeMagIdx); return { layer, smallerOrHigherInfo, @@ -617,7 +617,7 @@ export const getUnrenderableLayerInfosForCurrentZoom = reuseInstanceOnEquality( _getUnrenderableLayerInfosForCurrentZoom, ); -function _getActiveResolutionInfo(state: OxalisState) { +function _getActiveMagInfo(state: OxalisState) { const enabledLayers = getEnabledLayers(state.dataset, state.datasetConfiguration); const activeMagIndices = getActiveMagIndicesForLayers(state); const activeMagIndicesOfEnabledLayers = Object.fromEntries( @@ -630,12 +630,12 @@ function _getActiveResolutionInfo(state: OxalisState) { ]), ); - const isActiveResolutionGlobal = + const isActiveMagGlobal = _.uniqBy(Object.values(activeMagOfEnabledLayers), (mag) => (mag != null ? mag.join("-") : null)) .length === 1; - let representativeResolution: Vector3 | undefined | null; - if (isActiveResolutionGlobal) { - representativeResolution = Object.values(activeMagOfEnabledLayers)[0]; + let representativeMag: Vector3 | undefined | null; + if (isActiveMagGlobal) { + representativeMag = Object.values(activeMagOfEnabledLayers)[0]; } else { const activeMags = Object.values(activeMagOfEnabledLayers).filter((mag) => !!mag) as Vector3[]; @@ -647,7 +647,7 @@ function _getActiveResolutionInfo(state: OxalisState) { mag, // e.g., 4, 4, 1 sortedMag: _.sortBy(mag), // e.g., 1, 4, 4 })); - representativeResolution = _.sortBy( + representativeMag = _.sortBy( activeMagsWithSorted, ({ sortedMag }) => sortedMag[0], ({ sortedMag }) => sortedMag[1], @@ -656,11 +656,11 @@ function _getActiveResolutionInfo(state: OxalisState) { } return { - representativeResolution, + representativeMag, activeMagIndicesOfEnabledLayers, activeMagOfEnabledLayers, - isActiveResolutionGlobal, + isActiveMagGlobal, }; } -export const getActiveMagInfo = reuseInstanceOnEquality(_getActiveResolutionInfo); +export const getActiveMagInfo = reuseInstanceOnEquality(_getActiveMagInfo); diff --git a/frontend/javascripts/oxalis/model/accessors/tool_accessor.ts b/frontend/javascripts/oxalis/model/accessors/tool_accessor.ts index 7c4bb6d8b03..35dfe4c2b6b 100644 --- a/frontend/javascripts/oxalis/model/accessors/tool_accessor.ts +++ b/frontend/javascripts/oxalis/model/accessors/tool_accessor.ts @@ -274,11 +274,8 @@ function getDisabledVolumeInfo(state: OxalisState) { const hasVolume = state.tracing.volumes.length > 0; const hasSkeleton = state.tracing.skeleton != null; const segmentationTracingLayer = getActiveSegmentationTracing(state); - const labeledResolution = getRenderableMagForSegmentationTracing( - state, - segmentationTracingLayer, - )?.resolution; - const isSegmentationTracingVisibleForMag = labeledResolution != null; + const labeledMag = getRenderableMagForSegmentationTracing(state, segmentationTracingLayer)?.mag; + const isSegmentationTracingVisibleForMag = labeledMag != null; const visibleSegmentationLayer = getVisibleSegmentationLayer(state); const isSegmentationTracingTransformed = segmentationTracingLayer != null && diff --git a/frontend/javascripts/oxalis/model/accessors/volumetracing_accessor.ts b/frontend/javascripts/oxalis/model/accessors/volumetracing_accessor.ts index 076b7b61296..a3811acae5a 100644 --- a/frontend/javascripts/oxalis/model/accessors/volumetracing_accessor.ts +++ b/frontend/javascripts/oxalis/model/accessors/volumetracing_accessor.ts @@ -243,28 +243,28 @@ export function isVolumeAnnotationDisallowedForZoom(tool: AnnotationTool, state: return true; } - const volumeResolutions = getMagInfoOfActiveSegmentationTracingLayer(state); - const lowestExistingResolutionIndex = volumeResolutions.getFinestMagIndex(); + const volumeMags = getMagInfoOfActiveSegmentationTracingLayer(state); + const lowestExistingMagIndex = volumeMags.getFinestMagIndex(); // The current mag is too high for the tool // because too many voxels could be annotated at the same time. const isZoomStepTooHigh = getActiveMagIndexForLayer(state, activeSegmentation.tracingId) > - threshold + lowestExistingResolutionIndex; + threshold + lowestExistingMagIndex; return isZoomStepTooHigh; } const MAX_BRUSH_SIZE_FOR_MAG1 = 300; export function getMaximumBrushSize(state: OxalisState) { - const volumeResolutions = getMagInfoOfActiveSegmentationTracingLayer(state); + const volumeMags = getMagInfoOfActiveSegmentationTracingLayer(state); - if (volumeResolutions.mags.length === 0) { + if (volumeMags.mags.length === 0) { return MAX_BRUSH_SIZE_FOR_MAG1; } - const lowestExistingResolutionIndex = volumeResolutions.getFinestMagIndex(); + const lowestExistingMagIndex = volumeMags.getFinestMagIndex(); // For each leading magnification which does not exist, // we double the maximum brush size. - return MAX_BRUSH_SIZE_FOR_MAG1 * 2 ** lowestExistingResolutionIndex; + return MAX_BRUSH_SIZE_FOR_MAG1 * 2 ** lowestExistingMagIndex; } export function getRequestedOrVisibleSegmentationLayer( @@ -484,7 +484,7 @@ function _getRenderableMagForSegmentationTracing( segmentationTracing: VolumeTracing | null | undefined, ): | { - resolution: Vector3; + mag: Vector3; zoomStep: number; } | null @@ -497,7 +497,7 @@ function _getRenderableMagForSegmentationTracing( const requestedZoomStep = getActiveMagIndexForLayer(state, segmentationLayer.name); const { renderMissingDataBlack } = state.datasetConfiguration; - const resolutionInfo = getMagInfo(segmentationLayer.resolutions); + const magInfo = getMagInfo(segmentationLayer.resolutions); // Check whether the segmentation layer is enabled const segmentationSettings = state.datasetConfiguration.layers[segmentationLayer.name]; @@ -506,10 +506,10 @@ function _getRenderableMagForSegmentationTracing( } // Check whether the requested zoom step exists - if (resolutionInfo.hasIndex(requestedZoomStep)) { + if (magInfo.hasIndex(requestedZoomStep)) { return { zoomStep: requestedZoomStep, - resolution: resolutionInfo.getMagByIndexOrThrow(requestedZoomStep), + mag: magInfo.getMagByIndexOrThrow(requestedZoomStep), }; } @@ -527,10 +527,10 @@ function _getRenderableMagForSegmentationTracing( fallbackZoomStep <= requestedZoomStep + MAX_ZOOM_STEP_DIFF; fallbackZoomStep++ ) { - if (resolutionInfo.hasIndex(fallbackZoomStep)) { + if (magInfo.hasIndex(fallbackZoomStep)) { return { zoomStep: fallbackZoomStep, - resolution: resolutionInfo.getMagByIndexOrThrow(fallbackZoomStep), + mag: magInfo.getMagByIndexOrThrow(fallbackZoomStep), }; } } @@ -544,7 +544,7 @@ export const getRenderableMagForSegmentationTracing = reuseInstanceOnEquality( function _getRenderableMagForActiveSegmentationTracing(state: OxalisState): | { - resolution: Vector3; + mag: Vector3; zoomStep: number; } | null @@ -642,13 +642,13 @@ export function getLastLabelAction(volumeTracing: VolumeTracing): LabelAction | export function getLabelActionFromPreviousSlice( state: OxalisState, volumeTracing: VolumeTracing, - resolution: Vector3, + mag: Vector3, dim: 0 | 1 | 2, ): LabelAction | undefined { // Gets the last label action which was performed on a different slice. // Note that in coarser mags (e.g., 8-8-2), the comparison of the coordinates // is done while respecting how the coordinates are clipped due to that mag. - const adapt = (vec: Vector3) => V3.roundElementToMag(vec, resolution, dim); + const adapt = (vec: Vector3) => V3.roundElementToMag(vec, mag, dim); const position = adapt(getFlooredPosition(state.flycam)); return volumeTracing.lastLabelActions.find( diff --git a/frontend/javascripts/oxalis/model/actions/skeletontracing_actions.tsx b/frontend/javascripts/oxalis/model/actions/skeletontracing_actions.tsx index 54db3eef1c1..a5fd84d8b7c 100644 --- a/frontend/javascripts/oxalis/model/actions/skeletontracing_actions.tsx +++ b/frontend/javascripts/oxalis/model/actions/skeletontracing_actions.tsx @@ -191,7 +191,7 @@ export const createNodeAction = ( additionalCoordinates: AdditionalCoordinate[] | null, rotation: Vector3, viewport: number, - resolution: number, + mag: number, treeId?: number | null | undefined, dontActivate: boolean = false, timestamp: number = Date.now(), @@ -202,7 +202,7 @@ export const createNodeAction = ( additionalCoordinates, rotation, viewport, - resolution, + mag, treeId, dontActivate, timestamp, diff --git a/frontend/javascripts/oxalis/model/bucket_data_handling/bucket.ts b/frontend/javascripts/oxalis/model/bucket_data_handling/bucket.ts index 9bfd878cf21..94adfbfea5f 100644 --- a/frontend/javascripts/oxalis/model/bucket_data_handling/bucket.ts +++ b/frontend/javascripts/oxalis/model/bucket_data_handling/bucket.ts @@ -188,11 +188,11 @@ export class DataBucket { getBoundingBox(): BoundingBoxType { const min = bucketPositionToGlobalAddress(this.zoomedAddress, this.cube.magInfo); - const bucketResolution = this.cube.magInfo.getMagByIndexOrThrow(this.zoomedAddress[3]); + const bucketMag = this.cube.magInfo.getMagByIndexOrThrow(this.zoomedAddress[3]); const max: Vector3 = [ - min[0] + Constants.BUCKET_WIDTH * bucketResolution[0], - min[1] + Constants.BUCKET_WIDTH * bucketResolution[1], - min[2] + Constants.BUCKET_WIDTH * bucketResolution[2], + min[0] + Constants.BUCKET_WIDTH * bucketMag[0], + min[1] + Constants.BUCKET_WIDTH * bucketMag[1], + min[2] + Constants.BUCKET_WIDTH * bucketMag[2], ]; return { min, @@ -521,7 +521,7 @@ export class DataBucket { const voxelToLabel = out; voxelToLabel[thirdDimensionIndex] = (voxelToLabel[thirdDimensionIndex] + sliceCount) % Constants.BUCKET_WIDTH; - // The voxelToLabel is already within the bucket and in the correct resolution. + // The voxelToLabel is already within the bucket and in the correct magnification. const voxelAddress = this.cube.getVoxelIndexByVoxelOffset(voxelToLabel); const currentSegmentId = Number(data[voxelAddress]); diff --git a/frontend/javascripts/oxalis/model/bucket_data_handling/data_cube.ts b/frontend/javascripts/oxalis/model/bucket_data_handling/data_cube.ts index fed8881871c..479d8962888 100644 --- a/frontend/javascripts/oxalis/model/bucket_data_handling/data_cube.ts +++ b/frontend/javascripts/oxalis/model/bucket_data_handling/data_cube.ts @@ -239,8 +239,8 @@ class DataCube { ): CubeEntry | null { const cubeKey = this.getCubeKey(zoomStep, coords); if (this.cubes[cubeKey] == null) { - const resolution = this.magInfo.getMagByIndex(zoomStep); - if (resolution == null) { + const mag = this.magInfo.getMagByIndex(zoomStep); + if (mag == null) { return null; } @@ -254,9 +254,9 @@ class DataCube { } const zoomedCubeBoundary: Vector3 = [ - Math.ceil(this.boundingBox.max[0] / (constants.BUCKET_WIDTH * resolution[0])) + 1, - Math.ceil(this.boundingBox.max[1] / (constants.BUCKET_WIDTH * resolution[1])) + 1, - Math.ceil(this.boundingBox.max[2] / (constants.BUCKET_WIDTH * resolution[2])) + 1, + Math.ceil(this.boundingBox.max[0] / (constants.BUCKET_WIDTH * mag[0])) + 1, + Math.ceil(this.boundingBox.max[1] / (constants.BUCKET_WIDTH * mag[1])) + 1, + Math.ceil(this.boundingBox.max[2] / (constants.BUCKET_WIDTH * mag[2])) + 1, ]; this.cubes[cubeKey] = new CubeEntry(zoomedCubeBoundary); } @@ -433,13 +433,13 @@ class DataCube { // Please make use of a LabeledVoxelsMap instead. const promises = []; - for (const [resolutionIndex] of this.magInfo.getMagsWithIndices()) { + for (const [magIndex] of this.magInfo.getMagsWithIndices()) { promises.push( this._labelVoxelInResolution_DEPRECATED( voxel, additionalCoordinates, label, - resolutionIndex, + magIndex, activeSegmentId, ), ); @@ -630,14 +630,14 @@ class DataCube { const currentLabeledVoxelMap = bucketsWithLabeledVoxelsMap.get(currentBucket.zoomedAddress) || new Map(); - const currentResolution = this.magInfo.getMagByIndexOrThrow(currentBucket.zoomedAddress[3]); + const currentMag = this.magInfo.getMagByIndexOrThrow(currentBucket.zoomedAddress[3]); const markUvwInSliceAsLabeled = ([firstCoord, secondCoord, thirdCoord]: Vector3) => { // Convert bucket local W coordinate to global W (both mag-dependent) const w = dimensionIndices[2]; thirdCoord += currentBucket.getTopLeftInMag()[w]; // Convert mag-dependent W to mag-independent W - thirdCoord *= currentResolution[w]; + thirdCoord *= currentMag[w]; if (!currentLabeledVoxelMap.has(thirdCoord)) { currentLabeledVoxelMap.set( @@ -697,7 +697,7 @@ class DataCube { labeledVoxelCount++; const currentGlobalPosition = V3.add( currentGlobalBucketPosition, - V3.scale3(adjustedNeighbourVoxelXyz, currentResolution), + V3.scale3(adjustedNeighbourVoxelXyz, currentMag), ); coveredBBoxMin = [ Math.min(coveredBBoxMin[0], currentGlobalPosition[0]), @@ -821,12 +821,12 @@ class DataCube { additionalCoordinates: AdditionalCoordinate[] | null, zoomStep: number, ): number { - const resolutions = this.magInfo.getDenseMags(); + const mags = this.magInfo.getDenseMags(); let usableZoomStep = zoomStep; while ( position && - usableZoomStep < resolutions.length - 1 && + usableZoomStep < mags.length - 1 && !this.isZoomStepCurrentlyRenderableForVoxel(position, additionalCoordinates, usableZoomStep) ) { usableZoomStep++; @@ -840,12 +840,12 @@ class DataCube { additionalCoordinates: AdditionalCoordinate[] | null, zoomStep: number, ): Promise { - const resolutions = this.magInfo.getDenseMags(); + const mags = this.magInfo.getDenseMags(); let usableZoomStep = zoomStep; while ( position && - usableZoomStep < resolutions.length - 1 && + usableZoomStep < mags.length - 1 && !(await this.isZoomStepUltimatelyRenderableForVoxel( position, additionalCoordinates, @@ -920,10 +920,10 @@ class DataCube { getVoxelOffset(voxel: Vector3, zoomStep: number = 0): Vector3 { // No `map` for performance reasons const voxelOffset: Vector3 = [0, 0, 0]; - const resolution = this.magInfo.getMagByIndexOrThrow(zoomStep); + const mag = this.magInfo.getMagByIndexOrThrow(zoomStep); for (let i = 0; i < 3; i++) { - voxelOffset[i] = Math.floor(voxel[i] / resolution[i]) % constants.BUCKET_WIDTH; + voxelOffset[i] = Math.floor(voxel[i] / mag[i]) % constants.BUCKET_WIDTH; } return voxelOffset; diff --git a/frontend/javascripts/oxalis/model/bucket_data_handling/layer_rendering_manager.ts b/frontend/javascripts/oxalis/model/bucket_data_handling/layer_rendering_manager.ts index b19e1a51333..8d39d019265 100644 --- a/frontend/javascripts/oxalis/model/bucket_data_handling/layer_rendering_manager.ts +++ b/frontend/javascripts/oxalis/model/bucket_data_handling/layer_rendering_manager.ts @@ -187,16 +187,16 @@ export default class LayerRenderingManager { const state = Store.getState(); const { dataset, datasetConfiguration } = state; const layer = getLayerByName(dataset, this.name); - const resolutionInfo = getMagInfo(layer.resolutions); - const maximumResolutionIndex = resolutionInfo.getCoarsestMagIndex(); + const magInfo = getMagInfo(layer.resolutions); + const maximumMagIndex = magInfo.getCoarsestMagIndex(); - if (logZoomStep > maximumResolutionIndex) { + if (logZoomStep > maximumMagIndex) { // Don't render anything if the zoomStep is too high this.textureBucketManager.setActiveBuckets([]); return; } - const resolutions = getMagInfo(layer.resolutions).getDenseMags(); + const mags = getMagInfo(layer.resolutions).getDenseMags(); const layerMatrix = invertAndTranspose( getTransformsForLayer(dataset, layer, datasetConfiguration.nativelyRenderedLayerName) .affineMatrix, @@ -237,7 +237,7 @@ export default class LayerRenderingManager { pickingPromise = this.latestTaskExecutor.schedule(() => asyncBucketPick( viewMode, - resolutions, + mags, position, sphericalCapRadius, matrix, @@ -262,7 +262,7 @@ export default class LayerRenderingManager { // In general, pull buckets which are not available but should be sent to the GPU const missingBuckets = bucketsWithPriorities .filter(({ bucket }) => !bucket.hasData()) - .filter(({ bucket }) => resolutionInfo.hasIndex(bucket.zoomedAddress[3])) + .filter(({ bucket }) => magInfo.hasIndex(bucket.zoomedAddress[3])) .map(({ bucket, priority }) => ({ bucket: bucket.zoomedAddress, priority, diff --git a/frontend/javascripts/oxalis/model/bucket_data_handling/prefetch_strategy_arbitrary.ts b/frontend/javascripts/oxalis/model/bucket_data_handling/prefetch_strategy_arbitrary.ts index 3e95a92078b..dc7c6230e45 100644 --- a/frontend/javascripts/oxalis/model/bucket_data_handling/prefetch_strategy_arbitrary.ts +++ b/frontend/javascripts/oxalis/model/bucket_data_handling/prefetch_strategy_arbitrary.ts @@ -57,12 +57,12 @@ export class PrefetchStrategyArbitrary extends AbstractPrefetchStrategy { matrix: Matrix4x4, activeZoomStep: number, position: Vector3, - resolutions: Array, - resolutionInfo: MagInfo, + mags: Array, + magInfo: MagInfo, additionalCoordinates: AdditionalCoordinate[] | null, ): Array { const pullQueue: PullQueueItem[] = []; - const zoomStep = resolutionInfo.getIndexOrClosestHigherIndex(activeZoomStep); + const zoomStep = magInfo.getIndexOrClosestHigherIndex(activeZoomStep); if (zoomStep == null) { // The layer cannot be rendered at this zoom step, as necessary magnifications @@ -82,7 +82,7 @@ export class PrefetchStrategyArbitrary extends AbstractPrefetchStrategy { const bucketZ = testAddresses[i++]; const positionBucketWithZoomStep = globalPositionToBucketPosition( position, - resolutions, + mags, zoomStep, null, ); diff --git a/frontend/javascripts/oxalis/model/bucket_data_handling/prefetch_strategy_plane.ts b/frontend/javascripts/oxalis/model/bucket_data_handling/prefetch_strategy_plane.ts index 0585125bef4..52f78220e64 100644 --- a/frontend/javascripts/oxalis/model/bucket_data_handling/prefetch_strategy_plane.ts +++ b/frontend/javascripts/oxalis/model/bucket_data_handling/prefetch_strategy_plane.ts @@ -87,11 +87,11 @@ export class PrefetchStrategy extends AbstractPrefetchStrategy { currentZoomStep: number, activePlane: OrthoView, areas: OrthoViewMap, - resolutions: Vector3[], - resolutionInfo: MagInfo, + mags: Vector3[], + magInfo: MagInfo, additionalCoordinates: AdditionalCoordinate[] | null, ): Array { - const zoomStep = resolutionInfo.getIndexOrClosestHigherIndex(currentZoomStep); + const zoomStep = magInfo.getIndexOrClosestHigherIndex(currentZoomStep); if (zoomStep == null) { // The layer cannot be rendered at this zoom step, as necessary magnifications @@ -99,7 +99,7 @@ export class PrefetchStrategy extends AbstractPrefetchStrategy { return []; } - const maxZoomStep = resolutionInfo.getCoarsestMagIndex(); + const maxZoomStep = magInfo.getCoarsestMagIndex(); const zoomStepDiff = currentZoomStep - zoomStep; const queueItemsForCurrentZoomStep = this.prefetchImpl( cube, @@ -109,7 +109,7 @@ export class PrefetchStrategy extends AbstractPrefetchStrategy { zoomStepDiff, activePlane, areas, - resolutions, + mags, false, additionalCoordinates, ); @@ -125,7 +125,7 @@ export class PrefetchStrategy extends AbstractPrefetchStrategy { zoomStepDiff - 1, activePlane, areas, - resolutions, + mags, true, additionalCoordinates, ); @@ -142,7 +142,7 @@ export class PrefetchStrategy extends AbstractPrefetchStrategy { zoomStepDiff: number, activePlane: OrthoView, areas: OrthoViewMap, - resolutions: Vector3[], + mags: Vector3[], isFallback: boolean, additionalCoordinates: AdditionalCoordinate[] | null, ): Array { @@ -169,7 +169,7 @@ export class PrefetchStrategy extends AbstractPrefetchStrategy { widthHeightVector[v] = areas[plane].bottom - areas[plane].top; const scaledWidthHeightVector = zoomedAddressToAnotherZoomStep( widthHeightVector, - resolutions, + mags, zoomStep, ); const width = scaledWidthHeightVector[u]; diff --git a/frontend/javascripts/oxalis/model/bucket_data_handling/wkstore_adapter.ts b/frontend/javascripts/oxalis/model/bucket_data_handling/wkstore_adapter.ts index 15a91c259b3..f0237087f41 100644 --- a/frontend/javascripts/oxalis/model/bucket_data_handling/wkstore_adapter.ts +++ b/frontend/javascripts/oxalis/model/bucket_data_handling/wkstore_adapter.ts @@ -60,12 +60,12 @@ type RequestBucketInfo = SendBucketInfo & { // object as expected by the server on bucket request const createRequestBucketInfo = ( zoomedAddress: BucketAddress, - resolutionInfo: MagInfo, + magInfo: MagInfo, fourBit: boolean, applyAgglomerate: string | null | undefined, version: number | null | undefined, ): RequestBucketInfo => ({ - ...createSendBucketInfo(zoomedAddress, resolutionInfo), + ...createSendBucketInfo(zoomedAddress, magInfo), fourBit, ...(applyAgglomerate != null ? { @@ -79,14 +79,11 @@ const createRequestBucketInfo = ( : {}), }); -function createSendBucketInfo( - zoomedAddress: BucketAddress, - resolutionInfo: MagInfo, -): SendBucketInfo { +function createSendBucketInfo(zoomedAddress: BucketAddress, magInfo: MagInfo): SendBucketInfo { return { - position: bucketPositionToGlobalAddress(zoomedAddress, resolutionInfo), + position: bucketPositionToGlobalAddress(zoomedAddress, magInfo), additionalCoordinates: zoomedAddress[4], - mag: resolutionInfo.getMagByIndexOrThrow(zoomedAddress[3]), + mag: magInfo.getMagByIndexOrThrow(zoomedAddress[3]), cubeSize: constants.BUCKET_WIDTH, }; } @@ -198,7 +195,7 @@ export async function requestFromStore( : null; })(); - const resolutionInfo = getMagInfo(layerInfo.resolutions); + const magInfo = getMagInfo(layerInfo.resolutions); const version = !isVolumeFallback && isSegmentation && maybeVolumeTracing != null ? maybeVolumeTracing.version @@ -206,7 +203,7 @@ export async function requestFromStore( const bucketInfo = batch.map((zoomedAddress) => createRequestBucketInfo( zoomedAddress, - resolutionInfo, + magInfo, fourBit, agglomerateMappingNameToApplyOnServer, version, diff --git a/frontend/javascripts/oxalis/model/data_layer.ts b/frontend/javascripts/oxalis/model/data_layer.ts index a473c9edc7d..ee53bf58b4e 100644 --- a/frontend/javascripts/oxalis/model/data_layer.ts +++ b/frontend/javascripts/oxalis/model/data_layer.ts @@ -16,7 +16,7 @@ class DataLayer { pushQueue: PushQueue; mappings: Mappings | null | undefined; layerRenderingManager: LayerRenderingManager; - resolutions: Array; + mags: Array; fallbackLayer: string | null | undefined; fallbackLayerInfo: DataLayerType | null | undefined; isSegmentation: boolean; @@ -32,15 +32,15 @@ class DataLayer { ? layerInfo.fallbackLayerInfo : null; this.isSegmentation = layerInfo.category === "segmentation"; - this.resolutions = layerInfo.resolutions; + this.mags = layerInfo.resolutions; const { dataset } = Store.getState(); - ErrorHandling.assert(this.resolutions.length > 0, "Magnifications for layer cannot be empty"); + ErrorHandling.assert(this.mags.length > 0, "Magnifications for layer cannot be empty"); this.cube = new DataCube( getLayerBoundingBox(dataset, this.name), layerInfo.additionalAxes || [], - getMagInfo(this.resolutions), + getMagInfo(this.mags), layerInfo.elementClass, this.isSegmentation, this.name, diff --git a/frontend/javascripts/oxalis/model/helpers/generate_dummy_trees.ts b/frontend/javascripts/oxalis/model/helpers/generate_dummy_trees.ts index 3ed8d9b4174..be73a5c3161 100644 --- a/frontend/javascripts/oxalis/model/helpers/generate_dummy_trees.ts +++ b/frontend/javascripts/oxalis/model/helpers/generate_dummy_trees.ts @@ -34,7 +34,7 @@ export default function generateDummyTrees( }, radius: 112.39999389648438, viewport: 1, - mag: 1, + mag: 2, bitDepth: 4, interpolation: true, createdTimestamp: 1507550793899, diff --git a/frontend/javascripts/oxalis/model/helpers/mag_info.ts b/frontend/javascripts/oxalis/model/helpers/mag_info.ts index 38c9b1977d6..6658c15078a 100644 --- a/frontend/javascripts/oxalis/model/helpers/mag_info.ts +++ b/frontend/javascripts/oxalis/model/helpers/mag_info.ts @@ -36,8 +36,8 @@ export class MagInfo { throw new Error("Max dimension in magnifications is not unique."); } - for (const resolution of mags) { - magnificationMap.set(maxValue(resolution), resolution); + for (const mag of mags) { + magnificationMap.set(maxValue(mag), mag); } return magnificationMap; } @@ -49,10 +49,10 @@ export class MagInfo { getMagsWithIndices(): Array<[number, Vector3]> { return _.sortBy( Array.from(this.magnificationMap.entries()).map((entry) => { - const [powerOfTwo, resolution] = entry; - const resolutionIndex = Math.log2(powerOfTwo); - return [resolutionIndex, resolution]; - }), // Sort by resolutionIndex + const [powerOfTwo, mag] = entry; + const magIndex = Math.log2(powerOfTwo); + return [magIndex, mag]; + }), // Sort by magIndex (tuple) => tuple[0], ); } @@ -76,13 +76,13 @@ export class MagInfo { } getMagByIndexOrThrow(index: number): Vector3 { - const resolution = this.getMagByIndex(index); + const mag = this.getMagByIndex(index); - if (!resolution) { + if (!mag) { throw new Error(`Magnification with index ${index} does not exist.`); } - return resolution; + return mag; } getIndexByMag(magnification: Vector3): number { @@ -90,26 +90,26 @@ export class MagInfo { // Assert that the index exists and that the mag at that index // equals the mag argument - const resolutionMaybe = this.getMagByIndex(index); - if (!_.isEqual(magnification, resolutionMaybe)) { + const magMaybe = this.getMagByIndex(index); + if (!_.isEqual(magnification, magMaybe)) { throw new Error( - `Magnification ${magnification} with index ${index} is not equal to existing magnification at that index: ${resolutionMaybe}.`, + `Magnification ${magnification} with index ${index} is not equal to existing magnification at that index: ${magMaybe}.`, ); } return index; } getMagByIndexWithFallback(index: number, fallbackMagInfo: MagInfo | null | undefined): Vector3 { - let resolutionMaybe = this.getMagByIndex(index); + let magMaybe = this.getMagByIndex(index); - if (resolutionMaybe) { - return resolutionMaybe; + if (magMaybe) { + return magMaybe; } - resolutionMaybe = fallbackMagInfo != null ? fallbackMagInfo.getMagByIndex(index) : null; + magMaybe = fallbackMagInfo != null ? fallbackMagInfo.getMagByIndex(index) : null; - if (resolutionMaybe) { - return resolutionMaybe; + if (magMaybe) { + return magMaybe; } if (index === 0) { @@ -236,22 +236,22 @@ export function convertToDenseMag(magnifications: Array): Array maxValue(v)))); + const maxMag = Math.log2(maxValue(magnifications.map((v) => maxValue(v)))); - const resolutionsLookUp = _.keyBy(magnifications, maxValue); + const magnificationsLookUp = _.keyBy(magnifications, maxValue); - const maxResPower = 2 ** maxResolution; - let lastResolution = [maxResPower, maxResPower, maxResPower]; + const maxResPower = 2 ** maxMag; + let lastMag = [maxResPower, maxResPower, maxResPower]; - return _.range(maxResolution, -1, -1) + return _.range(maxMag, -1, -1) .map((exp) => { const resPower = 2 ** exp; // If the magnification does not exist, use the component-wise minimum of the next-higher // mag and an isotropic fallback mag. Otherwise for anisotropic mags, // the dense mags wouldn't be monotonously increasing. - const fallback = map3((i) => Math.min(lastResolution[i], resPower), [0, 1, 2]); - lastResolution = resolutionsLookUp[resPower] || fallback; - return lastResolution as Vector3; + const fallback = map3((i) => Math.min(lastMag[i], resPower), [0, 1, 2]); + lastMag = magnificationsLookUp[resPower] || fallback; + return lastMag as Vector3; }) .reverse(); } diff --git a/frontend/javascripts/oxalis/model/helpers/nml_helpers.ts b/frontend/javascripts/oxalis/model/helpers/nml_helpers.ts index 8ce0aa9f216..4312fb8c941 100644 --- a/frontend/javascripts/oxalis/model/helpers/nml_helpers.ts +++ b/frontend/javascripts/oxalis/model/helpers/nml_helpers.ts @@ -44,7 +44,7 @@ import { getTransformsForSkeletonLayer } from "../accessors/dataset_accessor"; const DEFAULT_COLOR: Vector3 = [1, 0, 0]; const TASK_BOUNDING_BOX_COLOR: Vector3 = [0, 1, 0]; const DEFAULT_VIEWPORT = 0; -const DEFAULT_RESOLUTION = 0; +const DEFAULT_MAG = 0; const DEFAULT_BITDEPTH = 0; const DEFAULT_INTERPOLATION = false; const DEFAULT_TIMESTAMP = 0; @@ -413,7 +413,7 @@ function serializeNodes( rotY: node.rotation[1], rotZ: node.rotation[2], inVp: node.viewport, - inMag: node.resolution, + inMag: node.mag, bitDepth: node.bitDepth, interpolation: node.interpolation, time: node.timestamp, @@ -964,7 +964,7 @@ export function parseNml(nmlString: string): Promise<{ }), bitDepth: _parseInt(attr, "bitDepth", { defaultValue: DEFAULT_BITDEPTH }), viewport: _parseInt(attr, "inVp", { defaultValue: DEFAULT_VIEWPORT }), - resolution: _parseInt(attr, "inMag", { defaultValue: DEFAULT_RESOLUTION }), + mag: _parseInt(attr, "inMag", { defaultValue: DEFAULT_MAG }), radius: _parseFloat(attr, "radius", { defaultValue: Constants.DEFAULT_NODE_RADIUS }), timestamp: _parseTimestamp(attr, "time", { defaultValue: DEFAULT_TIMESTAMP }), }; diff --git a/frontend/javascripts/oxalis/model/helpers/position_converter.ts b/frontend/javascripts/oxalis/model/helpers/position_converter.ts index 5769f4bd9d1..15cf9fb465d 100644 --- a/frontend/javascripts/oxalis/model/helpers/position_converter.ts +++ b/frontend/javascripts/oxalis/model/helpers/position_converter.ts @@ -9,11 +9,11 @@ export function globalPositionToBucketPosition( magIndex: number, additionalCoordinates: AdditionalCoordinate[] | null | undefined, ): BucketAddress { - const resolution = magIndex < mags.length ? mags[magIndex] : upsampleMag(mags, magIndex); + const mag = magIndex < mags.length ? mags[magIndex] : upsampleMag(mags, magIndex); return [ - Math.floor(x / (constants.BUCKET_WIDTH * resolution[0])), - Math.floor(y / (constants.BUCKET_WIDTH * resolution[1])), - Math.floor(z / (constants.BUCKET_WIDTH * resolution[2])), + Math.floor(x / (constants.BUCKET_WIDTH * mag[0])), + Math.floor(y / (constants.BUCKET_WIDTH * mag[1])), + Math.floor(z / (constants.BUCKET_WIDTH * mag[2])), magIndex, additionalCoordinates || [], ]; @@ -26,11 +26,8 @@ export function scaleGlobalPositionWithMagnification( const round = ceil ? Math.ceil : Math.floor; return [round(x / mag[0]), round(y / mag[1]), round(z / mag[2])]; } -export function zoomedPositionToGlobalPosition( - [x, y, z]: Vector3, - currentResolution: Vector3, -): Vector3 { - return [x * currentResolution[0], y * currentResolution[1], z * currentResolution[2]]; +export function zoomedPositionToGlobalPosition([x, y, z]: Vector3, currentMag: Vector3): Vector3 { + return [x * currentMag[0], y * currentMag[1], z * currentMag[2]]; } export function scaleGlobalPositionWithMagnificationFloat( [x, y, z]: Vector3, @@ -43,34 +40,30 @@ export function globalPositionToBucketPositionFloat( mags: Array, magIndex: number, ): Vector4 { - const resolution = magIndex < mags.length ? mags[magIndex] : upsampleMag(mags, magIndex); + const mag = magIndex < mags.length ? mags[magIndex] : upsampleMag(mags, magIndex); return [ - x / (constants.BUCKET_WIDTH * resolution[0]), - y / (constants.BUCKET_WIDTH * resolution[1]), - z / (constants.BUCKET_WIDTH * resolution[2]), + x / (constants.BUCKET_WIDTH * mag[0]), + y / (constants.BUCKET_WIDTH * mag[1]), + z / (constants.BUCKET_WIDTH * mag[2]), magIndex, ]; } -export function upsampleMag(resolutions: Array, resolutionIndex: number): Vector3 { - const lastResolutionIndex = resolutions.length - 1; - const lastResolution = resolutions[lastResolutionIndex]; - const multiplier = Math.pow(2, resolutionIndex - lastResolutionIndex); - return [ - lastResolution[0] * multiplier, - lastResolution[1] * multiplier, - lastResolution[2] * multiplier, - ]; +export function upsampleMag(mags: Array, magIndex: number): Vector3 { + const lastMagIndex = mags.length - 1; + const lastMag = mags[lastMagIndex]; + const multiplier = Math.pow(2, magIndex - lastMagIndex); + return [lastMag[0] * multiplier, lastMag[1] * multiplier, lastMag[2] * multiplier]; } export function bucketPositionToGlobalAddress( bucketPosition: BucketAddress, - resolutionInfo: MagInfo, + magInfo: MagInfo, ): Vector3 { - const [x, y, z, resolutionIndex, _additionalCoordinates] = bucketPosition; - const resolution = resolutionInfo.getMagByIndexOrThrow(resolutionIndex); + const [x, y, z, magIndex, _additionalCoordinates] = bucketPosition; + const mag = magInfo.getMagByIndexOrThrow(magIndex); return [ - x * constants.BUCKET_WIDTH * resolution[0], - y * constants.BUCKET_WIDTH * resolution[1], - z * constants.BUCKET_WIDTH * resolution[2], + x * constants.BUCKET_WIDTH * mag[0], + y * constants.BUCKET_WIDTH * mag[1], + z * constants.BUCKET_WIDTH * mag[2], ]; } export function getMagFactors(magA: Vector3, magB: Vector3): Vector3 { @@ -101,9 +94,9 @@ export function zoomedAddressToAnotherZoomStep( mags: Array, targetMagIndex: number, ): Vector4 { - const currentResolution = mags[magIndex]; - const targetResolution = mags[targetMagIndex]; - const factors = getMagFactors(currentResolution, targetResolution); + const currentMag = mags[magIndex]; + const targetMag = mags[targetMagIndex]; + const factors = getMagFactors(currentMag, targetMag); return [ Math.floor(x * factors[0]), Math.floor(y * factors[1]), @@ -121,9 +114,9 @@ export function zoomedAddressToAnotherZoomStepWithInfo( magInfo: MagInfo, targetMagIndex: number, ): Vector4 { - const currentResolution = magInfo.getMagByIndexWithFallback(magIndex, null); - const targetResolution = magInfo.getMagByIndexWithFallback(targetMagIndex, null); - const factors = getMagFactors(currentResolution, targetResolution); + const currentMag = magInfo.getMagByIndexWithFallback(magIndex, null); + const targetMag = magInfo.getMagByIndexWithFallback(targetMagIndex, null); + const factors = getMagFactors(currentMag, targetMag); return [ Math.floor(x * factors[0]), Math.floor(y * factors[1]), @@ -152,15 +145,15 @@ export function getBaseBucketsForFallbackBucket( mags, betterZoomStep, ); - // resolutionFactors is a [x, y, z] tuple with x, y, z being 1 or 2 each (because - // zoomStepDifference === 1). In the case of isotropic resolutions, it's simply [2, 2, 2] - const resolutionFactors = getMagFactors(mags[fallbackBucketZoomStep], mags[betterZoomStep]); + // magFactors is a [x, y, z] tuple with x, y, z being 1 or 2 each (because + // zoomStepDifference === 1). In the case of isotropic magnifications, it's simply [2, 2, 2] + const magFactors = getMagFactors(mags[fallbackBucketZoomStep], mags[betterZoomStep]); const bucketAddresses = []; const [baseX, baseY, baseZ] = betterBucketAddress; - for (let _x = 0; _x < resolutionFactors[0]; _x++) { - for (let _y = 0; _y < resolutionFactors[1]; _y++) { - for (let _z = 0; _z < resolutionFactors[2]; _z++) { + for (let _x = 0; _x < magFactors[0]; _x++) { + for (let _y = 0; _y < magFactors[1]; _y++) { + for (let _z = 0; _z < magFactors[2]; _z++) { const newAddress = [baseX + _x, baseY + _y, baseZ + _z, betterZoomStep]; bucketAddresses.push(newAddress); } diff --git a/frontend/javascripts/oxalis/model/reducers/skeletontracing_reducer.ts b/frontend/javascripts/oxalis/model/reducers/skeletontracing_reducer.ts index 473b07b3c8e..16b3c90e4f0 100644 --- a/frontend/javascripts/oxalis/model/reducers/skeletontracing_reducer.ts +++ b/frontend/javascripts/oxalis/model/reducers/skeletontracing_reducer.ts @@ -602,15 +602,8 @@ function SkeletonTracingReducer(state: OxalisState, action: Action): OxalisState // Don't create nodes if the skeleton layer is rendered with transforms. return state; } - const { - position, - rotation, - viewport, - resolution, - treeId, - timestamp, - additionalCoordinates, - } = action; + const { position, rotation, viewport, mag, treeId, timestamp, additionalCoordinates } = + action; return getOrCreateTree(state, skeletonTracing, treeId, timestamp, TreeTypeEnum.DEFAULT) .chain((tree) => createNode( @@ -621,7 +614,7 @@ function SkeletonTracingReducer(state: OxalisState, action: Action): OxalisState additionalCoordinates, rotation, viewport, - resolution, + mag, timestamp, ).map(([node, edges]) => { const diffableNodeMap = tree.nodes; diff --git a/frontend/javascripts/oxalis/model/reducers/skeletontracing_reducer_helpers.ts b/frontend/javascripts/oxalis/model/reducers/skeletontracing_reducer_helpers.ts index a46db81a1ec..ab66187254f 100644 --- a/frontend/javascripts/oxalis/model/reducers/skeletontracing_reducer_helpers.ts +++ b/frontend/javascripts/oxalis/model/reducers/skeletontracing_reducer_helpers.ts @@ -122,7 +122,7 @@ export function createNode( additionalCoordinates: AdditionalCoordinate[] | null, rotation: Vector3, viewport: number, - resolution: number, + mag: number, timestamp: number, ): Maybe<[Node, EdgeCollection]> { const activeNodeMaybe = getActiveNodeFromTree(skeletonTracing, tree); @@ -146,7 +146,7 @@ export function createNode( radius, rotation, viewport, - resolution, + mag, id: nextNewId, timestamp, bitDepth: state.datasetConfiguration.fourBit ? 4 : 8, @@ -851,7 +851,7 @@ function serverNodeToMutableNode(n: ServerNode): MutableNode { rotation: Utils.point3ToVector3(n.rotation), bitDepth: n.bitDepth, viewport: n.viewport, - resolution: n.mag, + mag: n.mag, radius: n.radius, timestamp: n.createdTimestamp, interpolation: n.interpolation, diff --git a/frontend/javascripts/oxalis/model/sagas/clip_histogram_saga.ts b/frontend/javascripts/oxalis/model/sagas/clip_histogram_saga.ts index c44689fa09f..b5fc6dc2c94 100644 --- a/frontend/javascripts/oxalis/model/sagas/clip_histogram_saga.ts +++ b/frontend/javascripts/oxalis/model/sagas/clip_histogram_saga.ts @@ -28,7 +28,7 @@ async function getClippingValues( // Ideally, we want to avoid mags 1 and 2 to keep // the amount of data that has to be loaded small and // to de-noise the data - const desiredResolutionIndex = Math.max(2, getActiveMagIndexForLayer(state, layerName) + 1); + const desiredMagIndex = Math.max(2, getActiveMagIndexForLayer(state, layerName) + 1); let dataForAllViewPorts; try { @@ -36,19 +36,19 @@ async function getClippingValues( api.data.getViewportData( OrthoViews.PLANE_XY, layerName, - desiredResolutionIndex, + desiredMagIndex, additionalCoordinates, ), api.data.getViewportData( OrthoViews.PLANE_XZ, layerName, - desiredResolutionIndex, + desiredMagIndex, additionalCoordinates, ), api.data.getViewportData( OrthoViews.PLANE_YZ, layerName, - desiredResolutionIndex, + desiredMagIndex, additionalCoordinates, ), ]); diff --git a/frontend/javascripts/oxalis/model/sagas/dataset_saga.ts b/frontend/javascripts/oxalis/model/sagas/dataset_saga.ts index 934adc87162..b10c681ba5c 100644 --- a/frontend/javascripts/oxalis/model/sagas/dataset_saga.ts +++ b/frontend/javascripts/oxalis/model/sagas/dataset_saga.ts @@ -111,9 +111,9 @@ export function* watchZ1Downsampling(): Saga { // is no appropriate mag for that layer. break; } - const resolutionInfo = getMagInfo(dataLayer.resolutions); - const bestExistingIndex = resolutionInfo.getFinestMagIndex(); - const currentIndex = resolutionInfo.getIndexByMag(currentRes); + const magInfo = getMagInfo(dataLayer.resolutions); + const bestExistingIndex = magInfo.getFinestMagIndex(); + const currentIndex = magInfo.getIndexByMag(currentRes); if (currentIndex <= bestExistingIndex) { // There's no better mag to render the current layer in. continue; diff --git a/frontend/javascripts/oxalis/model/sagas/mesh_saga.ts b/frontend/javascripts/oxalis/model/sagas/mesh_saga.ts index cef1f60737a..2fdf47b3710 100644 --- a/frontend/javascripts/oxalis/model/sagas/mesh_saga.ts +++ b/frontend/javascripts/oxalis/model/sagas/mesh_saga.ts @@ -240,17 +240,17 @@ function* getInfoForMeshLoading( zoomStep: number; magInfo: MagInfo; }> { - const resolutionInfo = getMagInfo(layer.resolutions); + const magInfo = getMagInfo(layer.mags); const preferredZoomStep = meshExtraInfo.preferredQuality != null ? meshExtraInfo.preferredQuality : yield* select( (state) => state.temporaryConfiguration.preferredQualityForMeshAdHocComputation, ); - const zoomStep = resolutionInfo.getClosestExistingIndex(preferredZoomStep); + const zoomStep = magInfo.getClosestExistingIndex(preferredZoomStep); return { zoomStep, - magInfo: resolutionInfo, + magInfo: magInfo, }; } @@ -273,11 +273,7 @@ function* loadAdHocMesh( const meshExtraInfo = yield* call(getMeshExtraInfo, layer.name, maybeExtraInfo); - const { zoomStep, magInfo: resolutionInfo } = yield* call( - getInfoForMeshLoading, - layer, - meshExtraInfo, - ); + const { zoomStep, magInfo } = yield* call(getInfoForMeshLoading, layer, meshExtraInfo); batchCounterPerSegment[segmentId] = 0; // If a REMOVE_MESH action is dispatched and consumed @@ -293,7 +289,7 @@ function* loadAdHocMesh( seedAdditionalCoordinates, zoomStep, meshExtraInfo, - resolutionInfo, + magInfo, removeExistingMesh, ), cancel: take( @@ -326,12 +322,12 @@ function* loadFullAdHocMesh( additionalCoordinates: AdditionalCoordinate[] | undefined | null, zoomStep: number, meshExtraInfo: AdHocMeshInfo, - resolutionInfo: MagInfo, + magInfo: MagInfo, removeExistingMesh: boolean, ): Saga { let isInitialRequest = true; const { mappingName, mappingType } = meshExtraInfo; - const clippedPosition = clipPositionToCubeBoundary(position, zoomStep, resolutionInfo); + const clippedPosition = clipPositionToCubeBoundary(position, zoomStep, magInfo); yield* put( addAdHocMeshAction( layer.name, @@ -346,7 +342,7 @@ function* loadFullAdHocMesh( const cubeSize = marchingCubeSizeInTargetMag(); const tracingStoreHost = yield* select((state) => state.tracing.tracingStore.url); - const mag = resolutionInfo.getMagByIndexOrThrow(zoomStep); + const mag = magInfo.getMagByIndexOrThrow(zoomStep); const volumeTracing = yield* select((state) => getActiveSegmentationTracing(state)); const visibleSegmentationLayer = yield* select((state) => getVisibleSegmentationLayer(state)); @@ -395,7 +391,7 @@ function* loadFullAdHocMesh( currentPosition, zoomStep, meshExtraInfo, - resolutionInfo, + magInfo, isInitialRequest, removeExistingMesh && isInitialRequest, useDataStore, @@ -446,7 +442,7 @@ function* maybeLoadMeshChunk( clippedPosition: Vector3, zoomStep: number, meshExtraInfo: AdHocMeshInfo, - resolutionInfo: MagInfo, + magInfo: MagInfo, isInitialRequest: boolean, removeExistingMesh: boolean, useDataStore: boolean, @@ -475,7 +471,7 @@ function* maybeLoadMeshChunk( }`; const tracingStoreUrl = `${tracingStoreHost}/tracings/volume/${layer.name}`; - const mag = resolutionInfo.getMagByIndexOrThrow(zoomStep); + const mag = magInfo.getMagByIndexOrThrow(zoomStep); if (isInitialRequest) { sendAnalyticsEvent("request_isosurface", { @@ -521,7 +517,7 @@ function* maybeLoadMeshChunk( additionalCoordinates, ); return neighbors.map((neighbor) => - getNeighborPosition(clippedPosition, neighbor, zoomStep, resolutionInfo), + getNeighborPosition(clippedPosition, neighbor, zoomStep, magInfo), ); } catch (exception) { retryCount++; @@ -1033,15 +1029,15 @@ function _getLoadChunksTasks( // Check if the mesh scale is different to all supported mags of the active segmentation scaled by the dataset scale and warn in the console to make debugging easier in such a case. // This hint at the mesh file being computed when the dataset scale was different than currently configured. - const segmentationLayerResolutions = yield* select( + const segmentationLayerMags = yield* select( (state) => getVisibleSegmentationLayer(state)?.resolutions, ); const datasetScaleFactor = dataset.dataSource.scale.factor; - if (segmentationLayerResolutions && scale) { - const doesSomeSegmResolutionMatchMeshScale = segmentationLayerResolutions.some( - (res) => areVec3AlmostEqual(V3.scale3(datasetScaleFactor, res), scale), + if (segmentationLayerMags && scale) { + const doesSomeSegmentMagMatchMeshScale = segmentationLayerMags.some((res) => + areVec3AlmostEqual(V3.scale3(datasetScaleFactor, res), scale), ); - if (!doesSomeSegmResolutionMatchMeshScale) { + if (!doesSomeSegmentMagMatchMeshScale) { console.warn( `Scale of mesh ${id} is different to dataset scale. Mesh scale: ${scale}, Dataset scale: ${dataset.dataSource.scale.factor}. This might lead to unexpected rendering results.`, ); diff --git a/frontend/javascripts/oxalis/model/sagas/min_cut_saga.ts b/frontend/javascripts/oxalis/model/sagas/min_cut_saga.ts index 4ddf0fdd28a..3453390fdeb 100644 --- a/frontend/javascripts/oxalis/model/sagas/min_cut_saga.ts +++ b/frontend/javascripts/oxalis/model/sagas/min_cut_saga.ts @@ -64,27 +64,23 @@ function selectAppropriateMags( boundingBoxMag1: BoundingBox, magInfo: MagInfo, ): Array<[number, Vector3]> { - const resolutionsWithIndices = magInfo.getMagsWithIndices(); - const appropriateResolutions: Array<[number, Vector3]> = []; - - for (const [resolutionIndex, resolution] of resolutionsWithIndices) { - if ( - resolutionIndex === 0 && - resolutionsWithIndices.length > 1 && - ALWAYS_IGNORE_FIRST_MAG_INITIALLY - ) { + const magsWithIndices = magInfo.getMagsWithIndices(); + const appropriateMags: Array<[number, Vector3]> = []; + + for (const [magIndex, mag] of magsWithIndices) { + if (magIndex === 0 && magsWithIndices.length > 1 && ALWAYS_IGNORE_FIRST_MAG_INITIALLY) { // Don't consider Mag 1, as it's usually too fine-granular continue; } - const boundingBoxTarget = boundingBoxMag1.fromMag1ToMag(resolution); + const boundingBoxTarget = boundingBoxMag1.fromMag1ToMag(mag); if (boundingBoxTarget.getVolume() < VOXEL_THRESHOLD) { - appropriateResolutions.push([resolutionIndex, resolution]); + appropriateMags.push([magIndex, mag]); } } - return appropriateResolutions; + return appropriateMags; } // @@ -284,10 +280,10 @@ function* performMinCut(action: Action): Saga { return; } - const resolutionInfo = getMagInfo(volumeTracingLayer.resolutions); - const appropriateResolutionInfos = selectAppropriateMags(boundingBoxMag1, resolutionInfo); + const magInfo = getMagInfo(volumeTracingLayer.resolutions); + const appropriateMagInfos = selectAppropriateMags(boundingBoxMag1, magInfo); - if (appropriateResolutionInfos.length === 0) { + if (appropriateMagInfos.length === 0) { yield* call( [Toast, Toast.warning], "The bounding box for the selected seeds is too large. Choose a smaller bounding box or lower the distance between the seeds. Alternatively, ensure that lower magnifications exist which can be used.", @@ -303,7 +299,7 @@ function* performMinCut(action: Action): Saga { // Try to perform a min-cut on the selected mags. If the min-cut // fails for one mag, it's tried again on the next mag. // If the min-cut succeeds, it's refined again with the better mags. - for (const [resolutionIndex, targetMag] of appropriateResolutionInfos) { + for (const [magIndex, targetMag] of appropriateMagInfos) { try { yield* call( progressCallback, @@ -314,7 +310,7 @@ function* performMinCut(action: Action): Saga { yield* call( tryMinCutAtMag, targetMag, - resolutionIndex, + magIndex, boundingBoxMag1, nodes, volumeTracingLayer, @@ -322,29 +318,21 @@ function* performMinCut(action: Action): Saga { ); console.groupEnd(); - for ( - let refiningResolutionIndex = resolutionIndex - 1; - refiningResolutionIndex >= 0; - refiningResolutionIndex-- - ) { + for (let refiningMagIndex = magIndex - 1; refiningMagIndex >= 0; refiningMagIndex--) { // Refine min-cut on lower mags, if they exist. - if (!resolutionInfo.hasIndex(refiningResolutionIndex)) { + if (!magInfo.hasIndex(refiningMagIndex)) { continue; } - const refiningResolution = resolutionInfo.getMagByIndexOrThrow(refiningResolutionIndex); - console.group("Refining min-cut at", refiningResolution.join("-")); - yield* call( - progressCallback, - false, - `Refining min-cut at Mag=${refiningResolution.join("-")}`, - ); + const refiningMag = magInfo.getMagByIndexOrThrow(refiningMagIndex); + console.group("Refining min-cut at", refiningMag.join("-")); + yield* call(progressCallback, false, `Refining min-cut at Mag=${refiningMag.join("-")}`); try { yield* call( tryMinCutAtMag, - refiningResolution, - refiningResolutionIndex, + refiningMag, + refiningMagIndex, boundingBoxMag1, nodes, volumeTracingLayer, diff --git a/frontend/javascripts/oxalis/model/sagas/prefetch_saga.ts b/frontend/javascripts/oxalis/model/sagas/prefetch_saga.ts index 56fae8eaa60..49e160331f1 100644 --- a/frontend/javascripts/oxalis/model/sagas/prefetch_saga.ts +++ b/frontend/javascripts/oxalis/model/sagas/prefetch_saga.ts @@ -103,14 +103,14 @@ export function* prefetchForPlaneMode( ): Saga { const position = yield* select((state) => getPosition(state.flycam)); const zoomStep = yield* select((state) => getActiveMagIndexForLayer(state, layer.name)); - const resolutionInfo = getMagInfo(layer.resolutions); + const magInfo = getMagInfo(layer.mags); const activePlane = yield* select((state) => state.viewModeData.plane.activeViewport); const tracingTypes = yield* select(getTracingTypes); const additionalCoordinates = yield* select((state) => state.flycam.additionalCoordinates); const lastConnectionStats = getGlobalDataConnectionInfo().lastStats; const { lastPosition, lastDirection, lastZoomStep, lastBucketPickerTick } = previousProperties; const direction = getTraceDirection(position, lastPosition, lastDirection); - const resolutions = resolutionInfo.getDenseMags(); + const mags = magInfo.getDenseMags(); const layerRenderingManager = yield* call( [Model, Model.getLayerRenderingManagerByName], layer.name, @@ -136,8 +136,8 @@ export function* prefetchForPlaneMode( zoomStep, activePlane, areas, - resolutions, - resolutionInfo, + mags, + magInfo, additionalCoordinates, ); @@ -171,8 +171,8 @@ export function* prefetchForArbitraryMode( const matrix = yield* select((state) => state.flycam.currentMatrix); const zoomStep = yield* select((state) => getActiveMagIndexForLayer(state, layer.name)); const tracingTypes = yield* select(getTracingTypes); - const resolutionInfo = getMagInfo(layer.resolutions); - const resolutions = resolutionInfo.getDenseMags(); + const magInfo = getMagInfo(layer.mags); + const mags = magInfo.getDenseMags(); const layerRenderingManager = yield* call( [Model, Model.getLayerRenderingManagerByName], layer.name, @@ -197,8 +197,8 @@ export function* prefetchForArbitraryMode( matrix, zoomStep, position, - resolutions, - resolutionInfo, + mags, + magInfo, additionalCoordinates, ); diff --git a/frontend/javascripts/oxalis/model/sagas/proofread_saga.ts b/frontend/javascripts/oxalis/model/sagas/proofread_saga.ts index 05910411232..3839d8f48c3 100644 --- a/frontend/javascripts/oxalis/model/sagas/proofread_saga.ts +++ b/frontend/javascripts/oxalis/model/sagas/proofread_saga.ts @@ -1036,18 +1036,18 @@ function* prepareSplitOrMerge(isSkeletonProofreading: boolean): Saga getCurrentMag(state, volumeTracingLayer.name)); const agglomerateFileMag = isSkeletonProofreading ? // In case of skeleton proofreading, the finest mag should be used. - resolutionInfo.getFinestMag() + magInfo.getFinestMag() : // For non-skeleton proofreading, the active mag suffices currentMag; if (agglomerateFileMag == null) { return null; } - const agglomerateFileZoomstep = resolutionInfo.getIndexByMag(agglomerateFileMag); + const agglomerateFileZoomstep = magInfo.getIndexByMag(agglomerateFileMag); const getUnmappedDataValue = (position: Vector3): Promise => { const { additionalCoordinates } = Store.getState().flycam; diff --git a/frontend/javascripts/oxalis/model/sagas/quick_select_heuristic_saga.ts b/frontend/javascripts/oxalis/model/sagas/quick_select_heuristic_saga.ts index 03e5b0965a7..8a6956f8cdb 100644 --- a/frontend/javascripts/oxalis/model/sagas/quick_select_heuristic_saga.ts +++ b/frontend/javascripts/oxalis/model/sagas/quick_select_heuristic_saga.ts @@ -145,16 +145,16 @@ export function* prepareQuickSelect( const requestedZoomStep = yield* select((store) => getActiveMagIndexForLayer(store, colorLayer.name), ); - const resolutionInfo = getMagInfo( + const magInfo = getMagInfo( // Ensure that a magnification is used which exists in the color layer as well as the // target segmentation layer. _.intersectionBy(colorLayer.resolutions, volumeLayer.resolutions, (mag) => mag.join("-")), ); - const labeledZoomStep = resolutionInfo.getClosestExistingIndex( + const labeledZoomStep = magInfo.getClosestExistingIndex( requestedZoomStep, "The visible color layer and the active segmentation layer don't have any magnifications in common. Cannot select segment.", ); - const labeledResolution = resolutionInfo.getMagByIndexOrThrow(labeledZoomStep); + const labeledMag = magInfo.getMagByIndexOrThrow(labeledZoomStep); return { labeledZoomStep, @@ -164,7 +164,7 @@ export function* prepareQuickSelect( colorLayer, quickSelectConfig, activeViewport, - labeledMag: labeledResolution, + labeledMag, volumeTracing, }; } @@ -184,7 +184,7 @@ export default function* performQuickSelect( colorLayer, quickSelectConfig, activeViewport, - labeledMag: labeledResolution, + labeledMag, volumeTracing, } = preparation; const { startPosition, endPosition, quickSelectGeometry } = action; @@ -204,7 +204,7 @@ export default function* performQuickSelect( const inclusiveMaxW = map3((el, idx) => (idx === thirdDim ? el - 1 : el), boundingBoxMag1.max); quickSelectGeometry.setCoordinates(boundingBoxMag1.min, inclusiveMaxW); - const boundingBoxInMag = boundingBoxMag1.fromMag1ToMag(labeledResolution); + const boundingBoxInMag = boundingBoxMag1.fromMag1ToMag(labeledMag); if (boundingBoxInMag.getVolume() === 0) { Toast.warning("The drawn rectangular had a width or height of zero."); @@ -288,7 +288,7 @@ export default function* performQuickSelect( quickSelectGeometry, volumeTracing, activeViewport, - labeledResolution, + labeledMag, boundingBoxMag1, boundingBoxMag1.min[thirdDim], thresholdField, @@ -358,7 +358,7 @@ export default function* performQuickSelect( quickSelectGeometry, volumeTracing, activeViewport, - labeledResolution, + labeledMag, boundingBoxMag1, boundingBoxMag1.min[thirdDim], thresholdField, diff --git a/frontend/javascripts/oxalis/model/sagas/quick_select_ml_saga.ts b/frontend/javascripts/oxalis/model/sagas/quick_select_ml_saga.ts index d1e66647247..cbc1db4181c 100644 --- a/frontend/javascripts/oxalis/model/sagas/quick_select_ml_saga.ts +++ b/frontend/javascripts/oxalis/model/sagas/quick_select_ml_saga.ts @@ -175,14 +175,8 @@ export default function* performQuickSelect( EXPECTED_DURATION_PER_SLICE_MS, ); try { - const { - labeledZoomStep, - labeledMag: labeledResolution, - thirdDim, - activeViewport, - volumeTracing, - colorLayer, - } = preparation; + const { labeledZoomStep, labeledMag, thirdDim, activeViewport, volumeTracing, colorLayer } = + preparation; const trans = (vec: Vector3) => Dimensions.transDim(vec, activeViewport); const { type, quickSelectGeometry } = action; @@ -202,7 +196,7 @@ export default function* performQuickSelect( } // Effectively, zero the first and second dimension in the mag. - const depthSummand = V3.scale3(labeledResolution, trans([0, 0, 1])); + const depthSummand = V3.scale3(labeledMag, trans([0, 0, 1])); const unalignedUserBoxMag1 = new BoundingBox({ min: V3.floor(V3.min(startPosition, endPosition)), max: V3.floor(V3.add(V3.max(startPosition, endPosition), depthSummand)), @@ -215,7 +209,7 @@ export default function* performQuickSelect( ); quickSelectGeometry.setCoordinates(unalignedUserBoxMag1.min, inclusiveMaxW); - const alignedUserBoxMag1 = unalignedUserBoxMag1.alignWithMag(labeledResolution, "floor"); + const alignedUserBoxMag1 = unalignedUserBoxMag1.alignWithMag(labeledMag, "floor"); const dataset = yield* select((state: OxalisState) => state.dataset); const layerConfiguration = yield* select( (state) => state.datasetConfiguration.layers[colorLayer.name], @@ -230,7 +224,7 @@ export default function* performQuickSelect( dataset, colorLayer.name, alignedUserBoxMag1, - labeledResolution, + labeledMag, activeViewport, additionalCoordinates || [], colorLayer.elementClass === "uint8" ? null : intensityRange, @@ -247,7 +241,7 @@ export default function* performQuickSelect( sendAnalyticsEvent("used_quick_select_with_ai"); - let userBoxInMag = alignedUserBoxMag1.fromMag1ToMag(labeledResolution); + let userBoxInMag = alignedUserBoxMag1.fromMag1ToMag(labeledMag); if (action.type === "COMPUTE_QUICK_SELECT_FOR_POINT") { // In the point case, the bounding box will have a volume of zero which // prevents the estimateBBoxInMask call from inferring the correct bbox. @@ -262,7 +256,7 @@ export default function* performQuickSelect( max: userBoxRelativeToMaskInMag.getMaxUV(activeViewport), }; for (const mask of masks) { - const targetW = alignedUserBoxMag1.min[thirdDim] + labeledResolution[thirdDim] * wOffset; + const targetW = alignedUserBoxMag1.min[thirdDim] + labeledMag[thirdDim] * wOffset; const { min: minUV, max: maxUV } = estimateBBoxInMask( mask, @@ -279,7 +273,7 @@ export default function* performQuickSelect( // bbox. const targetBox = new BoundingBox({ min: trans([...minUV, 0]), - max: trans([...maxUV, labeledResolution[thirdDim]]), + max: trans([...maxUV, labeledMag[thirdDim]]), }).offset(maskBoxInMag.min); // Let the UI (especially the progress bar) update @@ -288,8 +282,8 @@ export default function* performQuickSelect( quickSelectGeometry, volumeTracing, activeViewport, - labeledResolution, - targetBox.fromMagToMag1(labeledResolution), + labeledMag, + targetBox.fromMagToMag1(labeledMag), targetW, // a.hi(x,y) => a[:x, :y], // a.lo(x,y) => a[x:, y:] mask diff --git a/frontend/javascripts/oxalis/model/sagas/save_saga.ts b/frontend/javascripts/oxalis/model/sagas/save_saga.ts index d2acc8ca949..cf87972ffec 100644 --- a/frontend/javascripts/oxalis/model/sagas/save_saga.ts +++ b/frontend/javascripts/oxalis/model/sagas/save_saga.ts @@ -291,18 +291,18 @@ export function* sendRequestToServer( function* markBucketsAsNotDirty(saveQueue: Array, tracingId: string) { const segmentationLayer = Model.getSegmentationTracingLayer(tracingId); - const segmentationResolutionInfo = yield* call(getMagInfo, segmentationLayer.resolutions); + const segmentationMagInfo = yield* call(getMagInfo, segmentationLayer.mags); if (segmentationLayer != null) { for (const saveEntry of saveQueue) { for (const updateAction of saveEntry.actions) { if (updateAction.name === "updateBucket") { const { position, mag, additionalCoordinates } = updateAction.value; - const resolutionIndex = segmentationResolutionInfo.getIndexByMag(mag); + const magIndex = segmentationMagInfo.getIndexByMag(mag); const zoomedBucketAddress = globalPositionToBucketPosition( position, - segmentationResolutionInfo.getDenseMags(), - resolutionIndex, + segmentationMagInfo.getDenseMags(), + magIndex, additionalCoordinates, ); const bucket = segmentationLayer.cube.getOrCreateBucket(zoomedBucketAddress); diff --git a/frontend/javascripts/oxalis/model/sagas/update_actions.ts b/frontend/javascripts/oxalis/model/sagas/update_actions.ts index 32ed16ef2da..d2cf38aeb20 100644 --- a/frontend/javascripts/oxalis/model/sagas/update_actions.ts +++ b/frontend/javascripts/oxalis/model/sagas/update_actions.ts @@ -220,16 +220,27 @@ export function deleteEdge(treeId: number, sourceNodeId: number, targetNodeId: n } as const; } +export type CreateActionNode = Omit & { + position: Node["untransformedPosition"]; + treeId: number; + resolution: number; +}; + export type UpdateActionNode = Omit & { position: Node["untransformedPosition"]; treeId: number; }; export function createNode(treeId: number, node: Node) { - const { untransformedPosition, ...restNode } = node; + const { untransformedPosition, mag, ...restNode } = node; return { name: "createNode", - value: { ...restNode, position: untransformedPosition, treeId } as UpdateActionNode, + value: { + ...restNode, + position: untransformedPosition, + treeId, + resolution: mag, + } as CreateActionNode, } as const; } export function updateNode(treeId: number, node: Node) { diff --git a/frontend/javascripts/oxalis/model/sagas/volume/helpers.ts b/frontend/javascripts/oxalis/model/sagas/volume/helpers.ts index aa017a04584..63e6fe197ed 100644 --- a/frontend/javascripts/oxalis/model/sagas/volume/helpers.ts +++ b/frontend/javascripts/oxalis/model/sagas/volume/helpers.ts @@ -94,9 +94,9 @@ export function applyLabeledVoxelMapToAllMissingMags( // a 2D vector address to the corresponding 3D vector address. // The input address is local to a slice in the LabeledVoxelsMap (that's // why it's 2D). The output address is local to the corresponding bucket. - const get3DAddressCreator = (targetResolution: Vector3) => { + const get3DAddressCreator = (targetMags: Vector3) => { const sampledThirdDimensionValue = - Math.floor(thirdDimensionOfSlice / targetResolution[thirdDim]) % Constants.BUCKET_WIDTH; + Math.floor(thirdDimensionOfSlice / targetMags[thirdDim]) % Constants.BUCKET_WIDTH; return (x: number, y: number, out: Vector3 | Float32Array) => { out[dimensionIndices[0]] = x; out[dimensionIndices[1]] = y; @@ -105,17 +105,17 @@ export function applyLabeledVoxelMapToAllMissingMags( }; // Get all available magnifications and divide the list into two parts. - // The pivotIndex is the index within allResolutionsWithIndices which refers to + // The pivotIndex is the index within allMagsWithIndices which refers to // the labeled mag. // `downsampleSequence` contains the current mag and all higher mags (to which // should be downsampled) // `upsampleSequence` contains the current mag and all lower mags (to which // should be upsampled) - const labeledResolution = magInfo.getMagByIndexOrThrow(labeledZoomStep); - const allResolutionsWithIndices = magInfo.getMagsWithIndices(); - const pivotIndex = allResolutionsWithIndices.findIndex(([index]) => index === labeledZoomStep); - const downsampleSequence = allResolutionsWithIndices.slice(pivotIndex); - const upsampleSequence = allResolutionsWithIndices.slice(0, pivotIndex + 1).reverse(); + const labeledMag = magInfo.getMagByIndexOrThrow(labeledZoomStep); + const allMagsWithIndices = magInfo.getMagsWithIndices(); + const pivotIndex = allMagsWithIndices.findIndex(([index]) => index === labeledZoomStep); + const downsampleSequence = allMagsWithIndices.slice(pivotIndex); + const upsampleSequence = allMagsWithIndices.slice(0, pivotIndex + 1).reverse(); // Given a sequence of mags, the inputLabeledVoxelMap is applied // over all these mags. @@ -128,24 +128,24 @@ export function applyLabeledVoxelMapToAllMissingMags( let currentLabeledVoxelMap: LabeledVoxelsMap = inputLabeledVoxelMap; for (const [source, target] of pairwise(samplingSequence)) { - const [sourceZoomStep, sourceResolution] = source; - const [targetZoomStep, targetResolution] = target; + const [sourceZoomStep, sourceMag] = source; + const [targetZoomStep, targetMag] = target; currentLabeledVoxelMap = sampleVoxelMapToMagnification( currentLabeledVoxelMap, segmentationCube, - sourceResolution, + sourceMag, sourceZoomStep, - targetResolution, + targetMag, targetZoomStep, dimensionIndices, thirdDimensionOfSlice, ); - const numberOfSlices = getNumberOfSlices(targetResolution); + const numberOfSlices = getNumberOfSlices(targetMag); applyVoxelMap( currentLabeledVoxelMap, segmentationCube, segmentId, - get3DAddressCreator(targetResolution), + get3DAddressCreator(targetMag), numberOfSlices, thirdDim, shouldOverwrite, @@ -156,12 +156,12 @@ export function applyLabeledVoxelMapToAllMissingMags( // First upsample the voxel map and apply it to all better mags. // sourceZoomStep will be higher than targetZoomStep - processSamplingSequence(upsampleSequence, (targetResolution) => - Math.ceil(labeledResolution[thirdDim] / targetResolution[thirdDim]), + processSamplingSequence(upsampleSequence, (targetMag) => + Math.ceil(labeledMag[thirdDim] / targetMag[thirdDim]), ); // Next we downsample the annotation and apply it. // sourceZoomStep will be lower than targetZoomStep - processSamplingSequence(downsampleSequence, (_targetResolution) => 1); + processSamplingSequence(downsampleSequence, (_targetMag) => 1); } export function* labelWithVoxelBuffer2D( @@ -185,8 +185,8 @@ export function* labelWithVoxelBuffer2D( const { cube } = segmentationLayer; const currentLabeledVoxelMap: LabeledVoxelsMap = new Map(); const dimensionIndices = Dimensions.getIndices(viewport); - const resolutionInfo = yield* call(getMagInfo, segmentationLayer.resolutions); - const labeledResolution = resolutionInfo.getMagByIndexOrThrow(labeledZoomStep); + const magInfo = yield* call(getMagInfo, segmentationLayer.mags); + const labeledMag = magInfo.getMagByIndexOrThrow(labeledZoomStep); const get3DCoordinateFromLocal2D = ([x, y]: Vector2) => voxelBuffer.get3DCoordinate([x + voxelBuffer.minCoord2d[0], y + voxelBuffer.minCoord2d[1]]); @@ -241,7 +241,7 @@ export function* labelWithVoxelBuffer2D( const shouldOverwrite = overwriteMode === OverwriteModeEnum.OVERWRITE_ALL; // Since the LabeledVoxelMap is created in the current magnification, // we only need to annotate one slice in this mag. - // `applyLabeledVoxelMapToAllMissingResolutions` will take care of + // `applyLabeledVoxelMapToAllMissingMags` will take care of // annotating multiple slices const numberOfSlices = 1; const thirdDim = dimensionIndices[2]; @@ -262,12 +262,12 @@ export function* labelWithVoxelBuffer2D( if (wroteVoxels) { // thirdDimensionOfSlice needs to be provided in global coordinates const thirdDimensionOfSlice = - topLeft3DCoord[dimensionIndices[2]] * labeledResolution[dimensionIndices[2]]; + topLeft3DCoord[dimensionIndices[2]] * labeledMag[dimensionIndices[2]]; applyLabeledVoxelMapToAllMissingMags( currentLabeledVoxelMap, labeledZoomStep, dimensionIndices, - resolutionInfo, + magInfo, cube, newCellIdValue, thirdDimensionOfSlice, @@ -284,10 +284,10 @@ export function* labelWithVoxelBuffer2D( export function* createVolumeLayer( volumeTracing: VolumeTracing, planeId: OrthoView, - labeledResolution: Vector3, + labeledMags: Vector3, thirdDimValue?: number, ): Saga { const position = yield* select((state) => getFlooredPosition(state.flycam)); thirdDimValue = thirdDimValue ?? position[Dimensions.thirdDimensionForPlane(planeId)]; - return new VolumeLayer(volumeTracing.tracingId, planeId, thirdDimValue, labeledResolution); + return new VolumeLayer(volumeTracing.tracingId, planeId, thirdDimValue, labeledMags); } diff --git a/frontend/javascripts/oxalis/model/sagas/volume/volume_interpolation_saga.ts b/frontend/javascripts/oxalis/model/sagas/volume/volume_interpolation_saga.ts index 6a123d96060..55f47e57724 100644 --- a/frontend/javascripts/oxalis/model/sagas/volume/volume_interpolation_saga.ts +++ b/frontend/javascripts/oxalis/model/sagas/volume/volume_interpolation_saga.ts @@ -70,7 +70,7 @@ function _getInterpolationInfo(state: OxalisState, explanationPrefix: string) { isDisabled: true, activeViewport: OrthoViews.PLANE_XY, previousCentroid: null, - labeledResolution: [1, 1, 1] as Vector3, + labeledMag: [1, 1, 1] as Vector3, labeledZoomStep: 0, interpolationDepth, directionFactor, @@ -84,14 +84,14 @@ function _getInterpolationInfo(state: OxalisState, explanationPrefix: string) { const segmentationLayer = Model.getSegmentationTracingLayer(volumeTracing.tracingId); const requestedZoomStep = getActiveMagIndexForLayer(state, segmentationLayer.name); - const resolutionInfo = getMagInfo(segmentationLayer.resolutions); - const labeledZoomStep = resolutionInfo.getClosestExistingIndex(requestedZoomStep); - const labeledResolution = resolutionInfo.getMagByIndexOrThrow(labeledZoomStep); + const magInfo = getMagInfo(segmentationLayer.mags); + const labeledZoomStep = magInfo.getClosestExistingIndex(requestedZoomStep); + const labeledMag = magInfo.getMagByIndexOrThrow(labeledZoomStep); const previousCentroid = getLabelActionFromPreviousSlice( state, volumeTracing, - labeledResolution, + labeledMag, thirdDim, )?.centroid; @@ -101,12 +101,12 @@ function _getInterpolationInfo(state: OxalisState, explanationPrefix: string) { if (previousCentroid != null) { const position = getFlooredPosition(state.flycam); // Note that in coarser mags (e.g., 8-8-2), the comparison of the coordinates - // is done while respecting how the coordinates are clipped due to that resolution. + // is done while respecting how the coordinates are clipped due to that magnification. // For example, in mag 8-8-2, the z distance needs to be divided by two, since it is measured // in global coordinates. - const adapt = (vec: Vector3) => V3.roundElementToMag(vec, labeledResolution, thirdDim); + const adapt = (vec: Vector3) => V3.roundElementToMag(vec, labeledMag, thirdDim); const signedInterpolationDepth = Math.floor( - V3.sub(adapt(position), adapt(previousCentroid))[thirdDim] / labeledResolution[thirdDim], + V3.sub(adapt(position), adapt(previousCentroid))[thirdDim] / labeledMag[thirdDim], ); directionFactor = Math.sign(signedInterpolationDepth); interpolationDepth = Math.abs(signedInterpolationDepth); @@ -142,7 +142,7 @@ function _getInterpolationInfo(state: OxalisState, explanationPrefix: string) { isDisabled, activeViewport, previousCentroid, - labeledResolution, + labeledMag, labeledZoomStep, interpolationDepth, directionFactor, @@ -282,11 +282,11 @@ export default function* maybeInterpolateSegmentationLayer(): Saga { const overwriteMode = yield* select((state) => state.userConfiguration.overwriteMode); // Disable copy-segmentation for the same zoom steps where the brush/trace tool is forbidden, too. - const isResolutionTooLow = yield* select((state) => + const isMagTooLow = yield* select((state) => isVolumeAnnotationDisallowedForZoom(activeTool, state), ); - if (isResolutionTooLow) { + if (isMagTooLow) { Toast.warning( 'The "interpolate segmentation"-feature is not supported at this zoom level. Please zoom in further.', ); @@ -297,7 +297,7 @@ export default function* maybeInterpolateSegmentationLayer(): Saga { activeViewport, previousCentroid, disabledExplanation, - labeledResolution, + labeledMag, labeledZoomStep, interpolationDepth, directionFactor, @@ -333,11 +333,11 @@ export default function* maybeInterpolateSegmentationLayer(): Saga { const relevantBoxMag1 = viewportBoxMag1 // Consider the n previous/next slices .paddedWithSignedMargins( - transpose([0, 0, -directionFactor * interpolationDepth * labeledResolution[thirdDim]]), + transpose([0, 0, -directionFactor * interpolationDepth * labeledMag[thirdDim]]), ) - .alignWithMag(labeledResolution, "grow") + .alignWithMag(labeledMag, "grow") .rounded(); - const relevantBoxCurrentMag = relevantBoxMag1.fromMag1ToMag(labeledResolution); + const relevantBoxCurrentMag = relevantBoxMag1.fromMag1ToMag(labeledMag); const additionalCoordinates = yield* select((state) => state.flycam.additionalCoordinates); const inputData = yield* call( @@ -372,8 +372,8 @@ export default function* maybeInterpolateSegmentationLayer(): Saga { createVolumeLayer, volumeTracing, activeViewport, - labeledResolution, - relevantBoxMag1.min[thirdDim] + labeledResolution[thirdDim] * targetOffsetW, + labeledMag, + relevantBoxMag1.min[thirdDim] + labeledMag[thirdDim] * targetOffsetW, ); interpolationVoxelBuffers[targetOffsetW] = interpolationLayer.createVoxelBuffer2D( V2.floor( diff --git a/frontend/javascripts/oxalis/model/sagas/volumetracing_saga.tsx b/frontend/javascripts/oxalis/model/sagas/volumetracing_saga.tsx index 13fc5f01d81..f1770e8598c 100644 --- a/frontend/javascripts/oxalis/model/sagas/volumetracing_saga.tsx +++ b/frontend/javascripts/oxalis/model/sagas/volumetracing_saga.tsx @@ -212,11 +212,11 @@ export function* editVolumeLayerAsync(): Saga { continue; } - const maybeLabeledResolutionWithZoomStep = yield* select((state) => + const maybeLabeledMagWithZoomStep = yield* select((state) => getRenderableMagForSegmentationTracing(state, volumeTracing), ); - if (!maybeLabeledResolutionWithZoomStep) { + if (!maybeLabeledMagWithZoomStep) { // Volume data is currently not rendered. Don't annotate anything. continue; } @@ -251,13 +251,12 @@ export function* editVolumeLayerAsync(): Saga { volumeTracing.tracingId, ), ); - const { zoomStep: labeledZoomStep, resolution: labeledResolution } = - maybeLabeledResolutionWithZoomStep; + const { zoomStep: labeledZoomStep, mag: labeledMag } = maybeLabeledMagWithZoomStep; const currentLayer = yield* call( createVolumeLayer, volumeTracing, startEditingAction.planeId, - labeledResolution, + labeledMag, ); const initialViewport = yield* select((state) => state.viewModeData.plane.activeViewport); @@ -431,8 +430,8 @@ export function* floodFill(): Saga { const requestedZoomStep = yield* select((state) => getActiveMagIndexForLayer(state, segmentationLayer.name), ); - const resolutionInfo = yield* call(getMagInfo, segmentationLayer.resolutions); - const labeledZoomStep = resolutionInfo.getClosestExistingIndex(requestedZoomStep); + const magInfo = yield* call(getMagInfo, segmentationLayer.mags); + const labeledZoomStep = magInfo.getClosestExistingIndex(requestedZoomStep); const additionalCoordinates = yield* select((state) => state.flycam.additionalCoordinates); const oldSegmentIdAtSeed = cube.getDataValue( seedPosition, @@ -516,7 +515,7 @@ export function* floodFill(): Saga { labeledVoxelMapFromFloodFill, labeledZoomStep, dimensionIndices, - resolutionInfo, + magInfo, cube, activeCellId, indexZ, @@ -609,12 +608,12 @@ export function* ensureToolIsAllowedInMag(): Saga { while (true) { yield* take(["ZOOM_IN", "ZOOM_OUT", "ZOOM_BY_DELTA", "SET_ZOOM_STEP"]); - const isResolutionTooLow = yield* select((state) => { + const isMagTooLow = yield* select((state) => { const { activeTool } = state.uiInformation; return isVolumeAnnotationDisallowedForZoom(activeTool, state); }); - if (isResolutionTooLow) { + if (isMagTooLow) { yield* put(setToolAction(AnnotationToolEnum.MOVE)); } } diff --git a/frontend/javascripts/oxalis/model/volumetracing/volume_annotation_sampling.ts b/frontend/javascripts/oxalis/model/volumetracing/volume_annotation_sampling.ts index 70f88445805..89cf8ec610f 100644 --- a/frontend/javascripts/oxalis/model/volumetracing/volume_annotation_sampling.ts +++ b/frontend/javascripts/oxalis/model/volumetracing/volume_annotation_sampling.ts @@ -18,19 +18,19 @@ function upsampleVoxelMap( thirdDimensionVoxelValue: number, ): LabeledVoxelsMap { // This method upsamples a given LabeledVoxelsMap. For each bucket in the LabeledVoxelsMap this function - // iterates over the buckets in the higher resolution that are covered by the bucket. + // iterates over the buckets in the higher mag that are covered by the bucket. // For each covered bucket all labeled voxel entries are upsampled with a kernel and marked in an array for the covered bucket. // Therefore all covered buckets with their marked array build the upsampled version of the given LabeledVoxelsMap. if (sourceZoomStep <= targetZoomStep) { throw new Error("Trying to upsample a LabeledVoxelMap with the down sample function."); } - const labeledVoxelMapInTargetResolution: LabeledVoxelsMap = new Map(); + const labeledVoxelMapInTargetMag: LabeledVoxelsMap = new Map(); const scaleToSource = map3((val, index) => val / sourceMag[index], targetMag); // This array serves multiple purposes. It has a name / variable for each purpose. const scaleToGoal = map3((val, index) => val / targetMag[index], sourceMag); const numberOfBucketWithinSourceBucket = scaleToGoal; - const singleVoxelBoundsInTargetResolution = scaleToGoal; + const singleVoxelBoundsInTargetMag = scaleToGoal; const boundsOfGoalBucketWithinSourceBucket = map3( (value) => Math.ceil(value * constants.BUCKET_WIDTH), scaleToSource, @@ -109,26 +109,26 @@ function upsampleVoxelMap( secondDimVoxelOffset ] === 1 ) { - const kernelTopLeftVoxelInTargetResolution = [ - kernelLeft * singleVoxelBoundsInTargetResolution[dimensionIndices[0]], - kernelTop * singleVoxelBoundsInTargetResolution[dimensionIndices[1]], + const kernelTopLeftVoxelInTargetMag = [ + kernelLeft * singleVoxelBoundsInTargetMag[dimensionIndices[0]], + kernelTop * singleVoxelBoundsInTargetMag[dimensionIndices[1]], ]; // The labeled voxel is upscaled using a kernel. for ( let firstKernelOffset = 0; - firstKernelOffset < singleVoxelBoundsInTargetResolution[dimensionIndices[0]]; + firstKernelOffset < singleVoxelBoundsInTargetMag[dimensionIndices[0]]; firstKernelOffset++ ) { for ( let secondKernelOffset = 0; - secondKernelOffset < singleVoxelBoundsInTargetResolution[dimensionIndices[1]]; + secondKernelOffset < singleVoxelBoundsInTargetMag[dimensionIndices[1]]; secondKernelOffset++ ) { currentGoalVoxelMap[ - (kernelTopLeftVoxelInTargetResolution[0] + firstKernelOffset) * + (kernelTopLeftVoxelInTargetMag[0] + firstKernelOffset) * constants.BUCKET_WIDTH + - kernelTopLeftVoxelInTargetResolution[1] + + kernelTopLeftVoxelInTargetMag[1] + secondKernelOffset ] = 1; } @@ -140,16 +140,13 @@ function upsampleVoxelMap( } if (annotatedAtleastOneVoxel) { - labeledVoxelMapInTargetResolution.set( - currentGoalBucket.zoomedAddress, - currentGoalVoxelMap, - ); + labeledVoxelMapInTargetMag.set(currentGoalBucket.zoomedAddress, currentGoalVoxelMap); } } } } - return labeledVoxelMapInTargetResolution; + return labeledVoxelMapInTargetMag; } function downsampleVoxelMap( @@ -169,7 +166,7 @@ function downsampleVoxelMap( throw new Error("Trying to upsample a LabeledVoxelMap with the downsample function."); } - const labeledVoxelMapInTargetResolution: LabeledVoxelsMap = new Map(); + const labeledVoxelMapInTargetMag: LabeledVoxelsMap = new Map(); const scaleToSource = map3((val, index) => val / sourceMag[index], targetMag); const scaleToGoal = map3((val, index) => val / targetMag[index], sourceMag); @@ -216,9 +213,9 @@ function downsampleVoxelMap( bucketOffset, ); const goalVoxelMap = - labeledVoxelMapInTargetResolution.get(goalBucket.zoomedAddress) || + labeledVoxelMapInTargetMag.get(goalBucket.zoomedAddress) || new Uint8Array(constants.BUCKET_WIDTH ** 2).fill(0); - // Iterate over the voxelMap in the goal resolution and search in each voxel for a labeled voxel (kernel-wise iteration). + // Iterate over the voxelMap in the goal mag and search in each voxel for a labeled voxel (kernel-wise iteration). const kernelSize = map3((scaleValue) => Math.ceil(scaleValue), scaleToSource); // The next two for loops move the kernel. @@ -264,10 +261,10 @@ function downsampleVoxelMap( } } - labeledVoxelMapInTargetResolution.set(goalBucket.zoomedAddress, goalVoxelMap); + labeledVoxelMapInTargetMag.set(goalBucket.zoomedAddress, goalVoxelMap); } - return labeledVoxelMapInTargetResolution; + return labeledVoxelMapInTargetMag; } export default function sampleVoxelMapToMagnification( diff --git a/frontend/javascripts/oxalis/model_initialization.ts b/frontend/javascripts/oxalis/model_initialization.ts index 49436ed8152..3be1248d892 100644 --- a/frontend/javascripts/oxalis/model_initialization.ts +++ b/frontend/javascripts/oxalis/model_initialization.ts @@ -491,14 +491,14 @@ function getMergedDataLayersFromDatasetAndVolumeTracings( const fallbackLayer = fallbackLayerIndex > -1 ? originalLayers[fallbackLayerIndex] : null; const boundingBox = getDatasetBoundingBox(dataset).asServerBoundingBox(); - const resolutions = tracing.mags || []; - const tracingHasResolutionList = resolutions.length > 0; + const mags = tracing.mags || []; + const tracingHasMagList = mags.length > 0; // Legacy tracings don't have the `tracing.mags` property // since they were created before WK started to maintain multiple magnifications // in volume annotations. Therefore, this code falls back to mag (1, 1, 1) for // that case. - const tracingResolutions: Vector3[] = tracingHasResolutionList - ? resolutions.map(({ x, y, z }) => [x, y, z]) + const tracingMags: Vector3[] = tracingHasMagList + ? mags.map(({ x, y, z }) => [x, y, z]) : [[1, 1, 1]]; const tracingLayer: APISegmentationLayer = { name: tracing.id, @@ -507,7 +507,7 @@ function getMergedDataLayersFromDatasetAndVolumeTracings( category: "segmentation", largestSegmentId: tracing.largestSegmentId, boundingBox, - resolutions: tracingResolutions, + resolutions: tracingMags, mappings: fallbackLayer != null && "mappings" in fallbackLayer ? fallbackLayer.mappings : undefined, // Remember the name of the original layer (e.g., used to request mappings) diff --git a/frontend/javascripts/oxalis/shaders/coords.glsl.ts b/frontend/javascripts/oxalis/shaders/coords.glsl.ts index 5ae2157d59e..dff7a25cdfe 100644 --- a/frontend/javascripts/oxalis/shaders/coords.glsl.ts +++ b/frontend/javascripts/oxalis/shaders/coords.glsl.ts @@ -1,26 +1,26 @@ import { isFlightMode, getW } from "oxalis/shaders/utils.glsl"; import type { ShaderModule } from "./shader_module_system"; -export const getResolution: ShaderModule = { +export const getMagnification: ShaderModule = { code: ` - vec3 getResolution(uint zoomStep, uint globalLayerIndex) { - return allResolutions[zoomStep + resolutionCountCumSum[globalLayerIndex]]; + vec3 getMagnification(uint zoomStep, uint globalLayerIndex) { + return allMagnifications[zoomStep + magnificationCountCumSum[globalLayerIndex]]; } `, }; -export const getResolutionFactors: ShaderModule = { - requirements: [getResolution], +export const getMagnificationFactors: ShaderModule = { + requirements: [getMagnification], code: ` - vec3 getResolutionFactors(uint zoomStepA, uint zoomStepB, uint globalLayerIndex) { - return getResolution(zoomStepA, globalLayerIndex) / getResolution(zoomStepB, globalLayerIndex); + vec3 getMagnificationFactors(uint zoomStepA, uint zoomStepB, uint globalLayerIndex) { + return getMagnification(zoomStepA, globalLayerIndex) / getMagnification(zoomStepB, globalLayerIndex); } `, }; export const getAbsoluteCoords: ShaderModule = { - requirements: [getResolution], + requirements: [getMagnification], code: ` vec3 getAbsoluteCoords(vec3 worldCoordUVW, uint usedZoomStep, uint globalLayerIndex) { - vec3 resolution = getResolution(usedZoomStep, globalLayerIndex); - vec3 coords = transDim(worldCoordUVW) / resolution; + vec3 magnification = getMagnification(usedZoomStep, globalLayerIndex); + vec3 coords = transDim(worldCoordUVW) / magnification; return coords; } `, diff --git a/frontend/javascripts/oxalis/shaders/main_data_shaders.glsl.ts b/frontend/javascripts/oxalis/shaders/main_data_shaders.glsl.ts index e64d09f8839..4501f3bce64 100644 --- a/frontend/javascripts/oxalis/shaders/main_data_shaders.glsl.ts +++ b/frontend/javascripts/oxalis/shaders/main_data_shaders.glsl.ts @@ -11,7 +11,7 @@ import { import { getMaybeFilteredColorOrFallback } from "./filtering.glsl"; import { getAbsoluteCoords, - getResolution, + getMagnification, getWorldCoordUVW, isOutsideOfBoundingBox, } from "./coords.glsl"; @@ -41,7 +41,7 @@ type Params = { orderedColorLayerNames: string[]; segmentationLayerNames: string[]; textureLayerInfos: Record; - resolutionsCount: number; + magnificationsCount: number; voxelSizeFactor: Vector3; isOrthogonal: boolean; tpsTransformPerLayer: Record; @@ -52,8 +52,8 @@ uniform vec2 viewportExtent; uniform float activeMagIndices[<%= globalLayerCount %>]; uniform uint availableLayerIndexToGlobalLayerIndex[<%= globalLayerCount %>]; -uniform vec3 allResolutions[<%= resolutionsCount %>]; -uniform uint resolutionCountCumSum[<%= globalLayerCount %>]; +uniform vec3 allMagnifications[<%= magnificationsCount %>]; +uniform uint magnificationCountCumSum[<%= globalLayerCount %>]; uniform highp usampler2D lookup_texture; uniform highp uint lookup_seeds[3]; @@ -385,7 +385,7 @@ ${compileShader( isOutsideOfBoundingBox, getMaybeFilteredColorOrFallback, hasSegmentation ? getSegmentId : null, - getResolution, + getMagnification, almostEq, )} @@ -442,7 +442,7 @@ void main() { // Invert vertical axis to make calculation more intuitive with top-left coordinates. index.y = PLANE_SUBDIVISION - index.y; - // d is the width/height of a bucket in the current resolution. + // d is the width/height of a bucket in the current magnification. vec2 d = transDim(vec3(bucketWidth) * representativeMagForVertexAlignment).xy; vec3 voxelSizeFactorUVW = transDim(voxelSizeFactor); diff --git a/frontend/javascripts/oxalis/shaders/texture_access.glsl.ts b/frontend/javascripts/oxalis/shaders/texture_access.glsl.ts index e3a3bb82a4c..8e15185537e 100644 --- a/frontend/javascripts/oxalis/shaders/texture_access.glsl.ts +++ b/frontend/javascripts/oxalis/shaders/texture_access.glsl.ts @@ -1,5 +1,5 @@ import { MAX_ZOOM_STEP_DIFF } from "oxalis/model/bucket_data_handling/loading_strategy_logic"; -import { getResolutionFactors, getAbsoluteCoords } from "oxalis/shaders/coords.glsl"; +import { getMagnificationFactors, getAbsoluteCoords } from "oxalis/shaders/coords.glsl"; import { hashCombine } from "./hashing.glsl"; import type { ShaderModule } from "./shader_module_system"; import { transDim } from "./utils.glsl"; @@ -92,7 +92,7 @@ export const getColorForCoords: ShaderModule = { getRgbaAtIndex, getRgbaAtXYIndex, getAbsoluteCoords, - getResolutionFactors, + getMagnificationFactors, hashCombine, transDim, ], @@ -272,10 +272,10 @@ export const getColorForCoords: ShaderModule = { * If we are in the [5, _, _, 0]-bucket, we have to look into the **second** half * of the [2, _, _, 1]-bucket. * We can determine which "half" (subVolumeIndex) is relevant by doing a modulo operation - * with the resolution factor. A typical resolution factor is 2. + * with the magnification factor. A typical magnification factor is 2. */ - vec3 magnificationFactors = getResolutionFactors(renderedMagIdx, activeMagIdx, globalLayerIndex); + vec3 magnificationFactors = getMagnificationFactors(renderedMagIdx, activeMagIdx, globalLayerIndex); vec3 coords = floor(getAbsoluteCoords(worldPositionUVW, activeMagIdx, globalLayerIndex)); offsetInBucket = mod(coords, bucketWidth); vec3 worldBucketPosition = div(coords, bucketWidth); diff --git a/frontend/javascripts/oxalis/store.ts b/frontend/javascripts/oxalis/store.ts index 5d4e0114329..deca802926a 100644 --- a/frontend/javascripts/oxalis/store.ts +++ b/frontend/javascripts/oxalis/store.ts @@ -89,7 +89,7 @@ export type MutableNode = { rotation: Vector3; bitDepth: number; viewport: number; - resolution: number; + mag: number; radius: number; timestamp: number; interpolation: boolean; diff --git a/frontend/javascripts/oxalis/view/action-bar/download_modal_view.tsx b/frontend/javascripts/oxalis/view/action-bar/download_modal_view.tsx index 68cb57d499b..c7091569432 100644 --- a/frontend/javascripts/oxalis/view/action-bar/download_modal_view.tsx +++ b/frontend/javascripts/oxalis/view/action-bar/download_modal_view.tsx @@ -307,7 +307,7 @@ function _DownloadModalView({ const selectedLayer = getLayerByName(dataset, selectedLayerName); const selectedLayerInfos = getExportLayerInfos(selectedLayer, tracing); - const selectedLayerResolutionInfo = getMagInfo(selectedLayer.resolutions); + const selectedLayerMagInfo = getMagInfo(selectedLayer.resolutions); const userBoundingBoxes = [ ...rawUserBoundingBoxes, @@ -323,8 +323,8 @@ function _DownloadModalView({ const [selectedBoundingBoxId, setSelectedBoundingBoxId] = useState( initialBoundingBoxId ?? userBoundingBoxes[0].id, ); - const [rawMag, setMag] = useState(selectedLayerResolutionInfo.getFinestMag()); - const mag = selectedLayerResolutionInfo.getClosestExistingMag(rawMag); + const [rawMag, setMag] = useState(selectedLayerMagInfo.getFinestMag()); + const mag = selectedLayerMagInfo.getClosestExistingMag(rawMag); const [exportFormat, setExportFormat] = useState(ExportFormat.OME_TIFF); const selectedBoundingBox = userBoundingBoxes.find( @@ -672,11 +672,7 @@ function _DownloadModalView({ - + void; }) { - // Use `getResolutionsWithIndices` because returns a sorted list + // Use `getMagsWithIndices` because returns a sorted list const allMags = magnificationInfo.getMagsWithIndices(); return ( diff --git a/frontend/javascripts/oxalis/view/action-bar/toolbar_view.tsx b/frontend/javascripts/oxalis/view/action-bar/toolbar_view.tsx index b60db923cd8..2693a3d8cc5 100644 --- a/frontend/javascripts/oxalis/view/action-bar/toolbar_view.tsx +++ b/frontend/javascripts/oxalis/view/action-bar/toolbar_view.tsx @@ -866,12 +866,11 @@ export default function ToolbarView() { (state: OxalisState) => state.userConfiguration.useLegacyBindings, ); const activeTool = useSelector((state: OxalisState) => state.uiInformation.activeTool); - const maybeResolutionWithZoomStep = useSelector(getRenderableMagForActiveSegmentationTracing); + const maybeMagWithZoomStep = useSelector(getRenderableMagForActiveSegmentationTracing); - const labeledResolution = - maybeResolutionWithZoomStep != null ? maybeResolutionWithZoomStep.resolution : null; - const hasResolutionWithHigherDimension = (labeledResolution || []).some((val) => val > 1); - const multiSliceAnnotationInfoIcon = hasResolutionWithHigherDimension ? ( + const labeledMag = maybeMagWithZoomStep != null ? maybeMagWithZoomStep.mag : null; + const hasMagWithHigherDimension = (labeledMag || []).some((val) => val > 1); + const multiSliceAnnotationInfoIcon = hasMagWithHigherDimension ? ( - resolutions ? resolutions.map(Utils.point3ToVector3) : ([[1, 1, 1]] as Vector3[]), + volumeTracingMags: volumeServerTracings.map(({ mags }) => + mags ? mags.map(Utils.point3ToVector3) : ([[1, 1, 1]] as Vector3[]), ), userBoundingBoxes: userBoundingBoxes || [], }; diff --git a/frontend/javascripts/oxalis/view/left-border-tabs/layer_settings_tab.tsx b/frontend/javascripts/oxalis/view/left-border-tabs/layer_settings_tab.tsx index 9caf578d5cd..29fb787852b 100644 --- a/frontend/javascripts/oxalis/view/left-border-tabs/layer_settings_tab.tsx +++ b/frontend/javascripts/oxalis/view/left-border-tabs/layer_settings_tab.tsx @@ -66,7 +66,7 @@ import { getTransformsForLayer, hasDatasetTransforms, } from "oxalis/model/accessors/dataset_accessor"; -import { getMaxZoomValueForResolution, getPosition } from "oxalis/model/accessors/flycam_accessor"; +import { getMaxZoomValueForMag, getPosition } from "oxalis/model/accessors/flycam_accessor"; import { getAllReadableLayerNames, getReadableNameByVolumeTracingId, @@ -310,15 +310,15 @@ function LayerInfoIconWithTooltip({ }: { layer: APIDataLayer; dataset: APIDataset }) { const renderTooltipContent = useCallback(() => { const elementClass = getElementClass(dataset, layer.name); - const resolutionInfo = getMagInfo(layer.resolutions); - const resolutions = resolutionInfo.getMagList(); + const magInfo = getMagInfo(layer.resolutions); + const mags = magInfo.getMagList(); return (
Data Type: {elementClass}
Available magnifications:
    - {resolutions.map((r) => ( + {mags.map((r) => (
  • {r.join("-")}
  • ))}
@@ -1100,27 +1100,25 @@ class DatasetSettings extends React.PureComponent { const segmentationLayer = Model.getSegmentationTracingLayer(volumeTracing.tracingId); const { fallbackLayerInfo } = segmentationLayer; - const volumeTargetResolutions = + const volumeTargetMag = fallbackLayerInfo != null ? fallbackLayerInfo.resolutions : // This is only a heuristic. At some point, user configuration // might make sense here. getWidestMags(this.props.dataset); - const getMaxDim = (resolution: Vector3) => Math.max(...resolution); + const getMaxDim = (mag: Vector3) => Math.max(...mag); - const volumeTracingResolutions = segmentationLayer.resolutions; + const volumeTracingMags = segmentationLayer.mags; - const sourceMag = _.minBy(volumeTracingResolutions, getMaxDim); + const sourceMag = _.minBy(volumeTracingMags, getMaxDim); if (sourceMag === undefined) { return []; } - const possibleMags = volumeTargetResolutions.filter( - (resolution) => getMaxDim(resolution) >= getMaxDim(sourceMag), - ); + const possibleMags = volumeTargetMag.filter((mag) => getMaxDim(mag) >= getMaxDim(sourceMag)); - const magsToDownsample = _.differenceWith(possibleMags, volumeTracingResolutions, _.isEqual); + const magsToDownsample = _.differenceWith(possibleMags, volumeTracingMags, _.isEqual); return magsToDownsample; }; @@ -1131,9 +1129,9 @@ class DatasetSettings extends React.PureComponent { } const magsToDownsample = this.getVolumeMagsToDownsample(volumeTracing); - const hasExtensiveResolutions = magsToDownsample.length === 0; + const hasExtensiveMags = magsToDownsample.length === 0; - if (hasExtensiveResolutions) { + if (hasExtensiveMags) { return null; } @@ -1622,8 +1620,8 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({ dispatch(setShowSkeletonsAction(showSkeletons)); }, - onZoomToMag(layerName: string, resolution: Vector3) { - const targetZoomValue = getMaxZoomValueForResolution(Store.getState(), layerName, resolution); + onZoomToMag(layerName: string, mag: Vector3) { + const targetZoomValue = getMaxZoomValueForMag(Store.getState(), layerName, mag); dispatch(setZoomStepAction(targetZoomValue)); return targetZoomValue; }, diff --git a/frontend/javascripts/oxalis/view/left-border-tabs/modals/add_volume_layer_modal.tsx b/frontend/javascripts/oxalis/view/left-border-tabs/modals/add_volume_layer_modal.tsx index 565b8ace677..da85eb5fbb5 100644 --- a/frontend/javascripts/oxalis/view/left-border-tabs/modals/add_volume_layer_modal.tsx +++ b/frontend/javascripts/oxalis/view/left-border-tabs/modals/add_volume_layer_modal.tsx @@ -129,11 +129,11 @@ export default function AddVolumeLayerModal({ : null; const [newLayerName, setNewLayerName] = useState(initialNewLayerName); - const resolutionInfo = + const magInfo = selectedSegmentationLayer == null ? getSomeMagInfoForDataset(dataset) : getMagInfo(selectedSegmentationLayer.resolutions); - const [resolutionIndices, setResolutionIndices] = useState([0, 10000]); + const [magIndices, setMagIndices] = useState([0, 10000]); const handleSetNewLayerName = (evt: React.ChangeEvent) => setNewLayerName(evt.target.value); @@ -154,12 +154,8 @@ export default function AddVolumeLayerModal({ Toast.error(validationResult.message); return; } - const minResolutionAllowed = Math.max( - ...resolutionInfo.getMagByIndexOrThrow(resolutionIndices[0]), - ); - const maxResolutionAllowed = Math.max( - ...resolutionInfo.getMagByIndexOrThrow(resolutionIndices[1]), - ); + const minMagAllowed = Math.max(...magInfo.getMagByIndexOrThrow(magIndices[0])); + const maxMagAllowed = Math.max(...magInfo.getMagByIndexOrThrow(magIndices[1])); if (selectedSegmentationLayerName == null) { await addAnnotationLayer(tracing.annotationId, tracing.annotationType, { @@ -167,8 +163,8 @@ export default function AddVolumeLayerModal({ name: newLayerName, fallbackLayerName: undefined, magRestrictions: { - min: minResolutionAllowed, - max: maxResolutionAllowed, + min: minMagAllowed, + max: maxMagAllowed, }, }); } else { @@ -194,8 +190,8 @@ export default function AddVolumeLayerModal({ name: newLayerName, fallbackLayerName, magRestrictions: { - min: minResolutionAllowed, - max: maxResolutionAllowed, + min: minMagAllowed, + max: maxMagAllowed, }, mappingName: maybeMappingName, }); @@ -234,10 +230,10 @@ export default function AddVolumeLayerModal({ /> ) : null} }> diff --git a/frontend/javascripts/oxalis/view/right-border-tabs/connectome_tab/connectome_view.tsx b/frontend/javascripts/oxalis/view/right-border-tabs/connectome_tab/connectome_view.tsx index 3144b9cd252..ac50d3a0de1 100644 --- a/frontend/javascripts/oxalis/view/right-border-tabs/connectome_tab/connectome_view.tsx +++ b/frontend/javascripts/oxalis/view/right-border-tabs/connectome_tab/connectome_view.tsx @@ -163,7 +163,7 @@ const synapseNodeCreator = (synapseId: number, synapsePosition: Vector3): Mutabl radius: Constants.DEFAULT_NODE_RADIUS, rotation: [0, 0, 0], viewport: 0, - resolution: 0, + mag: 0, id: synapseId, timestamp: Date.now(), bitDepth: 8, diff --git a/frontend/javascripts/oxalis/view/right-border-tabs/dataset_info_tab_view.tsx b/frontend/javascripts/oxalis/view/right-border-tabs/dataset_info_tab_view.tsx index 77129bed116..f9e09e57d8c 100644 --- a/frontend/javascripts/oxalis/view/right-border-tabs/dataset_info_tab_view.tsx +++ b/frontend/javascripts/oxalis/view/right-border-tabs/dataset_info_tab_view.tsx @@ -544,10 +544,10 @@ export class DatasetInfoTabView extends React.PureComponent { ); } - renderResolutionsTooltip = () => { - const { dataset, annotation, activeMagInfo: activeResolutionInfo } = this.props; - const { activeMagOfEnabledLayers } = activeResolutionInfo; - const resolutionUnion = getMagnificationUnion(dataset); + renderMagsTooltip = () => { + const { dataset, annotation, activeMagInfo } = this.props; + const { activeMagOfEnabledLayers } = activeMagInfo; + const magUnion = getMagnificationUnion(dataset); return (
Rendered magnification per layer: @@ -564,7 +564,7 @@ export class DatasetInfoTabView extends React.PureComponent { Available magnifications:
    - {resolutionUnion.map((mags) => ( + {magUnion.map((mags) => (
  • {mags.map((mag) => mag.join("-")).join(", ")}
  • ))}
@@ -573,12 +573,12 @@ export class DatasetInfoTabView extends React.PureComponent { ); }; - getResolutionInfo() { - const { activeMagInfo: activeResolutionInfo } = this.props; - const { representativeResolution, isActiveResolutionGlobal } = activeResolutionInfo; + getMagInfo() { + const { activeMagInfo } = this.props; + const { representativeMag, isActiveMagGlobal } = activeMagInfo; - return representativeResolution != null ? ( - + return representativeMag != null ? ( + { paddingTop: 8, }} > - {representativeResolution.join("-")} - {isActiveResolutionGlobal ? "" : "*"}{" "} + {representativeMag.join("-")} + {isActiveMagGlobal ? "" : "*"}{" "} ) : null; @@ -626,7 +626,7 @@ export class DatasetInfoTabView extends React.PureComponent { - {this.getResolutionInfo()} + {this.getMagInfo()}
diff --git a/frontend/javascripts/oxalis/view/right-border-tabs/segments_tab/segment_statistics_modal.tsx b/frontend/javascripts/oxalis/view/right-border-tabs/segments_tab/segment_statistics_modal.tsx index 04a82101df0..b5efd828211 100644 --- a/frontend/javascripts/oxalis/view/right-border-tabs/segments_tab/segment_statistics_modal.tsx +++ b/frontend/javascripts/oxalis/view/right-border-tabs/segments_tab/segment_statistics_modal.tsx @@ -106,7 +106,7 @@ export function SegmentStatisticsModal({ }: Props) { const { dataset, tracing, temporaryConfiguration } = useSelector((state: OxalisState) => state); const magInfo = getMagInfo(visibleSegmentationLayer.resolutions); - const layersFinestResolution = magInfo.getFinestMag(); + const layersFinestMag = magInfo.getFinestMag(); const voxelSize = dataset.dataSource.scale; // Omit checking that all prerequisites for segment stats (such as a segment index) are // met right here because that should happen before opening the modal. @@ -141,14 +141,14 @@ export function SegmentStatisticsModal({ const segmentStatisticsObjects = await Promise.all([ getSegmentVolumes( requestUrl, - layersFinestResolution, + layersFinestMag, segments.map((segment) => segment.id), additionalCoordinates, maybeGetMappingName(), ), getSegmentBoundingBoxes( requestUrl, - layersFinestResolution, + layersFinestMag, segments.map((segment) => segment.id), additionalCoordinates, maybeGetMappingName(), @@ -164,14 +164,11 @@ export function SegmentStatisticsModal({ // Segments in request and their statistics in the response are in the same order const currentSegment = segments[i]; const currentBoundingBox = boundingBoxes[i]; - const boundingBoxInMag1 = getBoundingBoxInMag1( - currentBoundingBox, - layersFinestResolution, - ); + const boundingBoxInMag1 = getBoundingBoxInMag1(currentBoundingBox, layersFinestMag); const currentSegmentSizeInVx = segmentSizes[i]; const volumeInUnit3 = voxelToVolumeInUnit( voxelSize, - layersFinestResolution, + layersFinestMag, currentSegmentSizeInVx, ); const currentGroupId = getGroupIdForSegment(currentSegment); diff --git a/frontend/javascripts/oxalis/view/right-border-tabs/segments_tab/segments_view.tsx b/frontend/javascripts/oxalis/view/right-border-tabs/segments_tab/segments_view.tsx index c2b5a613dbb..d17eb5ea64f 100644 --- a/frontend/javascripts/oxalis/view/right-border-tabs/segments_tab/segments_view.tsx +++ b/frontend/javascripts/oxalis/view/right-border-tabs/segments_tab/segments_view.tsx @@ -828,17 +828,19 @@ class SegmentsView extends React.Component { const { mappingInfo, preferredQualityForMeshPrecomputation, - magInfoOfVisibleSegmentationLayer: resolutionInfo, + magInfoOfVisibleSegmentationLayer, } = this.props; - const defaultOrHigherIndex = resolutionInfo.getIndexOrClosestHigherIndex( + const defaultOrHigherIndex = magInfoOfVisibleSegmentationLayer.getIndexOrClosestHigherIndex( preferredQualityForMeshPrecomputation, ); - const meshfileResolutionIndex = + const meshfileMagIndex = defaultOrHigherIndex != null ? defaultOrHigherIndex - : resolutionInfo.getClosestExistingIndex(preferredQualityForMeshPrecomputation); - const meshfileResolution = resolutionInfo.getMagByIndexWithFallback( - meshfileResolutionIndex, + : magInfoOfVisibleSegmentationLayer.getClosestExistingIndex( + preferredQualityForMeshPrecomputation, + ); + const meshfileMag = magInfoOfVisibleSegmentationLayer.getMagByIndexWithFallback( + meshfileMagIndex, null, ); @@ -859,7 +861,7 @@ class SegmentsView extends React.Component { const job = await startComputeMeshFileJob( this.props.dataset.id, getBaseSegmentationName(this.props.visibleSegmentationLayer), - meshfileResolution, + meshfileMag, maybeMappingName, ); this.setState({ @@ -890,21 +892,17 @@ class SegmentsView extends React.Component { } }; - handleQualityChangeForPrecomputation = (resolutionIndex: number) => - Store.dispatch( - updateTemporarySettingAction("preferredQualityForMeshPrecomputation", resolutionIndex), - ); + handleQualityChangeForPrecomputation = (magIndex: number) => + Store.dispatch(updateTemporarySettingAction("preferredQualityForMeshPrecomputation", magIndex)); - handleQualityChangeForAdHocGeneration = (resolutionIndex: number) => + handleQualityChangeForAdHocGeneration = (magIndex: number) => Store.dispatch( - updateTemporarySettingAction("preferredQualityForMeshAdHocComputation", resolutionIndex), + updateTemporarySettingAction("preferredQualityForMeshAdHocComputation", magIndex), ); getAdHocMeshSettings = () => { - const { - preferredQualityForMeshAdHocComputation, - magInfoOfVisibleSegmentationLayer: resolutionInfo, - } = this.props; + const { preferredQualityForMeshAdHocComputation, magInfoOfVisibleSegmentationLayer: magInfo } = + this.props; return (
@@ -915,10 +913,10 @@ class SegmentsView extends React.Component { style={{ width: 220, }} - value={resolutionInfo.getClosestExistingIndex(preferredQualityForMeshAdHocComputation)} + value={magInfo.getClosestExistingIndex(preferredQualityForMeshAdHocComputation)} onChange={this.handleQualityChangeForAdHocGeneration} > - {resolutionInfo + {magInfo .getMagsWithIndices() .map(([log2Index, mag]: [number, Vector3], index: number) => (