def generate_results(
        self,
        samples,
        matches,
        eval_key=None,
        classes=None,
        missing=None,
        progress=None,
    ):
        """Generates aggregate evaluation results for the samples.

        If ``self.config.compute_mAP`` is True, this method performs
        ActivityNet-style evaluation as in :meth:`evaluate` to generate
        precision and recall sweeps over the range of IoU thresholds in
        ``self.config.iou_threshs``. In this case, an
        :class:`ActivityNetDetectionResults` instance is returned that can
        compute mAP and PR curves.

        Args:
            samples: a :class:`fiftyone.core.collections.SampleCollection`
            matches: a list of
                ``(gt_label, pred_label, iou, pred_confidence, gt_id, pred_id)``
                matches. Either label can be ``None`` to indicate an unmatched
                segment
            eval_key (None): the evaluation key for this evaluation
            classes (None): the list of possible classes. If not provided, the
                observed ground truth/predicted labels are used for results
                purposes
            missing (None): a missing label string. Any unmatched segments are
                given this label for results purposes
            progress (None): whether to render a progress bar (True/False), use
                the default value ``fiftyone.config.show_progress_bars``
                (None), or a progress callback function to invoke instead

        Returns:
            a :class:`DetectionResults`
        """
        if not self.config.compute_mAP:
            return DetectionResults(
                samples,
                self.config,
                eval_key,
                matches,
                classes=classes,
                missing=missing,
                backend=self,
            )

        gt_field = self.config.gt_field
        pred_field = self.config.pred_field

        _samples = samples.select_fields([gt_field, pred_field])

        iou_threshs = self.config.iou_threshs
        thresh_matches = {t: {} for t in iou_threshs}

        if classes is None:
            _classes = set()
        else:
            _classes = None

        # IoU sweep
        logger.info("Performing IoU sweep...")
        for sample in _samples.iter_samples(progress=progress):
            # Don't edit user's data during sweep
            gts = _copy_labels(sample[self.gt_field])
            preds = _copy_labels(sample[self.pred_field])

            video_matches = _activitynet_evaluation_iou_sweep(
                gts, preds, self.config
            )

            for t, t_matches in video_matches.items():
                for match in t_matches:
                    gt_label = match[0]
                    pred_label = match[1]

                    if _classes is not None:
                        _classes.add(gt_label)
                        _classes.add(pred_label)

                    c = gt_label if gt_label is not None else pred_label

                    if c not in thresh_matches[t]:
                        thresh_matches[t][c] = {
                            "tp": [],
                            "fp": [],
                            "num_gt": 0,
                        }

                    if gt_label == pred_label:
                        thresh_matches[t][c]["tp"].append(match)
                    elif pred_label:
                        thresh_matches[t][c]["fp"].append(match)

                    if gt_label:
                        thresh_matches[t][c]["num_gt"] += 1

        if _classes is not None:
            _classes.discard(None)
            classes = sorted(_classes)

        # Compute precision-recall array
        # https://github.com/activitynet/ActivityNet/blob/master/Evaluation/eval_detection.py
        num_threshs = len(iou_threshs)
        num_classes = len(classes)
        precision = -np.ones((num_threshs, num_classes, 101))
        thresholds = -np.ones((num_threshs, num_classes, 101))
        classwise_AP = -np.ones((num_threshs, num_classes))
        recall = np.linspace(0, 1, 101)
        for t in thresh_matches.keys():
            for c in thresh_matches[t].keys():
                tp = thresh_matches[t][c]["tp"]
                fp = thresh_matches[t][c]["fp"]
                num_gt = thresh_matches[t][c]["num_gt"]
                if num_gt == 0:
                    continue

                tp_fp = np.array([1] * len(tp) + [0] * len(fp))
                confs = np.array([m[3] for m in tp] + [m[3] for m in fp])
                if None in confs:
                    raise ValueError(
                        "All predicted segments must have their `confidence` "
                        "attribute populated in order to compute "
                        "precision-recall curves"
                    )
                inds = np.argsort(-confs, kind="mergesort")
                tp_fp = tp_fp[inds]
                confs = confs[inds]

                tp_sum = np.cumsum(tp_fp).astype(dtype=float)
                total = np.arange(1, len(tp_fp) + 1).astype(dtype=float)

                pre = tp_sum / total
                rec = tp_sum / num_gt

                for i in range(len(pre) - 1, 0, -1):
                    if pre[i] > pre[i - 1]:
                        pre[i - 1] = pre[i]

                # ActivityNet mAP is calculated without interpolated precision
                # This slightly differs from COCO evaluation
                mprec = np.hstack([[0], pre, [0]])
                mrec = np.hstack([[0], rec, [1]])
                idx = np.where(mrec[1::] != mrec[0:-1])[0] + 1
                ap = np.sum((mrec[idx] - mrec[idx - 1]) * mprec[idx])

                q = np.zeros(101)
                tr = np.zeros(101)

                # Interpolate precision values for PR curve plotting purposes
                inds = np.searchsorted(rec, recall, side="left")
                try:
                    for ri, pi in enumerate(inds):
                        q[ri] = pre[pi]
                        tr[ri] = confs[pi]
                except:
                    pass

                precision[iou_threshs.index(t)][classes.index(c)] = q
                thresholds[iou_threshs.index(t)][classes.index(c)] = tr
                classwise_AP[iou_threshs.index(t)][classes.index(c)] = ap

        return ActivityNetDetectionResults(
            samples,
            self.config,
            eval_key,
            matches,
            precision,
            recall,
            classwise_AP,
            iou_threshs,
            classes,
            thresholds=thresholds,
            missing=missing,
            backend=self,
        )
Generates aggregate evaluation results for the samples.

        If ``self.config.compute_mAP`` is True, this method performs
        ActivityNet-style evaluation as in :meth:`evaluate` to generate
        precision and recall sweeps over the range of IoU thresholds in
        ``self.config.iou_threshs``. In this case, an
        :class:`ActivityNetDetectionResults` instance is returned that can
        compute mAP and PR curves.

        Args:
            samples: a :class:`fiftyone.core.collections.SampleCollection`
            matches: a list of
                ``(gt_label, pred_label, iou, pred_confidence, gt_id, pred_id)``
                matches. Either label can be ``None`` to indicate an unmatched
                segment
            eval_key (None): the evaluation key for this evaluation
            classes (None): the list of possible classes. If not provided, the
                observed ground truth/predicted labels are used for results
                purposes
            missing (None): a missing label string. Any unmatched segments are
                given this label for results purposes
            progress (None): whether to render a progress bar (True/False), use
                the default value ``fiftyone.config.show_progress_bars``
                (None), or a progress callback function to invoke instead

        Returns:
            a :class:`DetectionResults`
        
fiftyone/utils/eval/activitynet.py