Skip to content

Commit bd70862

Browse files
Fix merging editable mappings where self-merge is generated; fix compacted update action writes (#8367)
* Fix merging editable mappings where self-merge is generated; fix compacted update action writes * Update application.conf * changelog * Apply suggestions from code review Co-authored-by: MichaelBuessemeyer <39529669+MichaelBuessemeyer@users.noreply.github.com> --------- Co-authored-by: MichaelBuessemeyer <39529669+MichaelBuessemeyer@users.noreply.github.com>
1 parent 2171b8f commit bd70862

File tree

3 files changed

+31
-16
lines changed

3 files changed

+31
-16
lines changed

CHANGELOG.unreleased.md

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released
1919

2020
### Fixed
2121
- Fixed a bug that lead to trees being dropped when merging to trees together. [#8359](https://github.com/scalableminds/webknossos/pull/8359)
22+
- Fixed a bug where merging editable mapping (“proofreading”) annotations would sometimes fail. [#8367](https://github.com/scalableminds/webknossos/pull/8367)
2223

2324
### Removed
2425
- Removed the feature to downsample existing volume annotations. All new volume annotations had a whole mag stack since [#4755](https://github.com/scalableminds/webknossos/pull/4755) (four years ago). [#7917](https://github.com/scalableminds/webknossos/pull/7917)

webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/tracings/editablemapping/EditableMappingUpdater.scala

+28-15
Original file line numberDiff line numberDiff line change
@@ -334,13 +334,15 @@ class EditableMappingUpdater(
334334
agglomerateId2 <- agglomerateIdForSegmentId(segmentId2) ?~> "Failed to look up agglomerate ids for merge action segments"
335335
agglomerateGraph1 <- agglomerateGraphForIdWithFallback(mapping, agglomerateId1) ?~> s"Failed to get agglomerate graph for id $agglomerateId1"
336336
agglomerateGraph2 <- agglomerateGraphForIdWithFallback(mapping, agglomerateId2) ?~> s"Failed to get agglomerate graph for id $agglomerateId2"
337-
_ <- bool2Fox(agglomerateGraph2.segments.contains(segmentId2)) ?~> s"Segment $segmentId2 as queried by position ${update.segmentPosition2} is not contained in fetched agglomerate graph for agglomerate $agglomerateId2"
337+
_ <- bool2Fox(agglomerateGraph2.segments.contains(segmentId2)) ?~> s"Segment $segmentId2 as queried by position ${update.segmentPosition2} is not contained in fetched agglomerate graph for agglomerate $agglomerateId2. actionTimestamp: ${update.actionTimestamp}, graph segments: ${agglomerateGraph2.segments}"
338338
mergedGraphOpt = mergeGraph(agglomerateGraph1, agglomerateGraph2, segmentId1, segmentId2)
339339
_ <- Fox.runOptional(mergedGraphOpt) { mergedGraph =>
340340
for {
341341
_ <- updateSegmentToAgglomerate(agglomerateGraph2.segments, agglomerateId1) ?~> s"Failed to update segment to agglomerate buffer"
342342
_ = updateAgglomerateGraph(agglomerateId1, mergedGraph)
343-
_ = updateAgglomerateGraph(agglomerateId2, AgglomerateGraph(List.empty, List.empty, List.empty, List.empty))
343+
_ = if (agglomerateId1 != agglomerateId2)
344+
// The second agglomerate vanishes, as all its segments have been moved to agglomerateId1
345+
updateAgglomerateGraph(agglomerateId2, AgglomerateGraph(List.empty, List.empty, List.empty, List.empty))
344346
} yield ()
345347
}
346348
} yield mapping
@@ -349,19 +351,30 @@ class EditableMappingUpdater(
349351
agglomerateGraph2: AgglomerateGraph,
350352
segmentId1: Long,
351353
segmentId2: Long): Option[AgglomerateGraph] = {
352-
val segment1IsValid = agglomerateGraph1.segments.contains(segmentId1)
353-
val segment2IsValid = agglomerateGraph2.segments.contains(segmentId2)
354-
if (segment1IsValid && segment2IsValid) {
355-
val newEdge = AgglomerateEdge(segmentId1, segmentId2)
356-
val newEdgeAffinity = 255.0f
357-
Some(
358-
AgglomerateGraph(
359-
segments = agglomerateGraph1.segments ++ agglomerateGraph2.segments,
360-
edges = newEdge +: (agglomerateGraph1.edges ++ agglomerateGraph2.edges),
361-
affinities = newEdgeAffinity +: (agglomerateGraph1.affinities ++ agglomerateGraph2.affinities),
362-
positions = agglomerateGraph1.positions ++ agglomerateGraph2.positions
363-
))
364-
} else None
354+
val newEdgeAffinity = 255.0f
355+
val newEdge = AgglomerateEdge(segmentId1, segmentId2)
356+
if (agglomerateGraph1 == agglomerateGraph2) {
357+
// Agglomerate is merged with itself. Insert new edge anyway, if it does not exist yet
358+
if (agglomerateGraph1.edges.contains(newEdge)) {
359+
Some(agglomerateGraph1)
360+
} else {
361+
Some(
362+
agglomerateGraph1.copy(edges = newEdge +: agglomerateGraph1.edges,
363+
affinities = newEdgeAffinity +: agglomerateGraph1.affinities))
364+
}
365+
} else {
366+
val segment1IsValid = agglomerateGraph1.segments.contains(segmentId1)
367+
val segment2IsValid = agglomerateGraph2.segments.contains(segmentId2)
368+
if (segment1IsValid && segment2IsValid) {
369+
Some(
370+
AgglomerateGraph(
371+
segments = agglomerateGraph1.segments ++ agglomerateGraph2.segments,
372+
edges = newEdge +: (agglomerateGraph1.edges ++ agglomerateGraph2.edges),
373+
affinities = newEdgeAffinity +: (agglomerateGraph1.affinities ++ agglomerateGraph2.affinities),
374+
positions = agglomerateGraph1.positions ++ agglomerateGraph2.positions
375+
))
376+
} else None
377+
}
365378
}
366379

367380
def revertToVersion(sourceVersion: Long)(implicit ec: ExecutionContext): Fox[Unit] =

webknossos-tracingstore/app/com/scalableminds/webknossos/tracingstore/tracings/volume/VolumeUpdateActions.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,8 @@ object CompactVolumeUpdateAction {
373373
"name" -> o.name,
374374
"value" -> (Json.obj("actionTracingId" -> o.actionTracingId,
375375
"actionTimestamp" -> o.actionTimestamp,
376-
"actionAuthorId" -> o.actionAuthorId) ++ o.value)
376+
"actionAuthorId" -> o.actionAuthorId) ++ o.value),
377+
"isCompacted" -> true
377378
)
378379
}
379380
}

0 commit comments

Comments
 (0)