def process(self, inputs, outputs):
        """
        Process the pair of inputs and outputs.
        If they contain batches, the pairs can be consumed one-by-one using `zip`:

        .. code-block:: python

            for input_, output in zip(inputs, outputs):
                # do evaluation on single input/output pair
                ...

        Args:
            inputs (list): the inputs that's used to call the model.
            outputs (list): the return value of `model(inputs)`
        """
        for input_per_image, pred_per_image in zip(inputs, outputs):
            pred_classes = pred_per_image['instances'].pred_classes
            pred_boxes = pred_per_image['instances'].pred_boxes.tensor
            pred_boxes3d = pred_per_image['instances'].pred_boxes3d
            # pred_boxes3d = pred_per_image['instances'].pred_box3d_as_vec
            scores = pred_per_image['instances'].scores
            scores_3d = pred_per_image['instances'].scores_3d

            file_name = input_per_image['file_name']
            image_id = input_per_image['image_id']

            # predictions
            predictions_kitti = []
            # for class_id, box3d_as_vec, score, box2d in zip(pred_classes, pred_boxes3d, scores, pred_boxes):
            for class_id, box3d, score_3d, box2d, score in zip(
                pred_classes, pred_boxes3d, scores_3d, pred_boxes, scores
            ):
                # class_name = self._metadata.thing_classes[class_id]
                class_name = self._class_names[class_id]

                box3d_as_vec = box3d.vectorize()[0].cpu().numpy()

                pred = OrderedDict(
                    category_id=int(class_id),  # COCO instances
                    category=class_name,
                    bbox3d=box3d_as_vec.tolist(),
                    # COCO instances uses "XYWH". Aligning with it as much as possible
                    bbox=BoxMode.convert(box2d.tolist(), from_mode=BoxMode.XYXY_ABS, to_mode=BoxMode.XYWH_ABS),
                    score=float(score),
                    score_3d=float(score_3d),
                    file_name=file_name,
                    image_id=image_id  # COCO instances
                )
                self._predictions_as_json.append(pred)

                # prediction in KITTI format.
                W, L, H, x, y, z, rot_y, alpha = convert_3d_box_to_kitti(box3d)
                l, t, r, b = box2d.tolist()
                predictions_kitti.append([
                    class_name, -1, -1, alpha, l, t, r, b, H, W, L, x, y, z, rot_y,
                    float(score_3d)
                ])
            self._predictions_kitti_format.append(pd.DataFrame(predictions_kitti))

            # groundtruths
            gt_dataset_dict = self._dataset_dicts[file_name]

            if "annotations" not in gt_dataset_dict:
                # test set
                continue

            raw_kitti_annotations = gt_dataset_dict.get('raw_kitti_annotations', None)
            if raw_kitti_annotations is not None:
                self._groundtruth_kitti_format.append(raw_kitti_annotations)
            else:
                # Otherwise, use the same format as predictions (minus 'score').
                groundtruth_kitti = []
                for anno in gt_dataset_dict['annotations']:
                    # class_name = self._metadata.thing_classes[anno['category_id']]
                    class_name = self._class_names[anno['category_id']]

                    # groundtruth in KITTI format.
                    box2d = BoxMode.convert(anno['bbox'], from_mode=anno['bbox_mode'], to_mode=BoxMode.XYXY_ABS)
                    box3d = GenericBoxes3D.from_vectors([anno['bbox3d']])
                    W, L, H, x, y, z, rot_y, alpha = convert_3d_box_to_kitti(box3d)
                    l, t, r, b = box2d
                    groundtruth_kitti.append([class_name, -1, -1, alpha, l, t, r, b, H, W, L, x, y, z, rot_y])
                self._groundtruth_kitti_format.append(pd.DataFrame(groundtruth_kitti))

        Process the pair of inputs and outputs.
        If they contain batches, the pairs can be consumed one-by-one using `zip`:

        .. code-block:: python

            for input_, output in zip(inputs, outputs):
                # do evaluation on single input/output pair
                ...

        Args:
            inputs (list): the inputs that's used to call the model.
            outputs (list): the return value of `model(inputs)`
        
tridet/evaluators/kitti_3d_evaluator.py