From 551ac27a88e4b0077c4560999af4246b6e86ed72 Mon Sep 17 00:00:00 2001 From: Nick Tustison Date: Wed, 22 Feb 2023 20:37:24 -0800 Subject: [PATCH 1/2] ENH: Add time-varying point set transform fitting. --- DESCRIPTION | 2 +- R/composeDisplacementFields.R | 4 +- R/fitTransformToPairedPoints.R | 332 +++++++++++++++++++++- R/invertDisplacementField.R | 6 +- man/composeDisplacementFields.Rd | 3 - man/fitTimeVaryingTransformToPointSets.Rd | 99 +++++++ man/fitTransformToPairedPoints.Rd | 6 +- man/invertDisplacementField.Rd | 3 - 8 files changed, 436 insertions(+), 19 deletions(-) create mode 100644 man/fitTimeVaryingTransformToPointSets.Rd diff --git a/DESCRIPTION b/DESCRIPTION index 6e9d569c..689b328e 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -89,5 +89,5 @@ SystemRequirements: cmake, git, clang Remotes: stnava/ITKR, ANTsX/ANTsRCore, cran/wmtsa, cran/ifultools NeedsCompilation: yes VignetteBuilder: knitr -RoxygenNote: 7.2.1 +RoxygenNote: 7.2.2 Encoding: UTF-8 diff --git a/R/composeDisplacementFields.R b/R/composeDisplacementFields.R index 934e38a6..9f948820 100644 --- a/R/composeDisplacementFields.R +++ b/R/composeDisplacementFields.R @@ -8,8 +8,6 @@ #' #' @author NJ Tustison #' -#' @examples -#' #' @export composeDisplacementFields composeDisplacementFields <- function( @@ -21,7 +19,7 @@ composeDisplacementFields <- function( compField <- .Call( "composeDisplacementFields", dimensionality, - displacementField, + displacementField, warpingField, PACKAGE = "ANTsR" ) return( compField ) diff --git a/R/fitTransformToPairedPoints.R b/R/fitTransformToPairedPoints.R index d95ba43d..a9fb2cfd 100644 --- a/R/fitTransformToPairedPoints.R +++ b/R/fitTransformToPairedPoints.R @@ -32,7 +32,7 @@ #' @param verbose Print progress to the screen. #' @return object containing ANTsR transform, error, and scale (or displacement field) #' -#' @author B Avants +#' @author B Avants, N Tustison #' @examples #' fixed <- matrix( c( 50, 50, 200, 50, 50, 200 ), ncol = 2, byrow = TRUE ) #' moving <- matrix( c( 50, 50, 50, 200, 200, 200 ), ncol = 2, byrow = TRUE ) @@ -551,5 +551,333 @@ fitTransformToPairedPoints <- function( } else { stop( "Unrecognized transformType." ) } - } + + +#' fitTimeVaryingTransformToPointSets +#' +#' Estimate a time-varying transform from corresponding point sets (> 2). +#' +#' @param pointSets Corresponding points across sets specified in physical space as a +#' \code{n x d} matrix where \code{n} is the number of points and \code{d} is the +#' dimensionality. +#' @param timePoints Set of scalar values, one for each point-set designating its time +#' position in the velocity flow. If not set, it defaults to equal spacing between 0 +#' and 1. +#' @param numberOfIntegrationPoints Time-varying velocity field parameter. Needs to +#' be equal to or greater than the number of point sets. If not specified, it +#' defaults to the number of point sets. +#' @param domainImage defines physical domain of the nonlinear transforms. +#' @param numberOfFittingLevels integer specifying the number of fitting levels +#' @param meshSize scalar or vector defining the mesh size at the initial fitting level +#' @param splineOrder spline order of the B-spline object. Default = 3. +#' @param displacementWeights vector defining the individual weighting of the corresponding +#' scattered data value. Default = NULL meaning all displacements are +#' weighted the same. +#' @param numberOfCompositions total number of compositions. +#' @param compositionStepSize scalar multiplication factor. +#' @param sigma gaussian smoothing sigma (in mm). +#' @param convergenceThreshold Composition-based convergence parameter for the diffeomorphic +#' transforms using a window size of 10 values. +#' @param rasterizePoints Use nearest neighbor rasterization of points for estimating update +#' field (potential speed-up). +#' @param verbose Print progress to the screen. +#' @return object containing ANTsR transform, error, and scale (or displacement field) +#' +#' @author B Avants, N Tustison +#' @examples +#' fixed <- matrix( c( 50, 50, 200, 50, 50, 200 ), ncol = 2, byrow = TRUE ) +#' moving <- matrix( c( 50, 50, 50, 200, 200, 200 ), ncol = 2, byrow = TRUE ) +#' +#' # Affine transform +#' xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "Affine", regularization = 0 ) +#' params <- getAntsrTransformParameters( xfrm ) +#' +#' # Rigid transform +#' xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "Rigid", regularization = 0 ) +#' params <- getAntsrTransformParameters( xfrm ) +#' +#' # Similarity transform +#' xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "Similarity", regularization = 0 ) +#' params <- getAntsrTransformParameters( xfrm ) +#' +#' # B-spline transform +#' domainImage <- antsImageRead( getANTsRData( "r16" ) ) +#' xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "Bspline", domainImage = domainImage, numberOfFittingLevels = 5 ) +#' +#' # Diffeo transform +#' domainImage <- antsImageRead( getANTsRData( "r16" ) ) +#' xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "Diffeo", domainImage = domainImage, numberOfFittingLevels = 6 ) +#' +#' # SyN transform +#' domainImage <- antsImageRead( getANTsRData( "r16" ) ) +#' xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "SyN", domainImage = domainImage, numberOfFittingLevels = 6, numberOfCompositions = 10, compositionStepSize = 0.01 ) +#' @export fitTransformToPairedPoints + +fitTimeVaryingTransformToPointSets <- function( + pointSets, + timePoints = NULL, + numberOfIntegrationPoints=NULL, + domainImage = NULL, + numberOfFittingLevels = 4, + meshSize = 1, + splineOrder = 3, + displacementWeights = NULL, + numberOfCompositions = 10, + compositionStepSize = 0.5, + sigma = 0.0, + convergenceThreshold = 0.0, + rasterizePoints = FALSE, + verbose = FALSE + ) { + + createZeroVelocityField <- function( domainImage, numberOfTimePoints = 2 ) + { + fieldArray <- array( data = 0, dim = c( domainImage@dimension, dim( domainImage ), numberOfTimePoints ) ) + origin <- c( antsGetOrigin( domainImage ), 0.0 ) + spacing <- c( antsGetSpacing( domainImage ), 1.0 ) + direction <- diag( domainImage@dimension + 1 ) + direction[1:domainImage@dimension, 1:domainImage@dimension] <- antsGetDirection( domainImage ) + field <- as.antsImage( fieldArray, origin = origin, spacing = spacing, direction = direction, components = TRUE ) + return( field ) + } + + convergenceMonitoring <- function( values, windowSize = 10 ) + { + if( length( values ) >= windowSize ) + { + u <- seq( from = 0.0, to = 1.0, length.out = windowSize ) + scatteredData <- as.matrix( tail( values, n = windowSize ), ncol = 1 ) + parametricData <- as.matrix( u, ncol = 1 ) + spacing <- 1.0 / ( windowSize - 1.0 ) + bsplineLine <- fitBsplineObjectToScatteredData( scatteredData, parametricData, + parametricDomainOrigin = c( 0.0 ), parametricDomainSpacing = c( spacing ), + parametricDomainSize = c( windowSize ), numberOfFittingLevels = 1, meshSize = 1, + splineOrder = 1 ) + bsplineSlope <- -( bsplineLine[2, 1] - bsplineLine[1, 1] ) / spacing + return( bsplineSlope ) + } + else + { + return( NA ) + } + } + + if( ! is.list( pointSets ) ) + { + stop( "Point sets should be a list of corresponding point sets." ) + } + + numberOfPointSets <- length( pointSets ) + + if( ! is.null( timePoints ) && length( timePoints ) != numberOfPointSets ) + { + stop( "The number of time points should be the same as the number of point sets." ) + } + + if( ! is.null( timePoints ) ) + { + timePoints <- seq( from = 0.0, to = 1.0, length.out = numberOfPointSets ) + } + + if( any( timePoints < 0.0 ) || any( timePoints > 1.0 ) ) + { + stop( "Time point values should be between 0 and 1." ) + } + + if( numberOfIntegrationPoints < numberOfPointSets ) + { + stop( "The number of integration points should be at least as great as the number of point sets." ) + } + + if( numberOfPointSets < 3 ) + { + stop( "Expecting three or greater point sets." ) + } + + numberOfPoints <- nrow( pointSets[[1]] ) + dimensionality <- ncol( pointSets[[1]] ) + for( i in seq.int( 2, numberOfPointSets ) ) + { + if( nrow( pointSets[[i]] ) != numberOfPoints ) + { + stop( "Point sets should match in terms of the number of points." ) + } + if( ncol( pointSets[[i]] ) != dimensionality ) + { + stop( "Point sets should match in terms of dimensionality." ) + } + } + + if( verbose ) + { + startTotalTime <- Sys.time() + } + + updatedFixedPoints <- array( data = 0, dim = dim( pointSets[[1]] ) ) + updatedMovingPoints <- array( data = 0, dim = dim( pointSets[[1]] ) ) + + velocityField <- createZeroVelocityField( domainImage, numberOfIntegrationPoints ) + velocityFieldArray <- as.array( velocityField ) + + lastUpdateDerivativeField <- createZeroVelocityField( domainImage, numberOfIntegrationPoints ) + lastUpdateDerivativeFieldArray <- as.array( lastUpdateDerivativeField ) + + errorValues <- c() + for( i in seq.int( numberOfCompositions ) ) + { + if( verbose ) + { + startTime <- Sys.time() + } + updateDerivativeField <- createZeroVelocityField( domainImage, numberOfIntegrationPoints ) + updateDerivativeFieldArray <- as.array( updateDerivativeField ) + + for( n in seq.int( numberOfIntegrationPoints ) ) + { + t <- ( n - 1 ) / ( numberOfIntegrationPoints - 1.0 ) + + tIndex <- 0 + for( j in seq.int( from = 2, to = numberOfPointSets ) ) + { + if( timePoints[j-1] <= t && timePoints[j] >= t ) + { + tIndex <- j + break + } + } + + if( n > 1 && n < number_of_integration_points && timePoints[tIndex-1] == t ) + { + updatedFixedPoints <- pointSets[[tIndex-1]] + integratedInverseField <- integrateVelocityField( velocityField, timePoints[tIndex], t, 100 ) + integratedInverseFieldXfrm <- createAntsrTransform( type = "DisplacementFieldTransform", displacement.field = integratedInverseField ) + updatedMovingPoints <- applyAntsrTransformToPoint( integratedInverseFieldXfrm, pointSets[[tIndex]] ) + + updateDerivativeFieldAtTimePointForward <- fitBsplineDisplacementField( + displacementOrigins = updatedFixedPoints, + displacements = updatedMovingPoints - updatedFixedPoints, + displacementWeights = displacementWeights, + origin = antsGetOrigin( domainImage ), + spacing = antsGetSpacing( domainImage ), + size = dim( domainImage ), + direction = antsGetDirection( domainImage ), + numberOfFittingLevels = numberOfFittingLevels, + meshSize = meshSize, + splineOrder = splineOrder, + enforceStationaryBoundary = TRUE, + rasterizePoints = rasterizePoints + ) + + updatedMovingPoints <- pointSets[[tIndex-1]] + integratedForwardField <- integrateVelocityField( velocityField, timePoints[tIndex-2], t, 100 ) + integratedForwardFieldXfrm <- createAntsrTransform( type = "DisplacementFieldTransform", displacement.field = integratedForwardField ) + updatedFixedPoints <- applyAntsrTransformToPoint( integratedForwardFieldXfrm, pointSets[[tIndex-2]] ) + + updateDerivativeFieldAtTimePointBack <- fitBsplineDisplacementField( + displacementOrigins = updatedFixedPoints, + displacements = updatedMovingPoints - updatedFixedPoints, + displacementWeights = displacementWeights, + origin = antsGetOrigin( domainImage ), + spacing = antsGetSpacing( domainImage ), + size = dim( domainImage ), + direction = antsGetDirection( domainImage ), + numberOfFittingLevels = numberOfFittingLevels, + meshSize = meshSize, + splineOrder = splineOrder, + enforceStationaryBoundary = TRUE, + rasterizePoints = rasterizePoints + ) + + updateDerivativeFieldAtTimePoint <- ( updateDerivativeFieldAtTimePointForward + + updateDerivativeFieldAtTimePointBack ) / 2.0 + + } else { + if( t == 0.0 && timePoints[tIndex-1] == 0.0 ) + { + updatedFixedPoints <- pointSets[[1]] + } else { + integratedForwardField <- integrateVelocityField( velocityField, timePoints[tIndex-1], t, 100 ) + integratedForwardFieldXfrm <- createAntsrTransform( type = "DisplacementFieldTransform", displacement.field = integratedForwardField ) + updatedFixedPoints <- applyAntsrTransformToPoint( integratedForwardFieldXfrm, pointSets[[tIndex-1]] ) + } + + if( t == 1.0 && timePoints[tIndex] == 1.0 ) + { + integratedInverseField <- integrateVelocityField( velocityField, timePoints[tIndex], t, 100 ) + integratedInverseFieldXfrm <- createAntsrTransform( type = "DisplacementFieldTransform", displacement.field = integratedInverseField ) + updatedMovingPoints <- applyAntsrTransformToPoint( integratedInverseFieldXfrm, pointSets[[tIndex]] ) + } + + updateDerivativeFieldAtTimePoint <- fitBsplineDisplacementField( + displacementOrigins = updatedFixedPoints, + displacements = updatedMovingPoints - updatedFixedPoints, + displacementWeights = displacementWeights, + origin = antsGetOrigin( domainImage ), + spacing = antsGetSpacing( domainImage ), + size = dim( domainImage ), + direction = antsGetDirection( domainImage ), + numberOfFittingLevels = numberOfFittingLevels, + meshSize = meshSize, + splineOrder = splineOrder, + enforceStationaryBoundary = TRUE, + rasterizePoints = rasterizePoints + ) + } + if( sigma > 0 ) + { + updateDerivativeFieldAtTimePoint <- smoothImage( updateDerivativeFieldAtTimePoint, sigma ) + } + + updateDerivativeFieldAtTimePointArray <- as.array( updateDerivativeFieldAtTimePoint ) + maxNorm <- sqrt( max( base::colSums( updateDerivativeFieldAtTimePointArray ^ 2, dims = 1 ) ) ) + updateDerivativeFieldAtTimePointArray <- updateDerivativeFieldAtTimePointArray / maxNorm + if( domainImage@dimension == 2 ) + { + updateDerivativeFieldArray[,,,n] <- updateDerivativeFieldAtTimePointArray + } else { + updateDerivativeFieldArray[,,,,n] <- updateDerivativeFieldAtTimePointArray + } + } + updateDerivativeFieldArray <- ( updateDerivativeFieldArray + lastUpdateDerivativeFieldArray ) * 0.5 + lastUpdateDerivativeFieldArray <- updateDerivativeFieldArray + + velocityFieldArray <- velocityFieldArray + updateDerivativeFieldArray * compositionStepSize + velocityField <- as.antsImage( velocityFieldArray, origin = antsGetOrigin( velocityField ), + spacing = antsGetSpacing( velocityField ), direction = antsGetDirection( velocityField ), + components = TRUE ) + + if( verbose ) + { + error <- mean( sqrt( rowSums( ( updatedFixedPoints - updatedMovingPoints )^2 ) ) ) + errorValues <- append( errorValues, error ) + convergenceValue <- convergenceMonitoring( errorValues ) + endTime <- Sys.time() + diffTime <- endTime - startTime + cat( "Composition ", i, ": error = ", error, " (convergence = ", convergenceValue, ", elapsed time = ", diffTime, ")\n", sep = "" ) + } + if( ! is.na( convergenceValue ) && convergenceValue < convergenceThreshold ) + { + break + } + } + + integratedForwardField <- integrateVelocityField( velocityField, 0.0, t, 100 ) + forwardXfrm <- createAntsrTransform( type = "DisplacementFieldTransform", displacement.field = integratedForwardField ) + + integratedInverseField <- integrateVelocityField( velocityField, 1.0, t, 100 ) + inverseXfrm <- createAntsrTransform( type = "DisplacementFieldTransform", displacement.field = integratedInverseField ) + + if( verbose ) + { + endTotalTime <- Sys.time() + diffTotalTime <- endTotalTime - startTotalTime + cat( "Total elapsed time = ", diffTotalTime, ".\n", sep = "" ) + } + + return( list( forwardTransform = forwardXfrm, + inverseTransform = inverseXfrm, + velocityField = velocityField ) ) + + } + diff --git a/R/invertDisplacementField.R b/R/invertDisplacementField.R index 39312b28..cd471b4a 100644 --- a/R/invertDisplacementField.R +++ b/R/invertDisplacementField.R @@ -12,8 +12,6 @@ #' #' @author NJ Tustison #' -#' @examples -#' #' @export invertDisplacementField invertDisplacementField <- function( @@ -29,9 +27,9 @@ invertDisplacementField <- function( inverseField <- .Call( "invertDisplacementField", dimensionality, - displacementField, + displacementField, inverseFieldInitialEstimate, - as.numeric( maximumNumberOfIterations ), + as.numeric( maximumNumberOfIterations ), as.numeric( meanErrorToleranceThreshold ), as.numeric( maxErrorToleranceThreshold ), as.numeric( enforceBoundaryCondition ), diff --git a/man/composeDisplacementFields.Rd b/man/composeDisplacementFields.Rd index 8423dbcc..5c7e0475 100644 --- a/man/composeDisplacementFields.Rd +++ b/man/composeDisplacementFields.Rd @@ -16,9 +16,6 @@ composite displacement field } \description{ Compose displacement fields. -} -\examples{ - } \author{ NJ Tustison diff --git a/man/fitTimeVaryingTransformToPointSets.Rd b/man/fitTimeVaryingTransformToPointSets.Rd new file mode 100644 index 00000000..726a31db --- /dev/null +++ b/man/fitTimeVaryingTransformToPointSets.Rd @@ -0,0 +1,99 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/fitTransformToPairedPoints.R +\name{fitTimeVaryingTransformToPointSets} +\alias{fitTimeVaryingTransformToPointSets} +\title{fitTimeVaryingTransformToPointSets} +\usage{ +fitTimeVaryingTransformToPointSets( + pointSets, + timePoints = NULL, + numberOfIntegrationPoints = NULL, + domainImage = NULL, + numberOfFittingLevels = 4, + meshSize = 1, + splineOrder = 3, + displacementWeights = NULL, + numberOfCompositions = 10, + compositionStepSize = 0.5, + sigma = 0, + convergenceThreshold = 0, + rasterizePoints = FALSE, + verbose = FALSE +) +} +\arguments{ +\item{pointSets}{Corresponding points across sets specified in physical space as a +\code{n x d} matrix where \code{n} is the number of points and \code{d} is the +dimensionality.} + +\item{timePoints}{Set of scalar values, one for each point-set designating its time +position in the velocity flow. If not set, it defaults to equal spacing between 0 +and 1.} + +\item{numberOfIntegrationPoints}{Time-varying velocity field parameter. Needs to +be equal to or greater than the number of point sets. If not specified, it +defaults to the number of point sets.} + +\item{domainImage}{defines physical domain of the nonlinear transforms.} + +\item{numberOfFittingLevels}{integer specifying the number of fitting levels} + +\item{meshSize}{scalar or vector defining the mesh size at the initial fitting level} + +\item{splineOrder}{spline order of the B-spline object. Default = 3.} + +\item{displacementWeights}{vector defining the individual weighting of the corresponding +scattered data value. Default = NULL meaning all displacements are +weighted the same.} + +\item{numberOfCompositions}{total number of compositions.} + +\item{compositionStepSize}{scalar multiplication factor.} + +\item{sigma}{gaussian smoothing sigma (in mm).} + +\item{convergenceThreshold}{Composition-based convergence parameter for the diffeomorphic +transforms using a window size of 10 values.} + +\item{rasterizePoints}{Use nearest neighbor rasterization of points for estimating update +field (potential speed-up).} + +\item{verbose}{Print progress to the screen.} +} +\value{ +object containing ANTsR transform, error, and scale (or displacement field) +} +\description{ +Estimate a time-varying transform from corresponding point sets (> 2). +} +\examples{ +fixed <- matrix( c( 50, 50, 200, 50, 50, 200 ), ncol = 2, byrow = TRUE ) +moving <- matrix( c( 50, 50, 50, 200, 200, 200 ), ncol = 2, byrow = TRUE ) + +# Affine transform +xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "Affine", regularization = 0 ) +params <- getAntsrTransformParameters( xfrm ) + +# Rigid transform +xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "Rigid", regularization = 0 ) +params <- getAntsrTransformParameters( xfrm ) + +# Similarity transform +xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "Similarity", regularization = 0 ) +params <- getAntsrTransformParameters( xfrm ) + +# B-spline transform +domainImage <- antsImageRead( getANTsRData( "r16" ) ) +xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "Bspline", domainImage = domainImage, numberOfFittingLevels = 5 ) + +# Diffeo transform +domainImage <- antsImageRead( getANTsRData( "r16" ) ) +xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "Diffeo", domainImage = domainImage, numberOfFittingLevels = 6 ) + +# SyN transform +domainImage <- antsImageRead( getANTsRData( "r16" ) ) +xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "SyN", domainImage = domainImage, numberOfFittingLevels = 6, numberOfCompositions = 10, compositionStepSize = 0.01 ) +} +\author{ +B Avants, N Tustison +} diff --git a/man/fitTransformToPairedPoints.Rd b/man/fitTransformToPairedPoints.Rd index 0051b415..1bda2acd 100644 --- a/man/fitTransformToPairedPoints.Rd +++ b/man/fitTransformToPairedPoints.Rd @@ -60,12 +60,12 @@ weighted the same.} \item{sigma}{gaussian smoothing sigma (in mm) for the diffeomorphic transform.} -\item{convergenceThreshold}{Composition-based convergence parameter for the diffeomorphic +\item{convergenceThreshold}{Composition-based convergence parameter for the diffeomorphic transforms using a window size of 10 values.} \item{numberOfIntegrationPoints}{Time-varying velocity field parameter.} -\item{rasterizePoints}{Use nearest neighbor rasterization of points for estimating update +\item{rasterizePoints}{Use nearest neighbor rasterization of points for estimating update field (potential speed-up).} \item{verbose}{Print progress to the screen.} @@ -105,5 +105,5 @@ domainImage <- antsImageRead( getANTsRData( "r16" ) ) xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "SyN", domainImage = domainImage, numberOfFittingLevels = 6, numberOfCompositions = 10, compositionStepSize = 0.01 ) } \author{ -B Avants +B Avants, N Tustison } diff --git a/man/invertDisplacementField.Rd b/man/invertDisplacementField.Rd index 0588b6b7..7625f396 100644 --- a/man/invertDisplacementField.Rd +++ b/man/invertDisplacementField.Rd @@ -31,9 +31,6 @@ inverse displacement field } \description{ Invert displacement field. -} -\examples{ - } \author{ NJ Tustison From fc0d33d0806661fb5cfdb0bd6387c6bb53012c96 Mon Sep 17 00:00:00 2001 From: Nick Tustison Date: Thu, 23 Feb 2023 22:12:42 -0800 Subject: [PATCH 2/2] ENH: More. --- NAMESPACE | 1 + ...mToPairedPoints.R => landmarkTransforms.R} | 49 ++++++------------- man/fitTimeVaryingTransformToPointSets.Rd | 30 +----------- man/fitTransformToPairedPoints.Rd | 2 +- 4 files changed, 17 insertions(+), 65 deletions(-) rename R/{fitTransformToPairedPoints.R => landmarkTransforms.R} (95%) diff --git a/NAMESPACE b/NAMESPACE index af835fda..d6c83813 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -47,6 +47,7 @@ export(fastMarchingExtension) export(filterfMRIforNetworkAnalysis) export(fitBsplineDisplacementField) export(fitBsplineObjectToScatteredData) +export(fitTimeVaryingTransformToPointSets) export(fitTransformToPairedPoints) export(frequencyFilterfMRI) export(fsl2antsrTransform) diff --git a/R/fitTransformToPairedPoints.R b/R/landmarkTransforms.R similarity index 95% rename from R/fitTransformToPairedPoints.R rename to R/landmarkTransforms.R index a9fb2cfd..ec376e59 100644 --- a/R/fitTransformToPairedPoints.R +++ b/R/landmarkTransforms.R @@ -457,7 +457,7 @@ fitTransformToPairedPoints <- function( updateDerivativeField <- createZeroVelocityField( domainImage, numberOfIntegrationPoints ) updateDerivativeFieldArray <- as.array( updateDerivativeField ) - for( n in seq.int( numberOfIntegrationPoints ) ) + for( n in seq_len( numberOfIntegrationPoints ) ) { t <- ( n - 1 ) / ( numberOfIntegrationPoints - 1.0 ) @@ -585,35 +585,7 @@ fitTransformToPairedPoints <- function( #' @return object containing ANTsR transform, error, and scale (or displacement field) #' #' @author B Avants, N Tustison -#' @examples -#' fixed <- matrix( c( 50, 50, 200, 50, 50, 200 ), ncol = 2, byrow = TRUE ) -#' moving <- matrix( c( 50, 50, 50, 200, 200, 200 ), ncol = 2, byrow = TRUE ) -#' -#' # Affine transform -#' xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "Affine", regularization = 0 ) -#' params <- getAntsrTransformParameters( xfrm ) -#' -#' # Rigid transform -#' xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "Rigid", regularization = 0 ) -#' params <- getAntsrTransformParameters( xfrm ) -#' -#' # Similarity transform -#' xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "Similarity", regularization = 0 ) -#' params <- getAntsrTransformParameters( xfrm ) -#' -#' # B-spline transform -#' domainImage <- antsImageRead( getANTsRData( "r16" ) ) -#' xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "Bspline", domainImage = domainImage, numberOfFittingLevels = 5 ) -#' -#' # Diffeo transform -#' domainImage <- antsImageRead( getANTsRData( "r16" ) ) -#' xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "Diffeo", domainImage = domainImage, numberOfFittingLevels = 6 ) -#' -#' # SyN transform -#' domainImage <- antsImageRead( getANTsRData( "r16" ) ) -#' xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "SyN", domainImage = domainImage, numberOfFittingLevels = 6, numberOfCompositions = 10, compositionStepSize = 0.01 ) -#' @export fitTransformToPairedPoints - +#' @export fitTimeVaryingTransformToPointSets fitTimeVaryingTransformToPointSets <- function( pointSets, timePoints = NULL, @@ -675,7 +647,7 @@ fitTimeVaryingTransformToPointSets <- function( stop( "The number of time points should be the same as the number of point sets." ) } - if( ! is.null( timePoints ) ) + if( is.null( timePoints ) ) { timePoints <- seq( from = 0.0, to = 1.0, length.out = numberOfPointSets ) } @@ -685,6 +657,11 @@ fitTimeVaryingTransformToPointSets <- function( stop( "Time point values should be between 0 and 1." ) } + if( is.null( numberOfIntegrationPoints ) ) + { + numberOfIntegrationPoints <- length( timePoints ) + } + if( numberOfIntegrationPoints < numberOfPointSets ) { stop( "The number of integration points should be at least as great as the number of point sets." ) @@ -733,7 +710,7 @@ fitTimeVaryingTransformToPointSets <- function( updateDerivativeField <- createZeroVelocityField( domainImage, numberOfIntegrationPoints ) updateDerivativeFieldArray <- as.array( updateDerivativeField ) - for( n in seq.int( numberOfIntegrationPoints ) ) + for( n in seq_len( numberOfIntegrationPoints ) ) { t <- ( n - 1 ) / ( numberOfIntegrationPoints - 1.0 ) @@ -747,7 +724,7 @@ fitTimeVaryingTransformToPointSets <- function( } } - if( n > 1 && n < number_of_integration_points && timePoints[tIndex-1] == t ) + if( n > 1 && n < numberOfIntegrationPoints && timePoints[tIndex-1] == t ) { updatedFixedPoints <- pointSets[[tIndex-1]] integratedInverseField <- integrateVelocityField( velocityField, timePoints[tIndex], t, 100 ) @@ -804,6 +781,8 @@ fitTimeVaryingTransformToPointSets <- function( if( t == 1.0 && timePoints[tIndex] == 1.0 ) { + updatedMovingPoints <- pointSets[[length( pointSets )]] + } else { integratedInverseField <- integrateVelocityField( velocityField, timePoints[tIndex], t, 100 ) integratedInverseFieldXfrm <- createAntsrTransform( type = "DisplacementFieldTransform", displacement.field = integratedInverseField ) updatedMovingPoints <- applyAntsrTransformToPoint( integratedInverseFieldXfrm, pointSets[[tIndex]] ) @@ -862,10 +841,10 @@ fitTimeVaryingTransformToPointSets <- function( } } - integratedForwardField <- integrateVelocityField( velocityField, 0.0, t, 100 ) + integratedForwardField <- integrateVelocityField( velocityField, 0.0, 1.0, 100 ) forwardXfrm <- createAntsrTransform( type = "DisplacementFieldTransform", displacement.field = integratedForwardField ) - integratedInverseField <- integrateVelocityField( velocityField, 1.0, t, 100 ) + integratedInverseField <- integrateVelocityField( velocityField, 1.0, 0.0, 100 ) inverseXfrm <- createAntsrTransform( type = "DisplacementFieldTransform", displacement.field = integratedInverseField ) if( verbose ) diff --git a/man/fitTimeVaryingTransformToPointSets.Rd b/man/fitTimeVaryingTransformToPointSets.Rd index 726a31db..8f4b1c74 100644 --- a/man/fitTimeVaryingTransformToPointSets.Rd +++ b/man/fitTimeVaryingTransformToPointSets.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/fitTransformToPairedPoints.R +% Please edit documentation in R/landmarkTransforms.R \name{fitTimeVaryingTransformToPointSets} \alias{fitTimeVaryingTransformToPointSets} \title{fitTimeVaryingTransformToPointSets} @@ -66,34 +66,6 @@ object containing ANTsR transform, error, and scale (or displacement field) \description{ Estimate a time-varying transform from corresponding point sets (> 2). } -\examples{ -fixed <- matrix( c( 50, 50, 200, 50, 50, 200 ), ncol = 2, byrow = TRUE ) -moving <- matrix( c( 50, 50, 50, 200, 200, 200 ), ncol = 2, byrow = TRUE ) - -# Affine transform -xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "Affine", regularization = 0 ) -params <- getAntsrTransformParameters( xfrm ) - -# Rigid transform -xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "Rigid", regularization = 0 ) -params <- getAntsrTransformParameters( xfrm ) - -# Similarity transform -xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "Similarity", regularization = 0 ) -params <- getAntsrTransformParameters( xfrm ) - -# B-spline transform -domainImage <- antsImageRead( getANTsRData( "r16" ) ) -xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "Bspline", domainImage = domainImage, numberOfFittingLevels = 5 ) - -# Diffeo transform -domainImage <- antsImageRead( getANTsRData( "r16" ) ) -xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "Diffeo", domainImage = domainImage, numberOfFittingLevels = 6 ) - -# SyN transform -domainImage <- antsImageRead( getANTsRData( "r16" ) ) -xfrm <- fitTransformToPairedPoints( moving, fixed, transformType = "SyN", domainImage = domainImage, numberOfFittingLevels = 6, numberOfCompositions = 10, compositionStepSize = 0.01 ) -} \author{ B Avants, N Tustison } diff --git a/man/fitTransformToPairedPoints.Rd b/man/fitTransformToPairedPoints.Rd index 1bda2acd..9b488c5d 100644 --- a/man/fitTransformToPairedPoints.Rd +++ b/man/fitTransformToPairedPoints.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/fitTransformToPairedPoints.R +% Please edit documentation in R/landmarkTransforms.R \name{fitTransformToPairedPoints} \alias{fitTransformToPairedPoints} \title{fitTransformToPairedPoints}