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

Release 1.0 into main #13

Merged
merged 7 commits into from
Oct 1, 2024
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
30 changes: 30 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Scala CI

on:
push:
branches: [ main, release* ]
pull_request:
branches: [ main, release* ]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 11
uses: actions/setup-java@v2
with:
distribution: 'temurin'
java-version: 11
- name: Run tests
run: |
sudo apt-get update
sudo apt-get install -y libopengl0
sbt -Djava.awt.headless=true +compile test

lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Formatting
run: sbt scalafmtSbtCheck scalafmtCheck test:scalafmtCheck
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
*.tasty
*.h5
*.h5.json

# bloop and metals
.bloop
.bsp
Expand Down
16 changes: 12 additions & 4 deletions .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
version = "3.5.3"
maxColumn = 120
align = true
align.preset = more
version=3.8.0
project.git = true
runner.dialect = scala3
align.openParenCallSite = true
align.openParenDefnSite = true
maxColumn = 120
continuationIndent.defnSite = 2
assumeStandardLibraryStripMargin = true
danglingParentheses.preset = true
rewrite.rules = [SortImports, SortModifiers]
docstrings.style = Asterisk

onTestFailure = "To fix this, run: sbt scalafmtAll"
48 changes: 26 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,50 +13,54 @@ BibTex:
}
```

The GiNGR framework allows one to perform non-rigid registration with an iterative algorithm that makes use of Gaussian Process Regression in each iteration to find its next state.
The GiNGR framework allows one to perform non-rigid registration with an iterative algorithm that uses Gaussian Process Regression in each iteration to find its next state.

Existing algorithms can be converted into the GiNGR framework, and compared based on 3 properties:
Existing algorithms can be converted into the GiNGR framework and compared based on three properties:

- Kernel function: how similar should the deformation of neighbouring points be - this is determined based on their correlation
- Correspondence estimation function: how to estimate corresponding points between the moving instance (reference) and the target.
- Observation uncertainty: what is the noise assumption of the correspondence estimations?
1. **Kernel function**: how similar should the deformation of neighboring points be - this is determined based on their correlation.
2. **Correspondence estimation function**: how to calculate/estimate anatomically corresponding points between the moving instance (reference) and the target (e.g., use the closest point as a naive approach).
3. **Observation uncertainty**: what is the noise assumption of the correspondence estimations?

This framework contains a general library to input these 3 properties.
This framework contains a general library to input these three properties.

The core part of the GiNGR framework is found in `gingr/api/GingrAlgorithm` with the `update` function performing one iteration of GiNGR update.
Different pre-implemented configuration files can be found in `gingr/api/registration/config` for CPD and ICP.
The core part of the GiNGR framework is found in `gingr/api/GingrAlgorithm`, with the `update` function performing one iteration of a GiNGR update.
Different pre-implemented configuration files can be found under `gingr/api/registration/config` for the CPD and the ICP algorithms.

## Installation
To use the GiNGR framework, you can make use of the maven snapshot by including the follow in your Scala 3 script:
To use the GiNGR framework, you can make use of the maven repository version by including the following in your Scala 3 script:

```
//> using repository "https://oss.sonatype.org/content/repositories/snapshots"
//> using lib "ch.unibas.cs.gravis::gingr:0.1.0-SNAPSHOT"
```scala
//> using lib "ch.unibas.cs.gravis::gingr:1.0-RC1"
```

If using SBT, then add the following to your `build.sbt`:

