// C-style comments: //

// The internal pixel type, used for internal computations
// Leave to float in general. 
// NB: this is not the type of the input images! The pixel 
// type of the input images is automatically read from the 
// images themselves.
// This setting can be changed to "short" to save some memory
// in case of very large 3D images.
(FixedInternalImagePixelType "float")
(MovingInternalImagePixelType "float")

// **************** Main Components **************************

// The following components should usually be left as they are:
(Registration "MultiResolutionRegistration")
(Interpolator "BSplineInterpolator")
(ResampleInterpolator "FinalBSplineInterpolator")
(Resampler "DefaultResampler")

// These may be changed to Fixed/MovingSmoothingImagePyramid.
// See the manual.
(FixedImagePyramid "FixedSmoothingImagePyramid")
(MovingImagePyramid "MovingSmoothingImagePyramid")
//(FixedImagePyramid "FixedRecursiveImagePyramid")
//(MovingImagePyramid "MovingRecursiveImagePyramid")

// The following components are most important:
// The optimizer AdaptiveStochasticGradientDescent (ASGD) works
// quite ok in general. The Transform and Metric are important
// and need to be chosen careful for each application. See manual.
(Optimizer "AdaptiveStochasticGradientDescent")
//(Transform "AffineTransform")
//(Transform "EulerTransform")
//(Transform "SimilarityTransform")
(Transform "BSplineTransform")

//(Metric "AdvancedMattesMutualInformation")
(Metric "AdvancedNormalizedCorrelation")
//(Metric "NormalizedMutualInformation")

// ***************** Transformation **************************

// Scales the affine matrix elements compared to the translations, to make
// sure they are in the same range. In general, it's best to  
// use automatic scales estimation:
(AutomaticScalesEstimation "true")

// Automatically guess an initial translation by aligning the
// geometric centers of the fixed and moving.
//(AutomaticTransformInitialization "true")
(AutomaticTransformInitialization "false")

// Whether transforms are combined by composition or by addition.
// In generally, Compose is the best option in most cases.
// It does not influence the results very much.
(HowToCombineTransforms "Compose")

//Save composite ITK transform
(ITKTransformOutputFileNameExtension "h5")
(WriteITKCompositeTransform "true")

// ******************* Similarity measure *********************

// Number of grey level bins in each resolution level,
// for the mutual information. 16 or 32 usually works fine.
// You could also employ a hierarchical strategy:
//(NumberOfHistogramBins 16 32 64)
//(NumberOfHistogramBins 128)
(NumberOfHistogramBins 32)

// If you use a mask, this option is important. 
// If the mask serves as region of interest, set it to false.
// If the mask indicates which pixels are valid, then set it to true.
// If you do not use a mask, the option doesn't matter.
(ErodeMask "false")

// ******************** Multiresolution **********************

// The number of resolutions. 1 Is only enough if the expected
// deformations are small. 3 or 4 mostly works fine. For large
// images and large deformations, 5 or 6 may even be useful.
//(NumberOfResolutions 1)
//(NumberOfResolutions 2)
//(NumberOfResolutions 3)
(NumberOfResolutions 4)
//(NumberOfResolutions 5)

//(FinalGridSpacingInPhysicalUnits 5 5 4)
//(FinalGridSpacingInPhysicalUnits 5 5 5)  //the one used before
(FinalGridSpacingInPhysicalUnits 10 10 10)
//(FinalGridSpacingInPhysicalUnits 10 10 4.4)

//(GridSpacingSchedule 1.0 1.0 1.0)
//(GridSpacingSchedule 4.0 4.0 1.0  2.0 2.0 1.0  1.0 1.0 1.0)

// The downsampling/blurring factors for the image pyramids.
// By default, the images are downsampled by a factor of 2
// compared to the next resolution.
// So, in 2D, with 4 resolutions, the following schedule is used:
//(ImagePyramidSchedule 8 8  4 4  2 2  1 1 )
// And in 3D:

//(ImagePyramidSchedule 16 16 2  8 8 2  4 4 1  2 2 1  1 1 1)
//(ImagePyramidSchedule  4 4 1  2 2 1  1 1 1)
//(ImagePyramidSchedule 12 12 2  6 6 1)

// You can specify any schedule, for example:
//(ImagePyramidSchedule 4 4  4 3  2 1  1 1 )
// Make sure that the number of elements equals the number
// of resolutions times the image dimension.

// ******************* Optimizer ****************************

// Maximum number of iterations in each resolution level:
// 200-500 works usually fine for affine registration.
// For more robustness, you may increase this to 1000-2000.
//(MaximumNumberOfIterations 50)
(MaximumNumberOfIterations 500)
//(MaximumNumberOfIterations 1000)
//(MaximumNumberOfIterations 3000)

//(MaximumNumberOfSamplingAttempts 50)

(AutomaticParameterEstimation "true")
//(SP_a 14894.798370 29578.381535 60408.219659 )
//(SP_A 20.000000 20.000000 20.000000 )
//(SP_alpha 1.000000 1.000000 1.000000 )
//(SigmoidMax 1.000000 1.000000 1.000000 )
//(SigmoidMin -0.069008 -0.366269 -0.602975 )
//(SigmoidScale 0.000000 0.000000 0.000000 )


// The step size of the optimizer, in mm. By default the voxel size is used.
// which usually works well. In case of unusual high-resolution images
// (eg histology) it is necessary to increase this value a bit, to the size
// of the "smallest visible structure" in the image:
//(MaximumStepLength 1.0)

// **************** Image sampling **********************

// Number of spatial samples used to compute the mutual
// information (and its derivative) in each iteration.
// With an AdaptiveStochasticGradientDescent optimizer,
// in combination with the two options below, around 2000
// samples may already suffice.
//(NumberOfSpatialSamples 500)
(NumberOfSpatialSamples 2000)
//(NumberOfSpatialSamples 3000)
//(NumberOfSpatialSamples 8192)

// Refresh these spatial samples in every iteration, and select
// them randomly. See the manual for information on other sampling
// strategies.
(NewSamplesEveryIteration "true")
(ImageSampler "RandomCoordinate")
//(ImageSampler "RandomSparseMask")

(UseRandomSampleRegion "true")
(SampleRegionSize 40.0 40.0 40.0)

// ************* Interpolation and Resampling ****************

// Order of B-Spline interpolation used during registration/optimisation.
// It may improve accuracy if you set this to 3. Never use 0.
// An order of 1 gives linear interpolation. This is in most 
// applications a good choice.
(BSplineInterpolationOrder 1)

// Order of B-Spline interpolation used for applying the final
// deformation.
// 3 gives good accuracy; recommended in most cases.
// 1 gives worse accuracy (linear interpolation)
// 0 gives worst accuracy, but is appropriate for binary images
// (masks, segmentations); equivalent to nearest neighbor interpolation.
(FinalBSplineInterpolationOrder 3)
//(FinalBSplineInterpolationOrder 0)

//Default pixel value for pixels that come from outside the picture:
(DefaultPixelValue 0)

// Choose whether to generate the deformed moving image.
// You can save some time by setting this to false, if you are
// only interested in the final (nonrigidly) deformed moving image
// for example.
//(WriteResultImage "true")
(WriteResultImage "false")
(WritePyramidImagesAfterEachResolution "false")

// The pixel type and format of the resulting deformed moving image
//(ResultImagePixelType "float")
(ResultImagePixelType "short")
(ResultImageFormat "mhd")