class_docstr: Bar tracking with a dynamic Bayesian network (DBN) approximated by a
  Hidden Markov Model (HMM).
  
  Parameters
  ----------
  beats_per_bar : int or list
      Number of beats per bar to be modeled. Can be either a single number
      or a list or array with bar lengths (in beats).
  observation_weight : int, optional
      Weight for the downbeat activations.
  meter_change_prob : float, optional
      Probability to change meter at bar boundaries.
  
  Examples
  --------
  Create a DBNBarTrackingProcessor. The returned array represents the
  positions of the beats and their position inside the bar. The position
  inside the bar follows the natural counting and starts at 1.
  
  The number of beats per bar which should be modelled must be given, all
  other parameters (e.g. probability to change the meter at bar boundaries)
  are optional but must have the same length as `beats_per_bar`.
  
  >>> proc = DBNBarTrackingProcessor(beats_per_bar=[3, 4])
  >>> proc  # doctest: +ELLIPSIS
  <madmom.features.downbeats.DBNBarTrackingProcessor object at 0x...>
  
  Call this DBNDownBeatTrackingProcessor with beat positions and downbeat
  activation function returned by RNNBarProcessor to obtain the positions.
  
  >>> beats = np.loadtxt('tests/data/detections/sample.dbn_beat_tracker.txt')
  >>> act = RNNBarProcessor()(('tests/data/audio/sample.wav', beats))
  >>> proc(act)  # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
  array([[0.1 , 1. ],
         [0.45, 2. ],
         [0.8 , 3. ],
         [1.12, 1. ],
         [1.48, 2. ],
         [1.8 , 3. ],
         [2.15, 1. ],
         [2.49, 2. ]])
class_docstr_tok: ["Bar","tracking","with","a","dynamic","Bayesian","network","(","DBN",")","approximated","by","a","Hidden","Markov","Model","(","HMM",")",".","Parameters","--","--","--","--","--","beats_per_bar",":","int","or","list","Number","of","beats","per","bar","to","be","modeled",".","Can","be","either","a","single","number","or","a","list","or","array","with","bar","lengths","(","in","beats",")",".","observation_weight",":","int",",","optional","Weight","for","the","downbeat","activations",".","meter_change_prob",":","float",",","optional","Probability","to","change","meter","at","bar","boundaries",".","Examples","--","--","--","--","Create","a","DBNBarTrackingProcessor",".","The","returned","array","represents","the","positions","of","the","beats","and","their","position","inside","the","bar",".","The","position","inside","the","bar","follows","the","natural","counting","and","starts","at","1",".","The","number","of","beats","per","bar","which","should","be","modelled","must","be","given",",","all","other","parameters","(","e.g",".","probability","to","change","the","meter","at","bar","boundaries",")","are","optional","but","must","have","the","same","length","as","`","beats_per_bar","`",".",">",">",">","proc","=","DBNBarTrackingProcessor","(","beats_per_bar=","[","3",",","4","]",")",">",">",">","proc","#","doctest",":","+ELLIPSIS","<","madmom.features.downbeats.DBNBarTrackingProcessor","object","at","0x","...",">","Call","this","DBNDownBeatTrackingProcessor","with","beat","positions","and","downbeat","activation","function","returned","by","RNNBarProcessor","to","obtain","the","positions",".",">",">",">","beats","=","np.loadtxt","(","'tests\/data\/detections\/sample.dbn_beat_tracker.txt","'",")",">",">",">","act","=","RNNBarProcessor","(",")","(","(","'tests\/data\/audio\/sample.wav","'",",","beats",")",")",">",">",">","proc","(","act",")","#","doctest",":","+ELLIPSIS","+NORMALIZE_WHITESPACE","array","(","[","[","0.1",",","1",".","]",",","[","0.45",",","2",".","]",",","[","0.8",",","3",".","]",",","[","1.12",",","1",".","]",",","[","1.48",",","2",".","]",",","[","1.8",",","3",".","]",",","[","2.15",",","1",".","]",",","[","2.49",",","2",".","]","]",")"]
docstr: Detect downbeats from the given beats and activation function with
  Viterbi decoding.
  
  Parameters
  ----------
  data : numpy array, shape (num_beats, 2)
      Array containing beat positions (first column) and corresponding
      downbeat activations (second column).
  
  Returns
  -------
  numpy array, shape (num_beats, 2)
      Decoded (down-)beat positions and beat numbers.
  
  Notes
  -----
  The position of the last beat is not decoded, but rather extrapolated
  based on the position and meter of the second to last beat.
code: def process(self, data, **kwargs):
      """
      Detect downbeats from the given beats and activation function with
      Viterbi decoding.
  
      Parameters
      ----------
      data : numpy array, shape (num_beats, 2)
          Array containing beat positions (first column) and corresponding
          downbeat activations (second column).
  
      Returns
      -------
      numpy array, shape (num_beats, 2)
          Decoded (down-)beat positions and beat numbers.
  
      Notes
      -----
      The position of the last beat is not decoded, but rather extrapolated
      based on the position and meter of the second to last beat.
  
      """
      # pylint: disable=unused-argument
      beats = data[:, 0]
      activations = data[:, 1]
      # remove unsynchronised (usually the last) values
      activations = activations[:-1]
      # TODO: expand to generic extrapolation of values? e.g.:
      #       activations = activations[~np.isnan(activations)]
      # Viterbi decoding
      path, _ = self.hmm.viterbi(activations)
      # get the position inside the bar
      position = self.st.state_positions[path]
      # the beat numbers are the counters + 1 at the transition points
      beat_numbers = position.astype(int) + 1
      # add the last beat (which has no activation function value)
      meter = self.beats_per_bar[self.st.state_patterns[path[-1]]]
      last_beat_number = np.mod(beat_numbers[-1], meter) + 1
      beat_numbers = np.append(beat_numbers, last_beat_number)
      # return beats and their beat numbers
      return np.vstack((beats, beat_numbers)).T
  
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 2 for calling the DBNBarTrackingProcessor obj's underlying member method code with example usage: obj.process(data) and returns: np