```
resolvers +=
"Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots"
libraryDependencies += "ch.unibas.cs.gravis" %% "gingr" % "0.1.0-SNAPSHOT"
```scala
libraryDependencies += "ch.unibas.cs.gravis" %% "gingr" % "1.0-RC1"
```

Or you can install GiNGR to your local repo (_.ivy2_) by running `sbt publishLocal`.

To run the examples, we make use of the VSCODE IDE. For installation help, please see https://scalismo.org/docs/Setup/vscode.
The examples can be run with [Scala-CLI](https://scala-cli.virtuslab.org/).
To run the first tutorial, first CD into the example directory and run:

```scala
# scala-cli project.scala DemoHelper CreateFemurGPMM.scala
```

Alternatively, the examples can be run with the VSCODE IDE. For installation help, please see https://scalismo.org/docs/Setup/vscode.

After installing VSCODE:

- Go to the examples folder: `cd examples`
- Setup Code IDE with `scala-cli setup-ide .`
- Open the IDE with `code .`
- Now run the individual examples from the "run" menu.
- Now run the individual examples

## General use
To use GiNGR, one need to specify the deformation model to use in form of a GPMM model as well as the correspondence estimation function and the uncertainty update.
To use GiNGR, one needs to specify the deformation model as a GPMM model, the correspondence estimation function, and the uncertainty update.
### Define the prior model
The creation of the GPMM is separate from the registration step. For examples, look in the `examples` folder where demo scripts have been created to compute and visualize GPMMs for an Armadillo, Bunny and a Femur bone. In the UI, the deformation model can be evaluated by sampling from it.
The creation of the GPMM is separate from the registration step. Look in the `examples` folder where demo scripts have been created to compute and visualize GPMMs for an Armadillo, Bunny and a Femur bone. The deformation model can be evaluated in the UI by sampling from it.
### Configure the registration algorithm
The next step is to define the correspondence and uncertainty estimation update.
For this, default configurations have been implemented for CPD and ICP.
Expand All @@ -65,7 +69,7 @@ Simple Demo applications can be found in `examples/DemoICP` and `examples/DemoCP
The demo scripts both perform deterministic and probabilistic registration one after the other.

### GiNGR state
In each iteration a new GiNGR state is computed which contains the GPMM model, the current `fit`, the target as well as all the GPMM model parameters (non-rigid and global pose).
In each iteration, a new GiNGR state is computed which contains the GPMM model, the current `fit`, the target as well as all the GPMM model parameters (non-rigid and global pose).

### Deterministic vs Probabilistic
The probabilistic implementation is based on the ICP-Proposal repository: https://github.com/unibas-gravis/icp-proposal
Expand All @@ -81,7 +85,7 @@ First CPD is used on a very coarse mesh (100 vertices), then CPD is used on a me


## Implementation of existing algorithms
In the GiNGR code base, the basic implementations of existing algorithms can also be found for comparison. The algoriths are found under `gingr/other/algorithms`
In the GiNGR code base, the basic implementations of existing algorithms can also be found for comparison. The algorithms are found under `gingr/other/algorithms`
### CPD: Coherent Point Drift (only Naïve version)
Implementation of the CPD algorithm from https://arxiv.org/pdf/0905.2635.pdf
### BCPD: Bayesian Coherent Point Drift (only Naïve version)
Expand Down
55 changes: 13 additions & 42 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
ThisBuild / scalaVersion := "3.3.1"
ThisBuild / version := "1.0-RC1"

