code: def rand_poses(
      size: int,
      radius_range: List[float] = [1, 1.5],
      theta_range: List[float] = [0, 120],
      phi_range: List[float] = [0, 360],
      angle_overhead: float = 30,
      angle_front: float = 60,
      uniform_sphere_rate: float = 0.5,
      jitter: bool = False,
      jitter_center: float = 0.2,
      jitter_target: float = 0.2,
      jitter_up: float = 0.02,
      return_dirs: bool = False,
      device: torch.device = "cuda",
  ) -> Tuple[
      torch.Tensor,
      torch.Tensor,
      torch.Tensor,
      torch.Tensor,
      Optional[torch.Tensor],
  ]:
      """
      Generate random poses from an orbit camera.
  
      Args:
          size (int): Number of poses to generate.
          radius_range (List[float]): Min and max radii for camera [min, max].
          theta_range (List[float]): Elevation angle range in degrees [min, max].
          phi_range (List[float]): Azimuth angle range in degrees [min, max].
          angle_overhead (float): Overhead angle in degrees.
          angle_front (float): Front angle in degrees.
          uniform_sphere_rate (float): The probability of sampling from a uniform sphere.
          jitter (bool): Whether to add noise to the poses.
          jitter_center (float): Noise range for the camera center.
          jitter_target (float): Noise range for the camera target.
          jitter_up (float): Noise range for the camera up vector.
          return_dirs (bool): Whether to return the view directions.
          device (torch.device): The device on which to allocate tensors.
  
      Returns:
          Tuple: Contains the following:
              - poses (torch.Tensor): Generated poses, shape [size, 4, 4].
              - thetas (torch.Tensor): Elevation angles in degrees, shape [size].
              - phis (torch.Tensor): Azimuth angles in degrees, shape [size].
              - radius (torch.Tensor): Radii of the camera orbits, shape [size].
              - dirs (torch.Tensor, optional): View directions, if requested.
      """
  
      # Convert angles from degrees to radians
      theta_range = np.radians(theta_range)
      phi_range = np.radians(phi_range)
      angle_overhead = np.radians(angle_overhead)
      angle_front = np.radians(angle_front)
  
      # Generate radius for each pose
      radius = (
          torch.rand(size, device=device)
          * (radius_range[1] - radius_range[0])
          + radius_range[0]
      )
  
      # Generate camera center positions
      if random.random() < uniform_sphere_rate:
          centers, thetas, phis = sample_uniform_sphere(
              size=size, radius=radius, device=device
          )
      else:
          centers, thetas, phis = sample_orbit(
              size=size,
              radius=radius,
              theta_range=theta_range,
              phi_range=phi_range,
              device=device,
          )
  
      # Initialize targets to 0 (assuming 0 is a point in 3D space that cameras are looking at)
      targets = torch.zeros_like(centers)
  
      # Apply jitter
      if jitter:
          centers += (
              torch.rand_like(centers) * jitter_center
              - jitter_center / 2.0
          )
          targets = torch.randn_like(centers) * jitter_target
  
      # Compute camera look-at matrix
      forward_vector, up_vector, right_vector = compute_look_at_vectors(
          centers=centers - targets,
          jitter_up=jitter_up if jitter else 0,
          device=device,
      )
  
      # Construct the 4x4 pose matrices
      poses = construct_poses(
          centers=centers,
          right_vector=right_vector,
          up_vector=up_vector,
          forward_vector=forward_vector,
          device=device,
      )
  
      # Optionally compute view directions
      dirs = (
          get_view_direction(thetas, phis, angle_overhead, angle_front)
          if return_dirs
          else None
      )
  
      # Convert back to degrees for thetas and phis
      thetas, phis = torch.rad2deg(thetas), torch.rad2deg(phis)
  
      return poses, thetas, phis, radius, dirs
  
file_path: NeMo/nemo/collections/multimodal/data/nerf/random_poses.py
imports: import random
  from typing import Any, Dict, Iterator, List, Optional, Tuple
  import numpy
  import torch
  import torch.nn.functional
  from torch.utils.data import IterableDataset
  from nemo.collections.multimodal.data.nerf.cameras import PinholeCamera
  from nemo.collections.multimodal.data.nerf.utils import compute_look_at_vectors, construct_poses, get_rays, get_view_direction
label_desc: Use image node_id 2 for calling a global function with example usage: rand_poses(size, radius_range, theta_range, phi_range, angle_overhead, angle_front, uniform_sphere_rate, jitter, jitter_center, jitter_target, jitter_up, return_dirs, device) and returns: poses,  thetas,  phis,  radius,  dirs