code: def evaluate_dense_captions(
      predicted_segments,
      gt_segments,
      predicted_captions,
      gt_captions,
      splits,
      keys,
      iou_thresholds=(0.3, 0.5, 0.7, 0.9),
      soda=False,
      tmponly=False,
  ):
      """Compute both the P/R and NLP metrics for the given predictions.
  
      This is the same as calling the above functions, however it aggregates the
      metrics generated by evaluate_detections and evaluate_caption_scores across
      a list of inputs.
  
      Args:
       predicted_segments: A list of numpy arrays, of shape [K x 2]
         containing the predicted segment intervals.
       gt_segments: A list of numpy arrays, of shape [S x 2]
         containing the ground truth segment intervals.
       predicted_captions: A list of lists, of string of shape [K]
         containing the corresponding K predicted captions.
       gt_captions: A list of lists, of strings of shape [S] containing the
         corresponding S ground truth captions.
       splits: A list of numpy arrays, of shape [S] indicating
         the annotation set (1/2 for ActivityNet).
       keys: A list of strings
       iou_thresholds: A list of thresholds for IOU to average over.
       soda: Whether to compute SODA or not.
       tmponly: In this case do not compute captioning metrics.
  
      Returns:
        (precision, recall): The precision and recall of the detections averaged
        over the IOU thresholds.
        metrics: The NLP metrics of the predictions averaged over the IOU
          thresholds.
      """
  
      # Handle if these are lists, or single samples.
      assert all(
          [
              isinstance(p, list)
              for p in [predicted_segments, gt_segments]
          ]
      )
      # Only construct the scorers once, so that we don't have any issues with
      # overhead when running multiple evaluations.
      scorers = {
          "CIDER": Cider(),
          "METEOR": Meteor(),
      }
      tokenizer = PTBTokenizer()
      metric_tiou = collections.defaultdict(list)
      gts = {str(threshold): {} for threshold in iou_thresholds}
      preds = {str(threshold): {} for threshold in iou_thresholds}
      vid2isx = {str(threshold): {} for threshold in iou_thresholds}
  
      assert (
          len(predicted_segments)
          == len(gt_segments)
          == len(predicted_captions)
          == len(gt_captions)
          == len(splits)
      )
  
      # Compute matches
      for pred_seg, gt_seg, pred_cap, gt_cap, key in zip(
          predicted_segments,
          gt_segments,
          predicted_captions,
          gt_captions,
          keys,
      ):
          gt, pred, isxes = match_captions(
              pred_seg, gt_seg, pred_cap, gt_cap, iou_thresholds
          )
          # Flatten for tokenization
          for threshold in iou_thresholds:
              for k, v in gt[str(threshold)].items():
                  gts[str(threshold)][key + "_" + str(k)] = v
              for k, v in pred[str(threshold)].items():
                  preds[str(threshold)][key + "_" + str(k)] = v
              vid2isx[str(threshold)][key] = isxes[str(threshold)]
  
      # Call tokenization once
      for threshold in iou_thresholds:
          gts[str(threshold)] = tokenizer.tokenize(gts[str(threshold)])
          preds[str(threshold)] = tokenizer.tokenize(
              preds[str(threshold)]
          )
  
      # Tokenize also the original lists for SODA computation
      predicted_captions_dict = (
          {  # pylint: disable=g-complex-comprehension
              keys[i] + "_" + str(j): [{"caption": p}]
              for i, ps in enumerate(predicted_captions)
              for j, p in enumerate(ps)
          }
      )
      gt_captions_dict = {  # pylint: disable=g-complex-comprehension
          keys[i] + "_" + str(j): [{"caption": g}]
          for i, gs in enumerate(gt_captions)
          for j, g in enumerate(gs)
      }
      predicted_captions_tok = tokenizer.tokenize(
          predicted_captions_dict
      )
      gt_captions_tok = tokenizer.tokenize(gt_captions_dict)
      predicted_captions_res = []
      gt_captions_res = []
      for i, ps in enumerate(predicted_captions):
          res = [
              predicted_captions_tok[keys[i] + "_" + str(j)][0]
              for j, _ in enumerate(ps)
          ]
          predicted_captions_res.append(res)
      for i, gs in enumerate(gt_captions):
          res = [
              gt_captions_tok[keys[i] + "_" + str(j)][0]
              for j, _ in enumerate(gs)
          ]
          gt_captions_res.append(res)
  
      # Reshape
      final_gts = {str(threshold): {} for threshold in iou_thresholds}
      final_preds = {str(threshold): {} for threshold in iou_thresholds}
      for threshold in iou_thresholds:
          for key in keys:
              final_gts[str(threshold)][key] = {
                  str(k): gts[str(threshold)][key + "_" + str(k)]
                  for k in vid2isx[str(threshold)][key]
              }
              final_preds[str(threshold)][key] = {
                  str(k): preds[str(threshold)][key + "_" + str(k)]
                  for k in vid2isx[str(threshold)][key]
              }
  
      # Compute dense video captioning metrics at the video level
      for i, key in enumerate(keys):
          pred_filt_i = {
              str(t): final_preds[str(t)][key] for t in iou_thresholds
          }
          gt_filt_i = {
              str(t): final_gts[str(t)][key] for t in iou_thresholds
          }
          res = evaluate_single_dense_captions(
              predicted_segments[i],
              gt_segments[i],
              pred_filt_i,
              gt_filt_i,
              predicted_captions_res[i],
              gt_captions_res[i],
              splits[i],
              key,
              iou_thresholds,
              soda,
              tmponly,
              scorers,
          )
          for met in res:
              metric_tiou[met].append(res[met])
          if soda:
              if "SODA_c_1" not in res:
                  metric_tiou["SODA_c_1"].append(-1)
              if "SODA_c_2" not in res:
                  metric_tiou["SODA_c_2"].append(-1)
  
      logging.info("Closing Meteor")
      with scorers["METEOR"].lock:
          scorers["METEOR"].meteor_p.stdin.close()
          scorers["METEOR"].meteor_p.stdout.close()
          scorers["METEOR"].meteor_p.kill()
          scorers["METEOR"].meteor_p.wait()
      del scorers
  
      return metric_tiou
  
imports: import collections
  import logging
  import random
  import re
  import string
  import numpy
  from scenic.projects.vid2seq.metrics.cider import Cider
  from scenic.projects.vid2seq.metrics.meteor import Meteor
  from scenic.projects.vid2seq.metrics.ptbtokenizer import PTBTokenizer
label_desc: Use image node_id 10 for calling a global function with example usage: evaluate_dense_captions(predicted_segments, gt_segments, predicted_captions, gt_captions, splits, keys, iou_thresholds, soda, tmponly) and returns: metric_tiou