code: def sample_ray(self, rays_o, rays_d, is_train=True, N_samples=-1):
      N_samples = N_samples if N_samples > 0 else self.nSamples
      stepsize = self.stepSize
      near, far = self.near_far
      vec = torch.where(
          rays_d == 0, torch.full_like(rays_d, 1e-6), rays_d
      )
      rate_a = (self.aabb[1] - rays_o) / vec
      rate_b = (self.aabb[0] - rays_o) / vec
      t_min = (
          torch.minimum(rate_a, rate_b)
          .amax(-1)
          .clamp(min=near, max=far)
      )
  
      rng = torch.arange(N_samples)[None].float()
      if is_train:
          rng = rng.repeat(rays_d.shape[-2], 1)
          rng += torch.rand_like(rng[:, [0]])
      step = stepsize * rng.to(rays_o.device)
      interpx = t_min[..., None] + step
  
      rays_pts = (
          rays_o[..., None, :]
          + rays_d[..., None, :] * interpx[..., None]
      )
      mask_outbbox = (
          (self.aabb[0] > rays_pts) | (rays_pts > self.aabb[1])
      ).any(dim=-1)
  
      return rays_pts, interpx, ~mask_outbbox
  
imports: import torch
  import torch.nn
  import torch.nn.functional
  from .sh import eval_sh_bases
  import numpy
  import time
label_desc: Use image node_id 14 for calling the TensorBase obj's underlying member method code with example usage: obj.sample_ray(rays_o, rays_d, is_train, N_samples) and returns: rays_pts,  interpx,  unknown