class_docstr: Class to manage spatial ray sampling.
  
  Args:
      min_depth: sampled rays minimal depth from cameras: float
      max_depth: sampled rays maximal depth from cameras: float
      ndc: convert ray parameters to normalized device coordinates: bool
      device: device for ray tensors: Union[str, torch.device]
docstr: Calculates ray parameters: origins, directions. Also stored are camera ids for each ray, and its pixel
  coordinates.
  
  Args:
      cameras: scene cameras: PinholeCamera
      points_2d_camera: a dictionary that groups Point2D objects by total number of casted rays
docstr_tok: ["Calculates","ray","parameters",":","origins",",","directions",".","Also","stored","are","camera","ids","for","each","ray",",","and","its","pixel","coordinates",".","Args",":","cameras",":","scene","cameras",":","PinholeCamera","points_2d_camera",":","a","dictionary","that","groups","Point2D","objects","by","total","number","of","casted","rays"]
code: def _calc_ray_params(
      self,
      cameras: PinholeCamera,
      points_2d_camera: Dict[int, Points2D],
  ) -> None:
      r"""Calculates ray parameters: origins, directions. Also stored are camera ids for each ray, and its pixel
      coordinates.
  
      Args:
          cameras: scene cameras: PinholeCamera
          points_2d_camera: a dictionary that groups Point2D objects by total number of casted rays
      """
      # Unproject 2d points in image plane to 3d world for two depths
      origins = []
      directions = []
      directions_cam = []
      origins_cam = []
      camera_ids = []
      points_2d = []
      for obj in points_2d_camera.values():
          # FIXME: Below both world and camera ray directions are calculated. It could be that world ray directions
          # will not be necessary and can be removed here
          (
              num_cams_group,
              num_points_per_cam_group,
          ) = obj._points_2d.shape[:2]
          depths = (
              torch.ones(
                  num_cams_group,
                  2 * num_points_per_cam_group,
                  3,
                  device=self._device,
                  dtype=self._dtype,
              )
              * self._min_depth
          )
          depths[:, num_points_per_cam_group:] = self._max_depth
          cams = cameras_for_ids(cameras, obj.camera_ids)
          points_3d = cams.unproject(
              obj._points_2d.repeat(1, 2, 1), depths
          )
          origins.append(
              points_3d[..., :num_points_per_cam_group, :].reshape(
                  -1, 3
              )
          )
          directions.append(
              (
                  points_3d[..., num_points_per_cam_group:, :]
                  - points_3d[..., :num_points_per_cam_group, :]
              ).reshape(-1, 3)
          )
          directions_cam.append(
              self._calc_ray_directions_cam(cams, obj._points_2d)
          )
          origins_cam.append(directions_cam[-1] * self._min_depth)
          camera_ids.append(
              tensor(obj.camera_ids)
              .repeat(num_points_per_cam_group, 1)
              .permute(1, 0)
              .reshape(1, -1)
              .squeeze(0)
          )
          points_2d.append(obj._points_2d.reshape(-1, 2).int())
      self._origins = torch.cat(origins)
      self._directions = torch.cat(directions)
      self._directions_cam = torch.cat(directions_cam)
      self._origins_cam = torch.cat(origins_cam)
      self._camera_ids = torch.cat(camera_ids)
      if self._ndc:  # Transform ray parameters to NDC, if defined
          (
              self._origins,
              self._directions,
          ) = self.transform_ray_params_world_to_ndc(cameras)
      self._points_2d = torch.cat(points_2d)
  
imports: import math
  from typing import Dict, List, Tuple
  import torch
  from kornia.core import Device, Tensor, tensor
  from kornia.geometry.camera import PinholeCamera
  from kornia.nerf.camera_utils import cameras_for_ids
  from kornia.utils._compat import torch_meshgrid
  from kornia.utils.helpers import _torch_inverse_cast
label_desc: Use image node_id 8 for calling the RaySampler obj's underlying member method code with example usage: obj._calc_ray_params(cameras, points_2d_camera) without return types