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

Remove unlink fallback layer functionality #6146

Merged
merged 4 commits into from
Apr 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG.unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released
- Fixed the "Copy Slice" shortcut (`v` and `shift + v`) in resolutions other than the most detailed one. [#6130](https://github.com/scalableminds/webknossos/pull/6130)

### Removed
- Removed the functionality to unlink the fallback layer from an existing segmentation layer. Either create an annotation without fallback layer or from within an annotation with a fallback layer, create a new volume layer, instead. [#6146](https://github.com/scalableminds/webknossos/pull/6146)

### Breaking Changes
23 changes: 0 additions & 23 deletions app/controllers/AnnotationController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -257,29 +257,6 @@ class AnnotationController @Inject()(
} yield JsonOk(json)
}

@ApiOperation(hidden = true, value = "")
def unlinkFallback(typ: String, id: String, tracingId: String): Action[AnyContent] = sil.SecuredAction.async {
implicit request =>
for {
_ <- bool2Fox(AnnotationType.Explorational.toString == typ) ?~> "annotation.unlinkFallback.explorationalsOnly"
restrictions <- provider.restrictionsFor(typ, id)
_ <- restrictions.allowUpdate(request.identity) ?~> "notAllowed" ~> FORBIDDEN
annotation <- provider.provideAnnotation(typ, id, request.identity)
annotationLayer <- annotation.annotationLayers
.find(_.tracingId == tracingId)
.toFox ?~> "annotation.unlinkFallback.layerNotFound"
_ <- bool2Fox(annotationLayer.typ == AnnotationLayerType.Volume) ?~> "annotation.unlinkFallback.noVolume"
dataSet <- dataSetDAO
.findOne(annotation._dataSet)(GlobalAccessContext) ?~> "dataSet.notFoundForAnnotation" ~> NOT_FOUND
dataSource <- dataSetService.dataSourceFor(dataSet).flatMap(_.toUsable) ?~> "dataSet.notImported"
tracingStoreClient <- tracingStoreService.clientFor(dataSet)
newTracingId <- tracingStoreClient.unlinkFallback(tracingId, dataSource)
_ <- annotationLayerDAO.replaceTracingId(annotation._id, tracingId, newTracingId)
updatedAnnotation <- provider.provideAnnotation(typ, id, request.identity)
js <- annotationService.publicWrites(updatedAnnotation, Some(request.identity))
} yield JsonOk(js)
}

private def finishAnnotation(typ: String, id: String, issuingUser: User, timestamp: Long)(
implicit ctx: DBAccessContext): Fox[(Annotation, String)] =
for {
Expand Down
9 changes: 0 additions & 9 deletions app/models/annotation/WKRemoteTracingStoreClient.scala
Original file line number Diff line number Diff line change
Expand Up @@ -198,13 +198,4 @@ class WKRemoteTracingStoreClient(tracingStore: TracingStore, dataSet: DataSet, r
} yield data
}

def unlinkFallback(tracingId: String, dataSource: DataSourceLike): Fox[String] = {
logger.debug(s"Called to unlink fallback segmentation for tracing $tracingId." + baseInfo)
for {
newId: String <- rpc(s"${tracingStore.url}/tracings/volume/$tracingId/unlinkFallback")
.addQueryString("token" -> RpcTokenHolder.webKnossosToken)
.postJsonWithJsonResponse[DataSourceLike, String](dataSource)
} yield newId
}

}
3 changes: 0 additions & 3 deletions conf/messages
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,6 @@ annotation.timelogging.read.failed=Time
annotation.write.failed=Could not convert annotation to json
annotation.noSkeleton=No skeleton tracing found for this annotation
annotation.needsEitherSkeletonOrVolume=Annotation needs at least one of skeleton or volume
annotation.unlinkFallback.explorationalsOnly=Could not unlink fallback segmentation (only allowed for explorational annotations).
annotation.unlinkFallback.noVolume=Could not unlink fallback segmentation (only allowed for annotations with volume layer).
annotation.unlinkFallback.layerNotFound=Could not unlink fallback segmentation (annotation layer not found)
annotation.downsample.layerNotFound=Could not downsample volume annotation (annotation layer not found)
annotation.makeHybrid.explorationalsOnly=Could not convert annotation to hybrid annotation because it is only allowed for explorational annotations.
annotation.makeHybrid.failed=Could not convert to hybrid.
Expand Down
1 change: 0 additions & 1 deletion conf/webknossos.latest.routes
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ PATCH /annotations/:typ/:id/transfer c
GET /annotations/:typ/:id/info controllers.AnnotationController.info(typ: String, id: String, timestamp: Long)
PATCH /annotations/:typ/:id/makeHybrid controllers.AnnotationController.makeHybrid(typ: String, id: String, fallbackLayerName: Option[String])
PATCH /annotations/:typ/:id/downsample controllers.AnnotationController.downsample(typ: String, id: String, tracingId: String)
PATCH /annotations/:typ/:id/unlinkFallback controllers.AnnotationController.unlinkFallback(typ: String, id: String, tracingId: String)
PATCH /annotations/:typ/:id/addAnnotationLayer controllers.AnnotationController.addAnnotationLayer(typ: String, id: String)
DELETE /annotations/:typ/:id controllers.AnnotationController.cancel(typ: String, id: String)
POST /annotations/:typ/:id/merge/:mergedTyp/:mergedId controllers.AnnotationController.merge(typ: String, id: String, mergedTyp: String, mergedId: String)
Expand Down
13 changes: 0 additions & 13 deletions frontend/javascripts/admin/admin_rest_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -895,19 +895,6 @@ export async function downloadNml(
saveAs(blob, filename);
}

