code: def compute_ms_ssim(
      y_pred: torch.Tensor,
      y: torch.Tensor,
      spatial_dims: int,
      data_range: float = 1.0,
      kernel_type: KernelType | str = KernelType.GAUSSIAN,
      kernel_size: int | Sequence[int] = 11,
      kernel_sigma: float | Sequence[float] = 1.5,
      k1: float = 0.01,
      k2: float = 0.03,
      weights: Sequence[float] = (
          0.0448,
          0.2856,
          0.3001,
          0.2363,
          0.1333,
      ),
  ) -> torch.Tensor:
      """
      Args:
          y_pred: Predicted image.
              It must be a 2D or 3D batch-first tensor [B,C,H,W] or [B,C,H,W,D].
          y: Reference image.
              It must be a 2D or 3D batch-first tensor [B,C,H,W] or [B,C,H,W,D].
          spatial_dims: number of spatial dimensions of the input images.
          data_range: value range of input images. (usually 1.0 or 255)
          kernel_type: type of kernel, can be "gaussian" or "uniform".
          kernel_size: size of kernel
          kernel_sigma: standard deviation for Gaussian kernel.
          k1: stability constant used in the luminance denominator
          k2: stability constant used in the contrast denominator
          weights: parameters for image similarity and contrast sensitivity at different resolution scores.
      Raises:
          ValueError: when `y_pred` is not a 2D or 3D image.
      """
      dims = y_pred.ndimension()
      if spatial_dims == 2 and dims != 4:
          raise ValueError(
              f"y_pred should have 4 dimensions (batch, channel, height, width) when using {spatial_dims} "
              f"spatial dimensions, got {dims}."
          )
  
      if spatial_dims == 3 and dims != 5:
          raise ValueError(
              f"y_pred should have 4 dimensions (batch, channel, height, width, depth) when using {spatial_dims}"
              f" spatial dimensions, got {dims}."
          )
  
      if not isinstance(kernel_size, Sequence):
          kernel_size = ensure_tuple_rep(kernel_size, spatial_dims)
  
      if not isinstance(kernel_sigma, Sequence):
          kernel_sigma = ensure_tuple_rep(kernel_sigma, spatial_dims)
      # check if image have enough size for the number of downsamplings and the size of the kernel
      weights_div = max(1, (len(weights) - 1)) ** 2
      y_pred_spatial_dims = y_pred.shape[2:]
      for i in range(len(y_pred_spatial_dims)):
          if (
              y_pred_spatial_dims[i] // weights_div
              <= kernel_size[i] - 1
          ):
              raise ValueError(
                  f"For a given number of `weights` parameters {len(weights)} and kernel size "
                  f"{kernel_size[i]}, the image height must be larger than "
                  f"{(kernel_size[i] - 1) * weights_div}."
              )
  
      weights_tensor = torch.tensor(
          weights, device=y_pred.device, dtype=torch.float
      )
  
      avg_pool = getattr(F, f"avg_pool{spatial_dims}d")
  
      multiscale_list: list[torch.Tensor] = []
      for _ in range(len(weights_tensor)):
          ssim, cs = compute_ssim_and_cs(
              y_pred=y_pred,
              y=y,
              spatial_dims=spatial_dims,
              data_range=data_range,
              kernel_type=kernel_type,
              kernel_size=kernel_size,
              kernel_sigma=kernel_sigma,
              k1=k1,
              k2=k2,
          )
  
          cs_per_batch = cs.view(cs.shape[0], -1).mean(1)
  
          multiscale_list.append(torch.relu(cs_per_batch))
          y_pred = avg_pool(y_pred, kernel_size=2)
          y = avg_pool(y, kernel_size=2)
  
      ssim = ssim.view(ssim.shape[0], -1).mean(1)
      multiscale_list[-1] = torch.relu(ssim)
      multiscale_list_tensor = torch.stack(multiscale_list)
  
      ms_ssim_value_full_image = torch.prod(
          multiscale_list_tensor ** weights_tensor.view(-1, 1), dim=0
      )
  
      ms_ssim_per_batch: torch.Tensor = ms_ssim_value_full_image.view(
          ms_ssim_value_full_image.shape[0], -1
      ).mean(1, keepdim=True)
  
      return ms_ssim_per_batch
  
imports: from __future__ import annotations
  import math
  from abc import abstractmethod
  from collections.abc import Callable, Sequence
  from functools import partial
  from typing import Any
  import torch
  import torch.nn.functional
  from monai.metrics.utils import do_metric_reduction
  from monai.utils import MetricReduction, StrEnum, convert_data_type, ensure_tuple_rep
  from monai.utils.type_conversion import convert_to_dst_type
  from .metric import CumulativeIterationMetric
label_desc: Use image node_id 4 for calling a global function with example usage: compute_ms_ssim(y_pred, y, spatial_dims, data_range, kernel_type, kernel_size, kernel_sigma, k1, k2, weights) and returns: ms_ssim_per_batch