class_docstr: Samples a fixed number of points along rays which are in turn sampled for
  each camera in a batch.
  
  This class utilizes `NDCMultinomialRaysampler` which allows to either
  randomly sample rays from an input foreground saliency mask
  (`RenderSamplingMode.MASK_SAMPLE`), or on a rectangular image grid
  (`RenderSamplingMode.FULL_GRID`). The sampling mode can be set separately
  for training and evaluation by setting `self.sampling_mode_training`
  and `self.sampling_mode_training` accordingly.
  
  The class allows to adjust the sampling points along rays by overwriting the
  `AbstractMaskRaySampler._get_min_max_depth_bounds` function which returns
  the near/far planes (`min_depth`/`max_depth`) `NDCMultinomialRaysampler`.
  
  Settings:
      image_width: The horizontal size of the image grid.
      image_height: The vertical size of the image grid.
      sampling_mode_training: The ray sampling mode for training. This should be a str
          option from the RenderSamplingMode Enum
      sampling_mode_evaluation: Same as above but for evaluation.
      n_pts_per_ray_training: The number of points sampled along each ray during training.
      n_pts_per_ray_evaluation: The number of points sampled along each ray during evaluation.
      n_rays_per_image_sampled_from_mask: The amount of rays to be sampled from the image
          grid. Given a batch of image grids, this many is sampled from each.
          `n_rays_per_image_sampled_from_mask` and `n_rays_total_training` cannot both be
          defined.
      n_rays_total_training: (optional) How many rays in total to sample from the entire
          batch of provided image grid. The result is as if `n_rays_total_training`
          cameras/image grids were sampled with replacement from the cameras / image grids
          provided and for every camera one ray was sampled.
          `n_rays_per_image_sampled_from_mask` and `n_rays_total_training` cannot both be
          defined, to use you have to set `n_rays_per_image` to None.
          Used only for EvaluationMode.TRAINING.
      stratified_point_sampling_training: if set, performs stratified random sampling
          along the ray; otherwise takes ray points at deterministic offsets.
      stratified_point_sampling_evaluation: Same as above but for evaluation.
      cast_ray_bundle_as_cone: If True, the sampling will generate the bins and radii
          attribute of ImplicitronRayBundle. The `bins` contain the z-coordinate
          (=depth) of each ray in world units and are of shape
          `(batch_size, n_rays_per_image, n_pts_per_ray_training/evaluation + 1)`
          while `lengths` is equal to the midpoint of the bins:
          (0.5 * (bins[..., 1:] + bins[..., :-1]).
          If False, `bins` is None, `radii` is None and `lengths` contains
          the z-coordinate (=depth) of each ray in world units and are of shape
          `(batch_size, n_rays_per_image, n_pts_per_ray_training/evaluation)`
  
  Raises:
      TypeError: if cast_ray_bundle_as_cone is set to True and n_rays_total_training
          is not None will result in an error. HeterogeneousRayBundle is
          not supported for conical frustum computation yet.
code: def __post_init__(self):
      if (self.n_rays_per_image_sampled_from_mask is not None) and (
          self.n_rays_total_training is not None
      ):
          raise ValueError(
              "Cannot both define n_rays_total_training and "
              "n_rays_per_image_sampled_from_mask."
          )
  
      self._sampling_mode = {
          EvaluationMode.TRAINING: RenderSamplingMode(
              self.sampling_mode_training
          ),
          EvaluationMode.EVALUATION: RenderSamplingMode(
              self.sampling_mode_evaluation
          ),
      }
  
      n_pts_per_ray_training = (
          self.n_pts_per_ray_training + 1
          if self.cast_ray_bundle_as_cone
          else self.n_pts_per_ray_training
      )
      n_pts_per_ray_evaluation = (
          self.n_pts_per_ray_evaluation + 1
          if self.cast_ray_bundle_as_cone
          else self.n_pts_per_ray_evaluation
      )
      self._training_raysampler = NDCMultinomialRaysampler(
          image_width=self.image_width,
          image_height=self.image_height,
          n_pts_per_ray=n_pts_per_ray_training,
          min_depth=0.0,
          max_depth=0.0,
          n_rays_per_image=self.n_rays_per_image_sampled_from_mask
          if self._sampling_mode[EvaluationMode.TRAINING]
          == RenderSamplingMode.MASK_SAMPLE
          else None,
          n_rays_total=self.n_rays_total_training,
          unit_directions=True,
          stratified_sampling=self.stratified_point_sampling_training,
      )
  
      self._evaluation_raysampler = NDCMultinomialRaysampler(
          image_width=self.image_width,
          image_height=self.image_height,
          n_pts_per_ray=n_pts_per_ray_evaluation,
          min_depth=0.0,
          max_depth=0.0,
          n_rays_per_image=self.n_rays_per_image_sampled_from_mask
          if self._sampling_mode[EvaluationMode.EVALUATION]
          == RenderSamplingMode.MASK_SAMPLE
          else None,
          unit_directions=True,
          stratified_sampling=self.stratified_point_sampling_evaluation,
      )
  
      max_y, min_y = (
          self._training_raysampler.max_y,
          self._training_raysampler.min_y,
      )
      max_x, min_x = (
          self._training_raysampler.max_x,
          self._training_raysampler.min_x,
      )
      self.pixel_height: float = (max_y - min_y) / (
          self.image_height - 1
      )
      self.pixel_width: float = (max_x - min_x) / (self.image_width - 1)
  
imports: from typing import Optional, Tuple
  import torch
  from pytorch3d.implicitron.tools import camera_utils
  from pytorch3d.implicitron.tools.config import registry, ReplaceableBase
  from pytorch3d.renderer import NDCMultinomialRaysampler
  from pytorch3d.renderer.cameras import CamerasBase
  from pytorch3d.renderer.implicit.utils import HeterogeneousRayBundle
  from .base import EvaluationMode, ImplicitronRayBundle, RenderSamplingMode
label_desc: Use image node_id 1 for calling the AbstractMaskRaySampler obj's underlying member method code with example usage: obj.__post_init__() without return types