code: def ray_to_importance_samples(
      ray_batch,
      z_vals,
      weights,
      importance_samples_per_ray,
      device="cpu",
      including_old=True,
      append_t=None,
  ):
      rays_o, rays_d = ray_batch["origin"].to(device), ray_batch[
          "direction"
      ].to(device)
  
      z_vals_mid = 0.5 * (z_vals[..., 1:] + z_vals[..., :-1])
      z_samples = sample_pdf(
          z_vals_mid,
          weights[..., 1:-1],
          importance_samples_per_ray,
          det=True,
          device=device,
      )
      z_samples = z_samples.detach()
      if including_old:
          z_vals, _ = torch.sort(torch.cat([z_vals, z_samples], -1), -1)
      else:
          z_vals = z_samples
      pts = (
          rays_o[..., None, :]
          + rays_d[..., None, :] * z_vals[..., :, None]
      )
      total_samples = pts.shape[1]
      dirs = torch.stack([rays_d] * total_samples, axis=1)
      if append_t is not None:
          pts = torch.cat([pts, append_t.to(device)], dim=-1)
      return pts, dirs, z_vals
  
file_path: ml-neuman/utils/ray_utils.py
imports: import numpy
  import torch
  import igl
  from geometry.pcd_projector import PointCloudProjectorNp
  from utils.constant import DEFAULT_GEO_THRESH, PERTURB_EPSILON
label_desc: Use image node_id 8 for calling a global function with example usage: ray_to_importance_samples(ray_batch, z_vals, weights, importance_samples_per_ray, device, including_old, append_t) and returns: pts,  dirs,  z_vals