class_docstr: Pattern tracking with a dynamic Bayesian network (DBN) approximated by a
  Hidden Markov Model (HMM).
  
  Parameters
  ----------
  pattern_files : list
      List of files with the patterns (including the fitted GMMs and
      information about the number of beats).
  min_bpm : list, optional
      Minimum tempi used for pattern tracking [bpm].
  max_bpm : list, optional
      Maximum tempi used for pattern tracking [bpm].
  num_tempi : int or list, optional
      Number of tempi to model; if set, limit the number of tempi and use a
      log spacings, otherwise a linear spacings.
  transition_lambda : float or list, optional
      Lambdas for the exponential tempo change distributions (higher values
      prefer constant tempi from one beat to the next one).
  fps : float, optional
      Frames per second.
  
  Notes
  -----
  `min_bpm`, `max_bpm`, `num_tempo_states`, and `transition_lambda` must
  contain as many items as rhythmic patterns are modeled (i.e. length of
  `pattern_files`).
  If a single value is given for `num_tempo_states` and `transition_lambda`,
  this value is used for all rhythmic patterns.
  
  Instead of the originally proposed state space and transition model for
  the DBN [1]_, the more efficient version proposed in [2]_ is used.
  
  References
  ----------
  .. [1] Florian Krebs, Sebastian Böck and Gerhard Widmer,
         "Rhythmic Pattern Modeling for Beat and Downbeat Tracking in Musical
         Audio",
         Proceedings of the 15th International Society for Music Information
         Retrieval Conference (ISMIR), 2013.
  .. [2] Florian Krebs, Sebastian Böck and Gerhard Widmer,
         "An Efficient State Space Model for Joint Tempo and Meter Tracking",
         Proceedings of the 16th International Society for Music Information
         Retrieval Conference (ISMIR), 2015.
  
  Examples
  --------
  Create a PatternTrackingProcessor from the given pattern files. These
  pattern files include fitted GMMs for the observation model of the HMM.
  The returned array represents the positions of the beats and their position
  inside the bar. The position is given in seconds, thus the expected
  sampling rate is needed. The position inside the bar follows the natural
  counting and starts at 1.
  
  >>> from madmom.models import PATTERNS_BALLROOM
  >>> proc = PatternTrackingProcessor(PATTERNS_BALLROOM, fps=50)
  >>> proc  # doctest: +ELLIPSIS
  <madmom.features.downbeats.PatternTrackingProcessor object at 0x...>
  
  Call this PatternTrackingProcessor with a multi-band spectrogram to obtain
  the beat and downbeat positions. The parameters of the spectrogram have to
  correspond to those used to fit the GMMs.
  
  >>> from madmom.audio.spectrogram import LogarithmicSpectrogramProcessor, SpectrogramDifferenceProcessor, MultiBandSpectrogramProcessor
  >>> from madmom.processors import SequentialProcessor
  >>> log = LogarithmicSpectrogramProcessor()
  >>> diff = SpectrogramDifferenceProcessor(positive_diffs=True)
  >>> mb = MultiBandSpectrogramProcessor(crossover_frequencies=[270])
  >>> pre_proc = SequentialProcessor([log, diff, mb])
  
  >>> act = pre_proc('tests/data/audio/sample.wav')
  >>> proc(act)  # doctest: +ELLIPSIS
  array([[0.82, 4.  ],
         [1.78, 1.  ],
         ...,
         [3.7 , 3.  ],
         [4.66, 4.  ]])