export async function unlinkFallbackSegmentation(
annotationId: string,
annotationType: APIAnnotationType,
tracingId: string,
): Promise<void> {
await Request.receiveJSON(
`/api/annotations/${annotationType}/${annotationId}/unlinkFallback?tracingId=${tracingId}`,
{
method: "PATCH",
},
);
}

// When the annotation is open, please use the corresponding method
// in api_latest.js. It will take care of saving the annotation and
// reloading it.
Expand Down
6 changes: 0 additions & 6 deletions frontend/javascripts/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,6 @@ instead. Only enable this option if you understand its effect. All layers will n
"There is no mesh for the active segment id available to download.",
"tracing.mesh_listing_failed":
"A precomputed mesh could not be loaded for this segment. More information was printed to the browser's console.",
"tracing.confirm_remove_fallback_layer.title":
"Are you sure you want to unlink the dataset's original segmentation layer?",
"tracing.confirm_remove_fallback_layer.explanation":
"This dataset already contains a segmentation layer provided by its author. If you do not wish to base your work on this original segmentation, you can unlink it by confirming this dialog.",
"tracing.confirm_remove_fallback_layer.notes":
"Note that this action also removes segments which were already annotated manually. This step cannot be undone.",
"tracing.area_to_fill_is_too_big":
"The area you want to fill is too big. Please annotate the area in multiple strokes.",
"tracing.agglomerate_skeleton.no_cell":
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
// @flow

