class_docstr: Tempo evaluation class.
  
  Parameters
  ----------
  detections : str, list of tuples or numpy array
      Detected tempi (rows) and their strengths (columns).
      If a file name is given, load them from this file.
  annotations : str, list or numpy array
      Annotated ground truth tempi (rows) and their strengths (columns).
      If a file name is given, load them from this file.
  tolerance : float, optional
      Evaluation tolerance (max. allowed deviation).
  double : bool, optional
      Include double and half tempo variations.
  triple : bool, optional
      Include triple and third tempo variations.
  sort : bool, optional
      Sort the tempi by their strengths (descending order).
  max_len : bool, optional
      Evaluate at most `max_len` tempi.
  name : str, optional
      Name of the evaluation to be displayed.
  
  Notes
  -----
  For P-Score, the number of detected tempi will be limited to the number
  of annotations (if not further limited by `max_len`).
  For Accuracy 1 & 2 only one detected tempo is used. Depending on `sort`,
  this can be either the first or the strongest one.
code: def __init__(
      self,
      detections,
      annotations,
      tolerance=TOLERANCE,
      double=DOUBLE,
      triple=TRIPLE,
      sort=True,
      max_len=None,
      name=None,
      **kwargs,
  ):
      # pylint: disable=unused-argument
      # convert to numpy array
      detections = np.array(detections, dtype=float, ndmin=1)
      annotations = np.array(annotations, dtype=float, ndmin=1)
      if sort and detections.ndim == 2:
          detections = sort_tempo(detections)
      if sort and annotations.ndim == 2:
          annotations = sort_tempo(annotations)
      # truncate detections and detections to the same length
      if max_len:
          detections = detections[:max_len]
          annotations = annotations[:max_len]
      # evaluate P-score with all tempo annotations
      self.pscore, self.any, self.all = tempo_evaluation(
          detections, annotations, tolerance
      )
      # evaluate accuracies only with the strongest/first tempo
      # Note: the strengths are irrelevant or acc1 & acc2 calculation
      #       the accuracies correspond to either any or all tempi
      # evaluate acc1 (i.e. any of the annotated tempi)
      self.acc1 = tempo_evaluation(
          detections[:1], annotations[:1], tolerance
      )[1]
      # evaluate acc2 like acc1 but include double/half & triple/third tempi
      try:
          tempi = annotations[:1, 0].copy()
      except IndexError:
          tempi = annotations[:1].copy()
      tempi_ = tempi.copy()
      if double:
          tempi_ = np.hstack((tempi_, tempi * 2.0, tempi / 2.0))
      if triple:
          tempi_ = np.hstack((tempi_, tempi * 3.0, tempi / 3.0))
      self.acc2 = tempo_evaluation(detections[:1], tempi_, tolerance)[1]
      # save the name
      self.name = name
  
imports: from __future__ import absolute_import, division, print_function
  import warnings
  import numpy
  from .None import EvaluationMixin, MeanEvaluation, evaluation_io
  from ..io import load_tempo
label_desc: Use image node_id 1 to create a new TempoEvaluation object from inherited base classes: EvaluationMixin with example: obj = TempoEvaluation(detections, annotations, tolerance, double, triple, sort, max_len, name)