Skip to content

Commit

Permalink
create a make-hybrid route which lets you turn any non-hybrid tracing…
Browse files Browse the repository at this point in the history
… into a hybrid tracing #3288
  • Loading branch information
Youri K committed Oct 5, 2018
1 parent 8b6795f commit d915005
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 20 deletions.
12 changes: 12 additions & 0 deletions app/controllers/AnnotationController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,18 @@ class AnnotationController @Inject()(annotationDAO: AnnotationDAO,
}
}

def makeHybrid(typ: String, id: String) = sil.SecuredAction.async { implicit request =>
for {
_ <- bool2Fox(AnnotationType.Explorational.toString == typ) ?~> "make hybrid only for explorationals"
annotation <- provider.provideAnnotation(typ, id, request.identity)
_ <- annotationService.makeAnnotationHybrid(request.identity, annotation)
updated <- provider.provideAnnotation(typ, id, request.identity)
json <- annotationService.publicWrites(updated, Some(request.identity)) ?~> "annotation.write.failed"
} yield {
JsonOk(json)
}
}

private def finishAnnotation(typ: String, id: String, issuingUser: User)(implicit ctx: DBAccessContext): Fox[(Annotation, String)] = {
for {
annotation <- provider.provideAnnotation(typ, id, issuingUser) ?~> "annotation.notFound"
Expand Down
6 changes: 6 additions & 0 deletions app/models/annotation/Annotation.scala
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,12 @@ class AnnotationDAO @Inject()(sqlClient: SQLClient)(implicit ec: ExecutionContex
_ <- run(sqlu"update webknossos.annotations set skeletonTracingId = ${newSkeletonTracingId} where _id = ${id.id}")
} yield ()

def updateVolumeTracingId(id: ObjectId, newVolumeTracingId: String)(implicit ctx: DBAccessContext): Fox[Unit] =
for {
_ <- assertUpdateAccess(id)
_ <- run(sqlu"update webknossos.annotations set volumeTracingId = ${newVolumeTracingId} where _id = ${id.id}")
} yield ()

def updateStatistics(id: ObjectId, statistics: JsObject)(implicit ctx: DBAccessContext): Fox[Unit] =
for {
_ <- assertUpdateAccess(id)
Expand Down
61 changes: 41 additions & 20 deletions app/models/annotation/AnnotationService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -97,35 +97,35 @@ class AnnotationService @Inject()(annotationInformationProvider: AnnotationInfor
)
}

def createTracings(dataSet: DataSet, dataSource: DataSource, tracingType: TracingType.Value, withFallback: Boolean)(implicit ctx: DBAccessContext): Fox[(Option[String], Option[String])] = tracingType match {
case TracingType.skeleton =>
for {
handler <- dataSetService.handlerFor(dataSet)
skeletonTracingId <- handler.saveSkeletonTracing(SkeletonTracingDefaults.createInstance.copy(dataSetName = dataSet.name, editPosition = dataSource.center))
} yield (Some(skeletonTracingId), None)
case TracingType.volume =>
for {
handler <- dataSetService.handlerFor(dataSet)
volumeTracingId <- handler.saveVolumeTracing(createVolumeTracing(dataSource, withFallback))
} yield (None, Some(volumeTracingId))
case TracingType.hybrid =>
for {
handler <- dataSetService.handlerFor(dataSet)
skeletonTracingId <- handler.saveSkeletonTracing(SkeletonTracingDefaults.createInstance.copy(dataSetName = dataSet.name, editPosition = dataSource.center))
volumeTracingId <- handler.saveVolumeTracing(createVolumeTracing(dataSource, withFallback))
} yield (Some(skeletonTracingId), Some(volumeTracingId))
}

def createExplorationalFor(
user: User,
_dataSet: ObjectId,
tracingType: TracingType.Value,
withFallback: Boolean)(implicit ctx: DBAccessContext): Fox[Annotation] = {

def createTracings(dataSet: DataSet, dataSource: DataSource): Fox[(Option[String], Option[String])] = tracingType match {
case TracingType.skeleton =>
for {
handler <- dataSetService.handlerFor(dataSet)
skeletonTracingId <- handler.saveSkeletonTracing(SkeletonTracingDefaults.createInstance.copy(dataSetName = dataSet.name, editPosition = dataSource.center))
} yield (Some(skeletonTracingId), None)
case TracingType.volume =>
for {
handler <- dataSetService.handlerFor(dataSet)
volumeTracingId <- handler.saveVolumeTracing(createVolumeTracing(dataSource, withFallback))
} yield (None, Some(volumeTracingId))
case TracingType.hybrid =>
for {
handler <- dataSetService.handlerFor(dataSet)
skeletonTracingId <- handler.saveSkeletonTracing(SkeletonTracingDefaults.createInstance.copy(dataSetName = dataSet.name, editPosition = dataSource.center))
volumeTracingId <- handler.saveVolumeTracing(createVolumeTracing(dataSource, withFallback))
} yield (Some(skeletonTracingId), Some(volumeTracingId))
}
for {
dataSet <- dataSetDAO.findOne(_dataSet)
dataSource <- dataSetService.dataSourceFor(dataSet)
usableDataSource <- dataSource.toUsable ?~> "DataSet is not imported."
tracingIds <- createTracings(dataSet, usableDataSource)
tracingIds <- createTracings(dataSet, usableDataSource, tracingType, withFallback)
teamId <- selectSuitableTeam(user, dataSet)
annotation = Annotation(
ObjectId.generate,
Expand All @@ -142,6 +142,27 @@ class AnnotationService @Inject()(annotationInformationProvider: AnnotationInfor
}
}

def makeAnnotationHybrid(user: User, annotation: Annotation)(implicit ctx: DBAccessContext) = {
def createNewTracings(dataSet: DataSet, dataSource: DataSource) = annotation.tracingType match {
case TracingType.skeleton => createTracings(dataSet, dataSource, TracingType.volume, false).flatMap {
case (_, Some(volumeId)) => annotationDAO.updateVolumeTracingId(annotation._id, volumeId)
case _ => Fox.failure("unexpected parameter return")
}
case TracingType.volume => createTracings(dataSet, dataSource, TracingType.skeleton, false).flatMap {
case (Some(skeletonId), _) => annotationDAO.updateSkeletonTracingId(annotation._id, skeletonId)
case _ => Fox.failure("unexpected parameter return")
}
case _ => Fox.failure("Cannot create additional tracing for hybrid annotation")
}

for {
dataSet <- dataSetDAO.findOne(annotation._dataSet)
dataSource <- dataSetService.dataSourceFor(dataSet).flatMap(_.toUsable)
_ <- createNewTracings(dataSet, dataSource)
} yield ()

}

// WARNING: needs to be repeatable, might be called multiple times for an annotation
def finish(annotation: Annotation, user: User, restrictions: AnnotationRestrictions)(implicit ctx: DBAccessContext): Fox[String] = {
def executeFinish: Fox[String] = {
Expand Down
1 change: 1 addition & 0 deletions conf/webknossos.routes
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ GET /api/annotations/:typ/:id/revert
POST /api/annotations/:typ/:id/transfer controllers.AnnotationController.transfer(typ: String, id: String)

GET /api/annotations/:typ/:id/info controllers.AnnotationController.info(typ: String, id: String)
PATCH /api/annotations/:typ/:id/makeHybrid controllers.AnnotationController.makeHybrid(typ: String, id: String)
DELETE /api/annotations/:typ/:id controllers.AnnotationController.cancel(typ: String, id: String)
GET /api/annotations/:typ/:id/merge/:mergedTyp/:mergedId controllers.AnnotationController.merge(typ: String, id: String, mergedTyp: String, mergedId: String)
GET /api/annotations/:typ/:id/download controllers.AnnotationIOController.download(typ: String, id: String)
Expand Down

0 comments on commit d915005

Please sign in to comment.