diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 694bcb21b3..783edf308b 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -27,6 +27,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released - The warning about a mismatch between the scale of a pre-computed mesh and the dataset scale's factor now also considers all supported mags of the active segmentation layer. This reduces the false posive rate regarding this warning. [#7921](https://github.com/scalableminds/webknossos/pull/7921/) - It is no longer allowed to edit annotations of other organizations, even if they are set to public and to others-may-edit. [#7923](https://github.com/scalableminds/webknossos/pull/7923) - When proofreading segmentations, the user can now interact with super-voxels directly in the data viewports. Additionally, proofreading is significantly faster because the segmentation data doesn't have to be re-downloaded after each merge/split operation. [#7654](https://github.com/scalableminds/webknossos/pull/7654) +- Because of the way our models are trained, AI analysis and training is disabled for 2D and ND datasets, as well as for color layers with data type uInt24. [#7957](https://github.com/scalableminds/webknossos/pull/7957) ### Fixed - Fixed a bug that allowed the default newly created bounding box to appear outside the dataset. In case the whole bounding box would be outside it is created regardless. [#7892](https://github.com/scalableminds/webknossos/pull/7892) diff --git a/frontend/javascripts/oxalis/view/action-bar/starting_job_modals.tsx b/frontend/javascripts/oxalis/view/action-bar/starting_job_modals.tsx index 0cd3a0ac2e..d0ff22ccb9 100644 --- a/frontend/javascripts/oxalis/view/action-bar/starting_job_modals.tsx +++ b/frontend/javascripts/oxalis/view/action-bar/starting_job_modals.tsx @@ -514,7 +514,8 @@ function StartJobForm(props: StartJobFormProps) { const dataset = useSelector((state: OxalisState) => state.dataset); const tracing = useSelector((state: OxalisState) => state.tracing); const activeUser = useSelector((state: OxalisState) => state.activeUser); - const layers = chooseSegmentationLayer ? getSegmentationLayers(dataset) : getColorLayers(dataset); + const colorLayers = getColorLayers(dataset); + const layers = chooseSegmentationLayer ? getSegmentationLayers(dataset) : colorLayers; const allLayers = getDataLayers(dataset); const defaultBBForLayers: UserBoundingBox[] = layers.map((layer, index) => { return { @@ -539,6 +540,13 @@ function StartJobForm(props: StartJobFormProps) { outputSegmentationLayerName: string; }) => { const selectedLayer = layers.find((layer) => layer.name === layerName); + if (selectedLayer?.elementClass === "uint24") { + const errorMessage = + "AI analysis jobs can not be started for color layers with the data type uInt24. Please select a color layer with another data type."; + Toast.error(errorMessage); + console.error(errorMessage); + return; + } const selectedBoundingBox = userBoundingBoxes.find((bbox) => bbox.id === boundingBoxId); if ( selectedLayer == null || @@ -608,6 +616,7 @@ function StartJobForm(props: StartJobFormProps) { ); }) .map((layer) => getReadableNameOfVolumeLayer(layer, tracing) || layer.name); + return (
{ location.href = `${location.origin}/annotations/${annotation.typ}/${annotation.id}${location.hash}`; }; - renderStartAIJobButton(disabled: boolean): React.ReactNode { - const tooltipText = disabled - ? "The dataset needs to have a color layer to start AI processing jobs." - : "Start a processing job using AI"; + renderStartAIJobButton(disabled: boolean, tooltipTextIfDisabled: string): React.ReactNode { + const tooltipText = disabled ? tooltipTextIfDisabled : "Start a processing job using AI"; return ( { const isAdminOrDatasetManager = activeUser && isUserAdminOrTeamManager(activeUser); const isViewMode = controlMode === ControlModeEnum.VIEW; const isArbitrarySupported = hasSkeleton || isViewMode; - const isAIAnalysisEnabled = () => { + const getIsAIAnalysisEnabled = () => { const jobsEnabled = dataset.dataStore.jobsSupportedByAvailableWorkers.includes(APIJobType.INFER_NEURONS) || dataset.dataStore.jobsSupportedByAvailableWorkers.includes(APIJobType.INFER_MITOCHONDRIA) || @@ -272,7 +270,19 @@ class ActionBarView extends React.PureComponent { onDeleteLayout: this.handleLayoutDeleted, }); - const datasetHasColorLayer = getColorLayers(dataset).length > 0; + const colorLayers = getColorLayers(dataset); + const datasetHasNoColorLayer = colorLayers.length === 0; + const isNd = (colorLayers[0]?.additionalAxes ?? []).length > 0; + const is2DOrNDDataset = isNd || is2d; + const isAIAnalysisDisabled = !getIsAIAnalysisEnabled(); + const shouldDisableAIJobButton = + isAIAnalysisDisabled || datasetHasNoColorLayer || is2DOrNDDataset; + let tooltip = "AI analysis is not enabled for this dataset."; + if (datasetHasNoColorLayer) { + tooltip = "The dataset needs to have a color layer to start AI processing jobs."; + } else if (is2DOrNDDataset) { + tooltip = `AI Analysis is not supported for ${is2d ? "2D" : "ND"} datasets.`; + } return ( @@ -286,8 +296,8 @@ class ActionBarView extends React.PureComponent { {isArbitrarySupported && !is2d ? : null} - {isAIAnalysisEnabled() && isAdminOrDatasetManager - ? this.renderStartAIJobButton(!datasetHasColorLayer) + {getIsAIAnalysisEnabled() && isAdminOrDatasetManager + ? this.renderStartAIJobButton(shouldDisableAIJobButton, tooltip) : null} {!isReadOnly && constants.MODES_PLANE.indexOf(viewMode) > -1 ? : null} {isViewMode ? this.renderStartTracingButton() : null} diff --git a/frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx b/frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx index 9d16c90eaf..1cd7f00e75 100644 --- a/frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx +++ b/frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx @@ -37,6 +37,16 @@ export function TrainAiModelTab({ onClose }: { onClose: () => void }) { await Model.ensureSavedState(); const readableVolumeName = getReadableNameForLayerName(dataset, tracing, values.layerName); const segmentationLayer = getSegmentationLayerByName(dataset, values.layerName); + const colorLayer = getColorLayers(dataset).find( + (layer) => layer.name === values.imageDataLayer, + ); + if (colorLayer?.elementClass === "uint24") { + const errorMessage = + "AI training jobs can not be started for color layers with the data type uInt24. Please select a color layer with another data type."; + Toast.error(errorMessage); + console.error(errorMessage); + return; + } await runTraining({ trainingAnnotations: [