code: def calc_class_counts(
      all_preds, all_labels, metric_type="group", span_type="exact"
  ):
      """
      Calculate per-class TP, FP and FN counts.
  
      :param all_preds, all_labels: A list of list of groups. If metric_type ==
      "joint", the groups should in be joint form with an "entities" key
      :param metric_type: A string, either "group" or "joint"
      :param span_type: A string, one of "exact", "token", "overlap", "superset"
      :return class_counts: A dictionary of the form:
          {
              "class1": {
                  "true_positives: 1,
                  "false_positives: 1,
                  "false_negatives": 1,
              }
              .
              .
              .
              "class_n: {...},
          }
      """
      if metric_type == "joint":
          assert (
              "entities" in all_preds[0][0]
              and "entities" in all_labels[0][0]
          ), (
              "To calculate joint metrics, groups must in in joint group format! "
              "Use create_joint_groups() to produce groups in joint group format."
          )
  
      count_fn = get_count_fn(metric_type, span_type)
      classes = _get_unique_classes(all_preds, all_labels)
      class_counts = {
          cls: {
              "true_positives": 0,
              "false_positives": 0,
              "false_negatives": 0,
          }
          for cls in classes
      }
  
      for doc_preds, doc_labels in zip(all_preds, all_labels):
          if doc_preds and doc_labels:
              assign_idxs, doc_counts = calc_group_assignment(
                  doc_preds, doc_labels, count_fn
              )
              for pred_idx, label_idx in assign_idxs:
                  TP, FP, FN = doc_counts[pred_idx][label_idx]
                  pred_label = doc_preds[pred_idx]["label"]
                  label_label = doc_labels[label_idx]["label"]
  
                  class_counts[label_label]["true_positives"] += TP
                  # False positives attributed to the predicted label
                  class_counts[pred_label]["false_positives"] += FP
                  # False negatives attributed to the ground truth label
                  class_counts[label_label]["false_negatives"] += FN
  
          pred_idxs, label_idxs = list(zip(*assign_idxs))
          if len(doc_preds) > len(doc_labels):
              missing_idxs = set(range(len(doc_preds))) - set(pred_idxs)
              extra_groups = doc_preds
              # All examples in extra pred groups are false positives
              add_count = "false_positives"
          elif len(doc_labels) > len(doc_preds):
              missing_idxs = set(range(len(doc_labels))) - set(
                  label_idxs
              )
              extra_groups = doc_labels
              # All examples in extra label groups are false negatives
              add_count = "false_negatives"
          if len(doc_labels) != len(doc_preds):
              for idx in missing_idxs:
                  group = extra_groups[idx]
                  if span_type == "token" and metric_type == "group":
                      group_len = len(
                          _convert_to_token_list(group["spans"])
                      )
                  elif span_type == "token" and metric_type == "joint":
                      group_len = len(
                          _convert_to_token_list(group["entities"])
                      )
                  else:
                      group_len = 1
                  class_counts[group["label"]][add_count] += group_len
  
      return class_counts
  
imports: from copy import deepcopy
  from collections import namedtuple
  import numpy
  from scipy.optimize import linear_sum_assignment
  from finetune.util.metrics import _convert_to_token_list, _get_unique_classes, calc_precision, calc_recall, calc_f1
label_desc: Use image node_id 11 for calling a global function with example usage: calc_class_counts(all_preds, all_labels, metric_type, span_type) and returns: class_counts