code: def cal_target_metadata_wer(
      manifest: str,
      target: str,
      meta_cfg: DictConfig,
      eval_metric: str = "wer",
  ) -> dict:
      """
      Caculating number of samples (samples), number of words/characters/tokens (tokens),
      wer/cer, insertion error rate (ins_rate), deletion error rate (del_rate), substitution error rate (sub_rate) of the group/slot of target metadata.
  
      The group could be [female, male] or slot group like [0-2s, 2-5s, >5s audios]
  
  
      Args:
          manifest (str): Filepath of the generated manifest which contains prediction and eval result for each samples.
          target (str): Target metadata. Execute the target metadata if field presents in manifest.
              such as 'duration', 'speaker', 'emotion', etc.
          meta_cfg (DictConfig): Config for calculating group eval_metric for the target metadata.
          eval_metric: (str): Supported evaluation metrics. Currently support 'wer' and 'cer'.
  
      Return:
          ret (dict): Generated dictionary containing all results regarding the target metadata.
      """
      if eval_metric not in ["wer", "cer"]:
          raise ValueError(
              "Currently support wer and cer as eval_metric. Please implement it in cal_target_metadata_wer if using different eval_metric"
          )
  
      wer_per_class = {}
      with open(manifest, "r") as fp:
          for line in fp:
              sample = json.loads(line)
              if target in sample:
                  target_class = sample[target]
                  if target_class not in wer_per_class:
                      wer_per_class[target_class] = {
                          "samples": 0,
                          "tokens": 0,
                          "errors": 0,
                          "inss": 0,
                          "dels": 0,
                          "subs": 0,
                      }
                  wer_per_class[target_class]["samples"] += 1
  
                  tokens = sample["tokens"]
                  wer_per_class[target_class]["tokens"] += tokens
                  wer_per_class[target_class]["errors"] += (
                      tokens * sample[eval_metric]
                  )
                  wer_per_class[target_class]["inss"] += (
                      tokens * sample["ins_rate"]
                  )
                  wer_per_class[target_class]["dels"] += (
                      tokens * sample["del_rate"]
                  )
                  wer_per_class[target_class]["subs"] += (
                      tokens * sample["sub_rate"]
                  )
  
      if len(wer_per_class) > 0:
          res_wer_per_class = {}
          for target_class in wer_per_class:
              res_wer_per_class[target_class] = {}
              res_wer_per_class[target_class][
                  "samples"
              ] = wer_per_class[target_class]["samples"]
              res_wer_per_class[target_class][eval_metric] = (
                  wer_per_class[target_class]["errors"]
                  / wer_per_class[target_class]["tokens"]
              )
              res_wer_per_class[target_class]["tokens"] = wer_per_class[
                  target_class
              ]["tokens"]
              res_wer_per_class[target_class]["ins_rate"] = (
                  wer_per_class[target_class]["inss"]
                  / wer_per_class[target_class]["tokens"]
              )
              res_wer_per_class[target_class]["del_rate"] = (
                  wer_per_class[target_class]["dels"]
                  / wer_per_class[target_class]["tokens"]
              )
              res_wer_per_class[target_class]["sub_rate"] = (
                  wer_per_class[target_class]["subs"]
                  / wer_per_class[target_class]["tokens"]
              )
      else:
          logging.info(
              f"metadata '{target}' does not present in manifest. Skipping! "
          )
          return None
  
      values = ["samples", "tokens", "errors", "inss", "dels", "subs"]
      slot_wer = {}
      if "slot" in meta_cfg and meta_cfg.slot:
          for target_class in wer_per_class:
              for s in meta_cfg.slot:
                  if isinstance(s[0], float) or isinstance(s[0], int):
                      if s[0] <= target_class < s[1]:
                          slot_key = "slot-" + ",".join(
                              str(i) for i in s
                          )
                          if slot_key not in slot_wer:
                              slot_wer[slot_key] = {
                                  "samples": 0,
                                  "tokens": 0,
                                  "errors": 0,
                                  "inss": 0,
                                  "dels": 0,
                                  "subs": 0,
                              }
  
                          for v in values:
                              slot_wer[slot_key][v] += wer_per_class[
                                  target_class
                              ][v]
                          break
  
                  elif isinstance(s[0], str):
                      if target_class in s:
                          slot_key = "slot-" + ",".join(s)
                          if slot_key not in slot_wer:
                              slot_wer[slot_key] = {
                                  "samples": 0,
                                  "tokens": 0,
                                  "errors": 0,
                                  "inss": 0,
                                  "dels": 0,
                                  "subs": 0,
                              }
  
                          for v in values:
                              slot_wer[slot_key][v] += wer_per_class[
                                  target_class
                              ][v]
                          break
                  else:
                      raise ValueError(
                          "Current only support target metadata belongs to numeric or string "
                      )
  
          for slot_key in slot_wer:
              slot_wer[slot_key][eval_metric] = (
                  slot_wer[slot_key]["errors"]
                  / slot_wer[slot_key]["tokens"]
              )
              slot_wer[slot_key]["ins_rate"] = (
                  slot_wer[slot_key]["inss"]
                  / slot_wer[slot_key]["tokens"]
              )
              slot_wer[slot_key]["del_rate"] = (
                  slot_wer[slot_key]["dels"]
                  / slot_wer[slot_key]["tokens"]
              )
              slot_wer[slot_key]["sub_rate"] = (
                  slot_wer[slot_key]["subs"]
                  / slot_wer[slot_key]["tokens"]
              )
              slot_wer[slot_key].pop("errors")
              slot_wer[slot_key].pop("inss")
              slot_wer[slot_key].pop("dels")
              slot_wer[slot_key].pop("subs")
          res_wer_per_class.update(slot_wer)
  
      ret = None
      if meta_cfg.save_wer_per_class:
          ret = res_wer_per_class
      if (not meta_cfg.save_wer_per_class) and (
          "slot" in meta_cfg and meta_cfg.slot
      ):
          ret = slot_wer
      return ret
  
file_path: NeMo/tools/asr_evaluator/utils.py
imports: import json
  import subprocess
  import tempfile
  from pathlib import Path
  from typing import Tuple
  from omegaconf import DictConfig, OmegaConf, open_dict
  from nemo.utils import logging
label_desc: Use image node_id 4 for calling a global function with example usage: cal_target_metadata_wer(manifest, target, meta_cfg, eval_metric) and returns: ret, None