-
Notifications
You must be signed in to change notification settings - Fork 26
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
Changes from 1 commit
435f2f1
ee1f591
4f7dcb0
db2998a
719a98a
c2190cd
a9fb85e
7f045f5
d0be7b9
60a5acf
c252d40
7512f3a
0aa7e31
9d16876
7688824
28a66f9
b81be12
77d6e32
cd5d318
485c2d3
7601d6f
ef24b0a
5d3a7e9
04e4f96
2d740f7
740efd6
4ec2dc9
a810b43
0bbbe0d
310375f
9f6a3e7
c02083c
edff465
b43250b
4d9ca99
4af34cf
dad50a8
b581c4b
89bb93f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,12 +2,16 @@ | |
import React, { useEffect, useState, type Node } from "react"; | ||
import { type APIDataset, type APIJob } from "types/api_flow_types"; | ||
import { Modal, Select, Button } from "antd"; | ||
import { startNucleiInferralJob, startNeuronInferralJob } from "admin/admin_rest_api"; | ||
import { | ||
startNucleiInferralJob, | ||
startNeuronInferralJob, | ||
startApplyMergerModeJob, | ||
} from "admin/admin_rest_api"; | ||
import { useSelector } from "react-redux"; | ||
import { getColorLayers } from "oxalis/model/accessors/dataset_accessor"; | ||
import { getColorLayers, getSegmentationLayers } from "oxalis/model/accessors/dataset_accessor"; | ||
import { getUserBoundingBoxesFromState } from "oxalis/model/accessors/tracing_accessor"; | ||
import Toast from "libs/toast"; | ||
import { type OxalisState, type UserBoundingBox } from "oxalis/store"; | ||
import { type UserBoundingBox } from "oxalis/store"; | ||
import { Unicode, type Vector3 } from "oxalis/constants"; | ||
import { capitalizeWords, computeArrayFromBoundingBox, rgbToHex } from "libs/utils"; | ||
|
||
|
@@ -28,23 +32,26 @@ type StartingJobModalProps = { | |
jobName: string, | ||
description: Node, | ||
isBoundingBoxConfigurable?: boolean, | ||
chooseSegmentationLayer?: boolean, | ||
}; | ||
|
||
function StartingJobModal(props: StartingJobModalProps) { | ||
const isBoundingBoxConfigurable = props.isBoundingBoxConfigurable || false; | ||
const chooseSegmentationLayer = props.chooseSegmentationLayer || false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The main changes here and below are that I enabled |
||
const { dataset, handleClose, jobName, description, jobApiCall } = props; | ||
const userBoundingBoxes = useSelector((state: OxalisState) => | ||
getUserBoundingBoxesFromState(state), | ||
); | ||
const [selectedColorLayerName, setSelectedColorLayerName] = useState<?string>(null); | ||
const userBoundingBoxes = useSelector(state => getUserBoundingBoxesFromState(state)); | ||
const [selectedLayerName, setSelectedLayerName] = useState<?string>(null); | ||
const [selectedBoundingBox, setSelectedBoundingBox] = useState<?UserBoundingBox>(null); | ||
const colorLayerNames = getColorLayers(dataset).map(layer => layer.name); | ||
const layerNames = (chooseSegmentationLayer | ||
? getSegmentationLayers(dataset) | ||
: getColorLayers(dataset) | ||
).map(layer => layer.name); | ||
useEffect(() => { | ||
if (colorLayerNames.length === 1) { | ||
setSelectedColorLayerName(colorLayerNames[0]); | ||
if (layerNames.length === 1) { | ||
setSelectedLayerName(layerNames[0]); | ||
} | ||
}); | ||
if (colorLayerNames.length < 1) { | ||
if (layerNames.length < 1) { | ||
return null; | ||
} | ||
const onChangeBoundingBox = (selectedBBoxId: number) => { | ||
|
@@ -54,15 +61,15 @@ function StartingJobModal(props: StartingJobModalProps) { | |
} | ||
}; | ||
const startJob = async () => { | ||
if (selectedColorLayerName == null) { | ||
if (selectedLayerName == null) { | ||
return; | ||
} | ||
try { | ||
let apiJob; | ||
if (isBoundingBoxConfigurable) { | ||
apiJob = await jobApiCall(selectedColorLayerName, selectedBoundingBox); | ||
apiJob = await jobApiCall(selectedLayerName, selectedBoundingBox); | ||
} else { | ||
apiJob = await jobApiCall(selectedColorLayerName); | ||
apiJob = await jobApiCall(selectedLayerName); | ||
} | ||
if (!apiJob) { | ||
return; | ||
|
@@ -87,24 +94,24 @@ function StartingJobModal(props: StartingJobModalProps) { | |
}; | ||
|
||
const ColorLayerSelection = (): Node => | ||
colorLayerNames.length > 1 ? ( | ||
layerNames.length > 1 ? ( | ||
<React.Fragment> | ||
<p>Please select the layer that should be used for the inferral.</p> | ||
<p>Please select the layer that should be used for this job.</p> | ||
<div style={{ textAlign: "center" }}> | ||
<Select | ||
showSearch | ||
style={{ width: 300 }} | ||
placeholder="Select a color layer" | ||
optionFilterProp="children" | ||
value={selectedColorLayerName} | ||
onChange={setSelectedColorLayerName} | ||
value={selectedLayerName} | ||
onChange={setSelectedLayerName} | ||
filterOption={(input, option) => | ||
option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0 | ||
} | ||
> | ||
{colorLayerNames.map(colorLayerName => ( | ||
<Select.Option key={colorLayerName} value={colorLayerName}> | ||
{colorLayerName} | ||
{layerNames.map(layerName => ( | ||
<Select.Option key={layerName} value={layerName}> | ||
{layerName} | ||
</Select.Option> | ||
))} | ||
</Select> | ||
|
@@ -166,7 +173,7 @@ function StartingJobModal(props: StartingJobModalProps) { | |
) : null; | ||
|
||
const hasUnselectedOptions = | ||
selectedColorLayerName == null || (isBoundingBoxConfigurable && selectedBoundingBox == null); | ||
selectedLayerName == null || (isBoundingBoxConfigurable && selectedBoundingBox == null); | ||
|
||
return ( | ||
<Modal | ||
|
@@ -198,7 +205,7 @@ function StartingJobModal(props: StartingJobModalProps) { | |
} | ||
|
||
export function NucleiInferralModal({ handleClose }: Props) { | ||
const dataset = useSelector((state: OxalisState) => state.dataset); | ||
const dataset = useSelector(state => state.dataset); | ||
philippotto marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return ( | ||
<StartingJobModal | ||
dataset={dataset} | ||
|
@@ -229,7 +236,7 @@ export function NucleiInferralModal({ handleClose }: Props) { | |
} | ||
|
||
export function NeuronInferralModal({ handleClose }: Props) { | ||
const dataset = useSelector((state: OxalisState) => state.dataset); | ||
const dataset = useSelector(state => state.dataset); | ||
return ( | ||
<StartingJobModal | ||
dataset={dataset} | ||
|
@@ -268,3 +275,34 @@ export function NeuronInferralModal({ handleClose }: Props) { | |
/> | ||
); | ||
} | ||
|
||
export function ApplyMergerModeModal({ handleClose }: Props) { | ||
const dataset = useSelector(state => state.dataset); | ||
const annotationId = useSelector(store => store.tracing.annotationId); | ||
return ( | ||
<StartingJobModal | ||
dataset={dataset} | ||
handleClose={handleClose} | ||
jobName="apply merger mode" | ||
chooseSegmentationLayer | ||
jobApiCall={async colorLayerName => | ||
startApplyMergerModeJob( | ||
dataset.owningOrganization, | ||
dataset.name, | ||
colorLayerName, | ||
annotationId, | ||
) | ||
} | ||
description={ | ||
<> | ||
<p> | ||
Start a job that take the current state of this merger mode tracing and apply it to the | ||
segmentation layer. This will create a new dataset which contains the merged | ||
segmentation layer. If this dataset has more than one segmentation layer, please select | ||
the segmentation layer to the merging should be applied to. | ||
</p> | ||
</> | ||
} | ||
/> | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure, whether this is everything I need to do here for the new job. I did not test the jobs list view and therefore this is likely untested.