class_docstr: A re-implementation of VoxelMorph framework for medical image registration as described in
  https://arxiv.org/pdf/1809.05231.pdf. For more details, please refer to VoxelMorph: A Learning Framework for
  Deformable Medical Image Registration, Guha Balakrishnan, Amy Zhao, Mert R. Sabuncu, John Guttag, Adrian V. Dalca
  IEEE TMI: Transactions on Medical Imaging. 2019. eprint arXiv:1809.05231.
  
  This class is intended to be a general framework, based on which a deformable image registration
  network can be built. Given a user-specified backbone network (e.g., UNet in the original VoxelMorph paper), this
  class serves as a wrapper that concatenates the input pair of moving and fixed images, passes through the backbone
  network, integrate the predicted stationary velocity field (DVF) from the backbone network to obtain the
  displacement field (DDF), and, finally, warp the moving image using the DDF.
  
  To construct a VoxelMorph network, one need to first construct a backbone network
  (e.g., a :py:class:`monai.networks.nets.VoxelMorphUNet`) and pass it to the constructor of
  :py:class:`monai.networks.nets.VoxelMorph`. The backbone network should be able to take a pair of moving and fixed
  images as input and produce a DVF (or DDF, details to be discussed later) as output.
  
  When `forward` is called, the input moving and fixed images are first concatenated along the channel dimension and
  passed through the specified backbone network to produce the prediction of the displacement field (DDF) in the
  non-diffeomorphic variant (i.e. when `integration_steps` is set to 0) or the stationary velocity field (DVF) in the
  diffeomorphic variant (i.e. when `integration_steps` is set to a positive integer). The DVF is then integrated using
  a scaling-and-squaring approach via a :py:class:`monai.networks.blocks.warp.DVF2DDF` module to produce the DDF.
  Finally, the DDF is used to warp the moving image to the fixed image using a
  :py:class:`monai.networks.blocks.warp.Warp` module. Optionally, the integration from DVF to DDF can be
  performed on reduced resolution by specifying `half_res` to be True, in which case the output DVF from the backbone
  network is first linearly interpolated to half resolution before integration. The output DDF is then linearly
  interpolated again back to full resolution before being used to warp the moving image.
  
  Args:
      backbone: a backbone network.
      integration_steps: number of integration steps used for obtaining DDF from DVF via scaling-and-squaring.
          Defaults to 7. If set to 0, the network will be non-diffeomorphic.
      half_res: whether to perform integration on half resolution. Defaults to False.
      spatial_dims: number of spatial dimensions, defaults to 3.
  
  Example::
  
      from monai.networks.nets import VoxelMorphUNet, VoxelMorph
  
      # The following example construct an instance of VoxelMorph that matches the original VoxelMorph paper
      # https://arxiv.org/pdf/1809.05231.pdf
  
      # First, a backbone network is constructed. In this case, we use a VoxelMorphUNet as the backbone network.
      backbone = VoxelMorphUNet(
          spatial_dims=3,
          in_channels=2,
          unet_out_channels=32,
          channels=(16, 32, 32, 32, 32, 32),  # this indicates the down block at the top takes 16 channels as
                                              # input, the corresponding up block at the top produces 32
                                              # channels as output, the second down block takes 32 channels as
                                              # input, and the corresponding up block at the same level
                                              # produces 32 channels as output, etc.
          final_conv_channels=(16, 16)
      )
  
      # Then, a full VoxelMorph network is constructed using the specified backbone network.
      net = VoxelMorph(
          backbone=backbone,
          integration_steps=7,
          half_res=False
      )
  
      # A forward pass through the network would look something like this
      moving = torch.randn(1, 1, 160, 192, 224)
      fixed = torch.randn(1, 1, 160, 192, 224)
      warped, ddf = net(moving, fixed)
