Skip to content

Commit

Permalink
Remove unlink fallback layer functionality (#6146)
Browse files Browse the repository at this point in the history
* remove unlink fallback layer feature
* update changelog
* Merge branch 'master' into remove-unlink-fallback
* Merge branch 'master' into remove-unlink-fallback
  • Loading branch information
daniel-wer authored Apr 20, 2022
1 parent ebc2223 commit 81980c3
Show file tree
Hide file tree
Showing 11 changed files with 3 additions and 128 deletions.
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

0 comments on commit 81980c3

Please sign in to comment.