docstr: Sample the ray in a given range and run secant on rays which have sign transition 
docstr_tok: ["Sample","the","ray","in","a","given","range","and","run","secant","on","rays","which","have","sign","transition"]
code: def ray_sampler(
      self,
      sdf,
      cam_loc,
      object_mask,
      ray_directions,
      sampler_min_max,
      sampler_mask,
  ):
      """Sample the ray in a given range and run secant on rays which have sign transition"""
  
      batch_size, num_pixels, _ = ray_directions.shape
      n_total_pxl = batch_size * num_pixels
      sampler_pts = torch.zeros(n_total_pxl, 3).cuda().float()
      sampler_dists = torch.zeros(n_total_pxl).cuda().float()
  
      intervals_dist = (
          torch.linspace(0, 1, steps=self.n_steps).cuda().view(1, 1, -1)
      )
  
      pts_intervals = sampler_min_max[:, :, 0].unsqueeze(
          -1
      ) + intervals_dist * (
          sampler_min_max[:, :, 1] - sampler_min_max[:, :, 0]
      ).unsqueeze(
          -1
      )
      points = cam_loc.reshape(
          batch_size, 1, 1, 3
      ) + pts_intervals.unsqueeze(-1) * ray_directions.unsqueeze(2)
  
      # Get the non convergent rays
      mask_intersect_idx = torch.nonzero(sampler_mask).flatten()
      points = points.reshape((-1, self.n_steps, 3))[sampler_mask, :, :]
      pts_intervals = pts_intervals.reshape((-1, self.n_steps))[
          sampler_mask
      ]
  
      sdf_val_all = []
      for pnts in torch.split(points.reshape(-1, 3), 100000, dim=0):
          sdf_val_all.append(sdf(pnts))
      sdf_val = torch.cat(sdf_val_all).reshape(-1, self.n_steps)
  
      tmp = torch.sign(sdf_val) * torch.arange(
          self.n_steps, 0, -1
      ).cuda().float().reshape(
          (1, self.n_steps)
      )  # Force argmin to return the first min value
      sampler_pts_ind = torch.argmin(tmp, -1)
      sampler_pts[mask_intersect_idx] = points[
          torch.arange(points.shape[0]), sampler_pts_ind, :
      ]
      sampler_dists[mask_intersect_idx] = pts_intervals[
          torch.arange(pts_intervals.shape[0]), sampler_pts_ind
      ]
  
      true_surface_pts = object_mask[sampler_mask]
      net_surface_pts = (
          sdf_val[torch.arange(sdf_val.shape[0]), sampler_pts_ind] < 0
      )
  
      # take points with minimal SDF value for P_out pixels
      p_out_mask = ~(true_surface_pts & net_surface_pts)
      n_p_out = p_out_mask.sum()
      if n_p_out > 0:
          out_pts_idx = torch.argmin(sdf_val[p_out_mask, :], -1)
          sampler_pts[mask_intersect_idx[p_out_mask]] = points[
              p_out_mask, :, :
          ][torch.arange(n_p_out), out_pts_idx, :]
          sampler_dists[mask_intersect_idx[p_out_mask]] = pts_intervals[
              p_out_mask, :
          ][torch.arange(n_p_out), out_pts_idx]
  
      # Get Network object mask
      sampler_net_obj_mask = sampler_mask.clone()
      sampler_net_obj_mask[mask_intersect_idx[~net_surface_pts]] = False
  
      # Run Secant method
      secant_pts = (
          net_surface_pts & true_surface_pts
          if self.training
          else net_surface_pts
      )
      n_secant_pts = secant_pts.sum()
      if n_secant_pts > 0:
          # Get secant z predictions
          z_high = pts_intervals[
              torch.arange(pts_intervals.shape[0]), sampler_pts_ind
          ][secant_pts]
          sdf_high = sdf_val[
              torch.arange(sdf_val.shape[0]), sampler_pts_ind
          ][secant_pts]
          z_low = pts_intervals[secant_pts][
              torch.arange(n_secant_pts),
              sampler_pts_ind[secant_pts] - 1,
          ]
          sdf_low = sdf_val[secant_pts][
              torch.arange(n_secant_pts),
              sampler_pts_ind[secant_pts] - 1,
          ]
          cam_loc_secant = (
              cam_loc.unsqueeze(1)
              .repeat(1, num_pixels, 1)
              .reshape((-1, 3))[mask_intersect_idx[secant_pts]]
          )
          ray_directions_secant = ray_directions.reshape((-1, 3))[
              mask_intersect_idx[secant_pts]
          ]
          z_pred_secant = self.secant(
              sdf_low,
              sdf_high,
              z_low,
              z_high,
              cam_loc_secant,
              ray_directions_secant,
              sdf,
          )
  
          # Get points
          sampler_pts[mask_intersect_idx[secant_pts]] = (
              cam_loc_secant
              + z_pred_secant.unsqueeze(-1) * ray_directions_secant
          )
          sampler_dists[mask_intersect_idx[secant_pts]] = z_pred_secant
  
      return sampler_pts, sampler_net_obj_mask, sampler_dists
  
file_path: insightface/reconstruction/PBIDR/code/model/ray_tracing.py
imports: import torch
  import torch.nn
  from utils import rend_util
label_desc: Use image node_id 4 for calling the RayTracing obj's underlying member method code with example usage: obj.ray_sampler(sdf, cam_loc, object_mask, ray_directions, sampler_min_max, sampler_mask) and returns: sampler_pts,  sampler_net_obj_mask,  sampler_dists