class_docstr_tok: ["A","re-implementation","of","VoxelMorph","framework","for","medical","image","registration","as","described","in","https",":","\/\/arxiv.org\/pdf\/1809.05231.pdf",".","For","more","details",",","please","refer","to","VoxelMorph",":","A","Learning","Framework","for","Deformable","Medical","Image","Registration",",","Guha","Balakrishnan",",","Amy","Zhao",",","Mert","R.","Sabuncu",",","John","Guttag",",","Adrian","V.","Dalca","IEEE","TMI",":","Transactions","on","Medical","Imaging",".","2019.","eprint","arXiv:1809.05231",".","This","class","is","intended","to","be","a","general","framework",",","based","on","which","a","deformable","image","registration","network","can","be","built",".","Given","a","user-specified","backbone","network","(","e.g.",",","UNet","in","the","original","VoxelMorph","paper",")",",","this","class","serves","as","a","wrapper","that","concatenates","the","input","pair","of","moving","and","fixed","images",",","passes","through","the","backbone","network",",","integrate","the","predicted","stationary","velocity","field","(","DVF",")","from","the","backbone","network","to","obtain","the","displacement","field","(","DDF",")",",","and",",","finally",",","warp","the","moving","image","using","the","DDF",".","To","construct","a","VoxelMorph","network",",","one","need","to","first","construct","a","backbone","network","(","e.g.",",","a",":","py",":","class",":","`","monai.networks.nets.VoxelMorphUNet","`",")","and","pass","it","to","the","constructor","of",":","py",":","class",":","`","monai.networks.nets.VoxelMorph","`",".","The","backbone","network","should","be","able","to","take","a","pair","of","moving","and","fixed","images","as","input","and","produce","a","DVF","(","or","DDF",",","details","to","be","discussed","later",")","as","output",".","When","`","forward","`","is","called",",","the","input","moving","and","fixed","images","are","first","concatenated","along","the","channel","dimension","and","passed","through","the","specified","backbone","network","to","produce","the","prediction","of","the","displacement","field","(","DDF",")","in","the","non-diffeomorphic","variant","(","i.e",".","when","`","integration_steps","`","is","set","to","0",")","or","the","stationary","velocity","field","(","DVF",")","in","the","diffeomorphic","variant","(","i.e",".","when","`","integration_steps","`","is","set","to","a","positive","integer",")",".","The","DVF","is","then","integrated","using","a","scaling-and-squaring","approach","via","a",":","py",":","class",":","`","monai.networks.blocks.warp.DVF2DDF","`","module","to","produce","the","DDF",".","Finally",",","the","DDF","is","used","to","warp","the","moving","image","to","the","fixed","image","using","a",":","py",":","class",":","`","monai.networks.blocks.warp.Warp","`","module",".","Optionally",",","the","integration","from","DVF","to","DDF","can","be","performed","on","reduced","resolution","by","specifying","`","half_res","`","to","be","True",",","in","which","case","the","output","DVF","from","the","backbone","network","is","first","linearly","interpolated","to","half","resolution","before","integration",".","The","output","DDF","is","then","linearly","interpolated","again","back","to","full","resolution","before","being","used","to","warp","the","moving","image",".","Args",":","backbone",":","a","backbone","network",".","integration_steps",":","number","of","integration","steps","used","for","obtaining","DDF","from","DVF","via","scaling-and-squaring",".","Defaults","to","7",".","If","set","to","0",",","the","network","will","be","non-diffeomorphic",".","half_res",":","whether","to","perform","integration","on","half","resolution",".","Defaults","to","False",".","spatial_dims",":","number","of","spatial","dimensions",",","defaults","to","3",".","Example",":",":","from","monai.networks.nets","import","VoxelMorphUNet",",","VoxelMorph","#","The","following","example","construct","an","instance","of","VoxelMorph","that","matches","the","original","VoxelMorph","paper","#","https",":","\/\/arxiv.org\/pdf\/1809.05231.pdf","#","First",",","a","backbone","network","is","constructed",".","In","this","case",",","we","use","a","VoxelMorphUNet","as","the","backbone","network",".","backbone","=","VoxelMorphUNet","(","spatial_dims=3",",","in_channels=2",",","unet_out_channels=32",",","channels=","(","16",",","32",",","32",",","32",",","32",",","32",")",",","#","this","indicates","the","down","block","at","the","top","takes","16","channels","as","#","input",",","the","corresponding","up","block","at","the","top","produces","32","#","channels","as","output",",","the","second","down","block","takes","32","channels","as","#","input",",","and","the","corresponding","up","block","at","the","same","level","#","produces","32","channels","as","output",",","etc",".","final_conv_channels=","(","16",",","16",")",")","#","Then",",","a","full","VoxelMorph","network","is","constructed","using","the","specified","backbone","network",".","net","=","VoxelMorph","(","backbone=backbone",",","integration_steps=7",",","half_res=False",")","#","A","forward","pass","through","the","network","would","look","something","like","this","moving","=","torch.randn","(","1",",","1",",","160",",","192",",","224",")","fixed","=","torch.randn","(","1",",","1",",","160",",","192",",","224",")","warped",",","ddf","=","net","(","moving",",","fixed",")"]
code: def __init__(
      self,
      backbone: VoxelMorphUNet | nn.Module | None = None,
      integration_steps: int = 7,
      half_res: bool = False,
      spatial_dims: int = 3,
  ) -> None:
      super().__init__()
  
      # specified backbone network
      self.backbone = (
          backbone
          if backbone is not None
          else VoxelMorphUNet(
              spatial_dims=spatial_dims,
              in_channels=2,
              unet_out_channels=32,
              channels=(16, 32, 32, 32, 32, 32),
              final_conv_channels=(16, 16),
          )
      )
  
      # helper attributes
      self.spatial_dims = spatial_dims
      self.half_res = half_res
      self.integration_steps = integration_steps
      self.diffeomorphic = True if self.integration_steps > 0 else False
  
      # create helpers
      if self.diffeomorphic:
          self.dvf2ddf = DVF2DDF(
              num_steps=self.integration_steps,
              mode="bilinear",
              padding_mode="zeros",
          )
      self.warp = Warp(mode="bilinear", padding_mode="zeros")
  
imports: from __future__ import annotations
  from collections.abc import Sequence
  import torch
  import torch.nn
  import torch.nn.functional
  from monai.networks.blocks.convolutions import Convolution
  from monai.networks.blocks.upsample import UpSample
  from monai.networks.blocks.warp import DVF2DDF, Warp
  from monai.networks.layers.simplelayers import SkipConnection
  from monai.utils import alias, export
label_desc: Use image node_id 1 to create a new VoxelMorph object from inherited base classes: nn with example: obj = VoxelMorph(backbone, integration_steps, half_res, spatial_dims)