class_docstr_tok: ["Pattern","tracking","with","a","dynamic","Bayesian","network","(","DBN",")","approximated","by","a","Hidden","Markov","Model","(","HMM",")",".","Parameters","--","--","--","--","--","pattern_files",":","list","List","of","files","with","the","patterns","(","including","the","fitted","GMMs","and","information","about","the","number","of","beats",")",".","min_bpm",":","list",",","optional","Minimum","tempi","used","for","pattern","tracking","[","bpm","]",".","max_bpm",":","list",",","optional","Maximum","tempi","used","for","pattern","tracking","[","bpm","]",".","num_tempi",":","int","or","list",",","optional","Number","of","tempi","to","model",";","if","set",",","limit","the","number","of","tempi","and","use","a","log","spacings",",","otherwise","a","linear","spacings",".","transition_lambda",":","float","or","list",",","optional","Lambdas","for","the","exponential","tempo","change","distributions","(","higher","values","prefer","constant","tempi","from","one","beat","to","the","next","one",")",".","fps",":","float",",","optional","Frames","per","second",".","Notes","--","--","-","`","min_bpm","`",",","`","max_bpm","`",",","`","num_tempo_states","`",",","and","`","transition_lambda","`","must","contain","as","many","items","as","rhythmic","patterns","are","modeled","(","i.e",".","length","of","`","pattern_files","`",")",".","If","a","single","value","is","given","for","`","num_tempo_states","`","and","`","transition_lambda","`",",","this","value","is","used","for","all","rhythmic","patterns",".","Instead","of","the","originally","proposed","state","space","and","transition","model","for","the","DBN","[","1","]","_",",","the","more","efficient","version","proposed","in","[","2","]","_","is","used",".","References","--","--","--","--","--","..","[","1","]","Florian","Krebs",",","Sebastian","B\u00f6ck","and","Gerhard","Widmer",",","``","Rhythmic","Pattern","Modeling","for","Beat","and","Downbeat","Tracking","in","Musical","Audio","''",",","Proceedings","of","the","15th","International","Society","for","Music","Information","Retrieval","Conference","(","ISMIR",")",",","2013",".","..","[","2","]","Florian","Krebs",",","Sebastian","B\u00f6ck","and","Gerhard","Widmer",",","``","An","Efficient","State","Space","Model","for","Joint","Tempo","and","Meter","Tracking","''",",","Proceedings","of","the","16th","International","Society","for","Music","Information","Retrieval","Conference","(","ISMIR",")",",","2015",".","Examples","--","--","--","--","Create","a","PatternTrackingProcessor","from","the","given","pattern","files",".","These","pattern","files","include","fitted","GMMs","for","the","observation","model","of","the","HMM",".","The","returned","array","represents","the","positions","of","the","beats","and","their","position","inside","the","bar",".","The","position","is","given","in","seconds",",","thus","the","expected","sampling","rate","is","needed",".","The","position","inside","the","bar","follows","the","natural","counting","and","starts","at","1",".",">",">",">","from","madmom.models","import","PATTERNS_BALLROOM",">",">",">","proc","=","PatternTrackingProcessor","(","PATTERNS_BALLROOM",",","fps=50",")",">",">",">","proc","#","doctest",":","+ELLIPSIS","<","madmom.features.downbeats.PatternTrackingProcessor","object","at","0x","...",">","Call","this","PatternTrackingProcessor","with","a","multi-band","spectrogram","to","obtain","the","beat","and","downbeat","positions",".","The","parameters","of","the","spectrogram","have","to","correspond","to","those","used","to","fit","the","GMMs",".",">",">",">","from","madmom.audio.spectrogram","import","LogarithmicSpectrogramProcessor",",","SpectrogramDifferenceProcessor",",","MultiBandSpectrogramProcessor",">",">",">","from","madmom.processors","import","SequentialProcessor",">",">",">","log","=","LogarithmicSpectrogramProcessor","(",")",">",">",">","diff","=","SpectrogramDifferenceProcessor","(","positive_diffs=True",")",">",">",">","mb","=","MultiBandSpectrogramProcessor","(","crossover_frequencies=","[","270","]",")",">",">",">","pre_proc","=","SequentialProcessor","(","[","log",",","diff",",","mb","]",")",">",">",">","act","=","pre_proc","(","'tests\/data\/audio\/sample.wav","'",")",">",">",">","proc","(","act",")","#","doctest",":","+ELLIPSIS","array","(","[","[","0.82",",","4",".","]",",","[","1.78",",","1",".","]",",","...",",","[","3.7",",","3",".","]",",","[","4.66",",","4",".","]","]",")"]
code: def __init__(
      self,
      pattern_files,
      min_bpm=MIN_BPM,
      max_bpm=MAX_BPM,
      num_tempi=NUM_TEMPI,
      transition_lambda=TRANSITION_LAMBDA,
      fps=None,
      **kwargs,
  ):
      # pylint: disable=unused-argument
      # pylint: disable=no-name-in-module
      import pickle
  
      min_bpm = np.array(min_bpm, ndmin=1)
      max_bpm = np.array(max_bpm, ndmin=1)
      num_tempi = np.array(num_tempi, ndmin=1)
      transition_lambda = np.array(transition_lambda, ndmin=1)
      # make sure arguments are given for each pattern (expand if needed)
      if len(min_bpm) != len(pattern_files):
          min_bpm = np.repeat(min_bpm, len(pattern_files))
      if len(max_bpm) != len(pattern_files):
          max_bpm = np.repeat(max_bpm, len(pattern_files))
      if len(num_tempi) != len(pattern_files):
          num_tempi = np.repeat(num_tempi, len(pattern_files))
      if len(transition_lambda) != len(pattern_files):
          transition_lambda = np.repeat(
              transition_lambda, len(pattern_files)
          )
      # check if all lists have the same length
      if not (
          len(min_bpm)
          == len(max_bpm)
          == len(num_tempi)
          == len(transition_lambda)
          == len(pattern_files)
      ):
          raise ValueError(
              "`min_bpm`, `max_bpm`, `num_tempi` and "
              "`transition_lambda` must have the same length "
              "as number of patterns."
          )
      # save some variables
      self.fps = fps
      self.num_beats = []
      # convert timing information to construct a state space
      min_interval = 60.0 * self.fps / np.asarray(max_bpm)
      max_interval = 60.0 * self.fps / np.asarray(min_bpm)
      # collect beat/bar state spaces, transition models, and GMMs
      state_spaces = []
      transition_models = []
      gmms = []
      # check that at least one pattern is given
      if not pattern_files:
          raise ValueError(
              "at least one rhythmical pattern must be given."
          )
      # load the patterns
      for p, pattern_file in enumerate(pattern_files):
          with open(pattern_file, "rb") as f:
              # Python 2 and 3 behave differently
              try:
                  # Python 3
                  pattern = pickle.load(f, encoding="latin1")
              except TypeError:
                  # Python 2 doesn't have/need the encoding
                  pattern = pickle.load(f)
          # get the fitted GMMs and number of beats
          gmms.append(pattern["gmms"])
          num_beats = pattern["num_beats"]
          self.num_beats.append(num_beats)
          # model each rhythmic pattern as a bar
          state_space = BarStateSpace(
              num_beats, min_interval[p], max_interval[p], num_tempi[p]
          )
          transition_model = BarTransitionModel(
              state_space, transition_lambda[p]
          )
          state_spaces.append(state_space)
          transition_models.append(transition_model)
      # create multi pattern state space, transition and observation model
      self.st = MultiPatternStateSpace(state_spaces)
      self.tm = MultiPatternTransitionModel(transition_models)
      self.om = GMMPatternTrackingObservationModel(gmms, self.st)
      # instantiate a HMM
      self.hmm = HiddenMarkovModel(self.tm, self.om, None)
  
imports: from __future__ import absolute_import, division, print_function
  import sys
  import warnings
  import numpy
  from .beats import threshold_activations
  from .beats_hmm import BarStateSpace, BarTransitionModel, GMMPatternTrackingObservationModel, MultiPatternStateSpace, MultiPatternTransitionModel, RNNBeatTrackingObservationModel, RNNDownBeatTrackingObservationModel
  from ..ml.hmm import HiddenMarkovModel
  from ..processors import ParallelProcessor, Processor, SequentialProcessor
  from ..utils import string_types
label_desc: Use image node_id 1 to create a new PatternTrackingProcessor object from inherited base classes: Processor with example: obj = PatternTrackingProcessor(pattern_files, min_bpm, max_bpm, num_tempi, transition_lambda, fps)