//  [python]
def render_lidar_eval(model, lidar_depends,testsavedir, ndc, render_kwargs):
    lidar_dists, lidar_origins,lidar_rays_directions,lidar_labels = lidar_depends
    segs = []
    depths = []
    import os
    for i in tqdm(range(len(lidar_origins))):
        rays_d= torch.tensor(lidar_rays_directions[i]).float()
        rays_o = torch.broadcast_to(torch.tensor(lidar_origins[i]).reshape(1,3),
                            rays_d.shape).float() 
        viewdirs = rays_d/torch.linalg.norm(rays_d,dim=-1,keepdim=True)
        # directions= lidar_rays_directions[i]
        # origin,directions = lidar2globals[i]
        keys = ['rgb_marched', 'depth', 'alphainv_last', 'segmentation']
       
        render_result_chunks = [
            {k: v for k, v in model(ro, rd, vd, **render_kwargs).items() if k in keys}
            for ro, rd, vd in zip(rays_o.split(1024, 0), rays_d.split(1024, 0), viewdirs.split(1024, 0))
        ]
        render_result = {
            k: torch.cat([ret[k] for ret in render_result_chunks]).reshape(rays_d.shape[0],-1)
            for k in render_result_chunks[0].keys()
        }
        depth = render_result['depth'].cpu().numpy()
        # if 'segmentation' in render_result.keys():
        seg = render_result['segmentation']
        logits_2_label = lambda x: torch.argmax(x, dim=-1)
        seg_ = logits_2_label(seg).cpu().numpy()
        segs.append(seg_)

        depths.append(depth)
        def get_points_corrds(rays,depth):
            origins =rays[0]
            directions =rays[1]
            points = origins + torch.tensor(depth)*directions#/directions[:,-2:-1]
            return points

        points = get_points_corrds((rays_o,rays_d),depth)

        # np.save(os.path.join(testsavedir, 'points_{:03d}.npy'.format(i)),points.detach().cpu().numpy())
        if i <len(lidar_origins) - len(lidar_labels):
            np.save(os.path.join(testsavedir, 'depth_{:03d}.npy'.format(i)),depth)
            np.save(os.path.join(testsavedir, 'gt_depth_{:03d}.npy'.format(i)),lidar_dists[i])
        # only save key frame semantic labels
        if i >= len(lidar_origins) - len(lidar_labels):
            np.save(os.path.join(testsavedir, 'points_semantic_{:03d}.npy'.format(i)),seg_)
            np.save(os.path.join(testsavedir, 'gt_points_semantic_{:03d}.npy'.format(i)),lidar_labels[i-len(lidar_origins) + len(lidar_labels)])

    
    import os
    import yaml
    with open('/SSD_DISK/users/zhangjunge/Scenes/6cam_scene1_revision/NeRFlidar_label_v7.yaml', 'r') as stream:
        # to 8 classes    
        semkittiyaml = yaml.safe_load(stream)
    learning_map = semkittiyaml['learning_map']
    points_labels = []
    for idx, label in enumerate(lidar_labels):
        points_label = np.vectorize(learning_map.__getitem__)(segs[idx+len(lidar_origins) - len(lidar_labels)])
        points_labels.append(points_label)

    # points_labels = np.concatenate(points_labels)
    # lidar_labels = np.concatenate(lidar_labels)
    from miou_cal import eval_miou
    per_class_iou = eval_miou(points_labels,lidar_labels)
    with open(os.path.join(testsavedir,'iou.txt'),'w') as f:
        for idx in range(len(per_class_iou)):
            f.write(f'{per_class_iou[idx]}\n')
        f.write(f'miou is {per_class_iou.mean()}')

    return None