class_docstr: Local squared zero-normalized cross-correlation.
  The loss is based on a moving kernel/window over the y_true/y_pred,
  within the window the square of zncc is calculated.
  The kernel can be a rectangular / triangular / gaussian window.
  The final loss is the averaged loss over all windows.
  
  Adapted from:
      https://github.com/voxelmorph/voxelmorph/blob/legacy/src/losses.py
      DeepReg (https://github.com/DeepRegNet/DeepReg)
class_docstr_tok: ["Local","squared","zero-normalized","cross-correlation",".","The","loss","is","based","on","a","moving","kernel\/window","over","the","y_true\/y_pred",",","within","the","window","the","square","of","zncc","is","calculated",".","The","kernel","can","be","a","rectangular","\/","triangular","\/","gaussian","window",".","The","final","loss","is","the","averaged","loss","over","all","windows",".","Adapted","from",":","https",":","\/\/github.com\/voxelmorph\/voxelmorph\/blob\/legacy\/src\/losses.py","DeepReg","(","https",":","\/\/github.com\/DeepRegNet\/DeepReg",")"]
docstr: Args:
      pred: the shape should be BNH[WD].
      target: the shape should be BNH[WD].
  Raises:
      ValueError: When ``self.reduction`` is not one of ["mean", "sum", "none"].
docstr_tok: ["Args",":","pred",":","the","shape","should","be","BNH","[","WD","]",".","target",":","the","shape","should","be","BNH","[","WD","]",".","Raises",":","ValueError",":","When","``","self.reduction","``","is","not","one","of","[","``","mean","''",",","``","sum","''",",","``","none","''","]","."]
code: def forward(
      self, pred: torch.Tensor, target: torch.Tensor
  ) -> torch.Tensor:
      """
      Args:
          pred: the shape should be BNH[WD].
          target: the shape should be BNH[WD].
      Raises:
          ValueError: When ``self.reduction`` is not one of ["mean", "sum", "none"].
      """
      if pred.ndim - 2 != self.ndim:
          raise ValueError(
              f"expecting pred with {self.ndim} spatial dimensions, got pred of shape {pred.shape}"
          )
      if target.shape != pred.shape:
          raise ValueError(
              f"ground truth has differing shape ({target.shape}) from pred ({pred.shape})"
          )
  
      t2, p2, tp = target * target, pred * pred, target * pred
      kernel, kernel_vol = self.kernel.to(pred), self.kernel_vol.to(
          pred
      )
      kernels = [kernel] * self.ndim
      # sum over kernel
      t_sum = separable_filtering(target, kernels=kernels)
      p_sum = separable_filtering(pred, kernels=kernels)
      t2_sum = separable_filtering(t2, kernels=kernels)
      p2_sum = separable_filtering(p2, kernels=kernels)
      tp_sum = separable_filtering(tp, kernels=kernels)
  
      # average over kernel
      t_avg = t_sum / kernel_vol
      p_avg = p_sum / kernel_vol
  
      # normalized cross correlation between t and p
      # sum[(t - mean[t]) * (p - mean[p])] / std[t] / std[p]
      # denoted by num / denom
      # assume we sum over N values
      # num = sum[t * p - mean[t] * p - t * mean[p] + mean[t] * mean[p]]
      #     = sum[t*p] - sum[t] * sum[p] / N * 2 + sum[t] * sum[p] / N
      #     = sum[t*p] - sum[t] * sum[p] / N
      #     = sum[t*p] - sum[t] * mean[p] = cross
      # the following is actually squared ncc
      cross = tp_sum - p_avg * t_sum
      t_var = torch.max(
          t2_sum - t_avg * t_sum,
          torch.as_tensor(
              self.smooth_dr, dtype=t2_sum.dtype, device=t2_sum.device
          ),
      )
      p_var = torch.max(
          p2_sum - p_avg * p_sum,
          torch.as_tensor(
              self.smooth_dr, dtype=p2_sum.dtype, device=p2_sum.device
          ),
      )
      ncc: torch.Tensor = (cross * cross + self.smooth_nr) / (
          t_var * p_var
      )
  
      if self.reduction == LossReduction.SUM.value:
          return torch.sum(
              ncc
          ).neg()  # sum over the batch, channel and spatial ndims
      if self.reduction == LossReduction.NONE.value:
          return ncc.neg()
      if self.reduction == LossReduction.MEAN.value:
          return torch.mean(
              ncc
          ).neg()  # average over the batch, channel and spatial ndims
      raise ValueError(
          f'Unsupported reduction: {self.reduction}, available options are ["mean", "sum", "none"].'
      )
  
imports: from __future__ import annotations
  import torch
  from torch.nn import functional
  from torch.nn.modules.loss import _Loss
  from monai.networks.layers import gaussian_1d, separable_filtering
  from monai.utils import LossReduction
  from monai.utils.module import look_up_option
label_desc: Use image node_id 3 for calling the LocalNormalizedCrossCorrelationLoss obj's underlying member method code with example usage: obj.forward(pred, target) and returns: torch, ncc, torch