code: def add_noise(
      image: tf.Tensor,
      rng: int,
      denoise_configs: ml_collections.ConfigDict,
      dtype: tf.DType = tf.float32,
  ) -> Tuple[
      tf.Tensor,
      tf.Tensor,
      Optional[tf.Tensor],
      tf.Tensor,
      Tuple[Optional[tf.Tensor], Optional[tf.Tensor]],
  ]:
      """Add noise to the given image.
  
      Args:
        image: A single image,must be in 0-1 range.
        rng: Seed for sampling the noise.
        denoise_configs: Configurations for the denoising process.
        dtype: Data type of the image.
  
      Returns:
        The corrupted image and either the noise or the image.
      """
      tf.debugging.assert_non_negative(
          image, message="Image must be in 0-1 range"
      )
  
      if denoise_configs.gamma != -1 and denoise_configs.sigma != -1:
          raise ValueError(
              "When gamma is being used, sigma must be set to -1 and vice versa."
          )
  
      noise_magnitude = (
          denoise_configs.sigma
          if denoise_configs.sigma != -1
          else denoise_configs.gamma
      )
      noise_magnitude = tf.constant(noise_magnitude, dtype=dtype)
      use_additive_noise = denoise_configs.sigma != -1
  
      # use 0 for runs that won't use timestep embedding
      timestep = tf.constant(0)
      # fallback to simple random gamma sampling scheme
      if (
          denoise_configs.random_noise_schedule
          and denoise_configs.random_noise_schedule.type == "simple"
      ):
          logging.info("Using a random noise schedule")
          c = tf.random.uniform(
              shape=[],
              minval=denoise_configs.random_noise_schedule.minval,
              maxval=denoise_configs.random_noise_schedule.maxval,
          )
          # to sample noiseless images maxval is set to a value slightly greater than
          # 1, random values of gamma that are greater than 1 are taken to be 1
          noise_magnitude = tf.minimum(c, 1.0)
      elif denoise_configs.random_noise_schedule:
          logging.info(
              "Using a random noise schedule with timestep embedding"
          )
          logging.info(
              "Number of timesteps: %d",
              denoise_configs.random_noise_schedule.n_timesteps,
          )
          noise_magnitudes = tf.linspace(
              denoise_configs.random_noise_schedule.maxval,
              denoise_configs.random_noise_schedule.minval,
              denoise_configs.random_noise_schedule.n_timesteps,
          )
  
          timestep = tf.random.uniform(
              shape=[],
              maxval=denoise_configs.random_noise_schedule.n_timesteps,
              dtype=tf.int32,
          )
          if denoise_configs.random_noise_schedule.type == "linear":
              noise_magnitude = noise_magnitudes[timestep]
          elif (
              denoise_configs.random_noise_schedule.type
              == "multiplicative"
          ):
              # Multipy gammas from step 1 to `timestep` as is done in DDPM
              noise_magnitude = tf.math.reduce_prod(
                  noise_magnitudes[:timestep]
              )
  
      patch = (None, None)
      if denoise_configs.type == "gaussian":
          logging.info("Adding gaussian noise to the image")
          noised_image, noise = add_gaussian_noise(
              image,
              noise_magnitude,
              use_additive_noise,
              rng,
              denoise_configs,
              dtype,
          )
      elif denoise_configs.type == "cutout_checkerboard":
          logging.info("Apply cutout to random portions of the image")
          noised_image, noise = cutout_checkerboard(
              image, noise_magnitude, rng, denoise_configs, dtype
          )
      elif denoise_configs.type == "cutout_bbox":
          logging.info("Apply cutout to random portions of the image")
          noised_image, noise = cutout_bbox(
              image, rng, denoise_configs, dtype
          )
      elif denoise_configs.type == "patch_noise":
          logging.info("Apply non uniform gaussian noise to the image")
          noised_image, noise, patch = patch_noise(
              image=image,
              gamma=noise_magnitude,
              patch_gamma=tf.constant(
                  denoise_configs.patch_gamma, dtype=dtype
              ),
              rng=rng,
              denoise_configs=denoise_configs,
              dtype=dtype,
          )
      else:
          raise ValueError(
              f"Noise type: {denoise_configs.type} is not defined"
          )
  
      return noised_image, noise, timestep, noise_magnitude, patch
  
file_path: scenic/scenic/projects/robust_segvit/datasets/denoise_utils.py
imports: from typing import Tuple, Optional
  from absl import logging
  import ml_collections
  import tensorflow
label_desc: Use image node_id 6 for calling a global function with example usage: add_noise(image, rng, denoise_configs, dtype) and returns: noised_image,  noise,  timestep,  noise_magnitude,  patch