lazy val root = (project in file("."))
.settings(
name := "GiNGR",
organization := "ch.unibas.cs.gravis",
scalaVersion := "3.1.0",
scalacOptions := Seq("-deprecation"),
name := "GiNGR",
homepage := Some(url("https://github.com/unibas-gravis/GiNGR")),
organization := "ch.unibas.cs.gravis",
licenses += ("Apache-2.0", url("http://www.apache.org/licenses/LICENSE-2.0")),
scmInfo := Some(
ScmInfo(url("https://github.com/unibas-gravis/GiNGR"), "[email protected]:unibas-gravis/GiNGR.git")
),
developers := List(
Developer("madsendennis", "madsendennis", "dennis[email protected]", url("https://github.com/madsendennis"))
Developer("madsendennis", "madsendennis", "dennis@dentexion.com", url("https://github.com/madsendennis"))
),
publishMavenStyle := true,
publishTo := Some(
Expand All @@ -18,11 +20,9 @@ lazy val root = (project in file("."))
else
Opts.resolver.sonatypeStaging
),
crossScalaVersions := Seq("2.13.6", "3.1.0"),
resolvers ++= Seq(
Resolver.jcenterRepo,
Resolver.sonatypeRepo("releases"),
Resolver.sonatypeRepo("snapshots")
Resolver.sonatypeRepo("releases")
),
scalacOptions ++= {
Seq(
Expand All @@ -32,41 +32,12 @@ lazy val root = (project in file("."))
"-language:implicitConversions"
// disabled during the migration
// "-Xfatal-warnings"
) ++
(CrossVersion.partialVersion(scalaVersion.value) match {
case Some((3, _)) =>
Seq(
"-unchecked",
"-source:3.0-migration"
)
case _ =>
Seq(
"-deprecation",
"-Xfatal-warnings",
"-Wunused:imports,privates,locals",
"-Wvalue-discard"
)
})
)
},
javacOptions ++= Seq("-source", "1.8", "-target", "1.8"),
libraryDependencies ++= Seq(
"ch.unibas.cs.gravis" %% "scalismo" % "0.91.+"
),
libraryDependencies ++= (scalaBinaryVersion.value match {
case "3" =>
Seq(
"org.scala-lang.modules" %% "scala-parallel-collections" % "1.0.4"
)
case "2.13" =>
Seq(
"org.scala-lang.modules" %% "scala-parallel-collections" % "0.2.0"
)
case _ => { println(scalaBinaryVersion.value); Seq() }
})
"org.scalatest" %% "scalatest" % "3.2.18" % "test",
"ch.unibas.cs.gravis" %% "scalismo" % "1.0-RC1",
"io.spray" %% "spray-json" % "1.3.6"
)
)
// .enablePlugins(GitVersioning)
// .settings(
// git.baseVersion := "develop",
// git.useGitDescribe := false,
// useJGit
// )
2 changes: 0 additions & 2 deletions examples/CreateArmadilloGPMM.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//> using scala "3"
//> using lib "ch.unibas.cs.gravis::scalismo-ui:0.91.2"
import DemoHelper.DemoDatasetLoader
import scalismo.ui.api.ScalismoUI

Expand Down
2 changes: 0 additions & 2 deletions examples/CreateBunnyGPMM.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//> using scala "3"
//> using lib "ch.unibas.cs.gravis::scalismo-ui:0.91.2"
import DemoHelper.DemoDatasetLoader
import scalismo.ui.api.ScalismoUI

Expand Down
2 changes: 0 additions & 2 deletions examples/CreateFemurGPMM.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//> using scala "3"
//> using lib "ch.unibas.cs.gravis::scalismo-ui:0.91.2"
import DemoHelper.DemoDatasetLoader
import scalismo.ui.api.ScalismoUI

Expand Down
4 changes: 0 additions & 4 deletions examples/DemoCPD.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
//> using scala "3"
//> using repository "https://oss.sonatype.org/content/repositories/snapshots"
//> using lib "ch.unibas.cs.gravis::gingr:0.1.0-SNAPSHOT"
//> using lib "ch.unibas.cs.gravis::scalismo-ui:0.91.2"
import DemoHelper.DemoDatasetLoader
import DemoHelper.CallBackFunctions.{visualLogger}
import gingr.simple.GingrInterface
Expand Down
3 changes: 0 additions & 3 deletions examples/DemoHelper/CallBackFunctions.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
//> using scala "3"
//> using lib "ch.unibas.cs.gravis::gingr:0.1.0-SNAPSHOT"
//> using lib "ch.unibas.cs.gravis::scalismo-ui:0.91.2"
package DemoHelper

import gingr.api.GingrRegistrationState
Expand Down
8 changes: 2 additions & 6 deletions examples/DemoHelper/DemoDatasetLoader.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
//> using scala "3"
//> using lib "ch.unibas.cs.gravis::gingr:0.1.0-SNAPSHOT"
//> using lib "ch.unibas.cs.gravis::scalismo:0.91.2"
package DemoHelper