import { Button, Col, Divider, Modal, Row, Switch, Tooltip } from "antd";
import { Button, Col, Divider, Row, Switch, Tooltip } from "antd";
import type { Dispatch } from "redux";
import {
EditOutlined,
InfoCircleOutlined,
ReloadOutlined,
ScanOutlined,
StopOutlined,
WarningOutlined,
PlusOutlined,
VerticalAlignMiddleOutlined,
Expand Down Expand Up @@ -35,7 +34,6 @@ import {
findDataPositionForLayer,
clearCache,
findDataPositionForVolumeTracing,
unlinkFallbackSegmentation,
} from "admin/admin_rest_api";
import {
getDefaultIntensityRangeOfLayer,
Expand Down Expand Up @@ -81,7 +79,7 @@ import Store, {
import Toast from "libs/toast";
import * as Utils from "libs/utils";
import api from "oxalis/api/internal_api";
import messages, { settings } from "messages";
import { settings } from "messages";

import AddVolumeLayerModal from "./modals/add_volume_layer_modal";
import DownsampleVolumeModal from "./modals/downsample_volume_modal";
Expand All @@ -105,7 +103,6 @@ type DatasetSettingsProps = {|
onSetPosition: Vector3 => void,
onZoomToResolution: Vector3 => number,
onChangeUser: (key: $Keys<UserConfiguration>, value: any) => void,
onUnlinkFallbackLayer: (Tracing, VolumeTracing) => Promise<void>,
tracing: Tracing,
task: ?Task,
onEditAnnotationLayer: (tracingId: string, layerProperties: EditableLayerProperties) => void,
Expand Down Expand Up @@ -185,37 +182,6 @@ class DatasetSettings extends React.PureComponent<DatasetSettingsProps, State> {
);
};

getDeleteButton = (volumeTracing: VolumeTracing) => (
<Tooltip title="Unlink dataset's original segmentation layer">
<StopOutlined
onClick={() => {
this.removeFallbackLayer(volumeTracing);
}}
style={{
cursor: "pointer",
}}
/>
</Tooltip>
);

removeFallbackLayer = (volumeTracing: VolumeTracing) => {
Modal.confirm({
title: messages["tracing.confirm_remove_fallback_layer.title"],
content: (
<div>
<p>{messages["tracing.confirm_remove_fallback_layer.explanation"]}</p>
<p>
<b>{messages["tracing.confirm_remove_fallback_layer.notes"]}</b>
</p>
</div>
),
onOk: async () => {
this.props.onUnlinkFallbackLayer(this.props.tracing, volumeTracing);
},
width: 600,
});
};

getEditMinMaxButton = (layerName: string, isInEditMode: boolean) => {
const tooltipText = isInEditMode
? "Stop editing the possible range of the histogram."
Expand Down Expand Up @@ -326,8 +292,6 @@ class DatasetSettings extends React.PureComponent<DatasetSettingsProps, State> {
const maybeTracingId = layer.category === "segmentation" ? layer.tracingId : null;
const maybeVolumeTracing =
maybeTracingId != null ? getVolumeTracingById(tracing, maybeTracingId) : null;
const hasFallbackLayer =
maybeVolumeTracing != null ? maybeVolumeTracing.fallbackLayer != null : false;
const maybeFallbackLayer =
maybeVolumeTracing != null && maybeVolumeTracing.fallbackLayer != null
? maybeVolumeTracing.fallbackLayer
Expand Down Expand Up @@ -456,11 +420,6 @@ class DatasetSettings extends React.PureComponent<DatasetSettingsProps, State> {
</div>

<div className="flex-container">
<div className="flex-item">
{maybeVolumeTracing && hasFallbackLayer
? this.getDeleteButton(maybeVolumeTracing)
: null}
</div>
<div className="flex-item">
{hasHistogram && !isDisabled ? this.getClipButton(layerName, isInEditMode) : null}
</div>
Expand Down Expand Up @@ -903,11 +862,6 @@ const mapDispatchToProps = (dispatch: Dispatch<*>) => ({
dispatch(setZoomStepAction(targetZoomValue));
return targetZoomValue;
},
async onUnlinkFallbackLayer(tracing: Tracing, volumeTracing: VolumeTracing) {
const { annotationId, annotationType } = tracing;
await unlinkFallbackSegmentation(annotationId, annotationType, volumeTracing.tracingId);
await api.tracing.hardReload();
},
onEditAnnotationLayer(tracingId: string, layerProperties: EditableLayerProperties) {
dispatch(editAnnotationLayerAction(tracingId, layerProperties));
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,21 +163,6 @@ class VolumeTracingController @Inject()(val tracingService: VolumeTracingService
}
}

def unlinkFallback(token: Option[String], tracingId: String): Action[DataSourceLike] =
Action.async(validateJson[DataSourceLike]) { implicit request =>
log() {
logTime(slackNotificationService.noticeSlowRequest) {
accessTokenService.validateAccess(UserAccessRequest.webknossos, token) {
for {
tracing <- tracingService.find(tracingId) ?~> Messages("tracing.notFound")
updatedTracing = tracingService.unlinkFallback(tracing, request.body)
newId <- tracingService.save(updatedTracing, None, 0L)
} yield Ok(Json.toJson(newId))
}
}
}
}

def importVolumeData(token: Option[String], tracingId: String): Action[MultipartFormData[TemporaryFile]] =
Action.async(parse.multipartFormData) { implicit request =>
log() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,15 +251,6 @@ class VolumeTracingService @Inject()(
data <- binaryDataService.handleDataRequests(requests)
} yield data

def unlinkFallback(tracing: VolumeTracing, dataSource: DataSourceLike): VolumeTracing =
tracing.copy(
activeSegmentId = None,
largestSegmentId = 0L,
fallbackLayer = None,
version = 0L,
resolutions = VolumeTracingDownsampling.resolutionsForVolumeTracing(dataSource, None).map(vec3IntToProto)
)

def duplicate(tracingId: String,
sourceTracing: VolumeTracing,
fromTask: Boolean,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ GET /volume/:tracingId/allData @com.scalablemin
GET /volume/:tracingId/allDataBlocking @com.scalableminds.webknossos.tracingstore.controllers.VolumeTracingController.allDataBlocking(token: Option[String], tracingId: String, version: Option[Long])
POST /volume/:tracingId/data @com.scalableminds.webknossos.tracingstore.controllers.VolumeTracingController.data(token: Option[String], tracingId: String)
POST /volume/:tracingId/duplicate @com.scalableminds.webknossos.tracingstore.controllers.VolumeTracingController.duplicate(token: Option[String], tracingId: String, fromTask: Option[Boolean], minResolution: Option[Int], maxResolution: Option[Int], downsample: Option[Boolean])
POST /volume/:tracingId/unlinkFallback @com.scalableminds.webknossos.tracingstore.controllers.VolumeTracingController.unlinkFallback(token: Option[String], tracingId: String)
GET /volume/:tracingId/updateActionLog @com.scalableminds.webknossos.tracingstore.controllers.VolumeTracingController.updateActionLog(token: Option[String], tracingId: String)
POST /volume/:tracingId/isosurface @com.scalableminds.webknossos.tracingstore.controllers.VolumeTracingController.requestIsosurface(token: Option[String], tracingId: String)
POST /volume/:tracingId/importVolumeData @com.scalableminds.webknossos.tracingstore.controllers.VolumeTracingController.importVolumeData(token: Option[String], tracingId: String)
Expand Down