Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add frontend and backend part for job to materialize a volume annotation #6086

Merged
merged 39 commits into from
May 9, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
435f2f1
add frontend and backend part for job to apply merger mode tracing
MichaelBuessemeyer Feb 28, 2022
ee1f591
renaming variable
MichaelBuessemeyer Feb 28, 2022
4f7dcb0
Merge branch 'master' of github.com:scalableminds/webknossos into add…
MichaelBuessemeyer Mar 21, 2022
db2998a
add annotation type as job parameter and make layer names more readable
MichaelBuessemeyer Mar 21, 2022
719a98a
fix layer selection for merger mode job modal
MichaelBuessemeyer Mar 22, 2022
c2190cd
add job output dataset name to start job modals
MichaelBuessemeyer Mar 31, 2022
a9fb85e
add output dataset name to nuclei & neuron & merger mode job params
MichaelBuessemeyer Mar 31, 2022
7f045f5
Merge branch 'master' of github.com:scalableminds/webknossos into add…
MichaelBuessemeyer Mar 31, 2022
d0be7b9
refactor starting modal for flood fills to use the same root componen…
MichaelBuessemeyer Mar 31, 2022
60a5acf
Merge branch 'master' into add-apply-merger-mode-job
MichaelBuessemeyer Apr 4, 2022
c252d40
Apply suggestions from code review
MichaelBuessemeyer Apr 5, 2022
7512f3a
Merge branch 'master' of github.com:scalableminds/webknossos into add…
MichaelBuessemeyer Apr 5, 2022
0aa7e31
apply pr feedback
MichaelBuessemeyer Apr 5, 2022
9d16876
Merge branch 'add-apply-merger-mode-job' of github.com:scalableminds/…
MichaelBuessemeyer Apr 5, 2022
7688824
disable jobs
MichaelBuessemeyer Apr 5, 2022
28a66f9
update docs
MichaelBuessemeyer Apr 25, 2022
b81be12
apply pr feedback
MichaelBuessemeyer Apr 25, 2022
77d6e32
Merge branch 'master' of github.com:scalableminds/webknossos into add…
MichaelBuessemeyer Apr 25, 2022
cd5d318
add changelog entry
MichaelBuessemeyer Apr 25, 2022
485c2d3
Update docs/volume_annotation.md
MichaelBuessemeyer Apr 27, 2022
7601d6f
only show merger mode job button whe jobs are enabled
MichaelBuessemeyer Apr 27, 2022
ef24b0a
Merge branch 'master' into add-apply-merger-mode-job
MichaelBuessemeyer Apr 27, 2022
5d3a7e9
add output segmentation layer name as user input field to apply merge…
MichaelBuessemeyer Apr 28, 2022
04e4f96
add segmentation output layer name to apply merger mode job api call
MichaelBuessemeyer May 2, 2022
2d740f7
Merge branch 'master' of github.com:scalableminds/webknossos into add…
MichaelBuessemeyer May 2, 2022
740efd6
make merger job available for volume annotation without skeletons
MichaelBuessemeyer May 4, 2022
4ec2dc9
Merge branch 'master' of github.com:scalableminds/webknossos into add…
MichaelBuessemeyer May 4, 2022
a810b43
fix returnLink of materialize job
MichaelBuessemeyer May 5, 2022
0bbbe0d
make materialize volume anotation job better compatible with volume …
MichaelBuessemeyer May 5, 2022
310375f
update doc images and add merge with fallback layer section to docs
MichaelBuessemeyer May 5, 2022
9f6a3e7
Apply suggestions from code review
MichaelBuessemeyer May 5, 2022
c02083c
apply review feedback
MichaelBuessemeyer May 5, 2022
edff465
Merge branch 'master' into add-apply-merger-mode-job
fm3 May 9, 2022
b43250b
Update docs/volume_annotation.md
MichaelBuessemeyer May 9, 2022
4d9ca99
Merge branch 'master' into add-apply-merger-mode-job
MichaelBuessemeyer May 9, 2022
4af34cf
apply pr feedback
MichaelBuessemeyer May 9, 2022
dad50a8
Merge branch 'master' of github.com:scalableminds/webknossos into add…
MichaelBuessemeyer May 9, 2022
b581c4b
Merge branch 'add-apply-merger-mode-job' of github.com:scalableminds/…
MichaelBuessemeyer May 9, 2022
89bb93f
rephrase commennt to make it clearer
MichaelBuessemeyer May 9, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/start_merger_mode_job_modal.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/start_merger_mode_job_modal_button.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/jobs.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Example workflows:
- [converting datasets on upload](./datasets.md#uploading-through-the-web-browser)
- [automated analysis](./automated_analysis.md), e.g., nuclei inferal
- [mesh file (pre)-computation](./mesh_visualization.md)
- [applying a merger mode annotation](./volume_annotation.md#proof_reading_and_merging_segments)
- Tiff export of a bounding box
- downsampling volume annotations

Expand Down
17 changes: 13 additions & 4 deletions docs/volume_annotation.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ The following interactions and modifiers are available when working with the vol
- `Change Brush Size`: Changes the size of the brushing tool.
- `Overwrite Everything`: When labelling with the brush/trace tool, you can annotate every available voxel without any regard if it was already labelled as a different segment or whether it is unlabelled. This allows you to draw over existing segments.
- `Only Overwrite Empty Areas`: In contrast to the `Overwrite Everything` modifier, the forces the brush/trace tool to only label voxels without any segment ID ("empty areas"). This is useful when annotating segments that directly touch each other to avoid accidental overwrites.
- `2D Fill`/ `3D Fill`: Modifies the flood filling tool to work in 2D (in-plane only) or 3D (volumetric fill/re-labelling). 3D flood fill is contraint to a small, regional bounding box for performance reasons. Read more about flood fills below.
- `2D Fill`/ `3D Fill`: Modifies the flood filling tool to work in 2D (in-plane only) or 3D (volumetric fill/re-labelling). 3D flood fill is constrained to a small, regional bounding box for performance reasons. Read more about flood fills below.

![Adding labels with the Trace tool](./images/volume_trace.gif)
![Adding labels with the Brush tool](./images/volume_brush.gif)
Expand All @@ -36,6 +36,15 @@ In the `Segmentation` tab on the right-hand sidepanel, you can see the segment I

The active segment ID under the cursor can be found in the status bar at the bottom of the screen or through the context-sensitive menu on right-click.

### Merging volume annotation with fallback data

After finishing the annotation of a volume layer with a fallback layer, the combined state of these layers can be materialized into a new dataset. For this go to the layer settings in the left border tab. On the top right of the volume layer is the following button:

![Icon to open the materialize volume annotation modal](./images/materialize_volume_annotation_icon.jpg)

This button opens up a modal that starts a long-running job which will materialize the volume annotation.


### Proof-Reading and Merging Segments

webKnossos support proof-reading of segments from automatic segmentation. With "Merger Mode" individual segments (e.g. from over-segmentation) can be combined ("merged") to refine the segmentation and fix split errors.
Expand All @@ -48,7 +57,7 @@ To fix split errors see section on flood filling below.

![Video: Proof-Reading Volume Annotations](https://www.youtube.com/watch?v=Sq4AuWanK14)

After finishing the proof-reading, a long-running job can be started to apply the merging of segments into a new dataset with the same layers. The job can be started via a modal. The modal can be open by clicking on the button next to the merger mode button.
After finishing the proof-reading, a long-running job can be started to apply the merging of segments into a new dataset with the same layers. The job can be started via a modal. The modal can be opened by clicking on the button next to the merger mode button.

![Button to open the Merger mode long-running job modal](./images/start_merger_mode_job_modal_button.jpg)
![Modal to start the Merger mode long-running job](./images/start_merger_mode_job_modal.jpg)
Expand All @@ -57,9 +66,9 @@ After finishing the proof-reading, a long-running job can be started to apply th
webKnossos supports volumetric flood fills (3D) to relabel a segment with a new ID. Instead of having the relabel segment slice-by-slice, webKnossos can do this for you. This operation allows you to fix both split and merge errors:

- For split errors: Combine two segments by relabeling one segment with the ID of the other. Since this operation is fairly compute intensive you might be better of with the `Merger Mode`, explained above.
- For merge errors: You have to manually split two segments at their intersection/border, e.g. a cell boundary. Use the eraser brush and make sure to establish a clear cut between both segments on a slice-by-slice basis. Both segments must not touch any longer. Create a new segment ID from the toolbar and apply to one of the partial segments that you just devided.
- For merge errors: You have to manually split two segments at their intersection/border, e.g. a cell boundary. Use the eraser brush and make sure to establish a clear cut between both segments on a slice-by-slice basis. Both segments must not touch any longer. Create a new segment ID from the toolbar and apply to one of the partial segments that you just divided.

Due to perfomance reasons, 3D flood-fills only work in a small, local bounding box. webKnossos will add bounding box around the affected area. In order to truly propagate the new segment ID(s) throughout a whole dataset, you can trigger a webKnossos job to apply this change globally. From the `BBox` tab in the right-hand menu, press the "Globalize Flood-Fill" button. Make sure to do all local fill operations first and apply them all at once.
Due to performance reasons, 3D flood-fills only work in a small, local bounding box. webKnossos will add bounding box around the affected area. In order to truly propagate the new segment ID(s) throughout a whole dataset, you can trigger a webKnossos job to apply this change globally. From the `BBox` tab in the right-hand menu, press the "Globalize Flood-Fill" button. Make sure to do all local fill operations first and apply them all at once.

Check the `Processing Jobs` page from the `Admin` menu at the top of the screen to track progress or cancel the operation. The finished, processed dataset will appear as new dataset in your dashboard.

Expand Down
22 changes: 15 additions & 7 deletions frontend/javascripts/oxalis/view/action-bar/toolbar_view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,12 @@ function RadioButtonWithTooltip({
disabled={disabled}
{...props}
onClick={(evt) => {
if (document.activeElement) (document.activeElement as HTMLElement).blur();
if (onClick) onClick(evt);
if (document.activeElement) {
(document.activeElement as HTMLElement).blur();
}
if (onClick) {
onClick(evt);
}
}}
/>
</Tooltip>
Expand Down Expand Up @@ -226,10 +230,12 @@ function AdditionalSkeletonModesButtons() {
const isMergerModeEnabled = useSelector(
(state: OxalisState) => state.temporaryConfiguration.isMergerModeEnabled,
);
const [showApplyMergerModeModal, setShowApplyMergerModeModal] = useState<boolean>(false);
const [showMaterializeVolumeAnnotationModal, setShowMaterializeVolumeAnnotationModal] =
useState<boolean>(false);
const isNewNodeNewTreeModeOn = useSelector(
(state: OxalisState) => state.userConfiguration.newNodeNewTree,
);

const toggleNewNodeNewTreeMode = () =>
dispatch(updateUserSettingAction("newNodeNewTree", !isNewNodeNewTreeModeOn));

Expand Down Expand Up @@ -266,17 +272,19 @@ function AdditionalSkeletonModesButtons() {
</ButtonComponent>
</Tooltip>
{features().jobsEnabled && isMergerModeEnabled && (
<Tooltip title="Apply this merger mode tracing.">
<Tooltip title="Materialize this merger mode annotation into a new dataset.">
<ButtonComponent
style={narrowButtonStyle}
onClick={() => setShowApplyMergerModeModal(true)}
onClick={() => setShowMaterializeVolumeAnnotationModal(true)}
>
<ExportOutlined />
</ButtonComponent>
</Tooltip>
)}
{features().jobsEnabled && showApplyMergerModeModal && (
<MaterializeVolumeAnnotationModal handleClose={() => setShowApplyMergerModeModal(false)} />
{features().jobsEnabled && showMaterializeVolumeAnnotationModal && (
<MaterializeVolumeAnnotationModal
handleClose={() => setShowMaterializeVolumeAnnotationModal(false)}
/>
)}
</React.Fragment>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,9 @@ class DatasetSettings extends React.PureComponent<DatasetSettingsProps, State> {
{hasHistogram && !isDisabled ? this.getEditMinMaxButton(layerName, isInEditMode) : null}
</div>
<div className="flex-item">
{isVolumeTracing && !isDisabled ? this.getMergeWithFallbackLayerButton(layer) : null}
{isVolumeTracing && !isDisabled && maybeFallbackLayer != null
? this.getMergeWithFallbackLayerButton(layer)
: null}
</div>
<div className="flex-item">
{this.getFindDataButton(layerName, isDisabled, isColorLayer, maybeVolumeTracing)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ import {
} from "admin/admin_rest_api";
import { useSelector } from "react-redux";
import { DatasetNameFormItem } from "admin/dataset/dataset_components";
import { getColorLayers, getSegmentationLayers } from "oxalis/model/accessors/dataset_accessor";
import {
getColorLayers,
getSegmentationLayers,
getDataLayers,
} from "oxalis/model/accessors/dataset_accessor";
import {
getReadableNameByVolumeTracingId,
getActiveSegmentationTracingLayer,
Expand All @@ -23,10 +27,16 @@ import { computeArrayFromBoundingBox, rgbToHex } from "libs/utils";
import { getBaseSegmentationName } from "oxalis/view/right-border-tabs/segments_tab/segments_view_helper";

const { ThinSpace } = Unicode;
const jobNameToImagePath = {
const enum JobNames {
NEURON_INFERRAL = "neuron inferral",
NUCLEI_INFERRAL = "nuclei inferral",
MATERIALIZE_VOLUME_ANNOTATION = "materialize volume annotation",
GLOBALIZE_FLODDFILLS = "globalization of the floodfill operation(s)",
}
const jobNameToImagePath: Record<JobNames, string | null> = {
"neuron inferral": "neuron_inferral_example.jpg",
"nuclei inferral": "nuclei_inferral_example.jpg",
"materializing this volume annotation": "materialize_volume_annotation_example.jpg",
"materialize volume annotation": "materialize_volume_annotation_example.jpg",
"globalization of the floodfill operation(s)": null,
};
type Props = {
Expand Down Expand Up @@ -177,14 +187,12 @@ function BoundingBoxSelectionFormItem({

type OutputSegmentationLayerNameProps = {
hasOutputSegmentationLayer: boolean;
layers: APIDataLayer[];
additionalAllowedNames: string[];
notAllowedLayerNames: string[];
};

export function OutputSegmentationLayerNameFormItem({
hasOutputSegmentationLayer,
layers,
additionalAllowedNames,
notAllowedLayerNames,
}: OutputSegmentationLayerNameProps) {
return (
<Form.Item
Expand All @@ -200,10 +208,7 @@ export function OutputSegmentationLayerNameFormItem({
},
{
validator: async (_rule, newOutputLayerName) => {
if (
layers.some((layer) => layer.name === newOutputLayerName) &&
!additionalAllowedNames.includes(newOutputLayerName)
) {
if (notAllowedLayerNames.includes(newOutputLayerName)) {
const reason =
"This name is already used by another segmentation layer of this dataset.";
return Promise.reject(reason);
Expand Down Expand Up @@ -232,6 +237,7 @@ function StartingJobModal(props: StartingJobModalProps) {
const tracing = useSelector((state: OxalisState) => state.tracing);
const activeUser = useSelector((state: OxalisState) => state.activeUser);
const layers = chooseSegmentationLayer ? getSegmentationLayers(dataset) : getColorLayers(dataset);
const allLayer = getDataLayers(dataset);

const startJob = async ({
layerName,
Expand Down Expand Up @@ -297,7 +303,19 @@ function StartingJobModal(props: StartingJobModalProps) {
initialOutputSegmentationLayerName || "segmentation"
}_corrected`;
// TODO: Other jobs also have an output segmentation layer. The names for these jobs should also be configurable.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This TODO needs to be kept, as the new OutputSegmentationLayerNameFormItem should also be used for the inferral jobs. I did not do it in this pr to avoid making this pr even bigger.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please open a follow-up issue for this :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: #6197

const hasOutputSegmentationLayer = jobName === "materializing this volume annotation";
const hasOutputSegmentationLayer = jobName === JobNames.MATERIALIZE_VOLUME_ANNOTATION;
const notAllowedOutputLayerNames = allLayer
.filter((layer) => {
// Filtering out the layer that is currently selected as this name is allowed
// because the output layer overwrites the selected layer.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Filtering out the layer that is currently selected as this name is allowed
// because the output layer overwrites the selected layer.
// Filtering out the layer that is currently selected as this name is not allowed
// because the output layer would overwrite the selected layer.

if I understood it correctly

Copy link
Contributor Author

@MichaelBuessemeyer MichaelBuessemeyer May 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No sorry, that is exactly not the case here.
All layer names are forbidden !except! the name of the selected volume layer, because this volume layer will don't exist in the output dataset, but it will be replaced with the modified version of this layer. The modified version then will have the name given by the OutputSegmentationLayerNameFormItem.
The list of these names is passed to OutputSegmentationLayerNameFormItem so that this form item can check against these names. In the case of a match, the form item is not submittable / in an error state to prevent the job running in the backend from having problems because of duplicate layer names.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you misunderstood this comment, do you have a different way to express this, that might be easier to understand / not misunderstand?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Filtering out the layer that is currently selected as this name is allowed
// because the output layer overwrites the selected layer.
// Existing layer names may not be used for the output layer. The only exception is the name of the currently selected layer.
// If that layer name is chosen, the original layer data won't exist in the output dataset, since it will be replaced by the new output.

Maybe like this? Needs prettier-formatting, though. You could also keep the comment as is. My interpretation didn't really make sense, which is why I'd hope I won't question the veracity of the comment in the future 😆

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// If that layer name is chosen, the original layer data won't exist in the output dataset, since it will be replaced by the new output.

Technically speaking, this is not correct. The selected layer will never directly exist in the output dataset, if the job has an output layer. Therefore, this is even the case if the layer name is not chosen. But your 3rd sentence reads like it is only the case when the layer name is chosen.

I rephrased your suggestion a little and made it more expressive:

   // is the name of the currently selected layer. This layer is the only one not
   // copied over from the original dataset to the output dataset.
   // Therefore, this name is available as the name for the output layer name.
   // That is why that layer is filtered out here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense 👍

const currentSelectedVolumeLayerName = form.getFieldValue("layerName") || initialLayerName;
return (
getReadableNameOfVolumeLayer(layer, tracing) !== currentSelectedVolumeLayerName &&
layer.name !== currentSelectedVolumeLayerName
);
})
.map((layer) => getReadableNameOfVolumeLayer(layer, tracing) || layer.name);

return (
<Modal title={title} onCancel={handleClose} visible width={700} footer={null}>
{description}
Expand Down Expand Up @@ -337,8 +355,7 @@ function StartingJobModal(props: StartingJobModalProps) {
/>
<OutputSegmentationLayerNameFormItem
hasOutputSegmentationLayer={hasOutputSegmentationLayer}
layers={layers}
additionalAllowedNames={[form.getFieldValue("layerName")]}
notAllowedLayerNames={notAllowedOutputLayerNames}
/>
<BoundingBoxSelectionFormItem
isBoundingBoxConfigurable={isBoundingBoxConfigurable}
Expand All @@ -359,7 +376,7 @@ export function NucleiInferralModal({ handleClose }: Props) {
return (
<StartingJobModal
handleClose={handleClose}
jobName="nuclei inferral"
jobName={JobNames.NUCLEI_INFERRAL}
title="Start a Nuclei Inferral"
suggestedDatasetSuffix="with_nuclei"
jobApiCall={async ({ newDatasetName, selectedLayer: colorLayer }) =>
Expand Down Expand Up @@ -395,7 +412,7 @@ export function NeuronInferralModal({ handleClose }: Props) {
return (
<StartingJobModal
handleClose={handleClose}
jobName="neuron inferral"
jobName={JobNames.NEURON_INFERRAL}
title="Start a Neuron Inferral"
suggestedDatasetSuffix="with_reconstructed_neurons"
isBoundingBoxConfigurable
Expand Down Expand Up @@ -446,17 +463,24 @@ export function MaterializeVolumeAnnotationModal({
const tracing = useSelector((state: OxalisState) => state.tracing);
const activeSegmentationTracingLayer = useSelector(getActiveSegmentationTracingLayer);
const fixedSelectedLayer = selectedVolumeLayer || activeSegmentationTracingLayer;
const readableVolumeLayerName =
fixedSelectedLayer && getReadableNameOfVolumeLayer(fixedSelectedLayer, tracing);
const hasFallbackLayer =
fixedSelectedLayer && "tracingId" in fixedSelectedLayer
? fixedSelectedLayer.fallbackLayer != null
: false;
const isMergerModeEnabled = useSelector(
(state: OxalisState) => state.temporaryConfiguration.isMergerModeEnabled,
);
let description = (
<p>
Start a job that takes the current state of this volume annotation and materializes it into a
new dataset. All annotations done on the
{` "${fixedSelectedLayer && getReadableNameOfVolumeLayer(fixedSelectedLayer, tracing)}" `}
volume layer will be merged with the data of the fallback layer.
new dataset.
{hasFallbackLayer
? ` All annotations done on the "${readableVolumeLayerName}" volume layer will be merged with the data of the fallback layer. `
: null}
{isMergerModeEnabled
? " Additionally, the skeletons will be used to merge segments as merger mode is active. "
? " Since merger mode is currently active, in the new output dataset the segments connected via skeleton nodes will be merged. "
: " "}
Please enter the name of the output dataset and the output segmentation layer.
</p>
Expand All @@ -465,8 +489,9 @@ export function MaterializeVolumeAnnotationModal({
description = (
<p>
Start a job that takes the current state of this merger mode tracing and materializes it
into a new dataset. In the new output dataset the segments connected via skeleton nodes will
be merged. Please enter the name of the output dataset and the output segmentation layer.
into a new dataset. Since merger mode is currently active, in the new output dataset the
segments connected via skeleton nodes will be merged. Please enter the name of the output
dataset and the output segmentation layer.
</p>
);
}
Expand All @@ -475,7 +500,7 @@ export function MaterializeVolumeAnnotationModal({
<StartingJobModal
handleClose={handleClose}
title="Start Materializing this Volume Annotation"
jobName="materializing this volume annotation"
jobName={JobNames.MATERIALIZE_VOLUME_ANNOTATION}
suggestedDatasetSuffix="with_merged_segmentation"
chooseSegmentationLayer
fixedSelectedLayer={fixedSelectedLayer}
Expand Down Expand Up @@ -513,7 +538,7 @@ export function StartGlobalizeFloodfillsModal({ handleClose }: Props) {
<StartingJobModal
handleClose={handleClose}
title="Start Globalizing of the Floodfill Operation(s)"
jobName="globalization of the floodfill operation(s)"
jobName={JobNames.GLOBALIZE_FLODDFILLS}
suggestedDatasetSuffix="with_floodfills"
chooseSegmentationLayer
jobApiCall={async ({ newDatasetName, selectedLayer: segmentationLayer }) => {
Expand Down