import scalismo.common.interpolation.TriangleMeshInterpolator3D
Expand Down Expand Up @@ -47,7 +44,7 @@ trait DataSetLoader:
): (PointDistributionModel[_3D, TriangleMesh], Option[Seq[Landmark[_3D]]]) =
val (ref, lm) = reference(decimate)
val decstring = if (decimate.nonEmpty) decimate.get.toString else "full"
val modelFile = new File(path, s"${name}_dec-${decstring}_${kernelSelect.name}_${kernelSelect.printpars}.h5")
val modelFile = new File(path, s"${name}_dec-${decstring}_${kernelSelect.name}_${kernelSelect.printpars}.h5.json")
val mdec = StatisticalModelIO.readStatisticalTriangleMeshModel3D(modelFile).getOrElse {
println(s"Model file does not exist, creating: ${modelFile}")
val m = SimpleTriangleModels3D.create(ref, kernelSelect, relativeTolerance = relativeTolerance)
Expand Down Expand Up @@ -109,8 +106,7 @@ trait DataSetLoader:


object DemoDatasetLoader:
scalismo.initialize()
val dataPath = new File("../data")
val dataPath = new File("data")
case object femur extends DataSetLoader:
override def name: String = "femur"
override def path: File = new File(dataPath, name)
Expand Down
4 changes: 0 additions & 4 deletions examples/DemoICP.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
//> using scala "3"
//> using repository "https://oss.sonatype.org/content/repositories/snapshots"
//> using lib "ch.unibas.cs.gravis::gingr:0.1.0-SNAPSHOT"
//> using lib "ch.unibas.cs.gravis::scalismo-ui:0.91.2"
import DemoHelper.DemoDatasetLoader
import DemoHelper.CallBackFunctions.{visualLogger}
import gingr.simple.GingrInterface
Expand Down
3 changes: 0 additions & 3 deletions examples/DemoLandmarks.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
//> using scala "3"
//> using lib "ch.unibas.cs.gravis::gingr:0.1.0-SNAPSHOT"
//> using lib "ch.unibas.cs.gravis::scalismo-ui:0.91.2"
import DemoHelper.DemoDatasetLoader
import DemoHelper.CallBackFunctions.{visualLogger}
import gingr.simple.GingrInterface
Expand Down
3 changes: 0 additions & 3 deletions examples/DemoMultiResolution.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
//> using scala "3"
//> using lib "ch.unibas.cs.gravis::gingr:0.1.0-SNAPSHOT"
//> using lib "ch.unibas.cs.gravis::scalismo-ui:0.91.2"
import DemoHelper.DemoDatasetLoader
import DemoHelper.CallBackFunctions.{visualLogger}
import gingr.simple.GingrInterface
Expand Down
3 changes: 0 additions & 3 deletions examples/DemoPosteriorVisualizationFemur.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
//> using scala "3"
//> using lib "ch.unibas.cs.gravis::gingr:0.1.0-SNAPSHOT"
//> using lib "ch.unibas.cs.gravis::scalismo-ui:0.91.2"
import DemoHelper.DemoDatasetLoader
import gingr.api.ModelFittingParameters
import gingr.api.helper.{LogHelper, PosteriorHelper}
Expand Down
3 changes: 0 additions & 3 deletions examples/VisualizeGPMMCorrelation.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
//> using scala "3"
//> using lib "ch.unibas.cs.gravis::gingr:0.1.0-SNAPSHOT"
//> using lib "ch.unibas.cs.gravis::scalismo-ui:0.91.2"
import DemoHelper.DemoDatasetLoader
import DemoHelper.CallBackFunctions.{visualLogger}
import gingr.api.gpmm.GPMMTriangleMesh3D
Expand Down
3 changes: 3 additions & 0 deletions examples/project.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
//> using scala "3.3"
//> using dep "ch.unibas.cs.gravis::scalismo-ui:1.0-RC1"
//> using dep "ch.unibas.cs.gravis::gingr:1.0-RC1"
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version=1.6.1
sbt.version=1.9.8
9 changes: 3 additions & 6 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
resolvers += "sonatype-releases" at "https://oss.sonatype.org/content/repositories/releases/"

addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.9.0")
addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "1.0.0")
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.10")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.3")
addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.1")
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.9.0")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2")
2 changes: 1 addition & 1 deletion src/main/scala/gingr/api/CorrespondencePairs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
package gingr.api

import scalismo.common.PointId
import scalismo.geometry.{Point, _3D}
import scalismo.geometry.{_3D, Point}

case class CorrespondencePairs(pairs: IndexedSeq[(PointId, Point[_3D])])

Expand Down
Loading
Loading